From 44f280af42396a72ab48712c09ae9d62fa1efb09 Mon Sep 17 00:00:00 2001 From: MickWang <1244134672@qq.com> Date: Thu, 9 Jan 2020 05:01:49 +0800 Subject: [PATCH] first commit (#1) * first commit * update readme --- .babelrc | 36 + .gitignore | 22 + .npmignore | 3 + CONTRIBUTING.md | 36 + LICENSE | 2 +- README.md | 129 + jest.config.js | 7 + package-lock.json | 11307 ++++++++++++++++ package.json | 99 + src/account.ts | 211 + src/claim/attestNotifyEvent.ts | 91 + src/claim/claim.ts | 308 + src/claim/claimProof.ts | 46 + src/claim/index.ts | 20 + src/claim/message.ts | 409 + src/common/bigInt.ts | 64 + src/common/fixed64.ts | 57 + src/common/int128.ts | 192 + src/common/uint160.ts | 57 + src/common/uint256.ts | 58 + src/consts.ts | 107 + src/crypto/AnonymousCredential.ts | 873 ++ src/crypto/CurveLabel.ts | 71 + src/crypto/Ecies.ts | 251 + src/crypto/Key.ts | 189 + src/crypto/KeyType.ts | 70 + src/crypto/PrivateKey.ts | 310 + src/crypto/PrivateKeyFactory.ts | 84 + src/crypto/PublicKey.ts | 221 + src/crypto/Signature.ts | 124 + src/crypto/SignatureScheme.ts | 94 + src/crypto/address.ts | 197 + src/crypto/index.ts | 30 + src/crypto/signable.ts | 32 + src/error.ts | 43 + src/global.d.ts | 32 + src/identity.ts | 228 + src/index.ts | 167 + src/merkle.ts | 173 + src/neocore/InvocationTransaction.ts | 38 + src/neocore/NeoRpc.ts | 48 + src/neocore/Program.ts | 54 + src/neocore/SmartContract.ts | 52 + src/neocore/TransactionInput.ts | 61 + src/neocore/TransactionNeo.ts | 132 + src/neocore/TransactionOutput.ts | 49 + src/neocore/index.ts | 25 + src/network/rest/restClient.ts | 372 + src/network/rest/urlConsts.ts | 44 + src/network/rpc/rpcClient.ts | 331 + src/network/websocket/deferred.ts | 43 + src/network/websocket/websocketBuilder.ts | 287 + src/network/websocket/websocketClient.ts | 357 + src/network/websocket/websocketSender.ts | 109 + src/scrypt.ts | 402 + src/smartcontract/abi/abiFunction.ts | 71 + src/smartcontract/abi/abiInfo.ts | 57 + .../abi/nativeVmParamsBuilder.ts | 129 + src/smartcontract/abi/parameter.ts | 76 + src/smartcontract/abi/struct.ts | 38 + src/smartcontract/data/attestClaim.avm | 1 + src/smartcontract/data/attestClaim.ts | 69 + src/smartcontract/data/idContract.abi.ts | 308 + src/smartcontract/nativevm/assetTxBuilder.ts | 349 + .../nativevm/authContractTxBuilder.ts | 269 + .../nativevm/governanceContractTxBuilder.ts | 783 ++ .../nativevm/idContractTxBuilder.ts | 477 + src/smartcontract/nativevm/token.ts | 216 + .../neovm/attestClaimTxBuilder.ts | 97 + src/smartcontract/neovm/nep5TxBuilder.ts | 122 + src/smartcontract/neovm/oep4TxBuilder.ts | 236 + src/smartcontract/neovm/oep5TxBuilder.ts | 222 + src/smartcontract/neovm/oep8TxBuilder.ts | 325 + src/transaction/ddo.ts | 145 + src/transaction/opcode.ts | 155 + src/transaction/payload/deployCode.ts | 120 + src/transaction/payload/invokeCode.ts | 144 + src/transaction/payload/payload.ts | 23 + src/transaction/program.ts | 263 + src/transaction/scriptBuilder.ts | 449 + src/transaction/transaction.ts | 255 + src/transaction/transactionBuilder.ts | 534 + src/transaction/transactionUtils.ts | 59 + src/transaction/transfer.ts | 27 + src/transaction/txAttribute.ts | 67 + src/transaction/txSender.ts | 67 + src/transaction/txSignature.ts | 147 + src/transaction/vmcode.ts | 49 + src/utils.ts | 558 + src/wallet.ts | 162 + test/abiInfo.test.ts | 72 + test/account.test.ts | 90 + test/anonymous.test.ts | 108 + test/attest.test.ts | 125 + test/bip44.test.ts | 62 + test/claim.test.ts | 173 + test/core.test.ts | 77 + test/ddo.test.ts | 33 + test/deployCodeTx.test.ts | 115 + test/ecdsa.crypto.test.ts | 59 + test/ecies.test.ts | 149 + test/governanceAuthorization.ts | 220 + test/hdkey.test.ts | 36 + test/idContract.test.ts | 253 + test/identity.test.ts | 100 + test/merkle.test.ts | 96 + test/oep4.test.ts | 181 + test/oep5.test.ts | 204 + test/oep8.test.ts | 245 + test/pri.test.ts | 37 + test/restClient.test.ts | 207 + test/rpcClient.test.ts | 197 + test/scParams.test.ts | 172 + test/scrypt.test.ts | 120 + test/sm.crypto.test.ts | 80 + test/smartcontract_abi_parameter.test.ts | 52 + test/transactionBuilder.test.ts | 265 + test/transfer.sign.test.ts | 49 + test/transfer.test.ts | 206 + test/transferParse.test.ts | 54 + test/wallet.test.ts | 69 + test/wasm/helloworld.wasm | Bin 0 -> 15242 bytes test/wasm/wasmContract.test.ts | 217 + test/wasm/wasm_demo_optimized.wasm | Bin 0 -> 19987 bytes test/websocket.test.ts | 283 + tsconfig.json | 63 + tslint.json | 31 + typedoc.js | 20 + webpack.config.js | 53 + yarn.lock | 6762 +++++++++ 130 files changed, 37257 insertions(+), 1 deletion(-) create mode 100644 .babelrc create mode 100644 .gitignore create mode 100644 .npmignore create mode 100644 CONTRIBUTING.md create mode 100644 README.md create mode 100644 jest.config.js create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 src/account.ts create mode 100644 src/claim/attestNotifyEvent.ts create mode 100644 src/claim/claim.ts create mode 100644 src/claim/claimProof.ts create mode 100644 src/claim/index.ts create mode 100644 src/claim/message.ts create mode 100644 src/common/bigInt.ts create mode 100644 src/common/fixed64.ts create mode 100644 src/common/int128.ts create mode 100644 src/common/uint160.ts create mode 100644 src/common/uint256.ts create mode 100644 src/consts.ts create mode 100644 src/crypto/AnonymousCredential.ts create mode 100644 src/crypto/CurveLabel.ts create mode 100644 src/crypto/Ecies.ts create mode 100644 src/crypto/Key.ts create mode 100644 src/crypto/KeyType.ts create mode 100644 src/crypto/PrivateKey.ts create mode 100644 src/crypto/PrivateKeyFactory.ts create mode 100644 src/crypto/PublicKey.ts create mode 100644 src/crypto/Signature.ts create mode 100644 src/crypto/SignatureScheme.ts create mode 100644 src/crypto/address.ts create mode 100644 src/crypto/index.ts create mode 100644 src/crypto/signable.ts create mode 100644 src/error.ts create mode 100644 src/global.d.ts create mode 100644 src/identity.ts create mode 100644 src/index.ts create mode 100644 src/merkle.ts create mode 100644 src/neocore/InvocationTransaction.ts create mode 100644 src/neocore/NeoRpc.ts create mode 100644 src/neocore/Program.ts create mode 100644 src/neocore/SmartContract.ts create mode 100644 src/neocore/TransactionInput.ts create mode 100644 src/neocore/TransactionNeo.ts create mode 100644 src/neocore/TransactionOutput.ts create mode 100644 src/neocore/index.ts create mode 100644 src/network/rest/restClient.ts create mode 100644 src/network/rest/urlConsts.ts create mode 100644 src/network/rpc/rpcClient.ts create mode 100644 src/network/websocket/deferred.ts create mode 100644 src/network/websocket/websocketBuilder.ts create mode 100644 src/network/websocket/websocketClient.ts create mode 100644 src/network/websocket/websocketSender.ts create mode 100644 src/scrypt.ts create mode 100644 src/smartcontract/abi/abiFunction.ts create mode 100644 src/smartcontract/abi/abiInfo.ts create mode 100644 src/smartcontract/abi/nativeVmParamsBuilder.ts create mode 100644 src/smartcontract/abi/parameter.ts create mode 100644 src/smartcontract/abi/struct.ts create mode 100755 src/smartcontract/data/attestClaim.avm create mode 100755 src/smartcontract/data/attestClaim.ts create mode 100644 src/smartcontract/data/idContract.abi.ts create mode 100644 src/smartcontract/nativevm/assetTxBuilder.ts create mode 100644 src/smartcontract/nativevm/authContractTxBuilder.ts create mode 100644 src/smartcontract/nativevm/governanceContractTxBuilder.ts create mode 100644 src/smartcontract/nativevm/idContractTxBuilder.ts create mode 100644 src/smartcontract/nativevm/token.ts create mode 100644 src/smartcontract/neovm/attestClaimTxBuilder.ts create mode 100644 src/smartcontract/neovm/nep5TxBuilder.ts create mode 100644 src/smartcontract/neovm/oep4TxBuilder.ts create mode 100644 src/smartcontract/neovm/oep5TxBuilder.ts create mode 100644 src/smartcontract/neovm/oep8TxBuilder.ts create mode 100644 src/transaction/ddo.ts create mode 100644 src/transaction/opcode.ts create mode 100644 src/transaction/payload/deployCode.ts create mode 100644 src/transaction/payload/invokeCode.ts create mode 100644 src/transaction/payload/payload.ts create mode 100644 src/transaction/program.ts create mode 100644 src/transaction/scriptBuilder.ts create mode 100644 src/transaction/transaction.ts create mode 100644 src/transaction/transactionBuilder.ts create mode 100644 src/transaction/transactionUtils.ts create mode 100644 src/transaction/transfer.ts create mode 100644 src/transaction/txAttribute.ts create mode 100644 src/transaction/txSender.ts create mode 100644 src/transaction/txSignature.ts create mode 100644 src/transaction/vmcode.ts create mode 100644 src/utils.ts create mode 100644 src/wallet.ts create mode 100644 test/abiInfo.test.ts create mode 100644 test/account.test.ts create mode 100644 test/anonymous.test.ts create mode 100644 test/attest.test.ts create mode 100644 test/bip44.test.ts create mode 100644 test/claim.test.ts create mode 100644 test/core.test.ts create mode 100644 test/ddo.test.ts create mode 100644 test/deployCodeTx.test.ts create mode 100644 test/ecdsa.crypto.test.ts create mode 100644 test/ecies.test.ts create mode 100644 test/governanceAuthorization.ts create mode 100644 test/hdkey.test.ts create mode 100644 test/idContract.test.ts create mode 100644 test/identity.test.ts create mode 100644 test/merkle.test.ts create mode 100644 test/oep4.test.ts create mode 100644 test/oep5.test.ts create mode 100644 test/oep8.test.ts create mode 100644 test/pri.test.ts create mode 100644 test/restClient.test.ts create mode 100644 test/rpcClient.test.ts create mode 100644 test/scParams.test.ts create mode 100644 test/scrypt.test.ts create mode 100644 test/sm.crypto.test.ts create mode 100644 test/smartcontract_abi_parameter.test.ts create mode 100644 test/transactionBuilder.test.ts create mode 100644 test/transfer.sign.test.ts create mode 100644 test/transfer.test.ts create mode 100644 test/transferParse.test.ts create mode 100644 test/wallet.test.ts create mode 100644 test/wasm/helloworld.wasm create mode 100644 test/wasm/wasmContract.test.ts create mode 100644 test/wasm/wasm_demo_optimized.wasm create mode 100644 test/websocket.test.ts create mode 100644 tsconfig.json create mode 100644 tslint.json create mode 100644 typedoc.js create mode 100644 webpack.config.js create mode 100644 yarn.lock diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..29ff19e --- /dev/null +++ b/.babelrc @@ -0,0 +1,36 @@ +{ + "env": { + "development": { + "presets": [ + [ + "env", + { + "modules": false, + "targets": { + "chrome": 67 + } + } + ] + ], + "plugins": [ + "transform-object-rest-spread" + ] + }, + "production": { + "presets": [ + [ + "env", + { + "modules": false + } + ] + ], + "plugins": [ + "transform-object-rest-spread", + ["transform-runtime", { + "regenerator": true + }] + ] + } + } +} \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..e52049f --- /dev/null +++ b/.gitignore @@ -0,0 +1,22 @@ +node_modules +/.project +/.settings/ + + +/docs/_build/ +lib/ + +# Logs +*.log + +# Coverage +/.nyc_output +/coverage + +# IDE specific +/.vscode + +/.DS_Store +src/.DS_Store + +apidoc/ \ No newline at end of file diff --git a/.npmignore b/.npmignore new file mode 100644 index 0000000..07dada0 --- /dev/null +++ b/.npmignore @@ -0,0 +1,3 @@ +src/ +node_modules/ +tsconfig.json diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..6cb7db9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,36 @@ +Contributing +========================================= + +We welcome contributions. Please follow the guidelines when opening issues and contributing code to the repo. + +Contributing +------------ + +We follow the [fork-and-pull](https://stackoverflow.com/a/11582996/3830876) Git workflow: + + 1. **Fork** the repo on GitHub + 2. **Clone** it to your own machine + 3. **Commit** changes to your fork + 4. **Push** changes to your fork + 5. Submit a **Pull request** for review + +**NOTE:** Be sure to merge the latest changes before making a pull request! + +Pull Requests +------ +As outlined in Keavy McMinn's article ["How to write the perfect pull request"](https://github.blog/2015-01-21-how-to-write-the-perfect-pull-request/), you should include: + + 1. The purpose of the PR + 2. A brief overview of what you did + 3. Tag any issues that the PR relates to and [close issues with a keyword](https://help.github.com/en/articles/closing-issues-using-keywords) + 4. What kind of feedback you're looking for (if any) + 5. Tag individuals you want feedback from (if any) + +Issues +------ + +Feel free to submit issues and enhancement requests [here](https://github.com/ontio/DNA-ts-sdk/issues/new). Please consider [how to ask a good question](https://stackoverflow.com/help/how-to-ask) and take the time to research your issue before asking for help. + +Duplicate questions will be closed. + +Any unrelated comments or questions can be asked in the [DNA Discord](https://discordapp.com/invite/4TQujHj). diff --git a/LICENSE b/LICENSE index 0a04128..65c5ca8 100644 --- a/LICENSE +++ b/LICENSE @@ -1,7 +1,7 @@ GNU LESSER GENERAL PUBLIC LICENSE Version 3, 29 June 2007 - Copyright (C) 2007 Free Software Foundation, Inc. + Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. diff --git a/README.md b/README.md new file mode 100644 index 0000000..bc0e6ab --- /dev/null +++ b/README.md @@ -0,0 +1,129 @@ + +

DNA TypeScript SDK

+

Version V1.1.0

+ +- [Overview](#overview) +- [Installation](#installation) + - [Download Through npm/Yarn](#download-through-npmyarn) + - [Build from Source Code](#build-from-source-code) + - [Downloading](#downloading) + - [Compiling](#compiling) + - [Testing](#testing) + - [Use in Project](#use-in-project) + - [Import](#import) + - [Require](#require) + - [In the Browser](#in-the-browser) +- [Contributing](#contributing) +- [License](#license) + +## Overview + +This is the official DNA TypeScript SDK - a comprehensive library for developing with the DNA blockchain in both TypeScript and JavaScript. It currently supports management of wallets, digital identities and digital assets - as well as the deployment and invocation of smart contracts. + +## Installation + +### Download Through npm/Yarn + +```` +npm install 'dna-ts-sdk' --save +```` + +or + +``` +yarn add 'dna-ts-sdk' +``` + +### Build from Source Code + +#### Downloading + +``` +git clone 'https://github.com/DNAProject/DNA-ts-SDK.git' +``` + +Then install the dependencies with: + +``` +npm install +``` + +or + +``` +yarn +``` + +#### Compiling + +Compile the project with the: + +```` +npm run build:dev // or npm run build:prod +```` + +or + +``` +yarn run build:dev // or yarn run build:prod +``` + +This will create a compiled version of the SDK in the `lib` directory. + +#### Testing + +To run the tests in the `test` directory, use: + +``` +npm run test +``` + +or + +``` +yarn run test +``` + +### Use in Project + +#### Import + +Using `import` to include the modules from `'DNA-ts-sdk'`: + +``` +import {Wallet} from 'DNA-ts-sdk'; +var wallet = Wallet.create('test'); +``` + +#### Require + +Using `require` to include the modules from `'DNA-ts-sdk'`: + +```` +var DNA = require('DNA-ts-sdk'); +var wallet = DNA.Wallet.create('test'); +```` + +#### In the Browser + +To use in the browser you must use the compiled version (as listed above). +The `browser.js` file is located in the `lib` directory. +Include it into the project with a ` +```` + +Everything will be available under the `DNA` variable, just like in the `require` example above. + +``` +var wallet = DNA.Wallet.create('test'); +``` + +## Contributing + +Contributors are welcome to the `DNA-ts-sdk`. Before beginning, please take a look at our [contributing guidelines](CONTRIBUTING.md). You can open an issue by [clicking here](https://github.com/DNAProject/DNA-ts-sdk/issues/new). + +## License + +The DNA TypeScript SDK is availabl under the [LGPL-3.0 License](LICENSE). diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000..60b2c71 --- /dev/null +++ b/jest.config.js @@ -0,0 +1,7 @@ +module.exports = { + transform: { + "^.+\\.tsx?$": "ts-jest", + }, + testRegex: "(/__tests__/.*|(\\.|/)(test|spec))\\.(jsx?|tsx?)$", + moduleFileExtensions: ["ts", "tsx", "js", "jsx", "json", "node"], + }; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..76c6e8d --- /dev/null +++ b/package-lock.json @@ -0,0 +1,11307 @@ +{ + "name": "DNA-ts-sdk", + "version": "1.1.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0-beta.49.tgz", + "integrity": "sha1-vs2AVIJzREDJ0TfkbXc0DmTX9Rs=", + "dev": true, + "requires": { + "@babel/highlight": "7.0.0-beta.49" + } + }, + "@babel/highlight": { + "version": "7.0.0-beta.49", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0-beta.49.tgz", + "integrity": "sha1-lr3GtD4TSCASumaRsQGEktOWIsw=", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^3.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "@babel/runtime": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.6.3.tgz", + "integrity": "sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.2" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.13.3", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", + "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "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 + }, + "@ont-community/hdkey-secp256r1": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@ont-community/hdkey-secp256r1/-/hdkey-secp256r1-1.0.1.tgz", + "integrity": "sha512-DMWQkLqvmuTXHqxdihP7BBZR1LGbFzVbkZK/iDT3aGrxOnY8AsvXZSGw/3WsJMjpSvKbfhPm3Jpf2JiyuY2SwQ==", + "requires": { + "coinstring": "^2.0.0", + "elliptic": "^6.4.0", + "safe-buffer": "^5.1.1" + } + }, + "@ont-community/html5-websocket": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@ont-community/html5-websocket/-/html5-websocket-2.0.3.tgz", + "integrity": "sha1-cCQZEWIX7HScbuoYsjS9PWALDFw=", + "requires": { + "ws": "^3.1.0" + }, + "dependencies": { + "ws": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz", + "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0", + "ultron": "~1.1.0" + } + } + } + }, + "@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/base-x": { + "version": "1.0.29", + "resolved": "https://registry.npmjs.org/@types/base-x/-/base-x-1.0.29.tgz", + "integrity": "sha1-ii1z5KXDEhdXpfiHDPpFCWVRhrY=", + "dev": true + }, + "@types/base64-url": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@types/base64-url/-/base64-url-2.2.0.tgz", + "integrity": "sha512-adGV3KUTc9uO7kZNQOF3u9WVuKZsgKPsaShZePe+hQXNYd+3dnIK+Y2Wyw7A6M4iIH01xKCRZCZWLQnG9bulIQ==", + "dev": true + }, + "@types/bigi": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@types/bigi/-/bigi-1.4.1.tgz", + "integrity": "sha512-TfC88qNLyU9n8ZStziF3UdOrxxwVDDhn/W5E7jv9W7G10rai8Tbv9ia4KK00ZvdIfSKf3RsK5lbugoBAS9yFAQ==", + "dev": true + }, + "@types/bs58": { + "version": "3.0.30", + "resolved": "https://registry.npmjs.org/@types/bs58/-/bs58-3.0.30.tgz", + "integrity": "sha1-kWuhCZJGXlb4GvxzXnk1/XSYk+E=", + "dev": true, + "requires": { + "@types/base-x": "*" + } + }, + "@types/crypto-js": { + "version": "3.1.39", + "resolved": "https://registry.npmjs.org/@types/crypto-js/-/crypto-js-3.1.39.tgz", + "integrity": "sha512-LNPf60hAYUnjqeUwWxFrJwjPwOFIwQNy/xdVRQMWnsly38M23lLjhG3osdAJQ74jOplIUCjOhibpqOos0l0FHA==", + "dev": true + }, + "@types/ecurve": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/ecurve/-/ecurve-1.0.0.tgz", + "integrity": "sha1-DR/OAi2LqyvEurKMXXgbZCEAGMQ=", + "dev": true, + "requires": { + "@types/bigi": "*", + "@types/node": "*" + } + }, + "@types/events": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/events/-/events-1.2.0.tgz", + "integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==", + "dev": true + }, + "@types/fs-extra": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-5.0.1.tgz", + "integrity": "sha512-h3wnflb+jMTipvbbZnClgA2BexrT4w0GcfoCz5qyxd0IRsbqhLSyesM6mqZTAnhbVmhyTm5tuxfRu9R+8l+lGw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/glob": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz", + "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/handlebars": { + "version": "4.0.36", + "resolved": "https://registry.npmjs.org/@types/handlebars/-/handlebars-4.0.36.tgz", + "integrity": "sha512-LjNiTX7TY7wtuC6y3QwC93hKMuqYhgV9A1uXBKNvZtVC8ZvyWAjZkJ5BvT0K7RKqORRYRLMrqCxpw5RgS+MdrQ==", + "dev": true + }, + "@types/highlight.js": { + "version": "9.12.2", + "resolved": "https://registry.npmjs.org/@types/highlight.js/-/highlight.js-9.12.2.tgz", + "integrity": "sha512-y5x0XD/WXDaGSyiTaTcKS4FurULJtSiYbGTeQd0m2LYZGBcZZ/7fM6t5H/DzeUF+kv8y6UfmF6yJABQsHcp9VQ==", + "dev": true + }, + "@types/jest": { + "version": "22.2.3", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-22.2.3.tgz", + "integrity": "sha512-e74sM9W/4qqWB6D4TWV9FQk0WoHtX1X4FJpbjxucMSVJHtFjbQOH3H6yp+xno4br0AKG0wz/kPtaN599GUOvAg==", + "dev": true + }, + "@types/lodash": { + "version": "4.14.104", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.104.tgz", + "integrity": "sha512-ufQcVg4daO8xQ5kopxRHanqFdL4AI7ondQkV+2f+7mz3gvp0LkBx2zBRC6hfs3T87mzQFmf5Fck7Fi145Ul6NQ==", + "dev": true + }, + "@types/long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.0.tgz", + "integrity": "sha512-1w52Nyx4Gq47uuu0EVcsHBxZFJgurQ+rTKS3qMHxR1GY2T8c2AJYd6vZoZ9q1rupaDjU0yT+Jc2XTyXkjeMA+Q==", + "dev": true + }, + "@types/marked": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@types/marked/-/marked-0.3.0.tgz", + "integrity": "sha512-CSf9YWJdX1DkTNu9zcNtdCcn6hkRtB5ILjbhRId4ZOQqx30fXmdecuaXhugQL6eyrhuXtaHJ7PHI+Vm7k9ZJjg==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "8.10.17", + "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.17.tgz", + "integrity": "sha512-3N3FRd/rA1v5glXjb90YdYUa+sOB7WrkU2rAhKZnF4TKD86Cym9swtulGuH0p9nxo7fP5woRNa8b0oFTpCO1bg==", + "dev": true + }, + "@types/promise-timeout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/promise-timeout/-/promise-timeout-1.3.0.tgz", + "integrity": "sha512-AtVKSZUtpBoZ4SshXJk5JcTXJllinHKKx615lsRNJUsbbFlI0AI8drlnoiQ+PNvjkeoF9Y8fJUh6UO2khsIBZw==", + "dev": true + }, + "@types/scrypt-async": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@types/scrypt-async/-/scrypt-async-1.3.0.tgz", + "integrity": "sha512-1g5RDIq2sLlbn3bk1RnXCZWV2gqv7A2ov5ivvcjvICUUtXWlqR95Q9Iio3/EhAdZc4Otat41rnK+bnTGieycSQ==", + "dev": true + }, + "@types/shelljs": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/@types/shelljs/-/shelljs-0.7.8.tgz", + "integrity": "sha512-M2giRw93PxKS7YjU6GZjtdV9HASdB7TWqizBXe4Ju7AqbKlWvTr0gNO92XH56D/gMxqD/jNHLNfC5hA34yGqrQ==", + "dev": true, + "requires": { + "@types/glob": "*", + "@types/node": "*" + } + }, + "@types/uuid": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-3.4.3.tgz", + "integrity": "sha512-5fRLCYhLtDb3hMWqQyH10qtF+Ud2JnNCXTCZ+9ktNdCcgslcuXkDTkFcJNk++MT29yDntDnlF1+jD+uVGumsbw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@webassemblyjs/ast": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.4.3.tgz", + "integrity": "sha512-S6npYhPcTHDYe9nlsKa9CyWByFi8Vj8HovcAgtmMAQZUOczOZbQ8CnwMYKYC5HEZzxEE+oY0jfQk4cVlI3J59Q==", + "dev": true, + "requires": { + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "debug": "^3.1.0", + "webassemblyjs": "1.4.3" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.4.3.tgz", + "integrity": "sha512-3zTkSFswwZOPNHnzkP9ONq4bjJSeKVMcuahGXubrlLmZP8fmTIJ58dW7h/zOVWiFSuG2em3/HH3BlCN7wyu9Rw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.4.3.tgz", + "integrity": "sha512-e8+KZHh+RV8MUvoSRtuT1sFXskFnWG9vbDy47Oa166xX+l0dD5sERJ21g5/tcH8Yo95e9IN3u7Jc3NbhnUcSkw==", + "dev": true, + "requires": { + "debug": "^3.1.0" + } + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.4.3.tgz", + "integrity": "sha512-9FgHEtNsZQYaKrGCtsjswBil48Qp1agrzRcPzCbQloCoaTbOXLJ9IRmqT+uEZbenpULLRNFugz3I4uw18hJM8w==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.4.3" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.4.3.tgz", + "integrity": "sha512-JINY76U+702IRf7ePukOt037RwmtH59JHvcdWbTTyHi18ixmQ+uOuNhcdCcQHTquDAH35/QgFlp3Y9KqtyJsCQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.4.3.tgz", + "integrity": "sha512-I7bS+HaO0K07Io89qhJv+z1QipTpuramGwUSDkwEaficbSvCcL92CUZEtgykfNtk5wb0CoLQwWlmXTwGbNZUeQ==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.4.3.tgz", + "integrity": "sha512-p0yeeO/h2r30PyjnJX9xXSR6EDcvJd/jC6xa/Pxg4lpfcNi7JUswOpqDToZQ55HMMVhXDih/yqkaywHWGLxqyQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "debug": "^3.1.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.4.3.tgz", + "integrity": "sha512-4u0LJLSPzuRDWHwdqsrThYn+WqMFVqbI2ltNrHvZZkzFPO8XOZ0HFQ5eVc4jY/TNHgXcnwrHjONhPGYuuf//KQ==", + "dev": true, + "requires": { + "leb": "^0.3.0" + } + }, + "@webassemblyjs/validation": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/validation/-/validation-1.4.3.tgz", + "integrity": "sha512-R+rRMKfhd9mq0rj2mhU9A9NKI2l/Rw65vIYzz4lui7eTKPcCu1l7iZNi4b9Gen8D42Sqh/KGiaQNk/x5Tn/iBQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3" + } + }, + "@webassemblyjs/wasm-edit": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.4.3.tgz", + "integrity": "sha512-qzuwUn771PV6/LilqkXcS0ozJYAeY/OKbXIWU3a8gexuqb6De2p4ya/baBeH5JQ2WJdfhWhSvSbu86Vienttpw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/helper-wasm-section": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-opt": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-printer": "1.4.3", + "debug": "^3.1.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.4.3.tgz", + "integrity": "sha512-eR394T8dHZfpLJ7U/Z5pFSvxl1L63JdREebpv9gYc55zLhzzdJPAuxjBYT4XqevUdW67qU2s0nNA3kBuNJHbaQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.4.3.tgz", + "integrity": "sha512-7Gp+nschuKiDuAL1xmp4Xz0rgEbxioFXw4nCFYEmy+ytynhBnTeGc9W9cB1XRu1w8pqRU2lbj2VBBA4cL5Z2Kw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-buffer": "1.4.3", + "@webassemblyjs/wasm-gen": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "debug": "^3.1.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.4.3.tgz", + "integrity": "sha512-KXBjtlwA3BVukR/yWHC9GF+SCzBcgj0a7lm92kTOaa4cbjaTaa47bCjXw6cX4SGQpkncB9PU2hHGYVyyI7wFRg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/helper-wasm-bytecode": "1.4.3", + "@webassemblyjs/leb128": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "webassemblyjs": "1.4.3" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.4.3.tgz", + "integrity": "sha512-QhCsQzqV0CpsEkRYyTzQDilCNUZ+5j92f+g35bHHNqS22FppNTywNFfHPq8ZWZfYCgbectc+PoghD+xfzVFh1Q==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/floating-point-hex-parser": "1.4.3", + "@webassemblyjs/helper-code-frame": "1.4.3", + "@webassemblyjs/helper-fsm": "1.4.3", + "long": "^3.2.0", + "webassemblyjs": "1.4.3" + }, + "dependencies": { + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", + "dev": true + } + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.4.3.tgz", + "integrity": "sha512-EgXk4anf8jKmuZJsqD8qy5bz2frEQhBvZruv+bqwNoLWUItjNSFygk8ywL3JTEz9KtxTlAmqTXNrdD1d9gNDtg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "^3.2.0" + }, + "dependencies": { + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", + "dev": true + } + } + }, + "abab": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/abab/-/abab-1.0.4.tgz", + "integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4=", + "dev": true + }, + "acorn": { + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", + "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz", + "integrity": "sha512-zVWV8Z8lislJoOKKqdNMOB+s6+XV5WERty8MnKBeFgwA+19XJjJHs2RP5dzM57FftIs+jQnRToLiWazKr6sSWg==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + } + }, + "acorn-globals": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.1.0.tgz", + "integrity": "sha512-KjZwU26uG3u6eZcfGbTULzFcsoz6pegNKtHPksZPOUsiKo5bUmiBPa38FuHZ/Eun+XYh/JCCkS9AS3Lu4McQOQ==", + "dev": true, + "requires": { + "acorn": "^5.0.0" + } + }, + "ajv": { + "version": "5.5.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", + "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "dev": true, + "requires": { + "co": "^4.6.0", + "fast-deep-equal": "^1.0.0", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.3.0" + } + }, + "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-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=", + "dev": true + }, + "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.4", + "normalize-path": "^2.1.1" + }, + "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 + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "append-transform": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-0.4.0.tgz", + "integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=", + "dev": true, + "requires": { + "default-require-extensions": "^1.0.0" + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-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-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", + "dev": true + }, + "array-filter": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/array-filter/-/array-filter-0.0.1.tgz", + "integrity": "sha1-fajPLiZijtcygDWB/SH2fKzS7uw=", + "dev": true + }, + "array-map": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-map/-/array-map-0.0.0.tgz", + "integrity": "sha1-iKK6tz0c97zVwbEYoAP2b2ZfpmI=", + "dev": true + }, + "array-reduce": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/array-reduce/-/array-reduce-0.0.0.tgz", + "integrity": "sha1-FziZ0//Rx9k4PkR5Ul2+J4yrXys=", + "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.1" + } + }, + "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 + }, + "asn1": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", + "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", + "dev": true + }, + "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.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "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-metadata-inferer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz", + "integrity": "sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw==", + "dev": true + }, + "ast-types": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.11.3.tgz", + "integrity": "sha512-XA5o5dsNw8MhyW0Q7MWXJWc4oOzZKbdsEJq45h7c8q/d9DwWZ5F2ugUc1PuMLPGsUnphCt/cNDHu8JeBbxf1qA==", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", + "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==", + "dev": true, + "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-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "dev": true + }, + "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=", + "dev": true + }, + "aws4": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", + "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "dev": true + }, + "axios": { + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", + "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", + "requires": { + "follow-redirects": "1.5.10", + "is-buffer": "^2.0.2" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==" + } + } + }, + "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.0", + "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.4", + "minimatch": "^3.0.4", + "path-is-absolute": "^1.0.1", + "private": "^0.1.8", + "slash": "^1.0.0", + "source-map": "^0.5.7" + }, + "dependencies": { + "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" + } + } + } + }, + "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.4", + "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.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.4" + } + }, + "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.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-types": "^6.24.1" + } + }, + "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.4" + } + }, + "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.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-template": "^6.24.1" + } + }, + "babel-jest": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-23.0.0.tgz", + "integrity": "sha1-Djg6KqazU14ZfbKSlXCiGCvQhOg=", + "dev": true, + "requires": { + "babel-plugin-istanbul": "^4.1.6", + "babel-preset-jest": "^23.0.0" + } + }, + "babel-loader": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz", + "integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==", + "dev": true, + "requires": { + "find-cache-dir": "^1.0.0", + "loader-utils": "^1.0.2", + "mkdirp": "^0.5.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.22.0" + } + }, + "babel-plugin-check-es2015-constants": { + "version": "6.22.0", + "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", + "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", + "dev": true, + "requires": { + "babel-runtime": "^6.22.0" + } + }, + "babel-plugin-istanbul": { + "version": "4.1.6", + "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz", + "integrity": "sha512-PWP9FQ1AhZhS01T/4qLSKoHGY/xvkZdVBGlKM/HuxxS3+sC66HhTNR7+MpbO/so/cz/wY94MeSWJuP1hXIPfwQ==", + "dev": true, + "requires": { + "babel-plugin-syntax-object-rest-spread": "^6.13.0", + "find-up": "^2.1.0", + "istanbul-lib-instrument": "^1.10.1", + "test-exclude": "^4.2.1" + } + }, + "babel-plugin-jest-hoist": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.0.0.tgz", + "integrity": "sha1-5h5oeZ90M5Gh5jBu4nBHeqz5Rsg=", + "dev": true + }, + "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.5.0", + "babel-runtime": "^6.22.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.8.0", + "babel-runtime": "^6.22.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.22.0", + "babel-template": "^6.24.1" + } + }, + "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.8.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "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.22.0", + "babel-template": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.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.22.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.4" + } + }, + "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.24.1", + "babel-helper-function-name": "^6.24.1", + "babel-helper-optimise-call-expression": "^6.24.1", + "babel-helper-replace-supers": "^6.24.1", + "babel-messages": "^6.23.0", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-template": "^6.24.1" + } + }, + "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.22.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.22.0", + "babel-types": "^6.24.1" + } + }, + "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.22.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.22.0", + "babel-types": "^6.24.1" + } + }, + "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.22.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.24.1", + "babel-runtime": "^6.22.0", + "babel-template": "^6.24.1" + } + }, + "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.22.0", + "babel-template": "^6.24.1" + } + }, + "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.22.0", + "babel-template": "^6.24.1" + } + }, + "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.22.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.22.0", + "babel-template": "^6.24.1", + "babel-traverse": "^6.24.1", + "babel-types": "^6.24.1" + } + }, + "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.22.0", + "babel-types": "^6.24.1" + } + }, + "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.22.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.24.1", + "babel-runtime": "^6.22.0", + "babel-types": "^6.24.1" + } + }, + "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.22.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.22.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.24.1", + "babel-runtime": "^6.22.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.8.0", + "babel-runtime": "^6.22.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.8.0", + "babel-runtime": "^6.22.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.22.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.8.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.0" + } + }, + "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.22.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.22.0", + "babel-types": "^6.24.1" + } + }, + "babel-polyfill": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz", + "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=", + "requires": { + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "regenerator-runtime": "^0.10.5" + } + }, + "babel-preset-env": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", + "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", + "dev": true, + "requires": { + "babel-plugin-check-es2015-constants": "^6.22.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", + "babel-plugin-transform-async-to-generator": "^6.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.23.0", + "babel-plugin-transform-es2015-classes": "^6.23.0", + "babel-plugin-transform-es2015-computed-properties": "^6.22.0", + "babel-plugin-transform-es2015-destructuring": "^6.23.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", + "babel-plugin-transform-es2015-for-of": "^6.23.0", + "babel-plugin-transform-es2015-function-name": "^6.22.0", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.22.0", + "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", + "babel-plugin-transform-es2015-modules-umd": "^6.23.0", + "babel-plugin-transform-es2015-object-super": "^6.22.0", + "babel-plugin-transform-es2015-parameters": "^6.23.0", + "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", + "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.22.0", + "babel-plugin-transform-exponentiation-operator": "^6.22.0", + "babel-plugin-transform-regenerator": "^6.22.0", + "browserslist": "^3.2.6", + "invariant": "^2.2.2", + "semver": "^5.3.0" + } + }, + "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.24.1", + "babel-plugin-transform-es2015-classes": "^6.24.1", + "babel-plugin-transform-es2015-computed-properties": "^6.24.1", + "babel-plugin-transform-es2015-destructuring": "^6.22.0", + "babel-plugin-transform-es2015-duplicate-keys": "^6.24.1", + "babel-plugin-transform-es2015-for-of": "^6.22.0", + "babel-plugin-transform-es2015-function-name": "^6.24.1", + "babel-plugin-transform-es2015-literals": "^6.22.0", + "babel-plugin-transform-es2015-modules-amd": "^6.24.1", + "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-systemjs": "^6.24.1", + "babel-plugin-transform-es2015-modules-umd": "^6.24.1", + "babel-plugin-transform-es2015-object-super": "^6.24.1", + "babel-plugin-transform-es2015-parameters": "^6.24.1", + "babel-plugin-transform-es2015-shorthand-properties": "^6.24.1", + "babel-plugin-transform-es2015-spread": "^6.22.0", + "babel-plugin-transform-es2015-sticky-regex": "^6.24.1", + "babel-plugin-transform-es2015-template-literals": "^6.22.0", + "babel-plugin-transform-es2015-typeof-symbol": "^6.22.0", + "babel-plugin-transform-es2015-unicode-regex": "^6.24.1", + "babel-plugin-transform-regenerator": "^6.24.1" + } + }, + "babel-preset-jest": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-23.0.0.tgz", + "integrity": "sha1-Sd4DA/G2h13K1hY+qn64Mw1Ugk0=", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^23.0.0", + "babel-plugin-syntax-object-rest-spread": "^6.13.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.22.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.0", + "babel-runtime": "^6.26.0", + "core-js": "^2.5.0", + "home-or-tmp": "^2.0.0", + "lodash": "^4.17.4", + "mkdirp": "^0.5.1", + "source-map-support": "^0.4.15" + } + }, + "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=", + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + }, + "dependencies": { + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + } + } + }, + "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.4" + } + }, + "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.8", + "globals": "^9.18.0", + "invariant": "^2.2.2", + "lodash": "^4.17.4" + }, + "dependencies": { + "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" + } + } + } + }, + "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.4", + "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=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "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-58": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/base-58/-/base-58-0.0.1.tgz", + "integrity": "sha1-hdPnAlEHVmGTM4j4MdHri49jFOM=" + }, + "base-x": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.4.tgz", + "integrity": "sha512-UYOadoSIkEI/VrRGSG6qp93rp2WdokiAiNYDfGW5qURAY8GiAQkvMbwNNSDYiVJopqv4gCna7xqf4rrNGp+5AA==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "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 + }, + "base64-url": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/base64-url/-/base64-url-2.2.0.tgz", + "integrity": "sha512-Y4qHHAE+rWjmAFPQmHPiiD+hWwM/XvuFLlP6kVxlwZJK7rjiE2uIQR9tZ37iEr1E6iCj9799yxMAmiXzITb3lQ==" + }, + "bcrypt-pbkdf": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", + "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "dev": true, + "optional": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "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 + }, + "bigi": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz", + "integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU=" + }, + "bignumber.js": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-7.2.1.tgz", + "integrity": "sha512-S4XzBk5sMB+Rcb/LNcpzXr57VRTxgAvaAEDAl1AwRx27j00hT84O6OkteE7u8UB3NuaaygCRrEpqox4uDOrbdQ==" + }, + "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 + }, + "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.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "bip66": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", + "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "bluebird": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", + "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" + }, + "browser-process-hrtime": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz", + "integrity": "sha1-Ql1opY00R/AqBKqJQYf86K+Le44=", + "dev": true + }, + "browser-resolve": { + "version": "1.11.2", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", + "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "dev": true, + "requires": { + "resolve": "1.1.7" + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "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.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1" + } + }, + "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.1.0", + "randombytes": "^2.0.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.1.1", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.2", + "elliptic": "^6.0.0", + "inherits": "^2.0.1", + "parse-asn1": "^5.0.0" + } + }, + "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.5" + } + }, + "browserslist": { + "version": "3.2.8", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", + "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000844", + "electron-to-chromium": "^1.3.47" + } + }, + "bs58": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", + "requires": { + "base-x": "^3.0.2" + } + }, + "bs58check": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.1.tgz", + "integrity": "sha512-okRQiWc5FJuA2VOwQ1hB7Sf0MyEFg/EwRN12h4b8HrJoGkZ3xq1CGjkaAfYloLcZyqixQnO5mhPpN6IcHSplVg==", + "requires": { + "bs58": "^4.0.0", + "create-hash": "^1.1.0" + } + }, + "bser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/bser/-/bser-2.0.0.tgz", + "integrity": "sha1-mseNPtXZFYBP2HrLFYvHlxR6Fxk=", + "dev": true, + "requires": { + "node-int64": "^0.4.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.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz", + "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=", + "dev": true + }, + "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 + }, + "cacache": { + "version": "10.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", + "dev": true, + "requires": { + "bluebird": "^3.5.1", + "chownr": "^1.0.1", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "lru-cache": "^4.1.1", + "mississippi": "^2.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^5.2.4", + "unique-filename": "^1.1.0", + "y18n": "^4.0.0" + }, + "dependencies": { + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "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 + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "caniuse-db": { + "version": "1.0.30001005", + "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30001005.tgz", + "integrity": "sha512-MSRfm2N6FRDSpAJ00ipCuFe0CNink5JJOFzl4S7fLSBJdowhGq3uMxzkWGTjvvReo1PuWfK5YYJydJJ+9mJebw==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000846", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000846.tgz", + "integrity": "sha512-qxUOHr5mTaadWH1ap0ueivHd8x42Bnemcn+JutVr7GWmm2bU4zoBhjuv5QdXgALQnnT626lOQros7cCDf8PwCg==", + "dev": true + }, + "capture-exit": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/capture-exit/-/capture-exit-1.2.0.tgz", + "integrity": "sha1-HF/MSJ/QqwDU8ax64QcuMXP7q28=", + "dev": true, + "requires": { + "rsvp": "^3.3.3" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "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.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "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 + }, + "chnl": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chnl/-/chnl-0.4.2.tgz", + "integrity": "sha512-RX0RsFTepIGn3fqg6E+FWVfk228Y5ndwaT6Gn6VbipxTWZr5aicJ/spbNQR2COMlQwidMLwtpfE3so+MMc2GvQ==" + }, + "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.0", + "async-each": "^1.0.0", + "fsevents": "^1.0.0", + "glob-parent": "^2.0.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^2.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0" + }, + "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, + "requires": { + "micromatch": "^2.1.5", + "normalize-path": "^2.0.0" + } + } + } + }, + "chownr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.0.1.tgz", + "integrity": "sha1-4qdQQqlVGQi+vSW4Uj1fl2nXkYE=", + "dev": true + }, + "chrome-trace-event": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-0.1.3.tgz", + "integrity": "sha512-sjndyZHrrWiu4RY7AkHgjn80GfAM2ZSzUkZLV/Js59Ldmh6JDThf0SUmOHU53rFu2rVxxfCzJ30Ukcfch3Gb/A==", + "dev": true + }, + "ci-info": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz", + "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-webpack-plugin": { + "version": "0.1.19", + "resolved": "https://registry.npmjs.org/clean-webpack-plugin/-/clean-webpack-plugin-0.1.19.tgz", + "integrity": "sha512-M1Li5yLHECcN2MahoreuODul5LkjohJGFxLPTjl3j1ttKrF5rgjZET1SJduuqxLAuT1gAPOdkhg03qcaaU1KeA==", + "dev": true, + "requires": { + "rimraf": "^2.6.1" + } + }, + "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-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.1" + }, + "dependencies": { + "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=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "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.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "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=", + "dev": true + }, + "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.1.1" + }, + "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.0" + } + }, + "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.1" + } + }, + "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=", + "dev": true, + "requires": { + "delayed-stream": "~1.0.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 + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "compare-versions": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.2.1.tgz", + "integrity": "sha512-2y2nHcopMG/NAyk6vWXlLs86XeM9sik4jmx1tKIgzMi9/RQ2eo758RGpxQO3ErihHmg0RlQITPqgz73y6s7quA==", + "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=", + "dev": true + }, + "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.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "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-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "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.6", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz", + "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ==" + }, + "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=", + "dev": true + }, + "cpx": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/cpx/-/cpx-1.5.0.tgz", + "integrity": "sha1-GFvgGFEdhycN7czCkxceN2VauI8=", + "dev": true, + "requires": { + "babel-runtime": "^6.9.2", + "chokidar": "^1.6.0", + "duplexer": "^0.1.1", + "glob": "^7.0.5", + "glob2base": "^0.0.12", + "minimatch": "^3.0.2", + "mkdirp": "^0.5.1", + "resolve": "^1.1.7", + "safe-buffer": "^5.0.1", + "shell-quote": "^1.6.1", + "subarg": "^1.0.0" + } + }, + "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.1.0", + "elliptic": "^6.0.0" + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-env": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.1.tgz", + "integrity": "sha512-1yHhtcfAd1r4nwQgknowuUNfIT9E8dOMMspC36g45dN+iD1blloi7xp8X/xAIDnjHWyt1uQ8PHk2fkNaym7soQ==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.5" + }, + "dependencies": { + "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.2.9" + } + } + } + }, + "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.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "crypto-js": { + "version": "3.1.9-1", + "resolved": "https://registry.npmjs.org/crypto-js/-/crypto-js-3.1.9-1.tgz", + "integrity": "sha1-/aGedh/Ad+Af+/3G6f38WeiAbNg=" + }, + "cssom": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.2.tgz", + "integrity": "sha1-uANhcMefB6kP8vFuIihAJ6JDhIs=", + "dev": true + }, + "cssstyle": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.3.1.tgz", + "integrity": "sha512-tNvaxM5blOnxanyxI6panOsnfiyLRj3HV4qjqqS45WPNS1usdYWRUQjqTEEELK73lpeP/1KoIGYUwrBn/VcECA==", + "dev": true, + "requires": { + "cssom": "0.3.x" + } + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true + }, + "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=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "data-urls": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.0.0.tgz", + "integrity": "sha512-ai40PPQR0Fn1lD2PPie79CibnlMN2AYiDhwFX/rZHVsxbs5kNJSjegqXIprhouGXlRdEnfybva7kqRGnB6mypA==", + "dev": true, + "requires": { + "abab": "^1.0.4", + "whatwg-mimetype": "^2.0.0", + "whatwg-url": "^6.4.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 + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "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=", + "dev": true + }, + "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-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 + }, + "default-require-extensions": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-1.0.0.tgz", + "integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=", + "dev": true, + "requires": { + "strip-bom": "^2.0.0" + } + }, + "define-properties": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", + "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "dev": true, + "requires": { + "foreach": "^2.0.5", + "object-keys": "^1.0.8" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "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 + } + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "dev": true + }, + "des.js": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", + "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "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.0" + } + }, + "detect-newline": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-2.1.0.tgz", + "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", + "dev": true + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + } + }, + "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" + } + } + } + }, + "doctrine": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz", + "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=", + "dev": true, + "requires": { + "esutils": "^1.1.6", + "isarray": "0.0.1" + }, + "dependencies": { + "esutils": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz", + "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=", + "dev": true + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "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 + }, + "domexception": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz", + "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==", + "dev": true, + "requires": { + "webidl-conversions": "^4.0.2" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexer3": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.4.tgz", + "integrity": "sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=", + "dev": true + }, + "duplexify": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz", + "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ecc-jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", + "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "dev": true, + "optional": true, + "requires": { + "jsbn": "~0.1.0" + } + }, + "ecdsa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ecdsa/-/ecdsa-0.7.0.tgz", + "integrity": "sha1-9lziMAInsWKBApArK5NgfIBt4dk=", + "requires": { + "bigi": "^1.2.1", + "bip66": "^1.1.0", + "create-hmac": "^1.1.4", + "ecurve": "^1.0.0", + "typeforce": "^1.6.1" + } + }, + "ecurve": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.6.tgz", + "integrity": "sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w==", + "requires": { + "bigi": "^1.1.0", + "safe-buffer": "^5.0.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 + }, + "electron-to-chromium": { + "version": "1.3.48", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.48.tgz", + "integrity": "sha1-07DYWTgUBE4JLs4hCPw6ya6kuQA=", + "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.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", + "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "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.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "envinfo": { + "version": "5.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-5.8.1.tgz", + "integrity": "sha512-6DUjb7ozlC09FNADu5WZfLr4NLsk44loPi8mDp+NjyVtCmcLDS4eYNFsU3gSYjsg1Gxp29ZXD06nsO5J0cUhFg==", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "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.0" + } + }, + "error-ex": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", + "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz", + "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==", + "dev": true, + "requires": { + "es-to-primitive": "^1.1.1", + "function-bind": "^1.1.1", + "has": "^1.0.1", + "is-callable": "^1.1.3", + "is-regex": "^1.0.4" + } + }, + "es-to-primitive": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", + "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "dev": true, + "requires": { + "is-callable": "^1.1.1", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.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.9.1", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz", + "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==", + "dev": true, + "requires": { + "esprima": "^3.1.3", + "estraverse": "^4.2.0", + "esutils": "^2.0.2", + "optionator": "^0.8.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "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, + "optional": true + } + } + }, + "eslint-plugin-compat": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.3.0.tgz", + "integrity": "sha512-QCgYy3pZ+zH10dkBJus1xER0359h1UhJjufhQRqp9Owm6BEoLZeSqxf2zINwL1OGao9Yc96xPYIW3nQj5HUryg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.4.5", + "ast-metadata-inferer": "^0.1.1", + "browserslist": "^4.6.3", + "caniuse-db": "^1.0.30000977", + "lodash.memoize": "4.1.2", + "mdn-browser-compat-data": "^0.0.84", + "semver": "^6.1.2" + }, + "dependencies": { + "browserslist": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.7.2.tgz", + "integrity": "sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001004", + "electron-to-chromium": "^1.3.295", + "node-releases": "^1.1.38" + } + }, + "caniuse-lite": { + "version": "1.0.30001005", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001005.tgz", + "integrity": "sha512-g78miZm1Z5njjYR216a5812oPiLgV1ssndgGxITHWUopmjUrCswMisA0a2kSB7a0vZRox6JOKhM51+efmYN8Mg==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.296", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.296.tgz", + "integrity": "sha512-s5hv+TSJSVRsxH190De66YHb50pBGTweT9XGWYu/LMR20KX6TsjFzObo36CjVAzM+PUeeKSBRtm/mISlCzeojQ==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-scope": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", + "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "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.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "exec-sh": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.1.tgz", + "integrity": "sha512-aLt95pexaugVtQerpmE51+4QfWrNc304uez7jvj6fWnN8GeEHpttB8F36n8N7uVhUMbH/1enbxQ9HImZ4w/9qg==", + "dev": true, + "requires": { + "merge": "^1.1.3" + } + }, + "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.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "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.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "expand-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.1.0" + }, + "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.0.0", + "randomatic": "^3.0.0", + "repeat-element": "^1.1.2", + "repeat-string": "^1.5.2" + } + }, + "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.0.2" + } + }, + "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" + } + }, + "expect": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-23.0.0.tgz", + "integrity": "sha1-LDqwpE2uMZ4Apz41YXYnaNA6Kyc=", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "jest-diff": "^23.0.0", + "jest-get-type": "^22.1.0", + "jest-matcher-utils": "^23.0.0", + "jest-message-util": "^23.0.0", + "jest-regex-util": "^23.0.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.0" + } + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "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.0", + "iconv-lite": "^0.4.17", + "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.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "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=", + "dev": true + }, + "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=", + "dev": true + }, + "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.0.1", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.1", + "micromatch": "^3.1.10" + }, + "dependencies": { + "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.0" + }, + "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.0" + } + } + } + }, + "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-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" + } + }, + "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 + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "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=", + "dev": true + }, + "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 + }, + "fb-watchman": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.0.tgz", + "integrity": "sha1-VOmr99+i8mzZsWNsWIwa/AXeXVg=", + "dev": true, + "requires": { + "bser": "^2.0.0" + } + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "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 + }, + "fileset": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/fileset/-/fileset-2.0.3.tgz", + "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", + "dev": true, + "requires": { + "glob": "^7.0.3", + "minimatch": "^3.0.3" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-cache-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", + "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^2.0.0" + } + }, + "find-index": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", + "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", + "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" + } + }, + "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.0.2" + } + }, + "flat-options": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/flat-options/-/flat-options-0.1.3.tgz", + "integrity": "sha512-z1vH9mb4ly55dWUZZFUeLNqhFWhwSQNngHpK8RQOhFuNw/sWcNDZhkHl3GS1YTHiYxB5qvcbSRbH7X6ThzX9UA==" + }, + "flow-parser": { + "version": "0.73.0", + "resolved": "https://registry.npmjs.org/flow-parser/-/flow-parser-0.73.0.tgz", + "integrity": "sha512-9JB+2hrKJ+S1OZ+upIwNTGlaLDRga2iC9KvpqWVFEVNlCxc51pkhNJRmA0PmUcLcEtFAW6IGBmVi70r+j+Qp9A==", + "dev": true + }, + "flush-write-stream": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", + "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.4" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "requires": { + "debug": "=3.1.0" + } + }, + "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.1" + } + }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", + "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "1.0.6", + "mime-types": "^2.1.12" + } + }, + "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.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.0.tgz", + "integrity": "sha512-lk2cUCo8QzbiEWEbt7Cw3m27WMiRG321xsssbcIpfMhpRjrlC08WBOVQqj1/nQYYNnPtyIhP1oqLO3QwT2tPCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "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.9.2", + "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, + "optional": 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.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": 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, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": 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.1" + } + }, + "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.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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.0" + } + }, + "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.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.2.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.1", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": 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.1.2", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.10.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.0", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.1.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "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.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "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.0", + "os-tmpdir": "^1.0.0" + } + }, + "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.0", + "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.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.0.5" + } + }, + "safe-buffer": { + "version": "5.1.1", + "bundled": true, + "dev": true, + "optional": 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, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "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.0", + "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, + "optional": true + }, + "yallist": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "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=", + "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=", + "dev": true, + "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.0.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.2.0", + "duplexer3": "^0.1.4", + "get-stream": "^3.0.0", + "is-plain-obj": "^1.1.0", + "is-retry-allowed": "^1.0.0", + "is-stream": "^1.0.0", + "isurl": "^1.0.0-alpha5", + "lowercase-keys": "^1.0.0", + "p-cancelable": "^0.3.0", + "p-timeout": "^1.1.1", + "safe-buffer": "^5.0.1", + "timed-out": "^4.0.0", + "url-parse-lax": "^1.0.0", + "url-to-options": "^1.0.1" + } + }, + "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.1" + } + } + } + }, + "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==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "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.0.5", + "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.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.0" + } + }, + "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 + }, + "glob2base": { + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", + "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", + "dev": true, + "requires": { + "find-index": "^0.1.1" + } + }, + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + } + }, + "globals": { + "version": "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.1", + "dir-glob": "^2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + } + }, + "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.1", + "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-alpha5", + "lowercase-keys": "^1.0.0", + "mimic-response": "^1.0.0", + "p-cancelable": "^0.4.0", + "p-timeout": "^2.0.1", + "pify": "^3.0.0", + "safe-buffer": "^5.1.1", + "timed-out": "^4.0.1", + "url-parse-lax": "^3.0.0", + "url-to-options": "^1.0.1" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "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.2" + } + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "handlebars": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.5.0.tgz", + "integrity": "sha512-yss1ZbupTpRfe86dpM1abxnnSfxa6eIRn3laqBPIgRYy87qgYtX6xinSOeybjYo/4AVzdTTWK5Kr06A6AllxJg==", + "dev": true, + "requires": { + "eslint-plugin-compat": "^3.3.0", + "neo-async": "^2.6.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true, + "optional": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "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 + }, + "uglify-js": { + "version": "3.6.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.6.4.tgz", + "integrity": "sha512-9Yc2i881pF4BPGhjteCXQNaXx1DCwm3dtOyBaG2hitHjLWOczw/ki8vD1bqyT3u6K0Ms/FpCShkmfg+FtlOfYA==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.20.3", + "source-map": "~0.6.1" + } + } + } + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz", + "integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=", + "dev": true, + "requires": { + "ajv": "^5.1.0", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.1.tgz", + "integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=", + "requires": { + "function-bind": "^1.0.2" + } + }, + "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.0.0" + } + }, + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + }, + "has-to-string-tag-x": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", + "integrity": "sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw==", + "dev": true, + "requires": { + "has-symbol-support-x": "^1.4.1" + } + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", + "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.0" + } + }, + "highlight.js": { + "version": "9.15.10", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-9.15.10.tgz", + "integrity": "sha512-RoV7OkQm0T3os3Dd2VHLNMoaoDVx77Wygln3n9l5YV172XonWG6rgQD3XnF/BuFFZw9A0TJgmMSO8FEWQgvcXw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "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.0", + "os-tmpdir": "^1.0.1" + } + }, + "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==", + "dev": true + }, + "html-encoding-sniffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz", + "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==", + "dev": true, + "requires": { + "whatwg-encoding": "^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-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + } + }, + "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.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "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 + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "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 + }, + "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" + } + }, + "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.0" + } + }, + "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=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inquirer": { + "version": "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.0.0", + "chalk": "^2.0.0", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^2.1.0", + "figures": "^2.0.0", + "lodash": "^4.3.0", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^5.5.2", + "string-width": "^2.1.0", + "strip-ansi": "^4.0.0", + "through": "^2.3.6" + }, + "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.0" + } + }, + "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.3.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.1.1", + "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.0.0" + } + }, + "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=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "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.0.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=", + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-callable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", + "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=", + "dev": true + }, + "is-ci": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz", + "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-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": "1.0.0", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "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.0" + } + }, + "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-generator-fn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-1.0.0.tgz", + "integrity": "sha1-lp1J4bszKfa7fwkIm+JleLLd1Go=", + "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" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "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.1.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.1" + } + }, + "is-retry-allowed": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz", + "integrity": "sha1-EaBgVotnM5REAz0BJaYaINVk+zQ=", + "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=", + "dev": true + }, + "is-symbol": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", + "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=", + "dev": true + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "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 + }, + "isstream": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz", + "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=", + "dev": true + }, + "istanbul-api": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz", + "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==", + "dev": true, + "requires": { + "async": "^2.1.4", + "compare-versions": "^3.1.0", + "fileset": "^2.0.2", + "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-hook": "^1.2.0", + "istanbul-lib-instrument": "^1.10.1", + "istanbul-lib-report": "^1.1.4", + "istanbul-lib-source-maps": "^1.2.4", + "istanbul-reports": "^1.3.0", + "js-yaml": "^3.7.0", + "mkdirp": "^0.5.1", + "once": "^1.4.0" + } + }, + "istanbul-lib-coverage": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz", + "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==", + "dev": true + }, + "istanbul-lib-hook": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.0.tgz", + "integrity": "sha512-p3En6/oGkFQV55Up8ZPC2oLxvgSxD8CzA0yBrhRZSh3pfv3OFj9aSGVC0yoerAi/O4u7jUVnOGVX1eVFM+0tmQ==", + "dev": true, + "requires": { + "append-transform": "^0.4.0" + } + }, + "istanbul-lib-instrument": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz", + "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==", + "dev": true, + "requires": { + "babel-generator": "^6.18.0", + "babel-template": "^6.16.0", + "babel-traverse": "^6.18.0", + "babel-types": "^6.18.0", + "babylon": "^6.18.0", + "istanbul-lib-coverage": "^1.2.0", + "semver": "^5.3.0" + } + }, + "istanbul-lib-report": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz", + "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==", + "dev": true, + "requires": { + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "path-parse": "^1.0.5", + "supports-color": "^3.1.2" + }, + "dependencies": { + "has-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true + }, + "supports-color": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", + "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, + "requires": { + "has-flag": "^1.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.4.tgz", + "integrity": "sha512-UzuK0g1wyQijiaYQxj/CdNycFhAd2TLtO2obKQMTZrZ1jzEMRY3rvpASEKkaxbRR6brvdovfA03znPa/pXcejg==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "istanbul-lib-coverage": "^1.2.0", + "mkdirp": "^0.5.1", + "rimraf": "^2.6.1", + "source-map": "^0.5.3" + } + }, + "istanbul-reports": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz", + "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==", + "dev": true, + "requires": { + "handlebars": "^4.0.3" + } + }, + "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", + "editions": "^1.3.3", + "textextensions": "2" + } + }, + "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.2.0", + "is-object": "^1.0.1" + } + }, + "jest": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-23.0.0.tgz", + "integrity": "sha1-koKYAwn1zeJ6rcWa5YPxEXwORDA=", + "dev": true, + "requires": { + "import-local": "^1.0.0", + "jest-cli": "^23.0.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 + }, + "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.0" + } + }, + "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.3.0" + } + }, + "jest-cli": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-23.0.0.tgz", + "integrity": "sha1-KSh0mMnYRNzaWq8BGkyC+aiIg24=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "chalk": "^2.0.1", + "exit": "^0.1.2", + "glob": "^7.1.2", + "graceful-fs": "^4.1.11", + "import-local": "^1.0.0", + "is-ci": "^1.0.10", + "istanbul-api": "^1.3.1", + "istanbul-lib-coverage": "^1.2.0", + "istanbul-lib-instrument": "^1.10.1", + "istanbul-lib-source-maps": "^1.2.4", + "jest-changed-files": "^22.2.0", + "jest-config": "^23.0.0", + "jest-environment-jsdom": "^23.0.0", + "jest-get-type": "^22.1.0", + "jest-haste-map": "^23.0.0", + "jest-message-util": "^23.0.0", + "jest-regex-util": "^23.0.0", + "jest-resolve-dependencies": "^23.0.0", + "jest-runner": "^23.0.0", + "jest-runtime": "^23.0.0", + "jest-snapshot": "^23.0.0", + "jest-util": "^23.0.0", + "jest-validate": "^23.0.0", + "jest-worker": "^23.0.0", + "micromatch": "^2.3.11", + "node-notifier": "^5.2.1", + "realpath-native": "^1.0.0", + "rimraf": "^2.5.4", + "slash": "^1.0.0", + "string-length": "^2.0.0", + "strip-ansi": "^4.0.0", + "which": "^1.2.12", + "yargs": "^11.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" + } + } + } + }, + "jest-changed-files": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-22.4.3.tgz", + "integrity": "sha512-83Dh0w1aSkUNFhy5d2dvqWxi/y6weDwVVLU6vmK0cV9VpRxPzhTeGimbsbRDSnEoszhF937M4sDLLeS7Cu/Tmw==", + "dev": true, + "requires": { + "throat": "^4.0.0" + } + }, + "jest-config": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-23.0.0.tgz", + "integrity": "sha1-lETYWIc61Wc3b4z+E5/Ygo6NSUs=", + "dev": true, + "requires": { + "babel-core": "^6.0.0", + "babel-jest": "^23.0.0", + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^23.0.0", + "jest-environment-node": "^23.0.0", + "jest-get-type": "^22.1.0", + "jest-jasmine2": "^23.0.0", + "jest-regex-util": "^23.0.0", + "jest-resolve": "^23.0.0", + "jest-util": "^23.0.0", + "jest-validate": "^23.0.0", + "pretty-format": "^23.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-diff": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-23.0.0.tgz", + "integrity": "sha1-CgCyFX9RjuwzgSHM+IecUpJpqI4=", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff": "^3.2.0", + "jest-get-type": "^22.1.0", + "pretty-format": "^23.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-docblock": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-22.4.3.tgz", + "integrity": "sha512-uPKBEAw7YrEMcXueMKZXn/rbMxBiSv48fSqy3uEnmgOlQhSX+lthBqHb1fKWNVmFqAp9E/RsSdBfiV31LbzaOg==", + "dev": true, + "requires": { + "detect-newline": "^2.1.0" + } + }, + "jest-environment-jsdom": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-23.0.0.tgz", + "integrity": "sha1-V7Dw3SYzWahteVKktxKz+ryhpiU=", + "dev": true, + "requires": { + "jest-mock": "^23.0.0", + "jest-util": "^23.0.0", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-23.0.0.tgz", + "integrity": "sha1-75OkFKYSSEz1hcizLMxa4wzmCVw=", + "dev": true, + "requires": { + "jest-mock": "^23.0.0", + "jest-util": "^23.0.0" + } + }, + "jest-get-type": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-22.4.3.tgz", + "integrity": "sha512-/jsz0Y+V29w1chdXVygEKSz2nBoHoYqNShPe+QgxSNjAuP1i8+k4LbQNrfoliKej0P45sivkSCh7yiD6ubHS3w==", + "dev": true + }, + "jest-haste-map": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-23.0.0.tgz", + "integrity": "sha1-Cb4cmjfBay4vJTmIZOsoBtMJypY=", + "dev": true, + "requires": { + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.1.11", + "jest-docblock": "^22.4.0", + "jest-serializer": "^23.0.0", + "jest-worker": "^23.0.0", + "micromatch": "^2.3.11", + "sane": "^2.0.0" + } + }, + "jest-jasmine2": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-23.0.0.tgz", + "integrity": "sha1-6ib4e1wiPhpwmFAy8HJ9j4VeWd8=", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^23.0.0", + "is-generator-fn": "^1.0.0", + "jest-diff": "^23.0.0", + "jest-matcher-utils": "^23.0.0", + "jest-message-util": "^23.0.0", + "jest-snapshot": "^23.0.0", + "jest-util": "^23.0.0", + "pretty-format": "^23.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-leak-detector": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-23.0.0.tgz", + "integrity": "sha1-7JPXVbIeiyxMTlm4zMqxgFpwSrM=", + "dev": true, + "requires": { + "pretty-format": "^23.0.0" + } + }, + "jest-matcher-utils": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-23.0.0.tgz", + "integrity": "sha1-yiFo/lp6QWwNfykW6Wnonczp2So=", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-get-type": "^22.1.0", + "pretty-format": "^23.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-message-util": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-23.0.0.tgz", + "integrity": "sha1-Bz89dscB98cYpLmvHrfxOHksR5Y=", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0-beta.35", + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0", + "stack-utils": "^1.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-mock": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-23.0.0.tgz", + "integrity": "sha1-2diXobdNwFxmpzchOTFJYhWJfdg=", + "dev": true + }, + "jest-regex-util": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-23.0.0.tgz", + "integrity": "sha1-3Vwf3gxG9DcTFM8Q96dRoj9Oj3Y=", + "dev": true + }, + "jest-resolve": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-23.0.0.tgz", + "integrity": "sha1-8ENi/QUxtFRjmd92xVwyFKn0XgI=", + "dev": true, + "requires": { + "browser-resolve": "^1.11.2", + "chalk": "^2.0.1", + "realpath-native": "^1.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-resolve-dependencies": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-23.0.0.tgz", + "integrity": "sha1-w+HP7g5UPe4Q5uwGKN9pzSOSRMk=", + "dev": true, + "requires": { + "jest-regex-util": "^23.0.0", + "jest-snapshot": "^23.0.0" + } + }, + "jest-runner": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-23.0.0.tgz", + "integrity": "sha1-sZii3XjVeiwPP418f5e2JnOSICA=", + "dev": true, + "requires": { + "exit": "^0.1.2", + "graceful-fs": "^4.1.11", + "jest-config": "^23.0.0", + "jest-docblock": "^22.4.0", + "jest-haste-map": "^23.0.0", + "jest-jasmine2": "^23.0.0", + "jest-leak-detector": "^23.0.0", + "jest-message-util": "^23.0.0", + "jest-runtime": "^23.0.0", + "jest-util": "^23.0.0", + "jest-worker": "^23.0.0", + "source-map-support": "^0.5.6", + "throat": "^4.0.0" + }, + "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.0.0", + "source-map": "^0.6.0" + } + } + } + }, + "jest-runtime": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-23.0.0.tgz", + "integrity": "sha1-hhkif+LgFgPVQrkQHdPmTvRZP2Y=", + "dev": true, + "requires": { + "babel-core": "^6.0.0", + "babel-plugin-istanbul": "^4.1.6", + "chalk": "^2.0.1", + "convert-source-map": "^1.4.0", + "exit": "^0.1.2", + "graceful-fs": "^4.1.11", + "jest-config": "^23.0.0", + "jest-haste-map": "^23.0.0", + "jest-message-util": "^23.0.0", + "jest-regex-util": "^23.0.0", + "jest-resolve": "^23.0.0", + "jest-snapshot": "^23.0.0", + "jest-util": "^23.0.0", + "jest-validate": "^23.0.0", + "json-stable-stringify": "^1.0.1", + "micromatch": "^2.3.11", + "realpath-native": "^1.0.0", + "slash": "^1.0.0", + "strip-bom": "3.0.0", + "write-file-atomic": "^2.1.0", + "yargs": "^11.0.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.0" + } + }, + "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.3.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": "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" + } + } + } + }, + "jest-serializer": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-23.0.0.tgz", + "integrity": "sha1-JjQRrJLh493iQ4WGQrsE6KmG6Mo=", + "dev": true + }, + "jest-snapshot": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-23.0.0.tgz", + "integrity": "sha1-Sc25Kmm5mZ2/kuBjTVuh6KhYaAM=", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^23.0.0", + "jest-matcher-utils": "^23.0.0", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^23.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-util": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-23.0.0.tgz", + "integrity": "sha1-hjhoAP++P+F6BjIODPnKm3hoJjs=", + "dev": true, + "requires": { + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "is-ci": "^1.0.10", + "jest-message-util": "^23.0.0", + "mkdirp": "^0.5.1", + "source-map": "^0.6.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.0" + } + }, + "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.3.0" + } + }, + "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 + }, + "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" + } + } + } + }, + "jest-validate": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-23.0.0.tgz", + "integrity": "sha1-+IvIl7bMN2l5r/AmLRAl3xMC1SA=", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-get-type": "^22.1.0", + "leven": "^2.1.0", + "pretty-format": "^23.0.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.0" + } + }, + "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.3.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" + } + } + } + }, + "jest-worker": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-23.0.0.tgz", + "integrity": "sha1-5rE3i4H45qEI874zofqoMMIupFA=", + "dev": true, + "requires": { + "merge-stream": "^1.0.1" + } + }, + "js-sha3": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.7.0.tgz", + "integrity": "sha512-Wpks3yBDm0UcL5qlVhwW9Jr9n9i4FfeWBFOOXP5puDS/SiudJGhw7DPyBqn3487qD4F0lsC0q3zxink37f7zeA==" + }, + "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.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsbn": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", + "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", + "dev": true, + "optional": true + }, + "jscodeshift": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jscodeshift/-/jscodeshift-0.5.0.tgz", + "integrity": "sha512-JAcQINNMFpdzzpKJN8k5xXjF3XDuckB1/48uScSzcnNyK199iWEc9AxKL9OoX5144M2w5zEx9Qs4/E/eBZZUlw==", + "dev": true, + "requires": { + "babel-plugin-transform-flow-strip-types": "^6.8.0", + "babel-preset-es2015": "^6.9.0", + "babel-preset-stage-1": "^6.5.0", + "babel-register": "^6.9.0", + "babylon": "^7.0.0-beta.30", + "colors": "^1.1.2", + "flow-parser": "^0.*", + "lodash": "^4.13.1", + "micromatch": "^2.3.7", + "neo-async": "^2.5.0", + "node-dir": "0.1.8", + "nomnom": "^1.8.1", + "recast": "^0.14.1", + "temp": "^0.8.1", + "write-file-atomic": "^1.2.0" + }, + "dependencies": { + "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 + }, + "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.5" + } + } + } + }, + "jsdom": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.11.0.tgz", + "integrity": "sha512-ou1VyfjwsSuWkudGxb03FotDajxAto6USAlmMZjE2lc0jCznt7sBWkhfRBRaWwbnmDqdMSTKTLT5d9sBFkkM7A==", + "dev": true, + "requires": { + "abab": "^1.0.4", + "acorn": "^5.3.0", + "acorn-globals": "^4.1.0", + "array-equal": "^1.0.0", + "cssom": ">= 0.3.2 < 0.4.0", + "cssstyle": ">= 0.3.1 < 0.4.0", + "data-urls": "^1.0.0", + "domexception": "^1.0.0", + "escodegen": "^1.9.0", + "html-encoding-sniffer": "^1.0.2", + "left-pad": "^1.2.0", + "nwsapi": "^2.0.0", + "parse5": "4.0.0", + "pn": "^1.1.0", + "request": "^2.83.0", + "request-promise-native": "^1.0.5", + "sax": "^1.2.4", + "symbol-tree": "^3.2.2", + "tough-cookie": "^2.3.3", + "w3c-hr-time": "^1.0.1", + "webidl-conversions": "^4.0.2", + "whatwg-encoding": "^1.0.3", + "whatwg-mimetype": "^2.1.0", + "whatwg-url": "^6.4.1", + "ws": "^4.0.0", + "xml-name-validator": "^3.0.0" + } + }, + "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-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=", + "dev": true + }, + "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=", + "dev": true + }, + "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=", + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "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=", + "dev": true, + "requires": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.2.3", + "verror": "1.10.0" + } + }, + "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.5" + } + }, + "lcid": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", + "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", + "dev": true, + "requires": { + "invert-kv": "^1.0.0" + } + }, + "leb": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/leb/-/leb-0.3.0.tgz", + "integrity": "sha1-Mr7p+tFoMo1q6oUi2DP0GA7tHaM=", + "dev": true + }, + "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 + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha1-wuep93IJTe6dNCAq6KzORoeHVYA=", + "dev": true + }, + "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.0", + "log-symbols": "^1.0.2", + "log-update": "^1.0.2", + "ora": "^0.2.3", + "p-map": "^1.1.1", + "rxjs": "^6.1.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.0" + } + }, + "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.0.0" + } + }, + "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.0" + } + } + } + }, + "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.0.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.0" + } + }, + "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.0.0" + } + } + } + }, + "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.27.2", + "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.0" + } + }, + "onetime": { + "version": "1.1.0", + "resolved": "https://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.0.0", + "onetime": "^1.0.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=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", + "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, + "requires": { + "big.js": "^3.1.3", + "emojis-list": "^2.0.0", + "json5": "^0.5.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.clone": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz", + "integrity": "sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "dev": true + }, + "lodash.sortby": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz", + "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=", + "dev": true + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + }, + "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.0" + } + }, + "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.3.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" + } + } + } + }, + "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.0.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": "https://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.0.0", + "onetime": "^1.0.0" + } + } + } + }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", + "integrity": "sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA==" + }, + "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.0" + } + }, + "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" + } + }, + "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" + } + }, + "makeerror": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", + "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "dev": true, + "requires": { + "tmpl": "1.0.x" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "marked": { + "version": "0.3.19", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", + "dev": true + }, + "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.0", + "inherits": "^2.0.1" + } + }, + "mdn-browser-compat-data": { + "version": "0.0.84", + "resolved": "https://registry.npmjs.org/mdn-browser-compat-data/-/mdn-browser-compat-data-0.0.84.tgz", + "integrity": "sha512-fAznuGNaQMQiWLVf+gyp33FaABTglYWqMT7JqvH+4RZn2UQPD12gbMqxwP9m0lj8AAbNpu5/kD6n4Ox1SOffpw==", + "dev": true, + "requires": { + "extend": "3.0.2" + } + }, + "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.0.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.0", + "vinyl": "^1.1.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.5.9", + "glob": "^7.0.3", + "globby": "^8.0.0", + "isbinaryfile": "^3.0.2", + "mkdirp": "^0.5.0", + "multimatch": "^2.0.0", + "rimraf": "^2.2.8", + "through2": "^2.0.0", + "vinyl": "^2.0.1" + }, + "dependencies": { + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", + "dev": true + }, + "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.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + } + } + } + }, + "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.3", + "readable-stream": "^2.0.1" + } + }, + "merge": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/merge/-/merge-1.2.1.tgz", + "integrity": "sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ==", + "dev": true + }, + "merge-stream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-1.0.1.tgz", + "integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "merge2": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.2.tgz", + "integrity": "sha512-bgM8twH86rWni21thii6WCMQMRMmwqqdW3sGWi9IipnVAszdLXRjwDwAnyrVXo6DuP3AjRMMttZKUB48QWIFGg==", + "dev": true + }, + "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.2", + "expand-brackets": "^0.1.4", + "extglob": "^0.3.1", + "filename-regex": "^2.0.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.1", + "kind-of": "^3.0.2", + "normalize-path": "^2.0.1", + "object.omit": "^2.0.0", + "parse-glob": "^3.0.4", + "regex-cache": "^0.4.2" + }, + "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.0.1" + } + }, + "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.1", + "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.0" + } + }, + "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" + } + } + } + }, + "milagro-crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/milagro-crypto-js/-/milagro-crypto-js-3.3.0.tgz", + "integrity": "sha512-WHgfNpMq2SlkZuqgDGMGUTib2lKe6UPpxT6aiWxmSWK+LWvpBlkKhnOK8ph+TIPk3a+ZvGJeBO89nW0LcgTL7w==" + }, + "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.0.0", + "brorand": "^1.0.1" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "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 + }, + "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==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mississippi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz", + "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^2.0.1", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.1", + "arrify": "^1.0.0", + "minimatch": "^3.0.0" + } + }, + "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==", + "dev": true, + "optional": true + }, + "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.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "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 + } + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "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 + }, + "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-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "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.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^1.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.0", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.10.3", + "vm-browserify": "0.0.4" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-notifier": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz", + "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "semver": "^5.4.1", + "shellwords": "^0.1.1", + "which": "^1.3.0" + } + }, + "node-releases": { + "version": "1.1.39", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.39.tgz", + "integrity": "sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA==", + "dev": true, + "requires": { + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "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.0", + "strip-ansi": "~0.1.0" + } + }, + "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 + } + } + }, + "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==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "is-builtin-module": "^1.0.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "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.0.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.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "nwsapi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.0.0.tgz", + "integrity": "sha512-9kj1oCEDNq+LHDAVPGDPg9+qRcBcpXb1IYC8q89jR8xJvOC2byQwEVsM3W1qQcSPVyzGGaXN7wZHnXORCiZl4w==", + "dev": true + }, + "oauth-sign": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", + "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "dev": true + }, + "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.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "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": "1.0.11", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", + "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.getownpropertydescriptors": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", + "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.5.1" + } + }, + "object.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.4", + "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=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "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.1", + "wordwrap": "~0.0.2" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + }, + "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.1", + "cli-cursor": "^1.0.2", + "cli-spinners": "^0.1.2", + "object-assign": "^4.0.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": "https://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.0.0", + "onetime": "^1.0.0" + } + } + } + }, + "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": "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" + } + }, + "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 + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz", + "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-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 + }, + "parallel-transform": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", + "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", + "dev": true, + "requires": { + "cyclist": "~0.2.2", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "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.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3" + } + }, + "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.0", + "is-extglob": "^1.0.0", + "is-glob": "^2.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "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 + }, + "parse5": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz", + "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "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=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", + "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "dev": true + }, + "path-type": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz", + "integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "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.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "performance-now": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", + "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkcs7": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pkcs7/-/pkcs7-1.0.2.tgz", + "integrity": "sha1-ttulJ1KMKUK/wSLOLa/NteWQdOc=" + }, + "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" + } + }, + "pn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz", + "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==", + "dev": true + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "prepend-http": { + "version": "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.12.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.12.1.tgz", + "integrity": "sha1-wa0g6APndJ+vkFpAnSNn4Gu+cyU=", + "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 + }, + "pretty-format": { + "version": "23.0.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-23.0.0.tgz", + "integrity": "sha1-tm3FhKCQexlpeDxMIOTRGAsYrHU=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.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 + }, + "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.0" + } + } + } + }, + "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.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "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==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-controller": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/promise-controller/-/promise-controller-0.2.0.tgz", + "integrity": "sha512-2NG+3/E2waxHNqBeS0/UeKyxim1yJ7Omwal1faR9hn+7nccMs9nQ/4Xy/7Fr510zKirbI+Tu1mVn+9uxYzTUsw==" + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "promise-timeout": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/promise-timeout/-/promise-timeout-1.3.0.tgz", + "integrity": "sha512-5yANTE0tmi5++POym6OgtFmwfDvOXABD9oj/jLQr5GPEyuNEb7jH4wbbANJceJid49jwhi1RddxnhnEAb/doqg==" + }, + "promise.prototype.finally": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/promise.prototype.finally/-/promise.prototype.finally-3.1.1.tgz", + "integrity": "sha512-gnt8tThx0heJoI3Ms8a/JdkYBVhYP/wv+T7yQimR+kdOEJL21xTFbiJhMRqnSPcr54UVvMbsscDk2w+ivyaLPw==", + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.13.0", + "function-bind": "^1.1.1" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "es-abstract": { + "version": "1.16.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.16.0.tgz", + "integrity": "sha512-xdQnfykZ9JMEiasTAJZJdMWCQ1Vm00NBw79/AWi7ELfZuuPCSOMDZbT9mkOfSctVtfhb+sAAzrm+j//GjjLHLg==", + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.0", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-inspect": "^1.6.0", + "object-keys": "^1.1.1", + "string.prototype.trimleft": "^2.1.0", + "string.prototype.trimright": "^2.1.0" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "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" + } + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==" + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "requires": { + "has-symbols": "^1.0.0" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", + "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1" + } + }, + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "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 + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "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.0", + "strict-uri-encode": "^1.0.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.0", + "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.0" + } + }, + "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.5", + "safe-buffer": "^5.1.0" + } + }, + "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.1" + } + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "dev": true, + "requires": { + "load-json-file": "^1.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^1.0.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=", + "dev": true, + "requires": { + "find-up": "^1.0.0", + "read-pkg": "^1.0.0" + }, + "dependencies": { + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "path-exists": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", + "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=", + "dev": true, + "requires": { + "pinkie-promise": "^2.0.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==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "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.2", + "minimatch": "^3.0.2", + "readable-stream": "^2.0.2", + "set-immediate-shim": "^1.0.1" + } + }, + "realpath-native": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/realpath-native/-/realpath-native-1.0.0.tgz", + "integrity": "sha512-XJtlRJ9jf0E1H1SLeJyQ9PGzQD7S65h1pRXEcAeK48doKOnKxcgPeNohJvD5u/2sI9J1oke6E8bZHS/fmW1UiQ==", + "dev": true, + "requires": { + "util.promisify": "^1.0.0" + } + }, + "recast": { + "version": "0.14.7", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.14.7.tgz", + "integrity": "sha512-/nwm9pkrcWagN40JeJhkPaRxiHXBRkXyRh/hgU088Z/v+qCy+zIHHY6bC6o7NaKAxPqtE6nD8zBH1LfU0/Wx6A==", + "dev": true, + "requires": { + "ast-types": "0.11.3", + "esprima": "~4.0.0", + "private": "~0.1.5", + "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.1.6" + } + }, + "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.10.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz", + "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=" + }, + "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.18.0", + "babel-types": "^6.19.0", + "private": "^0.1.6" + } + }, + "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.2.1", + "regjsgen": "^0.2.0", + "regjsparser": "^0.1.4" + } + }, + "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.0" + } + }, + "replace-ext": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true + }, + "request": { + "version": "2.87.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", + "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.6.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.5", + "extend": "~3.0.1", + "forever-agent": "~0.6.1", + "form-data": "~2.3.1", + "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.17", + "oauth-sign": "~0.8.2", + "performance-now": "^2.1.0", + "qs": "~6.5.1", + "safe-buffer": "^5.1.1", + "tough-cookie": "~2.3.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.1.0" + } + }, + "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.13.1" + } + }, + "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.0", + "tough-cookie": ">=2.3.3" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "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=", + "dev": true + }, + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + }, + "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.0", + "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.0" + } + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "rimraf": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", + "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, + "requires": { + "glob": "^7.0.5" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rsvp": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.6.2.tgz", + "integrity": "sha512-OfWGQTb9vnwRjwtA2QwpG2ICclHC3pgXZO5xt8H2EfgDquO0qVdSb5T88L4qJVAEugbS56pAuV4XZM58UX8ulw==", + "dev": true + }, + "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" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "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.10" + } + }, + "sane": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/sane/-/sane-2.5.2.tgz", + "integrity": "sha1-tNwYYcIbQn6SlQej51HiosuKs/o=", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "capture-exit": "^1.2.0", + "exec-sh": "^0.2.0", + "fb-watchman": "^2.0.0", + "fsevents": "^1.2.3", + "micromatch": "^3.1.4", + "minimist": "^1.1.1", + "walker": "~1.0.5", + "watch": "~0.18.0" + }, + "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 + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "0.4.5", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", + "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.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.0", + "uri-js": "^4.2.1" + } + }, + "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 + } + } + }, + "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-async": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/scrypt-async/-/scrypt-async-2.0.1.tgz", + "integrity": "sha512-wHR032jldwZNy7Tzrfu7RccOgGf8r5hyDMSP2uV6DpLiBUsR8JsDcx/in73o2UGVVrH5ivRFdNsFPcjtl3LErQ==" + }, + "secure-random": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/secure-random/-/secure-random-1.1.1.tgz", + "integrity": "sha1-CIDy2MUYX0vLRoQFjINrTdsHFFo=" + }, + "semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==", + "dev": true + }, + "serialize-javascript": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz", + "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==", + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "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.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "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.1", + "safe-buffer": "^5.0.1" + } + }, + "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 + }, + "shell-quote": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/shell-quote/-/shell-quote-1.6.1.tgz", + "integrity": "sha1-9HgZSczkAmlxJ0MOo7PFR29IF2c=", + "dev": true, + "requires": { + "array-filter": "~0.0.0", + "array-map": "~0.0.0", + "array-reduce": "~0.0.0", + "jsonify": "~0.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.0.0", + "interpret": "^1.0.0", + "rechoir": "^0.6.2" + } + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "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 + }, + "sm.js": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/sm.js/-/sm.js-0.1.7.tgz", + "integrity": "sha1-4qyBqygZMGwJcWdXBcUEMza6VUg=", + "requires": { + "bn.js": "^4.11.6", + "elliptic": "^6.4.0", + "hash.js": "^1.0.3", + "hmac-drbg": "^1.0.1", + "inherits": "^2.0.3" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "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" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "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.0" + } + }, + "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.0.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.6" + } + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz", + "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=", + "dev": true, + "requires": { + "asn1": "~0.2.3", + "assert-plus": "^1.0.0", + "bcrypt-pbkdf": "^1.0.0", + "dashdash": "^1.12.0", + "ecc-jsbn": "~0.1.1", + "getpass": "^0.1.1", + "jsbn": "~0.1.0", + "tweetnacl": "~0.14.0" + } + }, + "ssri": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz", + "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "stack-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-1.0.1.tgz", + "integrity": "sha1-1PM6tU6OOHeLDKXP07OvsS22hiA=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "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.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz", + "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.2", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz", + "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", + "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", + "dev": true + }, + "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-length": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-2.0.0.tgz", + "integrity": "sha1-1A27aGo6zpYMHP/KVivyxF+DY+0=", + "dev": true, + "requires": { + "astral-regex": "^1.0.0", + "strip-ansi": "^4.0.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 + }, + "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" + } + } + } + }, + "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": "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" + }, + "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 + }, + "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" + } + } + } + }, + "string.prototype.trimleft": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.0.tgz", + "integrity": "sha512-FJ6b7EgdKxxbDxc79cOlok6Afd++TTs5szo+zJTUyow3ycrRfJVE2pq3vcN53XexvKZu/DJMDfeI/qMiZTrjTw==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } + } + }, + "string.prototype.trimright": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.0.tgz", + "integrity": "sha512-fXZTSV55dNBwv16uw+hh5jkghxSnc5oHq+5K/gXgizHwAvMetdAJlHqqoFC1FSDVPYWLkAKl2cxpUT41sV7nSg==", + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + }, + "dependencies": { + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "requires": { + "object-keys": "^1.0.12" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==" + } + } + }, + "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.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-bom": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz", + "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=", + "dev": true, + "requires": { + "is-utf8": "^0.2.0" + } + }, + "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 + }, + "subarg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/subarg/-/subarg-1.0.0.tgz", + "integrity": "sha1-9izxdYHplrSPyWVpn1TAauJouNI=", + "dev": true, + "requires": { + "minimist": "^1.1.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "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 + }, + "symbol-tree": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz", + "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=", + "dev": true + }, + "tapable": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.0.0.tgz", + "integrity": "sha512-dQRhbNQkRnaqauC7WqSJ21EEksgT0fYZX2lqXzGkpo8JNig9zGZTYoMGvyI2nWmXlE2VSVXVDu7wLVGu/mQEsg==", + "dev": true + }, + "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.0", + "rimraf": "~2.2.6" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", + "dev": true + } + } + }, + "test-exclude": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-4.2.1.tgz", + "integrity": "sha512-qpqlP/8Zl+sosLxBcVKl9vYy26T9NPalxSzzCP/OY6K7j938ui2oKgo+kRZYfxAeIpLqpbVnsHq1tyV70E4lWQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "micromatch": "^3.1.8", + "object-assign": "^4.1.0", + "read-pkg-up": "^1.0.1", + "require-main-filename": "^1.0.1" + }, + "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 + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "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 + }, + "throat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/throat/-/throat-4.1.0.tgz", + "integrity": "sha1-iQN8vJLFarGJJua6TLsgDhVnKmo=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "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.1.5", + "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.4" + } + }, + "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" + } + }, + "tmpl": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", + "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "dev": true + }, + "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-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "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==", + "dev": true, + "requires": { + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "tr46": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz", + "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "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 + }, + "ts-jest": { + "version": "22.4.6", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-22.4.6.tgz", + "integrity": "sha512-kYQ6g1G1AU+bOO9rv+SSQXg4WTcni6Wx3AM48iHni0nP1vIuhdNRjKTE9Cxx36Ix/IOV7L85iKu07dgXJzH2pQ==", + "dev": true, + "requires": { + "babel-core": "^6.26.3", + "babel-plugin-istanbul": "^4.1.6", + "babel-plugin-transform-es2015-modules-commonjs": "^6.26.2", + "babel-preset-jest": "^22.4.3", + "cpx": "^1.5.0", + "fs-extra": "6.0.0", + "jest-config": "^22.4.3", + "lodash": "^4.17.10", + "pkg-dir": "^2.0.0", + "source-map-support": "^0.5.5", + "yargs": "^11.0.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 + }, + "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.0" + } + }, + "babel-plugin-jest-hoist": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.4.tgz", + "integrity": "sha512-DUvGfYaAIlkdnygVIEl0O4Av69NtuQWcrjMOv6DODPuhuGLDnbsARz3AwiiI/EkIMMlxQDUcrZ9yoyJvTNjcVQ==", + "dev": true + }, + "babel-preset-jest": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-22.4.4.tgz", + "integrity": "sha512-+dxMtOFwnSYWfum0NaEc0O03oSdwBsjx4tMSChRDPGwu/4wSY6Q6ANW3wkjKpJzzguaovRs/DODcT4hbSN8yiA==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^22.4.4", + "babel-plugin-syntax-object-rest-spread": "^6.13.0" + } + }, + "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.3.0" + } + }, + "expect": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/expect/-/expect-22.4.3.tgz", + "integrity": "sha512-XcNXEPehqn8b/jm8FYotdX0YrXn36qp4HWlrVT4ktwQas1l1LPxiVWncYnnL2eyMtKAmVIaG0XAp0QlrqJaxaA==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "jest-diff": "^22.4.3", + "jest-get-type": "^22.4.3", + "jest-matcher-utils": "^22.4.3", + "jest-message-util": "^22.4.3", + "jest-regex-util": "^22.4.3" + } + }, + "jest-config": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-22.4.4.tgz", + "integrity": "sha512-9CKfo1GC4zrXSoMLcNeDvQBfgtqGTB1uP8iDIZ97oB26RCUb886KkKWhVcpyxVDOUxbhN+uzcBCeFe7w+Iem4A==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "glob": "^7.1.1", + "jest-environment-jsdom": "^22.4.1", + "jest-environment-node": "^22.4.1", + "jest-get-type": "^22.1.0", + "jest-jasmine2": "^22.4.4", + "jest-regex-util": "^22.1.0", + "jest-resolve": "^22.4.2", + "jest-util": "^22.4.1", + "jest-validate": "^22.4.4", + "pretty-format": "^22.4.0" + } + }, + "jest-diff": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-22.4.3.tgz", + "integrity": "sha512-/QqGvCDP5oZOF6PebDuLwrB2BMD8ffJv6TAGAdEVuDx1+uEgrHpSFrfrOiMRx2eJ1hgNjlQrOQEHetVwij90KA==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "diff": "^3.2.0", + "jest-get-type": "^22.4.3", + "pretty-format": "^22.4.3" + } + }, + "jest-environment-jsdom": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz", + "integrity": "sha512-FviwfR+VyT3Datf13+ULjIMO5CSeajlayhhYQwpzgunswoaLIPutdbrnfUHEMyJCwvqQFaVtTmn9+Y8WCt6n1w==", + "dev": true, + "requires": { + "jest-mock": "^22.4.3", + "jest-util": "^22.4.3", + "jsdom": "^11.5.1" + } + }, + "jest-environment-node": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-22.4.3.tgz", + "integrity": "sha512-reZl8XF6t/lMEuPWwo9OLfttyC26A5AMgDyEQ6DBgZuyfyeNUzYT8BFo6uxCCP/Av/b7eb9fTi3sIHFPBzmlRA==", + "dev": true, + "requires": { + "jest-mock": "^22.4.3", + "jest-util": "^22.4.3" + } + }, + "jest-jasmine2": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-22.4.4.tgz", + "integrity": "sha512-nK3vdUl50MuH7vj/8at7EQVjPGWCi3d5+6aCi7Gxy/XMWdOdbH1qtO/LjKbqD8+8dUAEH+BVVh7HkjpCWC1CSw==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "co": "^4.6.0", + "expect": "^22.4.0", + "graceful-fs": "^4.1.11", + "is-generator-fn": "^1.0.0", + "jest-diff": "^22.4.0", + "jest-matcher-utils": "^22.4.0", + "jest-message-util": "^22.4.0", + "jest-snapshot": "^22.4.0", + "jest-util": "^22.4.1", + "source-map-support": "^0.5.0" + } + }, + "jest-matcher-utils": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz", + "integrity": "sha512-lsEHVaTnKzdAPR5t4B6OcxXo9Vy4K+kRRbG5gtddY8lBEC+Mlpvm1CJcsMESRjzUhzkz568exMV1hTB76nAKbA==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-get-type": "^22.4.3", + "pretty-format": "^22.4.3" + } + }, + "jest-message-util": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-22.4.3.tgz", + "integrity": "sha512-iAMeKxhB3Se5xkSjU0NndLLCHtP4n+GtCqV0bISKA5dmOXQfEbdEmYiu2qpnWBDCQdEafNDDU6Q+l6oBMd/+BA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0-beta.35", + "chalk": "^2.0.1", + "micromatch": "^2.3.11", + "slash": "^1.0.0", + "stack-utils": "^1.0.1" + } + }, + "jest-mock": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-22.4.3.tgz", + "integrity": "sha512-+4R6mH5M1G4NK16CKg9N1DtCaFmuxhcIqF4lQK/Q1CIotqMs/XBemfpDPeVZBFow6iyUNu6EBT9ugdNOTT5o5Q==", + "dev": true + }, + "jest-regex-util": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-22.4.3.tgz", + "integrity": "sha512-LFg1gWr3QinIjb8j833bq7jtQopiwdAs67OGfkPrvy7uNUbVMfTXXcOKXJaeY5GgjobELkKvKENqq1xrUectWg==", + "dev": true + }, + "jest-resolve": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-22.4.3.tgz", + "integrity": "sha512-u3BkD/MQBmwrOJDzDIaxpyqTxYH+XqAXzVJP51gt29H8jpj3QgKof5GGO2uPGKGeA1yTMlpbMs1gIQ6U4vcRhw==", + "dev": true, + "requires": { + "browser-resolve": "^1.11.2", + "chalk": "^2.0.1" + } + }, + "jest-snapshot": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-22.4.3.tgz", + "integrity": "sha512-JXA0gVs5YL0HtLDCGa9YxcmmV2LZbwJ+0MfyXBBc5qpgkEYITQFJP7XNhcHFbUvRiniRpRbGVfJrOoYhhGE0RQ==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-diff": "^22.4.3", + "jest-matcher-utils": "^22.4.3", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^22.4.3" + } + }, + "jest-util": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-22.4.3.tgz", + "integrity": "sha512-rfDfG8wyC5pDPNdcnAlZgwKnzHvZDu8Td2NJI/jAGKEGxJPYiE4F0ss/gSAkG4778Y23Hvbz+0GMrDJTeo7RjQ==", + "dev": true, + "requires": { + "callsites": "^2.0.0", + "chalk": "^2.0.1", + "graceful-fs": "^4.1.11", + "is-ci": "^1.0.10", + "jest-message-util": "^22.4.3", + "mkdirp": "^0.5.1", + "source-map": "^0.6.0" + } + }, + "jest-validate": { + "version": "22.4.4", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-22.4.4.tgz", + "integrity": "sha512-dmlf4CIZRGvkaVg3fa0uetepcua44DHtktHm6rcoNVtYlpwe6fEJRkMFsaUVcFHLzbuBJ2cPw9Gl9TKfnzMVwg==", + "dev": true, + "requires": { + "chalk": "^2.0.1", + "jest-config": "^22.4.4", + "jest-get-type": "^22.1.0", + "leven": "^2.1.0", + "pretty-format": "^22.4.0" + } + }, + "pretty-format": { + "version": "22.4.3", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-22.4.3.tgz", + "integrity": "sha512-S4oT9/sT6MN7/3COoOy+ZJeA92VmOnveLHgrwBE3Z1W5N9S2A1QGNYiE1z75DAENbJrXXUb+OWXhpJcg05QKQQ==", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0", + "ansi-styles": "^3.2.0" + } + }, + "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.0.0", + "source-map": "^0.6.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" + } + } + } + }, + "ts-loader": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-4.3.0.tgz", + "integrity": "sha512-+zduqQJaeouVrGY3y6+nUG7+OE1+Q7slGCHsiQM/aITCEZ0og3GxrJVsnjM5QcWvOcu9C4VR5dP+egIyT+sNNg==", + "dev": true, + "requires": { + "chalk": "^2.3.0", + "enhanced-resolve": "^4.0.0", + "loader-utils": "^1.0.2", + "micromatch": "^3.1.4", + "semver": "^5.0.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.0" + } + }, + "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.3.0" + } + }, + "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 + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "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" + } + } + } + }, + "tslib": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.1.tgz", + "integrity": "sha512-avfPS28HmGLLc2o4elcc2EIq2FcH++Yo5YxpBZi9Yw93BCTGFthI4HPE4Rpep6vSYQaK8e69PelM44tPj+RaQg==", + "dev": true + }, + "tslint": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.10.0.tgz", + "integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=", + "dev": true, + "requires": { + "babel-code-frame": "^6.22.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^3.2.0", + "glob": "^7.1.1", + "js-yaml": "^3.7.0", + "minimatch": "^3.0.4", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.8.0", + "tsutils": "^2.12.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.0" + } + }, + "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.3.0" + } + }, + "resolve": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "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" + } + } + } + }, + "tslint-eslint-rules": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/tslint-eslint-rules/-/tslint-eslint-rules-5.3.1.tgz", + "integrity": "sha512-qq2H/AU/FlFbQJKXuxhtIk+ni/nQu9jHHhsFKa6hnA0/n3zl1/RWRc3TVFlL8HfWFMzkST350VeTrFpy1u4OUg==", + "dev": true, + "requires": { + "doctrine": "0.7.2", + "tslib": "1.9.0", + "tsutils": "2.8.0" + }, + "dependencies": { + "tslib": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.0.tgz", + "integrity": "sha512-f/qGG2tUkrISBlQZEjEqoZ3B2+npJjIf04H1wuAv9iA8i04Icp+61KRXxFdha22670NJopsZCIjhC3SnjPRKrQ==", + "dev": true + }, + "tsutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.8.0.tgz", + "integrity": "sha1-AWAXNymzvxOGKN0UoVN+AIUdgUo=", + "dev": true, + "requires": { + "tslib": "^1.7.1" + } + } + } + }, + "tslint-no-circular-imports": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/tslint-no-circular-imports/-/tslint-no-circular-imports-0.4.0.tgz", + "integrity": "sha1-2iLUQjdvDrWwNziwuRo9iUn2uPM=", + "dev": true + }, + "tsutils": { + "version": "2.27.1", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.27.1.tgz", + "integrity": "sha512-AE/7uzp32MmaHvNNFES85hhUDHFdFZp6OAiZcd6y4ZKKIg6orJTm8keYWBhIhrJQH3a4LzNKat7ZPXZt5aTf6w==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "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=", + "dev": true, + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true, + "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" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typedoc": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/typedoc/-/typedoc-0.11.1.tgz", + "integrity": "sha512-jdNIoHm5wkZqxQTe/g9AQ3LKnZyrzHXqu6A/c9GUOeJyBWLxNr7/Dm3rwFvLksuxRNwTvY/0HRDU9sJTa9WQSg==", + "dev": true, + "requires": { + "@types/fs-extra": "5.0.1", + "@types/handlebars": "4.0.36", + "@types/highlight.js": "9.12.2", + "@types/lodash": "4.14.104", + "@types/marked": "0.3.0", + "@types/minimatch": "3.0.3", + "@types/shelljs": "0.7.8", + "fs-extra": "^5.0.0", + "handlebars": "^4.0.6", + "highlight.js": "^9.0.0", + "lodash": "^4.17.5", + "marked": "^0.3.17", + "minimatch": "^3.0.0", + "progress": "^2.0.0", + "shelljs": "^0.8.1", + "typedoc-default-themes": "^0.5.0", + "typescript": "2.7.2" + }, + "dependencies": { + "fs-extra": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz", + "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "typescript": { + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.7.2.tgz", + "integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==", + "dev": true + } + } + }, + "typedoc-default-themes": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz", + "integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=", + "dev": true + }, + "typedoc-webpack-plugin": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/typedoc-webpack-plugin/-/typedoc-webpack-plugin-1.1.4.tgz", + "integrity": "sha1-XTv8bYJKUvQBCe6J0r+8pfGsMKE=", + "dev": true, + "requires": { + "lodash.clone": "^4.5.0", + "lodash.merge": "^4.6.0" + } + }, + "typeforce": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.12.0.tgz", + "integrity": "sha512-fvnkvueAOFLhtAqDgIA/wMP21SMwS/NQESFKZuwVrj5m/Ew6eK2S0z0iB++cwtROPWDOhaT6OUfla8UwMw4Adg==" + }, + "typescript": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-2.8.3.tgz", + "integrity": "sha512-K7g15Bb6Ra4lKf7Iq2l/I5/En+hLIHmxWZGq3D4DIRNFxMNV6j2SHSvDOqs2tGd4UvD/fJvrwopzQXjLrT7Itw==", + "dev": true + }, + "uglifyjs-webpack-plugin": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz", + "integrity": "sha512-hIQJ1yxAPhEA2yW/i7Fr+SXZVMp+VEI3d42RTHBgQd2yhp/1UdBcR3QEWPV5ahBxlqQDMEMTuTEvDHSFINfwSw==", + "dev": true, + "requires": { + "cacache": "^10.0.4", + "find-cache-dir": "^1.0.0", + "schema-utils": "^0.4.5", + "serialize-javascript": "^1.4.0", + "source-map": "^0.6.1", + "uglify-es": "^3.3.4", + "webpack-sources": "^1.1.0", + "worker-farm": "^1.5.2" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==", + "dev": true + }, + "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 + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + } + } + } + }, + "ultron": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", + "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==" + }, + "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.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unique-filename": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.0.tgz", + "integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.0.tgz", + "integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.1.tgz", + "integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=", + "dev": true + }, + "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.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz", + "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "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 + } + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.0.tgz", + "integrity": "sha512-i+6qA2MPhvoKLuxnJNpXAGhg7HphQOSUq2LKMZD0m15EiskXUkMvKdF4Uui0WYeCUGea+o2cw/ZuwehtfsrNkA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "object.getownpropertydescriptors": "^2.0.3" + } + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + }, + "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 + }, + "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==", + "dev": true, + "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=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.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.0", + "clone-stats": "^0.0.1", + "replace-ext": "0.0.1" + } + }, + "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.2", + "pify": "^2.3.0", + "pinkie-promise": "^2.0.0", + "strip-bom": "^2.0.0", + "strip-bom-stream": "^2.0.0", + "vinyl": "^1.1.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "vm-browserify": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-0.0.4.tgz", + "integrity": "sha1-XX6kW7755Kb/ZflUOOCofDV9WnM=", + "dev": true, + "requires": { + "indexof": "0.0.1" + } + }, + "w3c-hr-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz", + "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=", + "dev": true, + "requires": { + "browser-process-hrtime": "^0.1.2" + } + }, + "walker": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", + "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "dev": true, + "requires": { + "makeerror": "1.0.x" + } + }, + "watch": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/watch/-/watch-0.18.0.tgz", + "integrity": "sha1-KAlUdsbffJDJYxOJkMClQj60uYY=", + "dev": true, + "requires": { + "exec-sh": "^0.2.0", + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "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.2", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0" + }, + "dependencies": { + "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.0", + "braces": "^2.3.0", + "fsevents": "^1.1.2", + "glob-parent": "^3.1.0", + "inherits": "^2.0.1", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^2.1.1", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.0.0", + "upath": "^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.0" + }, + "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.0" + } + } + } + }, + "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-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" + } + } + } + }, + "webassemblyjs": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webassemblyjs/-/webassemblyjs-1.4.3.tgz", + "integrity": "sha512-4lOV1Lv6olz0PJkDGQEp82HempAn147e6BXijWDzz9g7/2nSebVP9GVg62Fz5ZAs55mxq13GA0XLyvY8XkyDjg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/validation": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "@webassemblyjs/wast-parser": "1.4.3", + "long": "^3.2.0" + }, + "dependencies": { + "long": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/long/-/long-3.2.0.tgz", + "integrity": "sha1-2CG3E4yhy1gcFymQ7xTbIAtcR0s=", + "dev": true + } + } + }, + "webidl-conversions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", + "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==", + "dev": true + }, + "webpack": { + "version": "4.9.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.9.0.tgz", + "integrity": "sha512-QvdAfpDVNhm4MEoUSAw+mddeIUDvJqPVp2szvD2ze4x5K7ITxFhLw9taYHCh1KtzuH8WEkCZGYtkEfjKNF9Qjg==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.4.3", + "@webassemblyjs/wasm-edit": "1.4.3", + "@webassemblyjs/wasm-parser": "1.4.3", + "acorn": "^5.0.0", + "acorn-dynamic-import": "^3.0.0", + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0", + "chrome-trace-event": "^0.1.1", + "enhanced-resolve": "^4.0.0", + "eslint-scope": "^3.7.1", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.3.0", + "loader-utils": "^1.1.0", + "memory-fs": "~0.4.1", + "micromatch": "^3.1.8", + "mkdirp": "~0.5.0", + "neo-async": "^2.5.0", + "node-libs-browser": "^2.0.0", + "schema-utils": "^0.4.4", + "tapable": "^1.0.0", + "uglifyjs-webpack-plugin": "^1.2.4", + "watchpack": "^1.5.0", + "webpack-sources": "^1.0.1" + }, + "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.0", + "uri-js": "^4.2.1" + } + }, + "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 + }, + "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 + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + } + } + }, + "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.0" + }, + "dependencies": { + "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 + }, + "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.0", + "babel-plugin-transform-flow-strip-types": "^6.8.0", + "babel-preset-es2015": "^6.9.0", + "babel-preset-stage-1": "^6.5.0", + "babel-register": "^6.9.0", + "babylon": "^6.17.3", + "colors": "^1.1.2", + "flow-parser": "^0.*", + "lodash": "^4.13.1", + "micromatch": "^2.3.7", + "node-dir": "0.1.8", + "nomnom": "^1.8.1", + "recast": "^0.12.5", + "temp": "^0.8.1", + "write-file-atomic": "^1.2.0" + } + }, + "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.4.1", + "esprima": "~4.0.0", + "private": "~0.1.5", + "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 + }, + "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.5" + } + } + } + }, + "webpack-cli": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-2.1.4.tgz", + "integrity": "sha512-dcxBcTPhKczWHYE9jh8MoHGQFuJxfqshZ3XSNFZ8o34heVvkqNvSRbMKy17NML+XUea7CXLzHWDg7a0GsBp7Pg==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cross-spawn": "^6.0.5", + "diff": "^3.5.0", + "enhanced-resolve": "^4.0.0", + "envinfo": "^5.7.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.0", + "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.12.1", + "supports-color": "^5.4.0", + "v8-compile-cache": "^2.0.0", + "webpack-addons": "^1.1.5", + "yargs": "^11.1.0", + "yeoman-environment": "^2.1.1", + "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.0" + } + }, + "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.3.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.0.0" + } + }, + "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.2.9" + } + }, + "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" + } + }, + "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.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + } + } + } + }, + "webpack-node-externals": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz", + "integrity": "sha512-ajerHZ+BJKeCLviLUUmnyd5B4RavLF76uv3cs6KNuO8W+HuQaEs0y0L7o40NQxdPy5w0pcv8Ew7yPUAQG0UdCg==", + "dev": true + }, + "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 + } + } + }, + "websocket-as-promised": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/websocket-as-promised/-/websocket-as-promised-0.8.0.tgz", + "integrity": "sha512-CUqx+vX5Q8m9wwpFgm6aZNbBrPdGFob/oBz9m+DeS6Eox92mroE7MqKm5TWJtPjjseGyut6/megPcTFM3m37rA==", + "requires": { + "chnl": "^0.4.0", + "flat-options": "^0.1.3", + "promise-controller": "^0.2.0", + "promise.prototype.finally": "^3.1.0" + } + }, + "whatwg-encoding": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz", + "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.19" + } + }, + "whatwg-mimetype": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz", + "integrity": "sha512-FKxhYLytBQiUKjkYteN71fAUA3g6KpNXoho1isLiLSB3N1G4F35Q5vUxWfKFhBwi5IWF27VE6WxhrnnC+m0Mew==", + "dev": true + }, + "whatwg-url": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.1.tgz", + "integrity": "sha512-FwygsxsXx27x6XXuExA/ox3Ktwcbf+OAvrKmLulotDAiO1Q6ixchPFaHYsis2zZBZSJTR0+dR+JVtf7MlbqZjw==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", + "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wif": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz", + "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=", + "requires": { + "bs58check": "<3.0.0" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "worker-farm": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz", + "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write-file-atomic": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.3.0.tgz", + "integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "ws": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz", + "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==", + "requires": { + "async-limiter": "~1.0.0", + "safe-buffer": "~5.1.0" + } + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "y18n": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.0.0.tgz", + "integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.1.1", + "find-up": "^2.1.0", + "get-caller-file": "^1.0.1", + "os-locale": "^2.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1", + "yargs-parser": "^9.0.2" + }, + "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 + }, + "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.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" + } + } + } + }, + "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" + }, + "dependencies": { + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + } + } + }, + "yeoman-environment": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/yeoman-environment/-/yeoman-environment-2.1.1.tgz", + "integrity": "sha512-IBLwCUrJrDxBYuwdYm1wuF3O/CR2LpXR0rFS684QOrU6x69DPPrsdd20dZOFaedZ/M9sON7po73WhO3I1CbgNQ==", + "dev": true, + "requires": { + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^3.1.0", + "diff": "^3.3.1", + "escape-string-regexp": "^1.0.2", + "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.1.0", + "mem-fs": "^1.1.0", + "strip-ansi": "^4.0.0", + "text-table": "^0.2.0", + "untildify": "^3.0.2" + }, + "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.0" + } + }, + "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.3.0" + } + }, + "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.2.9" + } + }, + "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.0", + "chalk": "^2.3.0", + "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.0", + "error": "^7.0.2", + "find-up": "^2.1.0", + "github-username": "^4.0.0", + "istextorbinary": "^2.2.1", + "lodash": "^4.17.10", + "make-dir": "^1.1.0", + "mem-fs-editor": "^4.0.0", + "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.0.0", + "shelljs": "^0.8.0", + "text-table": "^0.2.0", + "through2": "^2.0.0", + "yeoman-environment": "^2.0.5" + }, + "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.0" + } + }, + "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.3.0" + } + }, + "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.2.9" + } + }, + "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.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "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.1" + } + }, + "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" + } + }, + "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.3.2", + "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.0.0", + "read-pkg": "^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": "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..5b5b359 --- /dev/null +++ b/package.json @@ -0,0 +1,99 @@ +{ + "name": "dna-ts-sdk", + "version": "1.1.0", + "description": "Comprehensive TypeScript library for the DNA blockchain.", + "main": "./lib/index.js", + "types": "./lib/types/index.d.ts", + "scripts": { + "test": "jest", + "lint": "tslint --project ./", + "build:dev": "cross-env NODE_ENV=development webpack --mode development --display-error-details --progress --color", + "build:prod": "cross-env NODE_ENV=production webpack --mode production --progress --color", + "prepublish": "npm run lint && npm run build:prod", + "compile": "tsc" + }, + "jest": { + "moduleFileExtensions": [ + "ts", + "tsx", + "js" + ], + "transform": { + "\\.(ts|tsx)$": "./node_modules/ts-jest/preprocessor.js" + }, + "testEnvironment": "node", + "testRegex": "/test/.*\\.(ts|tsx|js)$" + }, + "author": "DNAProject", + "license": "LGPL-3.0", + "repository": { + "type": "git", + "url": "git+https://github.com/DNAProject/DNA-ts-SDK" + }, + "keywords": [ + "ontology", + "ont", + "typescript", + "sdk" + ], + "bugs": { + "url": "https://github.com/DNAProject/DNA-ts-SDK/issues" + }, + "devDependencies": { + "@types/base64-url": "^2.2.0", + "@types/bs58": "^3.0.30", + "@types/crypto-js": "^3.1.38", + "@types/ecurve": "^1.0.0", + "@types/jest": "^22.1.2", + "@types/long": "^4.0.0", + "@types/node": "^8.5.2", + "@types/promise-timeout": "^1.3.0", + "@types/scrypt-async": "^1.3.0", + "@types/uuid": "^3.4.3", + "babel-core": "^6.26.3", + "babel-loader": "^7.1.4", + "babel-plugin-transform-runtime": "^6.23.0", + "babel-preset-env": "^1.7.0", + "babel-preset-stage-3": "^6.24.1", + "clean-webpack-plugin": "^0.1.19", + "cross-env": "^5.2.0", + "jest": "^23.0.0", + "ts-jest": "^22.4.6", + "ts-loader": "^4.3.0", + "tslint": "^5.10.0", + "tslint-eslint-rules": "^5.3.1", + "tslint-no-circular-imports": "^0.4.0", + "typedoc": "^0.11.1", + "typedoc-webpack-plugin": "^1.1.4", + "typescript": "^2.8.3", + "webpack": "^4.8.3", + "webpack-cli": "^2.1.4", + "webpack-node-externals": "^1.7.2" + }, + "dependencies": { + "@ont-community/hdkey-secp256r1": "^1.0.1", + "@ont-community/html5-websocket": "^2.0.2", + "axios": "^0.19.0", + "babel-polyfill": "^6.26.0", + "base-58": "^0.0.1", + "base64-url": "^2.2.0", + "bignumber.js": "^7.2.1", + "bip39": "^2.5.0", + "crypto-js": "^3.1.9-1", + "ecdsa": "^0.7.0", + "ecurve": "^1.0.6", + "elliptic": "^6.4.0", + "js-sha3": "^0.7.0", + "long": "^4.0.0", + "milagro-crypto-js": "^3.3.0", + "pkcs7": "^1.0.2", + "promise-timeout": "^1.3.0", + "scrypt-async": "^2.0.0", + "secure-random": "^1.1.1", + "sm.js": "0.1.7", + "uuid": "^3.2.1", + "websocket-as-promised": "^0.8.0", + "wif": "^2.0.6", + "ws": "^4.1.0" + } +} diff --git a/src/account.ts b/src/account.ts new file mode 100644 index 0000000..801f9d0 --- /dev/null +++ b/src/account.ts @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import * as bip39 from 'bip39'; +import { DNA_BIP44_PATH } from './consts'; +import { Address, PrivateKey } from './crypto'; +import { deserializeFromJson } from './crypto/PrivateKeyFactory'; +import { ERROR_CODE } from './error'; +import { ScryptParams } from './scrypt'; +import { Transaction } from './transaction/transaction'; +import { signTransaction } from './transaction/transactionBuilder'; +import { ab2hexstring, generateRandomArray, randomBytes } from './utils'; + +// tslint:disable-next-line:no-var-requires +const HDKey = require('@ont-community/hdkey-secp256r1'); + +export class Account { + /** + * Import account + * @param label Account's label + * @param encryptedPrivateKey Encrypted private key + * @param password User's password to decrypt private key + * @param address Account's address + * @param saltBase64 Salt to decrypt + * @param params Params used to decrypt + */ + static importAccount( + label: string , + encryptedPrivateKey: PrivateKey, + password: string, + address: Address, + saltBase64: string, + params?: ScryptParams + ): Account { + const account = new Account(); + const salt = Buffer.from(saltBase64, 'base64').toString('hex'); + const privateKey = encryptedPrivateKey.decrypt(password, address, salt, params); + + if (!label) { + label = ab2hexstring(generateRandomArray(4)); + } + account.label = label; + account.lock = false; + account.isDefault = false; + account.salt = saltBase64; + + account.encryptedKey = encryptedPrivateKey; + + const publicKey = privateKey.getPublicKey(); + account.publicKey = publicKey.key; + + account.address = Address.fromPubKey(publicKey); + + return account; + } + + /** + * Import account with mnemonic + * @param label Account's label + * @param mnemonic User's mnemonic + * @param password user's password to encrypt the private key + * @param params Params used to encrypt the private key. + */ + static importWithMnemonic( + label: string, + mnemonic: string, + password: string, + params?: ScryptParams + ): Account { + mnemonic = mnemonic.trim(); + if (!bip39.validateMnemonic(mnemonic)) { + throw ERROR_CODE.INVALID_PARAMS; + } + const seed = bip39.mnemonicToSeedHex(mnemonic); + const hdkey = HDKey.fromMasterSeed(Buffer.from(seed, 'hex')); + const pri = hdkey.derive(DNA_BIP44_PATH); + const key = Buffer.from(pri.privateKey).toString('hex'); + const privateKey = new PrivateKey(key); + const account = Account.create(privateKey, password, label, params); + return account; + } + + /** + * Creates Account object encrypting specified private key. + * + * The account does not need to be registered on blockchain. + * + * @param privateKey Private key associated with the account + * @param password Password use to encrypt the private key + * @param label Custom label + * @param params Optional scrypt params + */ + static create( + privateKey: PrivateKey, + password: string, + label?: string, + params?: ScryptParams + ): Account { + const account = new Account(); + if (!label) { + label = ab2hexstring(generateRandomArray(4)); + } + account.label = label; + account.lock = false; + account.isDefault = false; + + const salt = randomBytes(16); + const publicKey = privateKey.getPublicKey(); + const address = Address.fromPubKey(publicKey); + account.publicKey = publicKey.serializeHex(); + account.address = address; + account.encryptedKey = privateKey.encrypt(password, address, salt, params); + account.salt = Buffer.from(salt, 'hex').toString('base64'); + return account; + } + + static parseJson(json: string): Account { + return Account.parseJsonObj(JSON.parse(json)); + } + + /** + * Deserializes JSON object. + * + * Object should be real object, not stringified. + * + * @param obj JSON object + */ + static parseJsonObj(obj: any): Account { + const account = new Account(); + account.address = new Address(obj.address); + account.label = obj.label; + account.lock = obj.lock; + account.isDefault = obj.isDefault; + account.publicKey = obj.publicKey; + account.hash = obj.hash; + account.salt = obj.salt; + account.encryptedKey = deserializeFromJson({ + algorithm: obj.algorithm, + parameters: obj.parameters, + key: obj.key, + external: obj.external + }); + // account.contract = obj.contract + account.extra = obj.extra; + return account; + } + + address: Address; + label: string; + lock: boolean; + encryptedKey: PrivateKey; + extra: null; + + // to compatible with cli wallet + 'enc-alg': string = 'aes-256-gcm'; + hash: string = 'sha256'; + salt: string; + + publicKey: string; + isDefault: boolean; + + toJson(): string { + return JSON.stringify(this.toJsonObj()); + } + + /** + * Serializes to JSON object. + * + * Returned object will not be stringified. + * + */ + toJsonObj(): any { + const obj = { + 'address': this.address.toBase58(), + 'label': this.label, + 'lock': this.lock, + ...this.encryptedKey.serializeJson(), + 'enc-alg': this['enc-alg'], + 'hash': this.hash, + 'salt': this.salt, + 'isDefault': this.isDefault, + 'publicKey': this.publicKey, + 'signatureScheme': this.encryptedKey.algorithm.defaultSchema.label + }; + return obj; + } + + exportPrivateKey(password: string, params?: ScryptParams) { + return this.encryptedKey.decrypt(password, this.address, this.salt, params); + } + + signTransaction(password: string, tx: Transaction, params?: ScryptParams) { + const pri = this.exportPrivateKey(password, params); + signTransaction(tx, pri, pri.algorithm.defaultSchema); + return tx; + } +} diff --git a/src/claim/attestNotifyEvent.ts b/src/claim/attestNotifyEvent.ts new file mode 100644 index 0000000..e7e122d --- /dev/null +++ b/src/claim/attestNotifyEvent.ts @@ -0,0 +1,91 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { hexstr2str } from '../utils'; + +/** + * Represents Notify event of attest creation of revocation. + */ +export class AttestNotifyEvent { + /** + * Deserializes Notify event. + * + * States in events are hex encoded. + * + * @param e encoded event + */ + static deserialize(e: any): AttestNotifyEvent { + const event = new AttestNotifyEvent(); + + event.Action = e.Action; + event.Error = e.Error; + event.Desc = e.Desc; + event.Result = Result.deserialize(e.Result); + + return event; + } + + Action: string = 'Notify'; + Desc: string; + Error: number; + Result: Result; +} + +/** + * Result of Notify event. + */ +export class Result { + /** + * Deserializes result from event. + * + * States are hex encoded. + * + * @param r encoded result + */ + static deserialize(r: any): Result { + const result = new Result(); + + result.TxHash = r.TxHash; + result.State = r.State; + result.GasConsumed = r.GasConsumed; + result.Notify = r.Notify.map((n: any) => { + return { + ContractAddress: n.ContractAddress, + States: n.States.map( (s: any) => typeof s === 'string' ? hexstr2str(s) : s) + }; + }); + result.Version = r.Version; + return result; + } + + TxHash: string; + /** + * State = 1 : smartcontract executation success + * State = 0 : smartcontract executation failure + */ + State: number; + GasConsumed: number; + Notify: [{ + ContractAddress: string; + /** + * The value of States are usually hex string + */ + States: any[]; + }]; + Version: string; +} diff --git a/src/claim/claim.ts b/src/claim/claim.ts new file mode 100644 index 0000000..66c0b45 --- /dev/null +++ b/src/claim/claim.ts @@ -0,0 +1,308 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import * as b64 from 'base64-url'; +import { Address, PrivateKey, Signature, SignatureScheme } from '../crypto'; +import RestClient from '../network/rest/restClient'; +import { WebsocketClient } from '../network/websocket/websocketClient'; +import { + buildCommitRecordTx, + buildGetRecordStatusTx, + buildRevokeRecordTx +} from '../smartcontract/neovm/attestClaimTxBuilder'; +import { signTransactionAsync } from '../transaction/transactionBuilder'; +import { hexstr2str, StringReader } from '../utils'; +import { AttestNotifyEvent } from './attestNotifyEvent'; +import { ClaimProof } from './claimProof'; +import { Message, Metadata } from './message'; + +/** + * Type of revocation. + */ +export enum RevocationType { + AttestContract = 'AttestContract', + RevocationList = 'RevocationList' +} + +/** + * Revocation definition. + */ +export interface Revocation { + /** + * Type of revocation. + */ + type: RevocationType; + + /** + * Url of revocation list if type is RevocationList + */ + url?: string; + + /** + * Address of attest contract if type is AttestContract + */ + addr?: string; +} + +/** + * Verifiable claim. + * + * TODO: override verify to add claim proof verification. + */ +export class Claim extends Message { + static deserialize(jwt: string): Claim { + return super.deserializeInternal(jwt, (m: any, s: any) => new Claim(m, s)); + } + + version: string; + context: string; + content: any; + revocation?: Revocation; + + useProof: boolean; + proof?: ClaimProof; + + constructor(metadata: Metadata, signature?: Signature | undefined, useProof?: boolean) { + super(metadata, signature); + this.useProof = useProof === true; + } + + /** + * Overrides default message verification with added attest verification. + * + * TODO: return more than boolean + * + * const VerifyDNAidClaimResult = { + * CLAIM_NOT_ONCHAIN : 'CLAIM_NOT_ONCHAIN', + * INVALID_SIGNATURE : 'INVALID_SIGNATURE', + * PK_IN_REVOKED : 'PK_IN_REVOKED', + * NO_ISSUER_PK : 'NO_ISSUER_PK', + * EXPIRED_CLAIM : 'EXPIRED_CLAIM', + * REVOKED_CLAIM : 'REVOKED_CLAIM', + * VALID_CLAIM : 'VALID_CLAIM' + * }; + * + * @param url Restful endpoint of DNA node + * @param checkAttest Should be the attest tested + */ + async verify(url: string, checkAttest = true): Promise { + const result = await super.verify(url); + + if (result && checkAttest) { + return this.getStatus(url); + } else { + return result; + } + } + + /** + * Serializes the claim into JWT/JWT-X format. + * + * Override default implementation by adding proof if available. + */ + serialize(): string { + if (this.useProof) { + const jwt = super.serialize(); + const proof = this.serializeProof(); + + return jwt + '.' + proof; + } else { + return super.serialize(); + } + } + + /** + * Attests the claim onto blockchain. + * + * @param url Websocket endpoint of DNA node + * @param privateKey Private key to sign the transaction + * @param gasPrice gasPrice + * @param gasLimit gasLimit + * @param payer payer + */ + async attest(url: string, gasPrice: string, gasLimit: string, + payer: Address, privateKey: PrivateKey): Promise { + const attesterId = this.metadata.issuer; + const subjectId = this.metadata.subject; + const claimId = this.metadata.messageId; + if (claimId === undefined) { + throw new Error('Claim id not specified.'); + } + + const client = new WebsocketClient(url); + const tx = buildCommitRecordTx(claimId, attesterId, subjectId, gasPrice, gasLimit, payer); + await signTransactionAsync(tx, privateKey); + const response = await client.sendRawTransaction(tx.serialize(), false, true); + + const event = AttestNotifyEvent.deserialize(response); + // tslint:disable-next-line:no-console + console.log(JSON.stringify(event)); + return event.Result.Notify[0].States[0] === 'Push'; + } + + /** + * Revokes claim attest from blockchain. + * + * @param gas the cost of the transactoin + * @param payer the payer of the cost + * @param privateKey Private key to sign the transaction + * @param url Websocket endpoint of DNA node + * @param gasPrice gasPrice + * @param gasLimit gasLimit + * @param payer payer + */ + async revoke(url: string, gasPrice: string, + gasLimit: string, payer: Address, privateKey: PrivateKey): Promise { + const attesterId = this.metadata.issuer; + const claimId = this.metadata.messageId; + if (claimId === undefined) { + throw new Error('Claim id not specified.'); + } + const client = new WebsocketClient(url); + const tx = buildRevokeRecordTx(claimId, attesterId, gasPrice, gasLimit, payer); + await signTransactionAsync(tx, privateKey); + const response = await client.sendRawTransaction(tx.serialize(), false, true); + + const event = AttestNotifyEvent.deserialize(response); + + return event.Result.Notify[0].States[0] === 'Push'; + } + + /** + * Gets status of the claim attest. + * + * @param url Restful endpoint of DNA node + */ + async getStatus(url: string): Promise { + const attesterId = this.metadata.issuer; + const claimId = this.metadata.messageId; + if (claimId === undefined) { + throw new Error('Claim id not specified.'); + } + + const client = new RestClient(url); + const tx = buildGetRecordStatusTx(claimId); + + const response = await client.sendRawTransaction(tx.serialize(), true); + + const result = GetStatusResponse.deserialize(response); + // tslint:disable-next-line:no-console + console.log(result); + + return result.status === Status.ATTESTED && result.issuerId === attesterId; + } + + protected payloadToJSON(): any { + return { + 'ver': this.version, + '@context': this.context, + 'clm': this.content, + 'clm-rev': this.revocation + }; + } + + protected payloadFromJSON(json: any): void { + this.version = json.ver; + this.context = json['@context']; + this.content = json.clm; + this.revocation = json['clm-rev']; + } + + /** + * Serializes the header into JWT/JWT-X encoded header. + * + * Override default implementation by adding proof if available. + * + * @param algorithm Signature algorithm used + * @param publicKeyId The ID of a signature public key + */ + protected serializeHeader(algorithm: SignatureScheme | undefined, publicKeyId: string | undefined): string { + if (this.useProof) { + if (algorithm === undefined || publicKeyId === undefined) { + throw new Error('Signature is needed fow JWT-X.'); + } else { + const header = { + alg: algorithm.labelJWS, + typ: 'JWT-X', + kid: publicKeyId + }; + + const stringified = JSON.stringify(header); + return b64.encode(stringified, 'utf-8'); + } + } else { + return super.serializeHeader(algorithm, publicKeyId); + } + } + + /** + * Serializes the proof into JWT-X. + */ + protected serializeProof(): string { + const stringified = JSON.stringify(this.proof); + return b64.encode(stringified, 'utf-8'); + } +} + +/** + * Helper class for deserializing GetStatus response. + * fixme: DNA node changed the response + */ +export class GetStatusResponse { + static deserialize(r: any): GetStatusResponse { + const response = new GetStatusResponse(); + + if (r.Result !== undefined && r.Result.Result === '') { + response.status = Status.NOTFOUND; + return response; + } + const sr = new StringReader(r.Result.Result); + sr.read(1); // data type + sr.readNextLen(); // data length + sr.read(1); // data type + const claimId = hexstr2str(sr.readNextBytes()); + sr.read(1); // data type + const issuerId = hexstr2str(sr.readNextBytes()); + sr.read(1); // data type + const subjectId = hexstr2str(sr.readNextBytes()); + sr.read(1); // data type + let status = sr.readNextBytes(); + response.claimId = claimId; + response.issuerId = issuerId; + response.subjectId = subjectId; + if (!status) {// status is revoked + status = '00'; + } + response.status = status as Status; + return response; + } + + claimId: string; + issuerId: string; + subjectId: string; + status: Status; + // status: Status; + // attesterId: string; + // time: string; +} + +export enum Status { + REVOKED = '00', + ATTESTED = '01', + NOTFOUND = '-1' +} diff --git a/src/claim/claimProof.ts b/src/claim/claimProof.ts new file mode 100644 index 0000000..cdbb258 --- /dev/null +++ b/src/claim/claimProof.ts @@ -0,0 +1,46 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +/** + * Direction of noe in merkle proof + */ +export enum Direction { + Right = 'Right', + Left = 'Left' +} + +/** + * Node in merkle proof + */ +export interface Node { + Direction: Direction; + TargetHash: string; +} + +/** + * TODO: Add merkle proof verification. + * + */ +export class ClaimProof { + Type: 'MerkleProof'; + TxnHash: string; + ContractAddr: string; + BlockHeight: number; + MerkleRoot: string; + Nodes: Node[]; +} diff --git a/src/claim/index.ts b/src/claim/index.ts new file mode 100644 index 0000000..83ea6e7 --- /dev/null +++ b/src/claim/index.ts @@ -0,0 +1,20 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +export { Claim, Revocation, RevocationType } from './claim'; +export { Message, Metadata } from './message'; diff --git a/src/claim/message.ts b/src/claim/message.ts new file mode 100644 index 0000000..ff6b227 --- /dev/null +++ b/src/claim/message.ts @@ -0,0 +1,409 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as b64 from 'base64-url'; +import * as uuid from 'uuid'; +import { PrivateKey, PublicKey, PublicKeyStatus, Signature, SignatureScheme } from '../crypto'; +import RestClient from '../network/rest/restClient'; +import { buildGetDDOTx, buildGetPublicKeyStateTx } from '../smartcontract/nativevm/idContractTxBuilder'; +import { DDO } from '../transaction/ddo'; +import { now } from '../utils'; + +/** + * Factory method type used for creating concrete instances of Message. + */ +export type MessageFactory = ( + metadata: Metadata, + signature: Signature | undefined +) => T; + +/** + * Metadata about the message. + */ +export interface Metadata { + /** + * Message id. + * + * Will be assigned if not provided. + */ + messageId?: string; + + /** + * Issuer. + */ + issuer: string; + + /** + * Recipient. + */ + subject: string; + + /** + * Creation time. + */ + issuedAt: number; + + /** + * Expiration time. + */ + expireAt?: number; +} + +/** + * Common representation of Message in JWT form. + */ +export abstract class Message { + + /** + * Deserializes the message from JWT format. + * + * A concrete instance will be creater through the message factory method. This method + * is called from concrete class. + * + * @param jwt Encoded message + * @param creator Factory method + */ + protected static deserializeInternal(jwt: string, creator: MessageFactory): T { + const parts = jwt.split('.', 3); + + if (parts.length < 2) { + throw new Error('Invalid message.'); + } + + const header = Message.deserializeHeader(parts[0]); + const payload = Message.deserializePayload(parts[1]); + let signature: Signature | undefined; + + if (parts.length > 2) { + if (header.algorithm !== undefined && header.publicKeyId !== undefined) { + signature = Signature.deserializeJWT(parts[2], header.algorithm, header.publicKeyId); + } else { + throw new Error('Signature scheme was not specified.'); + } + } + + const msg = creator(payload.metadata, signature); + msg.payloadFromJSON(payload.rest); + return msg; + } + + /** + * Deserializes payload part of JWT message. + * + * @param encoded JWT encoded payload + */ + private static deserializePayload(encoded: string) { + const stringified = b64.decode(encoded); + const { jti, iss, sub, iat, exp, ...rest } = JSON.parse(stringified); + + return { + metadata: { + messageId: jti, + issuer: iss, + subject: sub, + issuedAt: iat, + expireAt: exp + } as Metadata, + rest + }; + } + + /** + * Deserializes the header from JWT encoded header. + * + * @param encoded JWT encoded header + */ + private static deserializeHeader(encoded: string) { + const stringified = b64.decode(encoded); + const header = JSON.parse(stringified); + + return { + algorithm: header.alg !== undefined ? SignatureScheme.fromLabelJWS(header.alg) : undefined, + publicKeyId: header.kid + }; + } + + metadata: Metadata; + signature?: Signature; + + constructor(metadata: Metadata, signature: Signature | undefined) { + this.metadata = metadata; + this.signature = signature; + + if (this.metadata.messageId === undefined) { + this.metadata.messageId = uuid(); + } + } + + /** + * Signs the message and store the signature inside the request. + * + * If the algorithm is not specified, then default algorithm for Private key type is used. + * + * @param url Restful endpoint of DNA node + * @param publicKeyId The ID of a signature public key + * @param privateKey Private key to sign the request with + * @param algorithm Signature algorithm used + */ + async sign( + url: string, + publicKeyId: string, + privateKey: PrivateKey, + algorithm?: SignatureScheme + ): Promise { + await retrievePublicKey(publicKeyId, url); + + if (algorithm === undefined) { + algorithm = privateKey.algorithm.defaultSchema; + } + + const msg = this.serializeUnsigned(algorithm, publicKeyId); + this.signature = await privateKey.signAsync(msg, algorithm, publicKeyId); + } + + /** + * Verifies the signature and check ownership of specified DNA ID through smart contract call. + * + * @param url Restful endpoint of DNA node + * @returns Boolean if the ownership is confirmed + */ + async verify(url: string): Promise { + const signature = this.signature; + + if (signature !== undefined && signature.publicKeyId !== undefined) { + try { + if (!this.verifyKeyOwnership()) { + return false; + } + + if (!this.verifyExpiration()) { + return false; + } + + const state = await retrievePublicKeyState(signature.publicKeyId, url); + if (state === PublicKeyStatus.REVOKED) { + return false; + } + + const publicKey = await retrievePublicKey(signature.publicKeyId, url); + + const msg = this.serializeUnsigned(signature.algorithm, signature.publicKeyId); + return publicKey.verify(msg, signature); + } catch (e) { + return false; + } + } else { + return false; + } + } + + /** + * Serializes the message without signature into JWT format. + * + * Header might contain algorithm and public key id. + * + * @param algorithm Signature algorithm used + * @param publicKeyId The ID of a signature public key + */ + serializeUnsigned(algorithm?: SignatureScheme, publicKeyId?: string): string { + const headerEncoded = this.serializeHeader(algorithm, publicKeyId); + const payloadEncoded = this.serializePayload(); + + return headerEncoded + '.' + payloadEncoded; + } + + /** + * Serializes the message into JWT format. + * + */ + serialize(): string { + const signature = this.signature; + + if (signature !== undefined) { + const signatureEncoded = signature.serializeJWT(); + return this.serializeUnsigned(signature.algorithm, signature.publicKeyId) + '.' + signatureEncoded; + } else { + return this.serializeUnsigned(); + } + } + + /** + * Serializes the header into JWT encoded header. + * + * @param algorithm Signature algorithm used + * @param publicKeyId The ID of a signature public key + */ + protected serializeHeader( + algorithm: SignatureScheme | undefined, + publicKeyId: string | undefined + ): string { + let header; + if (algorithm !== undefined) { + header = { + alg: algorithm.labelJWS, + typ: 'JWT', + kid: publicKeyId + }; + } else { + header = { + typ: 'JWT' + }; + } + + const stringified = JSON.stringify(header); + return b64.encode(stringified, 'utf-8'); + } + + /** + * Converts claim data to JSON for serialization. + */ + protected abstract payloadToJSON(): any; + + /** + * Retrieves data from JSON. + * + * @param json JSON object with data + */ + protected abstract payloadFromJSON(json: any): void; + + /** + * Verifies if the expiration date has passed + */ + private verifyExpiration(): boolean { + if (this.metadata.expireAt !== undefined) { + return now() < this.metadata.expireAt; + } else { + return true; + } + } + + /** + * Verifies if the declared public key id belongs to issuer. + */ + private verifyKeyOwnership(): boolean { + const signature = this.signature; + + if (signature !== undefined && signature.publicKeyId !== undefined) { + const dnaid = extractDNAId(signature.publicKeyId); + + return dnaid === this.metadata.issuer; + } else { + return false; + } + } + + /** + * Serializes payload part of JWT message. + */ + private serializePayload(): string { + const metadata = { + jti: this.metadata.messageId, + iss: this.metadata.issuer, + sub: this.metadata.subject, + iat: this.metadata.issuedAt, + exp: this.metadata.expireAt + }; + const rest = this.payloadToJSON(); + + const stringified = JSON.stringify({...metadata, ...rest}); + return b64.encode(stringified, 'utf-8'); + } +} + +/** + * Gets the public key associated with DNA ID from blockchain. + * + * @param publicKeyId The ID of a signature public key + * @param url Restful endpoint of DNA node + */ +export async function retrievePublicKey(publicKeyId: string, url: string): Promise { + const dnaid = extractDNAId(publicKeyId); + const keyId = extractKeyId(publicKeyId); + + const client = new RestClient(url); + const tx = buildGetDDOTx(dnaid); + const response = await client.sendRawTransaction(tx.serialize(), true); + + if (response.Result && response.Result.Result) { + const ddo = DDO.deserialize(response.Result.Result); + + const publicKey = ddo.publicKeys.find((pk) => pk.id === keyId); + + if (publicKey === undefined) { + throw new Error('Not found'); + } + + return publicKey.pk; + } else { + throw new Error('Not found'); + } +} + +/** + * Gets the state of public key associated with DNA ID from blockchain. + * + * @param publicKeyId The ID of a signature public key + * @param url Restful endpoint of DNA node + */ +export async function retrievePublicKeyState(publicKeyId: string, url: string): Promise { + const dnaid = extractDNAId(publicKeyId); + const keyId = extractKeyId(publicKeyId); + + const client = new RestClient(url); + const tx = buildGetPublicKeyStateTx(dnaid, keyId); + const response = await client.sendRawTransaction(tx.serialize(), true); + + if (response.Result && response.Result.Result) { + return PublicKeyStatus.fromHexLabel(response.Result.Result); + } else { + throw new Error('Not found'); + } +} + +/** + * Extracts DNA ID from public key Id. + * + * @param publicKeyId The ID of a signature public key + */ +export function extractDNAId(publicKeyId: string): string { + const index = publicKeyId.indexOf('#keys-'); + + if (index === -1) { + throw new Error('Is not a publicKeId.'); + } + + return publicKeyId.substr(0, index); +} + +/** + * Extracts key id from public key Id. + * + * @param publicKeyId The ID of a signature public key + */ +export function extractKeyId(publicKeyId: string): number { + const index = publicKeyId.indexOf('#keys-'); + + if (index === -1) { + throw new Error('Is not a publicKeId.'); + } + + // return num2hexstring( + // Number(publicKeyId.substr(index + '#keys-'.length)) + // ); + return Number(publicKeyId.substr(index + '#keys-'.length)); +} diff --git a/src/common/bigInt.ts b/src/common/bigInt.ts new file mode 100644 index 0000000..7dd6c25 --- /dev/null +++ b/src/common/bigInt.ts @@ -0,0 +1,64 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { BigNumber } from 'bignumber.js'; +import * as Long from 'long'; +import { ERROR_CODE } from './../error'; +import { bigIntFromBytes, bigIntToBytes } from './../utils'; + +const SIZE = 8; +/** + * Big positive integer base on BigNumber + */ +export default class BigInt { + /** + * Create BigInt from string + * @param hex Byte string value + */ + static fromHexstr(hex: string): BigInt { + // hex = reverseHex(hex); + // const bi = new BigNumber(hex, 16).toString(); + // return new BigInt(bi); + const long = bigIntFromBytes(hex); + return new BigInt(long.toString()); + } + + value: string | number; + ledgerCompatible: boolean; + + constructor(value: string | number, ledgerCompatible: boolean = true) { + const bi = new BigNumber(value); + if (!bi.isInteger()) { + throw new Error(String(ERROR_CODE.INVALID_PARAMS)); + } + this.value = value; + this.ledgerCompatible = ledgerCompatible; + } + + /** + * Create hex string from BigInt + */ + toHexstr(): string { + const bi = Long.fromValue(this.value); + let hex = bigIntToBytes(bi); + if (this.ledgerCompatible && (hex.length % 2 !== 0 || hex.length < 16)) { + hex = hex + '0'.repeat(SIZE * 2 - hex.length); + } + return hex; + } +} diff --git a/src/common/fixed64.ts b/src/common/fixed64.ts new file mode 100644 index 0000000..55634d3 --- /dev/null +++ b/src/common/fixed64.ts @@ -0,0 +1,57 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { BigNumber } from 'bignumber.js'; +import { reverseHex, StringReader } from '../utils'; + +const Fixed64Size = 8; +export default class Fixed64 { + static deserialize(sr: StringReader) { + const f = new Fixed64(); + let v = sr.read(8); + // f.value = hexstr2str(v) + v = reverseHex(v); + while (v.substr(0, 2) === '00' ) { + v = v.substring(2); + } + f.value = new BigNumber(v, 16).toString(); + return f; + } + + // 8 bytes + value: string; + constructor(value?: string) { + if (value && value.length > 16 || value && !/^[0-9]\d*$/.test(value)) { + throw new Error('Invalid value.' + value); + } + this.value = value || '0000000000000000'; + } + + serialize() { + // return str2hexstr(this.value) + let hexstring = new BigNumber(this.value).toString(16); + const size = Fixed64Size * 2; + + hexstring = hexstring.length % size === 0 + ? hexstring + : ('0'.repeat(size) + hexstring).substring(hexstring.length); + + hexstring = reverseHex(hexstring); + return hexstring; + } +} diff --git a/src/common/int128.ts b/src/common/int128.ts new file mode 100644 index 0000000..11eb5ad --- /dev/null +++ b/src/common/int128.ts @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { BigNumber } from 'bignumber.js'; +import { ab2hexstring, hexstring2ab, reverseHex, StringReader } from '../utils'; +import BigInt from './bigInt'; + +const I128_SIZE = 16; + +// little endian i128 +export class I128 { + static deserialize(sr: StringReader) { + const result = new I128(); + const hex = sr.read(I128_SIZE); + const v = hexstring2ab(hex); + result.value = v; + return result; + } + + value: number[] = new Array(I128_SIZE).fill(0); + + constructor(value?: number[]) { + if (value && value.length !== I128_SIZE) { + throw new Error(`Invalid value: ${value} for I128.`); + } + if (value) { + this.value = value; + } + } + + // little endian + compareTo(o: I128) { + const x = this.value; + const y = o.value; + for (let i = I128_SIZE - 1; i >= 0; i--) { + if (x[i] > y[i]) { + return 1; + } + if (x[i] < y[i]) { + return -1; + } + } + return 0; + } + + serialize() { + const hex = ab2hexstring(this.value); + return hex; + } + +} + +// little endian u128 +export class U128 { + static deserialize(sr: StringReader) { + const result = new U128(); + const hex = sr.read(I128_SIZE); + const v = hexstring2ab(hex); + + result.value = v; + return result; + } + + value: number[] = new Array(I128_SIZE).fill(0); + + constructor(value?: number[]) { + if (value && value.length !== I128_SIZE) { + throw new Error(`Invalid value: ${value} for U128.`); + } + if (value) { + this.value = value; + } + } + + // little endian + compareTo(o: U128) { + const x = this.value; + const y = o.value; + for (let i = I128_SIZE - 1; i >= 0; i--) { + if (x[i] > y[i]) { + return 1; + } + if (x[i] < y[i]) { + return -1; + } + } + return 0; + } + + serialize() { + const hex = ab2hexstring(this.value); + return hex; + } + + toBigInt(): BigInt { + const hex = ab2hexstring(this.value); + const buf = reverseHex(hex); + return BigInt.fromHexstr(buf); + } + + toI128(): I128 { + return new I128(this.value); + } + +} + +export function oneBits128() { + const val = []; + for (let i = 0; i < I128_SIZE; i++) { + val[i] = 255; + } + const i128 = new I128(val); + return i128; +} + +export function bigPow(a: number, b: number): BigNumber { + return new BigNumber(a).pow(b); +} + +export const pow128 = bigPow(2, 128); + +export const maxBigU128 = bigPow(2, 128).minus(1); + +export const maxI128 = bigPow(2, 127).minus(1); + +export const minI128 = bigPow(2, 127).negated(); + +export function I128FromInt(val: number) { + let i128 = new I128(); + if (val < 0) { + i128 = oneBits128(); + } + putUint64(i128.value, val); + return i128; +} + +export function I128FromBigInt(val: string) { + let valBN = new BigNumber(val); + if (valBN.isGreaterThan(maxI128) || valBN.isLessThan(minI128)) { + throw new Error('The value is out of I128 range'); + } + + if (valBN.isLessThan(0)) { + valBN = valBN.plus(pow128); + } + const size = I128_SIZE * 2; + let hexstring = valBN.toString(16); + hexstring = hexstring.length % size === 0 ? hexstring : ('0'.repeat(size) + hexstring).substring(hexstring.length); + hexstring = reverseHex(hexstring); + const bufRArray = hexstring2ab(hexstring); + + const i128 = new I128(); + const value = new Array(I128_SIZE).fill(0); + for (let i = 0; i < bufRArray.length; i++) { + value[i] = bufRArray[i]; + } + i128.value = value; + return i128; +} + +export function putUint64(value: number[], val: number) { + value[0] = val & 0xFF; + val = val >> 8; + value[1] = val & 0xFF; + val = val >> 8; + value[2] = val & 0xFF; + val = val >> 8; + value[3] = val & 0xFF; + val = val >> 8; + value[4] = val & 0xFF; + val = val >> 8; + value[5] = val & 0xFF; + val = val >> 8; + value[6] = val & 0xFF; + val = val >> 8; + value[7] = val & 0xFF; +} diff --git a/src/common/uint160.ts b/src/common/uint160.ts new file mode 100644 index 0000000..af67e62 --- /dev/null +++ b/src/common/uint160.ts @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { ab2hexstring, hex2VarBytes, hexstring2ab, StringReader } from '../utils'; + +const UINT160SIZE = 20; + +export default class Uint160 { + static deserialize(sr: StringReader) { + const result = new Uint160(); + const hex = sr.readNextBytes(); + let v = hexstring2ab(hex); + + // little endian + v = v.reverse(); + const value = new Uint8Array(v); + result.value = value; + return result; + } + + value: Uint8Array; + + // little endian + compareTo(o: Uint160) { + const x = this.value; + const y = o.value; + for (let i = UINT160SIZE - 1; i >= 0; i--) { + if (x[i] > y[i]) { + return 1; + } + if (x[i] < y[i]) { + return -1; + } + } + return 0; + } + + serialize() { + const hex = ab2hexstring(this.value); + return hex2VarBytes(hex); + } +} diff --git a/src/common/uint256.ts b/src/common/uint256.ts new file mode 100644 index 0000000..79d82a2 --- /dev/null +++ b/src/common/uint256.ts @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { ab2hexstring, hex2VarBytes, hexstring2ab, StringReader } from '../utils'; + +const UINT256SIZE = 32; + +export default class Uint256 { + static deserialize(sr: StringReader) { + const result = new Uint256(); + const hex = sr.readNextBytes(); + let v = hexstring2ab(hex); + + // little endian + v = v.reverse(); + const value = new Uint8Array(v); + result.value = value; + return result; + } + + value: Uint8Array; + + // little endian + compareTo(o: Uint256) { + const x = this.value; + const y = o.value; + + for (let i = UINT256SIZE - 1; i >= 0; i--) { + if (x[i] > y[i]) { + return 1; + } + if (x[i] < y[i]) { + return -1; + } + } + return 0; + } + + serialize() { + const hex = ab2hexstring(this.value); + return hex2VarBytes(hex); + } +} diff --git a/src/consts.ts b/src/consts.ts new file mode 100644 index 0000000..74f8f72 --- /dev/null +++ b/src/consts.ts @@ -0,0 +1,107 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +// export const ADDR_VERSION = '41'; +export const ADDR_VERSION = '17'; + +export const DEFAULT_SCRYPT = { + cost: 4096, // 除以2时间减半 + blockSize: 8, + parallel: 8, + size: 64 +}; + +// specified by oep, same as bip38 +export const OEP_HEADER = '0142'; + +export const OEP_FLAG = 'e0'; + +export const DEFAULT_ALGORITHM = { + algorithm: 'ECDSA', + parameters: { + curve: 'P-256' // also called secp256r1 + } +}; + +export const DEFAULT_SM2_ID = '1234567812345678'; + +export const TEST_NODE = 'polaris1.dna.io'; // 0.9 +// export const TEST_NODE = '139.219.129.26'; // 0.81 +// export const TEST_NODE = '192.168.50.74'; +// export const TEST_NODE = '127.0.0.1'; + +export const MAIN_NODE = 'dappnode1.dna.io'; + +export const HTTP_REST_PORT = '20334'; +export const HTTP_WS_PORT = '20335'; +export const HTTP_JSON_PORT = '20336'; + +export const REST_API = { + getBalance: '/api/v1/balance', + sendRawTx: '/api/v1/transaction', + getMerkleProof: '/api/v1/merkleproof' // end with /txHash +}; + +export const DNA_NETWORK = { + MAIN: 'MainNet', + TEST: 'TestNet' +}; + +export const TEST_DNA_URL = { + SOCKET_URL: `ws://${TEST_NODE}:${HTTP_WS_PORT}`, + + RPC_URL: `http://${TEST_NODE}:${HTTP_JSON_PORT}`, + + REST_URL: `http://${TEST_NODE}:${HTTP_REST_PORT}`, + + sendRawTxByRestful: `http://${TEST_NODE}:${HTTP_REST_PORT}${REST_API.sendRawTx}` +}; + +export const MAIN_DNA_URL = { + SOCKET_URL: `ws://${MAIN_NODE}:${HTTP_WS_PORT}`, + + RPC_URL: `http://${MAIN_NODE}:${HTTP_JSON_PORT}/`, + + REST_URL: `http://${MAIN_NODE}:${HTTP_REST_PORT}/`, + + sendRawTxByRestful: `http://${TEST_NODE}:${HTTP_REST_PORT}${REST_API.sendRawTx}` + +}; + +export const TOKEN_TYPE = { + GAS: 'GAS' +}; + +export const DEFAULT_GAS_LIMIT = 30000; + +export const NATIVE_INVOKE_NAME = 'DNA.Native.Invoke'; + +export const VERSION_CONTRACT_GAS = 0; + +export const TX_MAX_SIG_SIZE = 16; + +// tslint:disable-next-line:quotemark +export const DNA_BIP44_PATH = "m/44'/1024'/0'/0/0"; + +export const UNBOUND_GENERATION_AMOUNT = [5, 4, 3, 3, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]; + +export const UNBOUND_TIME_INTERVAL = 31536000; + +export const DNA_TOTAL_SUPPLY = 1000000000; + +export const GENESIS_BLOCK_TIMESTAMP = 1530316800; diff --git a/src/crypto/AnonymousCredential.ts b/src/crypto/AnonymousCredential.ts new file mode 100644 index 0000000..3aa0c77 --- /dev/null +++ b/src/crypto/AnonymousCredential.ts @@ -0,0 +1,873 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as CTX from 'milagro-crypto-js'; +import * as utils from '../utils'; + +/** + * Issuer + * Issuer in Anonymous Credential + */ +export class Issuer { + + sk: SecretKey; + pk: IssuerPublicKey; + // AttrMap: Map; + AttributeName: string[]; + + param: CryptoSuite; + + constructor(curve: string) { + this.param = new CryptoSuite(curve); + this.sk = new SecretKey(this.param); + } + + /* GenerateSk():SecretKey + * generate a random secret key + */ + GenerateSk(): SecretKey { + this.sk.Rand(); + return this.sk; + } + + /* GenerateKeyPair() + * generate a random secret key + */ + GenerateKeyPair() { + this.sk = SecretKey.GenerateSk(this.param); + this.pk = this.sk.GenerateIssuerPublicKey(); + } + + /* SetAttributeSet(AttributeName:string[]) + * generate a random secret key + */ + SetAttributeSet(AttributeName: string[]) { + this.AttributeName = AttributeName; + this.pk.GenerateAttr(AttributeName); + } + + /* Sign(Nym, attrs):Credential + * sign a credential for a user + */ + Sign(Nym: any, attrs: any[]): Credential { + // random e, s + const e = this.param.getRandBN(); + const s = this.param.getRandBN(); + const B = new this.param.ECP(); // B = g1 · HRand^s · Nym · MulAll(HAttrs[i]^(Attrs[i])) + B.copy(this.param.g1); + B.add(this.param.PAIR.G1mul(this.pk.h0, s)); + B.add(Nym); + for (let i = 0; i < this.pk.attr.length; i++) { + B.add(this.param.PAIR.G1mul(this.pk.h[i], attrs[i])); + } + + let A = new this.param.ECP(); // A = B^(1/(e+x)) + const tmp = new this.param.BIG(); // tmp = (1/(e+x)) + tmp.copy(e); + tmp.add(this.sk.value); // !!!!!!!!!!! + tmp.invmodp(this.param.order); + + A = this.param.PAIR.G1mul(B, tmp); + + const cred = new Credential(this.param); + cred.Set(A, B, e, s, attrs); + return cred; + } + + /* GetPk() + * get issuer's public key + */ + GetPk(): IssuerPublicKey { + return IssuerPublicKey.COPY(this.pk); + } + + /* GenerateSk():SecretKey + * generate a random secret key + */ + GenerateNonce(): any { + const nonce = this.param.getRandBN(); + return nonce; + } + + VerifyCredentialRequest(CR: any): boolean { + return this.pk.VerifyCredentialRequest(CR); + } + +} + +/** + * User + * An user in Anonymous Credential + * Prover and Verifier are all user. + */ +export class User { + + attrs: any[]; + + private sk: SecretKey; + private Nym: any; + // private pi: { + // C: any, + // S: any + // }; + + private Cred: Credential; + + private ipk: IssuerPublicKey; + + private param: CryptoSuite; + + constructor(curve: string) { + this.param = new CryptoSuite(curve); + } + + /* GenerateSk():SecretKey + * generate a random secret key + */ + GenerateSk(): SecretKey { + this.sk = SecretKey.GenerateSk(this.param); + return this.sk; + } + + /* SetIpk(ipk:IssuerPublicKey) + * save issuer's public key + */ + SetIpk(ipk: IssuerPublicKey) { + this.ipk = IssuerPublicKey.COPY(ipk); + } + + GenerateCrendentialRequest(nonce: any): any { + if (this.ipk === undefined) { + // tslint:disable-next-line:no-console + console.log('Please set ipk first.'); + return; + } + + const ipk = this.ipk; + const Nym = this.param.PAIR.G1mul(ipk.h_sk, this.sk.value); // Nym + + const r = this.param.getRandBN(); // r + const t1 = this.param.PAIR.G1mul(ipk.h_sk, r); // t1 + + const C = this.param.hashToBN(t1, ipk.h_sk, Nym, nonce); + + const S = this.param.BIG.modmul(C, this.sk.value, this.param.order); + S.add(r); + S.mod(this.param.order); + + const pi = { + C, + S + }; + + const attrs = this.param.genAttrBN(ipk.attr); + + this.Nym = Nym; + this.attrs = attrs; + + const CR = { + Nym, + pi, + nonce, + attrs + }; + + return CR; + } + + VerifyBBSplus(Cred: Credential): boolean { + // pk <- ipk.w + // m <- attrs + // sig <- (A,E,s) + + // check if + // e(A, g2^E * pk) == e(B, g2) + // and if + // B == g1 * HRand^s * Nym * (h1^m1 * ... * hL^mL) + + const wg2e = new this.param.ECP2(); + wg2e.copy(this.ipk.w); + wg2e.add(this.param.PAIR.G2mul(this.param.g2, Cred.sig.e)); + wg2e.affine(); // ~!!!!use affine() after ECP's mul operation, for pairing. + + const A = new this.param.ECP(); + A.copy(Cred.sig.A); + A.affine(); + + let left = this.param.PAIR.ate(wg2e, A); + left = this.param.PAIR.fexp(left); + + const B = new this.param.ECP(); + B.copy(this.param.g1); + B.add(this.param.PAIR.G1mul(this.ipk.h0, Cred.sig.s)); + B.add(this.Nym); + + for (let i = 0; i < Cred.attrs.length; i++) { + B.add(this.param.PAIR.G1mul(this.ipk.h[i], Cred.attrs[i])); + } + + B.affine(); + let right = this.param.PAIR.ate(this.param.g2, B); + right = this.param.PAIR.fexp(right); + + return left.equals(right); + } + + SetCredential(Cred: Credential) { + this.Cred = new Credential(this.param); + this.Cred.Copy(Cred); + return true; + } + + Prove(D: any[]) { + const ipk = this.ipk; + const Cred = this.Cred; + + const r1 = this.param.getRandBN(); // r1 + + const A_ = this.param.PAIR.G1mul(Cred.sig.A, r1); // A' + + const r3 = new this.param.BIG(0); // r3 + r3.copy(r1); + r3.invmodp(this.param.order); + + // tslint:disable-next-line:variable-name + let _e = new this.param.BIG(0); // -e + _e.copy(Cred.sig.e); + _e = this.param.BIG.modneg(_e, this.param.order); + + const _A = this.param.PAIR.G1mul(A_, _e); // _A + _A.add(this.param.PAIR.G1mul(Cred.sig.B, r1)); + + const r2 = this.param.getRandBN(); // r2 + // tslint:disable-next-line:variable-name + let _r2 = new this.param.BIG(0); // -r2 + _r2.copy(r2); + _r2 = this.param.BIG.modneg(_r2, this.param.order); + + const B_ = this.param.PAIR.G1mul(Cred.sig.B, r1); // B' + B_.add(this.param.PAIR.G1mul(ipk.h0, _r2)); + + // tslint:disable-next-line:variable-name + let s_ = this.param.BIG.modmul(r2, r3, this.param.order); // s' + s_ = this.param.BIG.modneg(s_, this.param.order); + s_.add(Cred.sig.s); + s_.mod(this.param.order); + + // tslint:disable-next-line:variable-name + const r_a = []; // r_a[] + for (let i = 0; i < D.length; i++) { + if (D[i] === 0) { + r_a[i] = this.param.getRandBN(); + } else { + r_a[i] = false; + } + } + + // tslint:disable-next-line:variable-name + const r_e = this.param.getRandBN(); + // tslint:disable-next-line:variable-name + const r_r2 = this.param.getRandBN(); + // tslint:disable-next-line:variable-name + const r_r3 = this.param.getRandBN(); + // tslint:disable-next-line:variable-name + const r_s_ = this.param.getRandBN(); + // tslint:disable-next-line:variable-name + const r_sk = this.param.getRandBN(); + + const E = this.param.PAIR.G1mul(ipk.h_sk, r_sk); // E + + const t1 = this.param.PAIR.G1mul(A_, r_e); // t1 + t1.add(this.param.PAIR.G1mul(ipk.h0, r_r2)); + + const t2 = this.param.PAIR.G1mul(B_, r_r3); // t2 + t2.add(this.param.PAIR.G1mul(ipk.h0, r_s_)); + t2.add(this.param.PAIR.G1mul(E, new this.param.BIG(-1))); + for (let i = 0; i < r_a.length; i++) { + if (r_a[i] !== false) { + t2.add(this.param.PAIR.G1mul(ipk.h[i], r_a[i])); + } + } + + // c' = H(A', _A, B', Nym, t1, t2, g1, HRand, h1, ... , hL, w) + // tslint:disable-next-line:variable-name + const c_ = this.param.hashToBN( + A_, + _A, + B_, + this.Nym, + t1, + t2, + this.param.g1, + ipk.h0, + ipk.h, + ipk.w + ); + + const nonce = this.param.getRandBN(); + // c = H(nonce, c', (D, I)) + const c = this.param.hashToBN(nonce, c_, D, this.attrs); + + // tslint:disable-next-line:variable-name + const s_sk = new this.param.BIG(0); + s_sk.copy(r_sk); + s_sk.add(this.param.BIG.modmul(c, this.sk.value, this.param.order)); + s_sk.mod(this.param.order); + + // tslint:disable-next-line:variable-name + const s_a = []; + for (let i = 0; i < D.length; i++) { + if (D[i] === 0) { + s_a[i] = new this.param.BIG(0); + s_a[i].copy(r_a[i]); + s_a[i].sub(this.param.BIG.modmul(c, this.attrs[i], this.param.order)); + s_a[i].mod(this.param.order); + } else { + s_a[i] = false; + } + } + + // tslint:disable-next-line:variable-name + const s_e = new this.param.BIG(0); + s_e.copy(r_e); + s_e.sub(this.param.BIG.modmul(c, Cred.sig.e, this.param.order)); + s_e.mod(this.param.order); + + // tslint:disable-next-line:variable-name + const s_r2 = new this.param.BIG(0); + s_r2.copy(r_r2); + s_r2.add(this.param.BIG.modmul(c, r2, this.param.order)); + s_r2.mod(this.param.order); + + // tslint:disable-next-line:variable-name + const s_r3 = new this.param.BIG(0); + s_r3.copy(r_r3); + s_r3.add(this.param.BIG.modmul(c, r3, this.param.order)); + s_r3.mod(this.param.order); + + // tslint:disable-next-line:variable-name + const s_s_ = new this.param.BIG(0); + s_s_.copy(r_s_); + s_s_.sub(this.param.BIG.modmul(c, s_, this.param.order)); + s_s_.mod(this.param.order); + + const pi = { + c, + s_sk, + s_a, + s_e, + s_r2, + s_r3, + s_s_, + nonce + }; + + const proof = { + A_, + _A, + B_, + Nym: this.Nym, + pi + }; + + return proof; + } + + Verify(proof: any, D: any[], attrs: any[]): boolean { + const ipk = this.ipk; + + // make sure A is not infinity + const O = new this.param.ECP(0); // Add + // let O = new this.param.ECP(1); // Muliply + if (proof.A_.equals(O)) { + // tslint:disable-next-line:no-console + console.log('A\' == O return true, verify failed.'); + return false; + } + + const A_ = new this.param.ECP(); + A_.copy(proof.A_); + const w = new this.param.ECP2(); + w.copy(ipk.w); + const _A = new this.param.ECP(); + _A.copy(proof._A); + const g2Dup = new this.param.ECP2(); + g2Dup.copy(this.param.g2); + + A_.affine(); + w.affine(); + _A.affine(); + g2Dup.affine(); + + let left = this.param.PAIR.ate(w, A_); + let right = this.param.PAIR.ate(g2Dup, _A); + + left = this.param.PAIR.fexp(left); + right = this.param.PAIR.fexp(right); + + if (!left.equals(right)) { + // tslint:disable-next-line:no-console + console.log('e(A\', w) == e(_A, g2) return false, verify failed.'); + return false; + } + + _A.copy(proof._A); + // tslint:disable-next-line:variable-name + const _t1 = this.param.PAIR.G1mul(A_, proof.pi.s_e); + _t1.add(this.param.PAIR.G1mul(ipk.h0, proof.pi.s_r2)); + _A.sub(proof.B_); + _t1.add(this.param.PAIR.G1mul(_A, this.param.BIG.modneg(proof.pi.c, this.param.order))); + + // ~t2 : (B')^s_r3 · HRand^s_s' · HSk^(-s_sk) · MulAll(hi^(-s_ai)) · (g1·MulAll(hi^ai))^(-c) + // tslint:disable-next-line:variable-name + const _t2 = this.param.PAIR.G1mul(proof.B_, proof.pi.s_r3); + _t2.add(this.param.PAIR.G1mul(ipk.h0, proof.pi.s_s_)); + _t2.add( + this.param.PAIR.G1mul(ipk.h_sk, this.param.BIG.modneg(proof.pi.s_sk, this.param.order)) + ); + + const sum = new this.param.ECP(); + sum.copy(this.param.g1); + for (let i = 0; i < D.length; i++) { + if (D[i] === 0) { + _t2.add(this.param.PAIR.G1mul(ipk.h[i], proof.pi.s_a[i])); + } else { + sum.add(this.param.PAIR.G1mul(ipk.h[i], attrs[i])); + } + } + + _t2.add(this.param.PAIR.G1mul(sum, this.param.BIG.modneg(proof.pi.c, this.param.order))); + + const c1 = this.param.hashToBN( + proof.A_, + proof._A, + proof.B_, + proof.Nym, + _t1, + _t2, + this.param.g1, + ipk.h0, + ipk.h, + ipk.w + ); + const c2 = this.param.hashToBN(proof.pi.nonce, c1, D, attrs); + + if (this.param.BIG.comp(c2, proof.pi.c) !== 0) { + // tslint:disable-next-line:no-console + console.log( + // tslint:disable-next-line:max-line-length + 'c == H(nonce, H(A\', _A, B\', Nym, ~t1, ~t2, g1, HRand, h1, ... , hL, w), (D, I)) return false, verify failed.' + ); + return false; + } + + return true; + } +} + +/** + * CryptoSuite + * contains everything in Paring Based Cryptography + */ +export class CryptoSuite { + curve: string; + ctx: any; + order: any; + PAIR: any; + ECP: any; + ECP2: any; + BIG: any; + rng: any; + g1: any; + g2: any; + + constructor(curve: string) { + this.curve = curve; + this.ctx = new CTX(curve); + + this.PAIR = this.ctx.PAIR; // Set pairing interface + this.ECP = this.ctx.ECP; // Set G1 interface + this.ECP2 = this.ctx.ECP2; // Set G2 interface + this.BIG = this.ctx.BIG; // Set BN interface + this.rng = new this.ctx.RAND(); // new random number generator + + this.g1 = this.getG1Generator(); // g1 + this.g2 = this.getG2Generator(); // g2 + this.order = this.getOrder(); // n + } + + getG1Generator() { + const g1 = new this.ctx.ECP(0); // new G1 + const x = new this.ctx.BIG(0); + const y = new this.ctx.BIG(0); + x.rcopy(this.ctx.ROM_CURVE.CURVE_Gx); + y.rcopy(this.ctx.ROM_CURVE.CURVE_Gy); + g1.setxy(x, y); + return g1; + } + + getG2Generator() { + const g2 = new this.ctx.ECP2(0); + const x = new this.ctx.BIG(0); + const y = new this.ctx.BIG(0); + const qx = new this.ctx.FP2(0); + const qy = new this.ctx.FP2(0); + x.rcopy(this.ctx.ROM_CURVE.CURVE_Pxa); + y.rcopy(this.ctx.ROM_CURVE.CURVE_Pxb); + qx.bset(x, y); + x.rcopy(this.ctx.ROM_CURVE.CURVE_Pya); + y.rcopy(this.ctx.ROM_CURVE.CURVE_Pyb); + qy.bset(x, y); + g2.setxy(qx, qy); + return g2; + } + + getOrder() { + const r = new this.ctx.BIG(0); // new BN + r.rcopy(this.ctx.ROM_CURVE.CURVE_Order); + return r; + } + + getRandBN(): any { + const buf = utils.generateRandomArray(256); + this.rng.clean(); + this.rng.seed(256, buf); + const r = this.BIG.randomnum(this.order, this.rng); + return r; + } + + getRandG1(): any { + const r = this.getRandBN(); + const g = this.PAIR.G1mul(this.g1, r); + return g; + } + + getRandG2(): any { + const r = this.getRandBN(); + const g = this.PAIR.G2mul(this.g2, r); + return g; + } + + hashToBN(...points: any[]): any { + let all: any[] = []; + let tmp: ConcatArray = []; + points.forEach((p) => { + if (Array.isArray(p)) { + if (typeof p[0] === 'number') { + all = all.concat(p); + tmp = []; + } else { + p.forEach((pp) => { + pp.toBytes(tmp); + all = all.concat(tmp); + tmp = []; + }); + } + } else { + p.toBytes(tmp); + all = all.concat(tmp); + tmp = []; + } + }); + const H = new this.ctx.HASH256(); + H.process_array(all); + const R = H.hash(); + const C = this.BIG.fromBytes(R); + C.mod(this.order); + return C; + } + + genAttrBN(attrs: any): any { + const HAttr = []; + + for (let i = 0; i < attrs.length; i++) { + const t = this.getRandBN(); + HAttr[i] = t; + } + + return HAttr; + } + + genAttrElement(attrs: any): any { + const HAttr = []; + + for (let i = 0; i < attrs.length; i++) { + const t = this.getRandG1(); + HAttr[i] = t; + } + + return HAttr; + } +} + +/** + * CryptoBase + * contains a refrence to a CryptoSuite instance. + */ +export class CryptoBase { + param: CryptoSuite; + constructor(param: CryptoSuite) { + this.param = param; + } +} + +export class SecretKey extends CryptoBase { + /* + * GenerateSk():SecretKey + * Generate a random secret key. + */ + static GenerateSk(param: CryptoSuite): SecretKey { + const x = param.getRandBN(); // isk + const sk = new SecretKey(param); + sk.setValue(x); + return sk; + } + + value: any; + + constructor(param: CryptoSuite) { + super(param); + this.value = new this.param.BIG(0); + } + + setValue(v: any) { + this.value.copy(v); + } + + GenerateIssuerPublicKey(): IssuerPublicKey { + const x = this.value; + const w = this.param.PAIR.G2mul(this.param.g2, x); // w + let r = this.param.getRandBN(); // random number + // tslint:disable-next-line:variable-name + const _g1 = this.param.PAIR.G1mul(this.param.g1, r); + // tslint:disable-next-line:variable-name + const _g2 = this.param.PAIR.G1mul(_g1, x); + + // zkp - pi + r = this.param.getRandBN(); + const t1 = this.param.PAIR.G2mul(this.param.g2, r); + const t2 = this.param.PAIR.G1mul(_g1, r); + + const C = this.param.hashToBN(t1, t2, this.param.g2, _g1, w, _g2); + + const S = this.param.BIG.modmul(C, x, this.param.order); + S.add(r); + S.mod(this.param.order); + + const pi = { + C, + S + }; + + const pk = new IssuerPublicKey(this.param); + pk.SetBasicValue(w, _g1, _g2, pi); + return pk; + } + + /* + * ToBytes() + * convert secret key to string format. + * TODO:: add serialize function. + */ + ToBytes() { + if (this.value === undefined) { + return ''; + } + return this.value.toBytes(); + } + + /* + * FromString(s: any) + * convert string to a SecretKey. + * TODO:: add unserialize function. + */ + FromBytes(s: any) { + this.value = this.param.BIG.fromBytes(s); + return this.value.toString(); + } + + /* + * GenerateSk():SecretKey + * Generate a random secret key. + */ + Rand() { + const x = this.param.getRandBN(); // isk + this.setValue(x); + } + +} + +export class IssuerPublicKey extends CryptoBase { + /* + * COPY(target: IssuerPublicKey):IssuerPublicKey + * copy and return a new public key + */ + static COPY(target: IssuerPublicKey): IssuerPublicKey { + const pk = new IssuerPublicKey(target.param); + pk.SetBasicValue(target.w, target._g1, target._g2, target.pi); + pk.SetAttrValue(target.h0, target.h_sk, target.h, target.attr); + return pk; + } + + w: any; + // tslint:disable-next-line:variable-name + _g1: any; + // tslint:disable-next-line:variable-name + _g2: any; + pi: { + C: any, + S: any + }; + h0: any; + // tslint:disable-next-line:variable-name + h_sk: any; + h: any; + attr: any[]; + + constructor(param: CryptoSuite) { + super(param); + + this.w = new this.param.ECP2(); + this._g1 = new this.param.ECP(); + this._g2 = new this.param.ECP(); + + const C = new this.param.BIG(); + const S = new this.param.BIG(); + this.pi = {C, S}; + + this.h0 = new this.param.ECP(); + this.h_sk = new this.param.ECP(); + this.attr = []; + } + + /* + * SetBasicValue(w, _g1, _g2, pi) + * set basic values of the public key + */ + // tslint:disable-next-line:variable-name + SetBasicValue(w: any, _g1: any, _g2: any, pi: any) { + this.w.copy(w); + this._g1.copy(_g1); + this._g2.copy(_g2); + this.pi.C.copy(pi.C); + this.pi.S.copy(pi.S); + } + + /* + * SetAttrValue(h0, h_sk, h, attr) + * set basic values of the public key + */ + // tslint:disable-next-line:variable-name + SetAttrValue(h0: any, h_sk: any, h: any[], attr: any[]) { + this.h0.copy(h0); + this.h_sk.copy(h_sk); + this.h = []; + this.attr = []; + + for (let i = 0; i < h.length; i++) { + this.h[i] = new this.param.ECP(); + this.h[i].copy(h[i]); + } + for (let i = 0; i < attr.length; i++) { + this.attr[i] = attr[i]; + } + } + + /* + * GenerateAttr(AttributeName) + * generates + * ipk.h0: rand G1 + * ipk.h_sk: rand G1 + * ipk.h[]: Rand G1 array, match to AttributeName + */ + GenerateAttr(AttributeName: any) { + const HAttr = this.param.genAttrElement(AttributeName); + const h0 = this.param.getRandG1(); + // tslint:disable-next-line:variable-name + const h_sk = this.param.getRandG1(); + const h: any[] = []; + + HAttr.forEach((a: any) => { + h.push(a); + }); + + this.h0 = h0; + this.h_sk = h_sk; + this.h = h; + this.attr = AttributeName; + } + + /* + * VerifyCredentialRequest(Nym, pi, n) + * verifies user's credential request + */ + VerifyCredentialRequest(CR: any): boolean { + const C = new this.param.BIG(0); + C.copy(CR.pi.C); + + // tslint:disable-next-line:variable-name + const _t1 = this.param.PAIR.G1mul(this.h_sk, CR.pi.S); + _t1.add(this.param.PAIR.G1mul(CR.Nym, this.param.BIG.modneg(C, this.param.order))); + + const _C = this.param.hashToBN(_t1, this.h_sk, CR.Nym, CR.nonce); + + return this.param.BIG.comp(CR.pi.C, _C) === 0; + } + +} + +/** + * Credential + * The credential generated from issuer + */ +export class Credential extends CryptoBase { + sig: { + A: any, + B: any, + e: any, + s: any + }; + attrs: any[]; + + constructor(param: CryptoSuite) { + super(param); + const A = new this.param.ECP(); + const B = new this.param.ECP(); + const e = new this.param.BIG(); + const s = new this.param.BIG(); + this.sig = {A, B, e, s}; + this.attrs = []; + } + + Set(A: any, B: any, e: any, s: any, attrs: any) { + this.sig.A.copy(A); + this.sig.B.copy(B); + this.sig.e.copy(e); + this.sig.s.copy(s); + + for (let i = 0; i < attrs.length; i++) { + this.attrs[i] = new this.param.BIG(); + this.attrs[i].copy(attrs[i]); + } + } + + Copy(target: Credential) { + this.Set(target.sig.A, target.sig.B, target.sig.e, target.sig.s, target.attrs); + } + +} diff --git a/src/crypto/CurveLabel.ts b/src/crypto/CurveLabel.ts new file mode 100644 index 0000000..dc130de --- /dev/null +++ b/src/crypto/CurveLabel.ts @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +/** + * Elliptic curve used. + */ +export class CurveLabel { + static values: CurveLabel[] = []; + + static SECP224R1 = new CurveLabel('P-224', 1, 'p224'); + static SECP256R1 = new CurveLabel('P-256', 2, 'p256'); + static SECP384R1 = new CurveLabel('P-384', 3, 'p384'); + static SECP521R1 = new CurveLabel('P-521', 4, 'p521'); + static SM2P256V1 = new CurveLabel('sm2p256v1', 20, 'sm2p256v1'); + static ED25519 = new CurveLabel('ed25519', 25, 'ed25519'); + + /** + * Finds Curvecorresponding to specified hex representation. + * + * @param hex Byte hex value + */ + static fromHex(hex: number): CurveLabel { + const item = CurveLabel.values.find((v) => v.hex === hex); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + /** + * Finds Curve corresponding to specified label representation. + * + * @param label Label + */ + static fromLabel(label: string): CurveLabel { + const item = CurveLabel.values.find((v) => v.label === label); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + label: string; + hex: number; + preset: string; + + constructor(label: string, hex: number, preset: string) { + this.label = label; + this.hex = hex; + this.preset = preset; + + CurveLabel.values.push(this); + } +} diff --git a/src/crypto/Ecies.ts b/src/crypto/Ecies.ts new file mode 100644 index 0000000..2884af7 --- /dev/null +++ b/src/crypto/Ecies.ts @@ -0,0 +1,251 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as crypto from 'crypto'; +import * as elliptic from 'elliptic'; +import * as pkcs7 from 'pkcs7'; + +export class Ecies { + /** + * Algorithm used for encryption. + */ + encAlg: string; + /** + * Hash Algorithm used for kdf. + */ + hashAlg: string; + /** + * Hash digest byte size. + */ + digestSize: number; + /** + * Key input and out put format. + */ + keyFormat: string; + /** + * Initialized Vector + */ + iv: Buffer; + /** + * Elliptic Curve instance + */ + ec: any; + /** + * key pair from + * ec instance + */ + keyPair: any; + + /** + * if true, the pubkey will be + * in compressed format, begin with '02' or '03'. + * if false, begin with '04' + */ + compact: boolean; + + /** + * for curve name, + * go https://github.com/indutny/elliptic + * for reference + */ + constructor(Curve?: string) { + // default setting + this.encAlg = 'aes-256-cbc'; + this.hashAlg = 'sha256'; + this.digestSize = 32; + this.keyFormat = 'hex'; + this.compact = true; + + // const curve = Curve || 'secp256r1'; + const curve = Curve || 'p256'; + + this.ec = new elliptic.ec(curve); + this.keyPair = this.ec.genKeyPair(); + this.iv = Buffer.alloc(0); + } + /** + * generate random key pair + */ + generateKeyPair(): any { + this.keyPair = this.ec.genKeyPair(); + return { + priv: this.keyPair.getPrivate('hex'), + pub: this.keyPair.getPublic(this.compact, 'hex') + }; + } + /** + * set key pair with private key + * @param privHex private key in hex coding. + */ + setKeyPair(privHex: string) { + this.keyPair = this.ec.keyFromPrivate(privHex, 'hex'); + } + /** + * get key pair in use + * @return = {pri, pub} + * all in hex coding. + */ + getKeyPair(): any { + return { + priv: this.keyPair.getPrivate('hex'), + pub: this.keyPair.getPublic(this.compact, 'hex') + }; + } + + /** + * encrypt a message with given + * public key and initialized vector + * + * @param pubkey hex string of public key + * @param msg byte buffer of message + * @param keylen byte length of kdf's output. + */ + // tslint:disable-next-line:variable-name + enc(pubkey: string, msg: Buffer, keylen: number, _iv?: string): any { + const publicB = this.ec.keyFromPublic(pubkey, 'hex').getPublic(); + + // generate a random number + // r = (0, order) + const tmpKP = this.ec.genKeyPair(); + const r = tmpKP.getPrivate(); + + const gTilde = tmpKP.getPublic(); + const hTilde = publicB.mul(r); + + const out = gTilde.encode('hex'); + const PEH = hTilde.getX().toString('hex'); + const seed = Buffer.from(out + PEH, 'hex'); + + const derivedKeyArray = this.kdf2( + seed, + keylen * 8, + this.digestSize, + this.hashAlg + ); + if (!derivedKeyArray) { + return; + } + const derivedKey = Buffer.concat(derivedKeyArray); + + let iv = Buffer.alloc(16); + if (!_iv) { + // generate a random iv, fixed size + crypto.randomFillSync(iv); + } else { + iv = Buffer.from(_iv, 'hex'); + } + + const algorithm = this.encAlg; + + const cipher = crypto.createCipheriv(algorithm, derivedKey, iv); + cipher.setAutoPadding(false); + + const msgCipher = + cipher.update(pkcs7.pad(msg), 'binary', 'hex') + + cipher.final('hex'); + + return { + iv: iv.toString('hex'), + out, + msgCipher + }; + } + /** + * encrypt a message with given + * public key and initialized vector + * + * @param msgCipher + * @param out + * @param iv + * @param keylen + */ + dec(msgCipher: string, out: string, iv: any, keylen: number): Buffer { + const gTilde = this.ec.keyFromPublic(out, 'hex').getPublic(); + + const hTilde = gTilde.mul(this.keyPair.getPrivate()); + const PEH = hTilde.getX().toString('hex'); + const seed = Buffer.from(out + PEH, 'hex'); + + const derivedKeyArray = this.kdf2( + seed, + keylen * 8, + this.digestSize, + this.hashAlg + ); + if (!derivedKeyArray) { + return Buffer.alloc(0); + } + const derivedKey = Buffer.concat(derivedKeyArray); + const iv2 = Buffer.from(iv, 'hex'); + + const algorithm = this.encAlg; + const decipher = crypto.createDecipheriv(algorithm, derivedKey, iv2); + decipher.setAutoPadding(false); + const plain = + decipher.update(msgCipher, 'hex', 'binary') + + decipher.final('binary'); + + // un padding + const unpad = pkcs7.unpad(Buffer.from(plain, 'binary')); + + return Buffer.from(unpad); + } + + /* utils */ + kdf2( + seed: Buffer, + len: number, + digestSize: number, + hashFunc: string + ): Buffer[] { + if (len < 0) { + return []; + } + const byteLen = Math.ceil(len / 8); + const b = Math.ceil(byteLen / digestSize); + const key = []; + const offset = byteLen - (b - 1) * digestSize; // byte offset + + let counter = 1; // 1 for pbkdf2, 0 for pbkdf1 + + let hashIns; + while (counter < b) { + hashIns = crypto.createHash(hashFunc); + const h = hashIns + .update(Buffer.concat([seed, this.I2OSP(counter, 4)])) + .digest(); + key[counter - 1] = Buffer.alloc(offset); + key[counter - 1] = h; + counter++; + } + hashIns = crypto.createHash(hashFunc); + const hEnd = hashIns + .update(Buffer.concat([seed, this.I2OSP(counter, 4)])) + .digest(); + key[counter - 1] = Buffer.alloc(offset); + key[counter - 1] = hEnd; + + return key; + } + + I2OSP(num: number, len: number): Buffer { + const buf = Buffer.allocUnsafe(len); + buf.writeUIntBE(num, 0, len); + return buf; + } +} diff --git a/src/crypto/Key.ts b/src/crypto/Key.ts new file mode 100644 index 0000000..4001dd5 --- /dev/null +++ b/src/crypto/Key.ts @@ -0,0 +1,189 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as cryptoJS from 'crypto-js'; +import { sha3_224, sha3_256, sha3_384, sha3_512 } from 'js-sha3'; +import { sm3 } from 'sm.js'; +import { DEFAULT_ALGORITHM } from '../consts'; +import { hexstring2ab } from '../utils'; +import { CurveLabel } from './CurveLabel'; +import { KeyType } from './KeyType'; +import { SignatureScheme } from './SignatureScheme'; + +/** + * Specific parameters for the key type. + */ +export class KeyParameters { + /** + * Create KeyParameters from json. + * @param json JsonKeyParameters + */ + static deserializeJson(json: JsonKeyParameters): KeyParameters { + return new KeyParameters( + CurveLabel.fromLabel(json.curve) + ); + } + curve: CurveLabel; + + constructor(curve: CurveLabel) { + this.curve = curve; + } + + /** + * Serialize KeyParameters to json. + */ + serializeJson(): JsonKeyParameters { + return { + curve: this.curve.label + }; + } +} + +/** + * Common representation of private or public key + */ +export class Key { + /** + * Algorithm used for key generation. + */ + algorithm: KeyType; + + /** + * Parameters of the algorithm. + */ + parameters: KeyParameters; + + /** + * Key data. + */ + key: string; + + /** + * Creates Key. + * + * If no algorithm or parameters are specified, default values will be used. + * This is strongly discurraged, because it will forbid using other Key types. + * Therefore use it only for testing. + * + * @param key Hex encoded key value + * @param algorithm Key type + * @param parameters Parameters of the key type + */ + constructor(key: string, algorithm?: KeyType, parameters?: KeyParameters) { + this.key = key; + + if (algorithm === undefined) { + algorithm = KeyType.fromLabel(DEFAULT_ALGORITHM.algorithm); + } + + if (parameters === undefined) { + parameters = KeyParameters.deserializeJson(DEFAULT_ALGORITHM.parameters); + } + + this.algorithm = algorithm; + this.parameters = parameters; + } + + /** + * Computes hash of message using hashing function of signature schema. + * + * @param msg Hex encoded input data + * @param scheme Signing schema to use + */ + computeHash(msg: string, scheme: SignatureScheme): string { + switch (scheme) { + case SignatureScheme.ECDSAwithSHA224: + return cryptoJS.SHA224(cryptoJS.enc.Hex.parse(msg)).toString(); + case SignatureScheme.ECDSAwithSHA256: + return cryptoJS.SHA256(cryptoJS.enc.Hex.parse(msg)).toString(); + case SignatureScheme.ECDSAwithSHA384: + return cryptoJS.SHA384(cryptoJS.enc.Hex.parse(msg)).toString(); + case SignatureScheme.ECDSAwithSHA512: + case SignatureScheme.EDDSAwithSHA512: + return cryptoJS.SHA512(cryptoJS.enc.Hex.parse(msg)).toString(); + case SignatureScheme.ECDSAwithSHA3_224: + return sha3_224(hexstring2ab(msg)); + case SignatureScheme.ECDSAwithSHA3_256: + return sha3_256(hexstring2ab(msg)); + case SignatureScheme.ECDSAwithSHA3_384: + return sha3_384(hexstring2ab(msg)); + case SignatureScheme.ECDSAwithSHA3_512: + return sha3_512(hexstring2ab(msg)); + case SignatureScheme.ECDSAwithRIPEMD160: + return cryptoJS.RIPEMD160(cryptoJS.enc.Hex.parse(msg)).toString(); + case SignatureScheme.SM2withSM3: + return (new sm3()).sum(hexstring2ab(msg), 'hex'); + default: + throw new Error('Unsupported hash algorithm.'); + } + } + + /** + * Tests if signing schema is compatible with key type. + * + * @param schema Signing schema to use + */ + isSchemaSupported(schema: SignatureScheme): boolean { + switch (schema) { + case SignatureScheme.ECDSAwithSHA224: + case SignatureScheme.ECDSAwithSHA256: + case SignatureScheme.ECDSAwithSHA384: + case SignatureScheme.ECDSAwithSHA512: + case SignatureScheme.ECDSAwithSHA3_224: + case SignatureScheme.ECDSAwithSHA3_256: + case SignatureScheme.ECDSAwithSHA3_384: + case SignatureScheme.ECDSAwithSHA3_512: + case SignatureScheme.ECDSAwithRIPEMD160: + return this.algorithm === KeyType.ECDSA; + case SignatureScheme.EDDSAwithSHA512: + return this.algorithm === KeyType.EDDSA; + case SignatureScheme.SM2withSM3: + return this.algorithm === KeyType.SM2; + default: + throw new Error('Unsupported signature schema.'); + } + } + + /** + * Gets JSON representation of the Key (Public/Private). + */ + serializeJson(): JsonKey { + return { + algorithm: this.algorithm.label, + parameters: this.parameters.serializeJson(), + key: this.key + }; + } +} + +/** + * Json representation of the Key. + */ +export interface JsonKey { + algorithm: string; + parameters: JsonKeyParameters; + key: string | null; + external?: any | null; +} + +/** + * Json representation of the Key parameters. + */ +export interface JsonKeyParameters { + curve: string; +} diff --git a/src/crypto/KeyType.ts b/src/crypto/KeyType.ts new file mode 100644 index 0000000..3024244 --- /dev/null +++ b/src/crypto/KeyType.ts @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { SignatureScheme } from './SignatureScheme'; + +/** + * Type of key. ECDSA is the default one to use. + */ +export class KeyType { + static values: KeyType[] = []; + + static ECDSA = new KeyType('ECDSA', 0x12, SignatureScheme.ECDSAwithSHA256); + static SM2 = new KeyType('SM2', 0x13, SignatureScheme.SM2withSM3); + static EDDSA = new KeyType('EDDSA', 0x14, SignatureScheme.EDDSAwithSHA512); + + /** + * Finds Key type corresponding to specified hex representation. + * + * @param hex Byte hex value + */ + static fromHex(hex: number): KeyType { + const item = KeyType.values.find((v) => v.hex === hex); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + /** + * Finds Key type corresponding to specified label representation. + * + * @param label Label + */ + static fromLabel(label: string): KeyType { + const item = KeyType.values.find((v) => v.label === label); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + label: string; + hex: number; + defaultSchema: SignatureScheme; + + constructor(label: string, hex: number, defaultSchema: SignatureScheme) { + this.label = label; + this.hex = hex; + this.defaultSchema = defaultSchema; + + KeyType.values.push(this); + } +} diff --git a/src/crypto/PrivateKey.ts b/src/crypto/PrivateKey.ts new file mode 100644 index 0000000..3ed05ed --- /dev/null +++ b/src/crypto/PrivateKey.ts @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as bip39 from 'bip39'; +import * as elliptic from 'elliptic'; +import * as secureRandom from 'secure-random'; +import { sm2 } from 'sm.js'; +import * as wif from 'wif'; +import { DEFAULT_ALGORITHM, DEFAULT_SM2_ID, DNA_BIP44_PATH } from '../consts'; +import { ERROR_CODE } from '../error'; +import { decryptWithGcm, encryptWithGcm, ScryptParams } from '../scrypt'; +import { ab2hexstring, hexstring2ab, isBase64, str2hexstr } from '../utils'; +import { Address } from './address'; +import { Key, KeyParameters } from './Key'; +import { KeyType } from './KeyType'; +import { PublicKey } from './PublicKey'; +import { Signable } from './signable'; +import { Signature } from './Signature'; +import { SignatureScheme } from './SignatureScheme'; + +// tslint:disable-next-line:no-var-requires +const HDKey = require('@ont-community/hdkey-secp256r1'); + +export class PrivateKey extends Key { + /** + * Generates random Private key using supplied Key type and parameters. + * + * If no Key type or parameters is supplied, default SDK key type with default parameters will be used. + * + * @param keyType The key type + * @param parameters The parameters for the key type + */ + static random(keyType?: KeyType, parameters?: KeyParameters): PrivateKey { + if (keyType === undefined) { + keyType = KeyType.fromLabel(DEFAULT_ALGORITHM.algorithm); + } + + if (parameters === undefined) { + parameters = KeyParameters.deserializeJson(DEFAULT_ALGORITHM.parameters); + } + + return new PrivateKey(ab2hexstring(secureRandom(32)), keyType, parameters); + } + + /** + * Creates PrivateKey from Wallet Import Format (WIF) representation. + * + * @param wifkey WIF private key representation + * + */ + static deserializeWIF(wifkey: string): PrivateKey { + const key = ab2hexstring(wif.decode(wifkey, 128).privateKey); + return new PrivateKey(key); + } + + /** + * Creates PrivateKey from mnemonic according to BIP39 protocol. + * + * @param mnemonic Space separated list of words + * + */ + static generateFromMnemonic(mnemonic: string, derivePath: string = DNA_BIP44_PATH): PrivateKey { + if (mnemonic.split(' ').length < 12) { + throw ERROR_CODE.INVALID_PARAMS; + } + const seed = bip39.mnemonicToSeedHex(mnemonic); + + // generate privateKey + // const pri = seed.substr(0, 64); + const hdkey = HDKey.fromMasterSeed(Buffer.from(seed, 'hex')); + const pri = hdkey.derive(derivePath); + const key = Buffer.from(pri.privateKey).toString('hex'); + const privateKey = new PrivateKey(key); + return privateKey; + } + + /** + * Signs the data with supplied private key using signature schema. + * + * If the signature schema is not provided, the default schema for this key type is used. + * + * This method is not suitable, if external keys (Ledger, TPM, ...) support is required. + * + * @param msg Hex encoded input data or Signable object + * @param schema Signing schema to use + * @param publicKeyId Id of public key + */ + sign(msg: string | Signable, schema?: SignatureScheme, publicKeyId?: string): Signature { + if (schema === undefined) { + schema = this.algorithm.defaultSchema; + } + + if (!this.isSchemaSupported(schema)) { + throw new Error('Signature schema does not match key type.'); + } + + // retrieves content to sign if not provided directly + if (typeof msg !== 'string') { + msg = msg.getSignContent(); + } + + let hash: string; + if (schema === SignatureScheme.SM2withSM3) { + // library sm.js (SM2withSM3) has implemented hashing as part of signing, therefore it is skipped + hash = msg; + } else { + hash = this.computeHash(msg, schema); + } + + const signed = this.computeSignature(hash, schema); + return new Signature(schema, signed, publicKeyId); + } + + /** + * Asynchroniously signs the data with supplied private key using signature schema. + * + * If the signature schema is not provided, the default schema for this key type is used. + * + * This method is suitable, if external keys (Ledger, TPM, ...) support is required. + * + * @param msg Hex encoded input data or Signable object + * @param schema Signing schema to use + * @param publicKeyId Id of public key + */ + async signAsync(msg: string | Signable, schema?: SignatureScheme, publicKeyId?: string): Promise { + return this.sign(msg, schema, publicKeyId); + } + + /** + * Derives Public key out of Private key. + */ + getPublicKey(): PublicKey { + switch (this.algorithm) { + case KeyType.ECDSA: + return this.getEcDSAPublicKey(); + case KeyType.EDDSA: + return this.getEdDSAPublicKey(); + case KeyType.SM2: + return this.getSM2PublicKey(); + default: + throw new Error('Unsupported signature schema.'); + } + } + + /** + * Decrypts encrypted private key with supplied password. + * + * @param keyphrase Password to decrypt with + * @param address For aad in decryption + * @param 16 secure random bytes + * @param params Optional Scrypt params + */ + decrypt(keyphrase: string, address: Address, salt: string, params?: ScryptParams): PrivateKey { + // const decrypted = decrypt(this.key, keyphrase, checksum, params); + if (salt.length === 24 && isBase64(salt)) { + salt = Buffer.from(salt, 'base64').toString('hex'); + } + const decrypted = decryptWithGcm(this.key, address, salt, keyphrase, params); + const decryptedKey = new PrivateKey(decrypted, this.algorithm, this.parameters); + // checkDecrypted(checksum, decryptedKey.getPublicKey().serializeHex()); + const pk = decryptedKey.getPublicKey(); + const addrTmp = Address.fromPubKey(pk); + if (addrTmp.toBase58() !== address.toBase58()) { + throw ERROR_CODE.Decrypto_ERROR; + } + return decryptedKey; + } + + /** + * Encrypts private key with supplied password. + * + * @param keyphrase Password to encrypt with + * @param address For aad in encryption + * @param salt 16 secure random bytes + * @param params Optional Scrypt params + */ + encrypt(keyphrase: string, address: Address, salt: string, params?: ScryptParams): PrivateKey { + // add address check + const publicKey = this.getPublicKey(); + const addr = Address.fromPubKey(publicKey).toBase58(); + if (addr !== address.toBase58()) { + throw ERROR_CODE.INVALID_ADDR; + } + const encrypted = encryptWithGcm(this.key, address, salt, keyphrase, params); + return new PrivateKey(encrypted, this.algorithm, this.parameters); + } + + /** + * Derives Public key out of Private key using EcDSA algorithm. + */ + getEcDSAPublicKey(): PublicKey { + const ec = new elliptic.ec(this.parameters.curve.preset); + const keyPair = ec.keyFromPrivate(this.key, 'hex'); + const pk = keyPair.getPublic(true, 'hex'); + + return new PublicKey(pk, this.algorithm, this.parameters); + } + + /** + * Derives Public key out of Private key using EdDSA algorithm. + */ + getEdDSAPublicKey(): PublicKey { + const eddsa = new elliptic.eddsa(this.parameters.curve.preset); + const keyPair = eddsa.keyFromSecret(this.key, 'hex'); + const pk = keyPair.getPublic(true, 'hex'); + + return new PublicKey(pk, this.algorithm, this.parameters); + } + + /** + * Derives Public key out of Private key using SM2 algorithm. + */ + getSM2PublicKey(): PublicKey { + const keyPair = sm2.SM2KeyPair(null, this.key); + const pk = keyPair.pubToString('compress'); + + return new PublicKey(pk, this.algorithm, this.parameters); + } + + /** + * Computes signature of message hash using specified signature schema. + * + * @param hash Message hash + * @param schema Signature schema to use + */ + computeSignature(hash: string, schema: SignatureScheme): string { + switch (schema) { + case SignatureScheme.ECDSAwithSHA224: + case SignatureScheme.ECDSAwithSHA256: + case SignatureScheme.ECDSAwithSHA384: + case SignatureScheme.ECDSAwithSHA512: + case SignatureScheme.ECDSAwithSHA3_224: + case SignatureScheme.ECDSAwithSHA3_256: + case SignatureScheme.ECDSAwithSHA3_384: + case SignatureScheme.ECDSAwithSHA3_512: + case SignatureScheme.ECDSAwithRIPEMD160: + return this.computeEcDSASignature(hash); + case SignatureScheme.EDDSAwithSHA512: + return this.computeEdDSASignature(hash); + case SignatureScheme.SM2withSM3: + return this.computeSM2Signature(hash); + default: + throw new Error('Unsupported signature schema.'); + } + } + + /** + * Computes EcDSA signature of message hash. Curve name is derrived from private key. + * + * @param hash Message hash + */ + computeEcDSASignature(hash: string): string { + const ec = new elliptic.ec(this.parameters.curve.preset); + const signed = ec.sign(hash, this.key, { canonical: true }); + return Buffer.concat([ + signed.r.toArrayLike(Buffer, 'be', 32), + signed.s.toArrayLike(Buffer, 'be', 32) + ]).toString('hex'); + } + + /** + * Computes EdDSA signature of message hash. Curve name is derrived from private key. + * + * @param hash Message hash + */ + computeEdDSASignature(hash: string): string { + const eddsa = new elliptic.eddsa(this.parameters.curve.preset); + const signed = eddsa.sign(hash, this.key); + return signed.toHex().toLowerCase(); + } + + /** + * Computes SM2 signature of message hash. + * + * Only default SM2 ID is supported. + * + * @param hash Message hash + */ + computeSM2Signature(hash: string): string { + const keyPair = sm2.SM2KeyPair(null, this.key); + const signed = keyPair.sign(hexstring2ab(hash)); + + const id = DEFAULT_SM2_ID; + + return str2hexstr(id + '\0') + signed.r + signed.s; + } + + /** + * Gets Wallet Import Format (WIF) representation of the PrivateKey. + * + */ + serializeWIF(): string { + return wif.encode(128, Buffer.from(this.key, 'hex'), true); + } +} diff --git a/src/crypto/PrivateKeyFactory.ts b/src/crypto/PrivateKeyFactory.ts new file mode 100644 index 0000000..36d6421 --- /dev/null +++ b/src/crypto/PrivateKeyFactory.ts @@ -0,0 +1,84 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { JsonKey, KeyParameters } from './Key'; +import { KeyType } from './KeyType'; +import { PrivateKey } from './PrivateKey'; + +/** + * Interface for Key deserializers + */ +export interface KeyDeserializer { + getType(): string; + deserialize(json: JsonKey): PrivateKey; +} + +/** + * Default private key deserializer. + */ +export class DefaultKeyDeserializer implements KeyDeserializer { + getType(): string { + return ''; + } + + deserialize(json: JsonKey): PrivateKey { + if (json.key != null) { + return new PrivateKey( + json.key, + KeyType.fromLabel(json.algorithm), + KeyParameters.deserializeJson(json.parameters) + ); + } else { + throw new Error('Unsupported Key type.'); + } + } +} + +/** + * Registered key deserializers + */ +const keyDeserializers: KeyDeserializer[] = []; +const defaultKeyDeserializer = new DefaultKeyDeserializer(); + +/** + * Registers new external deserializer for private keys. + * + * @param deserializer Deserializer instance + */ +export function registerKeyDeserializer(deserializer: KeyDeserializer) { + keyDeserializers.push(deserializer); +} + +/** + * Creates PrivateKey from Json representation. + * + * @param json Json private key representation + * + */ +export function deserializeFromJson(json: JsonKey): PrivateKey { + if (json.external == null) { + return defaultKeyDeserializer.deserialize(json); + } else { + for (const deserializer of keyDeserializers) { + if (deserializer.getType() === json.external.type) { + return deserializer.deserialize(json); + } + } + + throw new Error('Unsupported Key type.'); + } +} diff --git a/src/crypto/PublicKey.ts b/src/crypto/PublicKey.ts new file mode 100644 index 0000000..58ee769 --- /dev/null +++ b/src/crypto/PublicKey.ts @@ -0,0 +1,221 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as elliptic from 'elliptic'; +import { sm2 } from 'sm.js'; +import { DEFAULT_SM2_ID } from '../consts'; +import { hexstr2str, hexstring2ab, num2hexstring, StringReader } from '../utils'; +import { CurveLabel } from './CurveLabel'; +import { Key, KeyParameters } from './Key'; +import { KeyType } from './KeyType'; +import { Signable } from './signable'; +import { Signature } from './Signature'; +import { SignatureScheme } from './SignatureScheme'; + +/** + * Class to manage the public key with some userful functions. + */ +export class PublicKey extends Key { + /** + * Creates PublicKey from Hex representation. + * + * @param sr String reader + * @param length Byte length of the serialized object + * + */ + static deserializeHex(sr: StringReader, length: number = 33): PublicKey { + if (length === 33) { // ECDSA + const algorithm = KeyType.ECDSA; + const curve = CurveLabel.SECP256R1; + const pk = sr.read(33); + return new PublicKey(pk, algorithm, new KeyParameters(curve)); + } else { + const algorithmHex = parseInt(sr.read(1), 16); + const curveHex = parseInt(sr.read(1), 16); + const pk = sr.read(length - 2); + + return new PublicKey( + pk, + KeyType.fromHex(algorithmHex), + new KeyParameters(CurveLabel.fromHex(curveHex)) + ); + } + } + + /** + * Verifies if the signature was created with private key corresponding to supplied public key + * and was not tampered with using signature schema. + * + * @param msg Hex encoded input data or Signable object + * @param signature Signature object + */ + verify(msg: string | Signable, signature: Signature): boolean { + if (!this.isSchemaSupported(signature.algorithm)) { + throw new Error('Signature schema does not match key type.'); + } + + // retrieves content to sign if not provided directly + if (typeof msg !== 'string') { + msg = msg.getSignContent(); + } + + let hash: string; + if (signature.algorithm === SignatureScheme.SM2withSM3) { + // library sm.js (SM2withSM3) has implemented hashing as part of verification, therefore it is skipped + hash = msg; + } else { + hash = this.computeHash(msg, signature.algorithm); + } + + return this.verifySignature(hash, signature.value, signature.algorithm); + } + + /** + * Serializes public key to Hex representation. + * + * Length definition is not included. + */ + serializeHex(): string { + let result = ''; + switch (this.algorithm) { + case KeyType.ECDSA: + result += this.key; + break; + case KeyType.EDDSA: + case KeyType.SM2: + result += num2hexstring(this.algorithm.hex); + result += num2hexstring(this.parameters.curve.hex); + result += this.key; + break; + } + return result; + } + + /** + * For internal use. + * @param hash Message hash + * @param signature Hex encoded signature + * @param schema Signature scheme to use + */ + verifySignature(hash: string, signature: string, schema: SignatureScheme): boolean { + switch (schema) { + case SignatureScheme.ECDSAwithSHA224: + case SignatureScheme.ECDSAwithSHA256: + case SignatureScheme.ECDSAwithSHA384: + case SignatureScheme.ECDSAwithSHA512: + case SignatureScheme.ECDSAwithSHA3_224: + case SignatureScheme.ECDSAwithSHA3_256: + case SignatureScheme.ECDSAwithSHA3_384: + case SignatureScheme.ECDSAwithSHA3_512: + case SignatureScheme.ECDSAwithRIPEMD160: + return this.verifyEcDSASignature(hash, signature); + case SignatureScheme.EDDSAwithSHA512: + return this.verifyEdDSASignature(hash, signature); + case SignatureScheme.SM2withSM3: + return this.verifySM2Signature(hash, signature); + default: + throw new Error('Unsupported signature schema.'); + } + } + + /** + * Verifies EcDSA signature of message hash. Curve name is derrived from private key. + * + * @param hash Message hash + * @param signature Hex encoded signature + */ + verifyEcDSASignature(hash: string, signature: string): boolean { + const r = signature.substr(0, 64); + const s = signature.substr(64, 64); + + const ec = new elliptic.ec(this.parameters.curve.preset); + return ec.verify(hash, { r, s }, this.key, 'hex'); + } + + /** + * Verifies EdDSA signature of message hash. Curve name is derrived from private key. + * + * @param hash Message hash + * @param signature Hex encoded signature + */ + verifyEdDSASignature(hash: string, signature: string): boolean { + const r = signature.substr(0, 64); + const s = signature.substr(64, 64); + + const eddsa = new elliptic.eddsa(this.parameters.curve.preset); + return eddsa.verify(hash, { r, s }, this.key, 'hex'); + } + + /** + * Verifies SM2 signature of message hash. + * + * Only default SM2 ID is supported. + * + * @param hash Message hash + * @param signature Hex encoded signature + */ + verifySM2Signature(hash: string, signature: string): boolean { + const reader = new StringReader(signature); + + const id = hexstr2str(reader.readNullTerminated()); + if (id !== DEFAULT_SM2_ID && id !== '') { + throw new Error('Unsupported SM2 id used.'); + } + + const r = reader.read(32); + const s = reader.read(32); + + const keyPair = sm2.SM2KeyPair(this.key); + return keyPair.verify(hexstring2ab(hash), r, s); + } +} + +/** + * Public key status enumaration. + */ +export class PublicKeyStatus { + static values: PublicKeyStatus[] = []; + + static IN_USE = new PublicKeyStatus('in use'); + + static REVOKED = new PublicKeyStatus('revoked'); + + /** + * Finds Public key status corresponding to specified label representation. + * + * @param label Hex encoded label + */ + static fromHexLabel(hexLabel: string): PublicKeyStatus { + const label = hexstr2str(hexLabel); + + const item = PublicKeyStatus.values.find((v) => v.label === label); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + label: string; + + constructor(label: string) { + this.label = label; + + PublicKeyStatus.values.push(this); + } +} diff --git a/src/crypto/Signature.ts b/src/crypto/Signature.ts new file mode 100644 index 0000000..9239ae7 --- /dev/null +++ b/src/crypto/Signature.ts @@ -0,0 +1,124 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as b64 from 'base64-url'; +import { num2hexstring, StringReader } from '../utils'; +import { SignatureScheme } from './SignatureScheme'; + +/** + * Signature generated by signing data with Private Key. + */ +export class Signature { + static deserializeJWT(encoded: string, algorithm: SignatureScheme, publicKeyId: string): Signature { + const decoded = b64.decode(encoded, 'hex'); + + return new Signature( + algorithm, + decoded, + publicKeyId + ); + } + + /** + * Deserializes PgpSignature to Signature. + * @param pgpSignature PgpSignature + */ + static deserializePgp(pgpSignature: PgpSignature): Signature { + const value = new Buffer(pgpSignature.Value, 'base64').toString('hex'); + const deserialzedValue = Signature.deserializeHex(value).value; + return new Signature( + SignatureScheme.fromLabel(pgpSignature.Algorithm), + deserialzedValue + ); + } + + /** + * Deserializes hex representation to Signature + * @param data hex string + */ + static deserializeHex(data: string): Signature { + if (data.length < 4) { + throw new Error('Invalid params.'); + } + const sr = new StringReader(data); + const scheme = parseInt(sr.read(1), 16); + const sigScheme = SignatureScheme.fromHex(scheme); + const value = data.substr(2); + const sig = new Signature(sigScheme, value); + return sig; + } + + algorithm: SignatureScheme; + value: string; + + /** + * Public key Id used for create this signature. + * + */ + publicKeyId?: string; + + constructor(algorithm: SignatureScheme, value: string, publicKeyId?: string) { + this.algorithm = algorithm; + this.value = value; + this.publicKeyId = publicKeyId; + } + + /** + * Serializes signature to Hex representation. + * For transfer to java backend and verify it. + */ + serializeHex(): string { + let result = ''; + result += num2hexstring(this.algorithm.hex); + result += this.value; + return result; + + } + + /** + * Serializes signature to PGP representation with optional PublicKeyId. + * + * @param keyId Whole Public Key Id in the form #keys- + */ + serializePgp(keyId?: string): PgpSignature { + const encoded = new Buffer(this.serializeHex(), 'hex').toString('base64'); + return { + PublicKeyId: keyId, + Format: 'pgp', + Value: encoded, + Algorithm: this.algorithm.label + }; + } + + /** + * Serializes signature to base64url format. + */ + serializeJWT(): string { + return b64.encode(this.value, 'hex'); + } +} + +/** + * PGP representation of the signature with embedded KeyId + */ +export interface PgpSignature { + PublicKeyId?: string; + Format: 'pgp'; + Algorithm: string; + Value: string; +} diff --git a/src/crypto/SignatureScheme.ts b/src/crypto/SignatureScheme.ts new file mode 100644 index 0000000..6bbf4fe --- /dev/null +++ b/src/crypto/SignatureScheme.ts @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +/** + * Schema used during signing and verification of signature. + */ +export class SignatureScheme { + static values: SignatureScheme[] = []; + + static ECDSAwithSHA224 = new SignatureScheme('SHA224withECDSA', 0, 'ES224'); + static ECDSAwithSHA256 = new SignatureScheme('SHA256withECDSA', 1, 'ES256'); + static ECDSAwithSHA384 = new SignatureScheme('SHA384withECDSA', 2, 'ES384'); + static ECDSAwithSHA512 = new SignatureScheme('SHA512withECDSA', 3, 'ES512'); + // tslint:disable-next-line:variable-name + static ECDSAwithSHA3_224 = new SignatureScheme('SHA3-224withECDSA', 4, 'ES3-224'); + // tslint:disable-next-line:variable-name + static ECDSAwithSHA3_256 = new SignatureScheme('SHA3-256withECDSA', 5, 'ES3-256'); + // tslint:disable-next-line:variable-name + static ECDSAwithSHA3_384 = new SignatureScheme('SHA3-384withECDSA', 6, 'ES3-384'); + // tslint:disable-next-line:variable-name + static ECDSAwithSHA3_512 = new SignatureScheme('SHA3-512withECDSA', 7, 'ES3-512'); + static ECDSAwithRIPEMD160 = new SignatureScheme('RIPEMD160withECDSA', 8, 'ER160'); + static SM2withSM3 = new SignatureScheme('SM3withSM2', 9, 'SM'); + static EDDSAwithSHA512 = new SignatureScheme('SHA512withEdDSA', 10, 'EDS512'); + + /** + * Finds Signature schema corresponding to specified hex representation. + * + * @param hex Byte hex value + */ + static fromHex(hex: number): SignatureScheme { + const item = SignatureScheme.values.find((v) => v.hex === hex); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + /** + * Finds Signature schema corresponding to specified label representation. + * + * @param label Label + */ + static fromLabel(label: string): SignatureScheme { + const item = SignatureScheme.values.find((v) => v.label === label); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + /** + * Finds Signature schema corresponding to specified label representation in JWS. + * + * @param label Label + */ + static fromLabelJWS(label: string): SignatureScheme { + const item = SignatureScheme.values.find((v) => v.labelJWS === label); + if (item === undefined) { + throw new Error('Enum value not found'); + } + + return item; + } + + label: string; + hex: number; + labelJWS: string; + + constructor(label: string, hex: number, labelJWS: string) { + this.label = label; + this.hex = hex; + this.labelJWS = labelJWS; + + SignatureScheme.values.push(this); + } +} diff --git a/src/crypto/address.ts b/src/crypto/address.ts new file mode 100644 index 0000000..252d655 --- /dev/null +++ b/src/crypto/address.ts @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import * as base58 from 'base-58'; +import * as cryptoJS from 'crypto-js'; +import { ADDR_VERSION } from '../consts'; +import { ERROR_CODE } from '../error'; +import opcode from '../transaction/opcode'; +import { comparePublicKeys, programFromPubKey, pushBigInt } from '../transaction/program'; +import { pushHexString } from '../transaction/program'; +import { ab2hexstring, hash160, num2hexstring, sha256, StringReader } from '../utils'; +import { reverseHex } from './../utils'; +import { PublicKey } from './PublicKey'; + +/** + * Representation of Address. + * + * There are 4 types of address: + * 1. Public key based + * 2. Multi public key based (m, n) + * 3. Contract based + * 4. DID based + * + * The value is stored as base58 or hex encoded, therefore always use + * toBase58() or serialize() according to requirements. + */ +export class Address { + static deserialize(sr: StringReader): Address { + return new Address(sr.read(20)); + } + /** + * Generates public key based address. + * + * @param publicKey Public key to use + */ + static fromPubKey(publicKey: PublicKey): Address { + const program = programFromPubKey(publicKey); + // const program = publicKey.key + num2hexstring(opcode.CHECKSIG); + const programHash = hash160(program); + return new Address(programHash); + } + + /** + * Generates identity based address. + * @param did DNA ID in the form did:dna:AXmQDzzvpEtPkNwBEFsREzApTTDZFW6frD + */ + static fromDNAid(did: string): Address { + const address = did.substr(8); + return new Address(address); + } + + /** + * Generates address from smart contract code. + * + * @param vmCode Hex encoded smart contract code + */ + static fromVmCode(vmCode: string): Address { + const programHash = hash160(vmCode); + // programHash = num2hexstring(vmType) + programHash.substring(2); + return new Address(programHash); + } + + /** + * Generates (m, n) threshold address. + * + * m - threshold + * n - total number of public keys + * + * @param m The threshold + * @param publicKeys Public key + */ + static fromMultiPubKeys(m: number, publicKeys: PublicKey[]): Address { + const n = publicKeys.length; + + if (m <= 0 || m > n || n > 24 ) { + throw ERROR_CODE.INVALID_PARAMS; + } + + // const pkHexStrs = publicKeys.map((p) => p.serializeHex()); + // pkHexStrs.sort(); + publicKeys.sort(comparePublicKeys); + let result = ''; + result += pushBigInt(m); + for (const s of publicKeys) { + result += pushHexString(s.serializeHex()); + } + result += pushBigInt(n); + result += num2hexstring(opcode.CHECKMULTISIG); + const programHash = hash160(result); + return new Address(programHash); + } + + /** + * Deterministicaly generates DNA ID from this public key. + */ + static generateDNAid(publicKey: PublicKey): string { + const address = Address.fromPubKey(publicKey); + const did = 'did:dna:' + address.toBase58(); + + return did; + } + + /** + * Base58 or Hex encoded address + */ + value: string; + + constructor(value: string) { + if (value.length === 40 || value.length === 34) { + this.value = value; + } else { + throw ERROR_CODE.INVALID_PARAMS; + } + } + + /** + * Gets Base58 encoded representation of the address. + */ + toBase58() { + if (this.value.length === 34) { + return this.value; + } else { + return hexToBase58(this.value); + } + } + + /** + * Gets Hex encoded representation of the address. + */ + toHexString() { + let val; + if (this.value.length === 40) { + val = this.value; + } else { + val = base58ToHex(this.value); + } + return reverseHex(val); + } + + serialize() { + if (this.value.length === 40) { + return this.value; + } else { + return base58ToHex(this.value); + } + } + + /** + * Computes the salt from address for decrypt. + */ + getB58Checksum() { + const address = this.toBase58(); + const hash = cryptoJS.SHA256(address).toString(); + const hash2 = sha256(hash); + return hash2.slice(0, 8); + } +} + +/** + * + * @param programhash + */ +function hexToBase58(hexEncoded: string): string { + const data = ADDR_VERSION + hexEncoded; + + const hash = sha256(data); + const hash2 = sha256(hash); + const checksum = hash2.slice(0, 8); + + const datas = data + checksum; + + return base58.encode(new Buffer(datas, 'hex')); +} + +function base58ToHex(base58Encoded: string) { + const decoded = base58.decode(base58Encoded); + const hexEncoded = ab2hexstring(decoded).substr(2, 40); + + if (base58Encoded !== hexToBase58(hexEncoded)) { + throw new Error('[addressToU160] decode encoded verify failed'); + } + return hexEncoded; +} diff --git a/src/crypto/index.ts b/src/crypto/index.ts new file mode 100644 index 0000000..5aa66c5 --- /dev/null +++ b/src/crypto/index.ts @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +export { Address } from './address'; +export { KeyType } from './KeyType'; +export { CurveLabel } from './CurveLabel'; +export { SignatureScheme } from './SignatureScheme'; +export { KeyParameters, JsonKeyParameters, JsonKey } from './Key'; +export { PrivateKey } from './PrivateKey'; +export { KeyDeserializer, registerKeyDeserializer } from './PrivateKeyFactory'; +export { PublicKey, PublicKeyStatus } from './PublicKey'; +export { Signature, PgpSignature } from './Signature'; +export { Signable } from './signable'; +export { Issuer, User } from './AnonymousCredential'; +export { Ecies } from './Ecies'; diff --git a/src/crypto/signable.ts b/src/crypto/signable.ts new file mode 100644 index 0000000..9a9a715 --- /dev/null +++ b/src/crypto/signable.ts @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +/** + * Interface for other classes to implement, which should be signable. + */ +export interface Signable { + /** + * Get the sign content of object + */ + getSignContent(): string; + + /** + * Gets the raw serialized content of signable object without hashing + */ + serializeUnsignedData(): string; +} diff --git a/src/error.ts b/src/error.ts new file mode 100644 index 0000000..1fb5cf3 --- /dev/null +++ b/src/error.ts @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +export enum ERROR_CODE { + SUCCESS = 0, // 成功 + SESSION_EXPIRED = 41001, // 会话无效或已过期( 需要重新登录) | + SERVICE_CEILING = 41002, // 达到服务上限 | + ILLEGAL_DATAFORMAT = 41003, // 不合法数据格式 | + INVALID_VERSION = 41004, // 不合法的版本 | + INVALID_METHOD = 42001, // 无效的方法 | + INVALID_PARAMS = 42002, // 无效的参数 | + INVALID_TRANSACTION = 43001, // 无效的交易 | + INVALID_ASSET = 43002, // 无效的资产 | + INVALID_BLOCK = 43003, // 无效的块 | + UNKNOWN_TRANSACTION = 44001, // 找不到交易 | + UNKNOWN_ASSET = 44002, // 找不到资产 | + UNKNOWN_BLOCK = 44003, // 找不到块 | + UNKNWN_CONTRACT = 44004, // 找不到合约 | + INTERNAL_ERROR = 45001, // 内部错误 | + SMARTCODE_ERROR = 47001, // 智能合约错误 | + + UNKNOWN_DNAID = 51000, // DNA ID, + NETWORK_ERROR = 52000, // 网络错误, + Decrypto_ERROR = 53000, // 解密错误, + INVALID_ADDR = 53001, // 地址验证失败 + + PreExec_ERROR = 54000 // 预执行错误 +} diff --git a/src/global.d.ts b/src/global.d.ts new file mode 100644 index 0000000..1ed256a --- /dev/null +++ b/src/global.d.ts @@ -0,0 +1,32 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +/** + * Dummy declarations for modues which does not have Typescript definitions. + * This is the preffered way instead of using require. + */ +declare module 'elliptic'; +declare module 'bn.js'; +declare module 'secure-random'; +declare module 'sm.js'; +declare module 'wif'; +declare module 'bip39'; +declare module 'websocket-as-promised'; +declare module 'milagro-crypto-js'; +declare module 'base-58'; +declare module 'pkcs7'; diff --git a/src/identity.ts b/src/identity.ts new file mode 100644 index 0000000..ed7e703 --- /dev/null +++ b/src/identity.ts @@ -0,0 +1,228 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import { Address, JsonKey, PrivateKey } from './crypto'; +import { deserializeFromJson } from './crypto/PrivateKeyFactory'; +import { ScryptParams } from './scrypt'; +import { Transaction } from './transaction/transaction'; +import { signTransaction } from './transaction/transactionBuilder'; +import { ab2hexstring, generateRandomArray, randomBytes } from './utils'; + +/** + * Control data of identity + */ +export class ControlData { + static fromJson(json: any): ControlData { + const privateKey = deserializeFromJson(json as JsonKey); + const cd = new ControlData(json.id, privateKey, new Address(json.address), json.salt); + cd.publicKey = json.publicKey; + cd.hash = json.hash; + return cd; + } + + /** + * Id of control data + */ + id: string; + /** + * Encrypted private key + */ + encryptedKey: PrivateKey; + /** + * Address of control data + */ + address: Address; + /** + * Salt of control data + */ + salt: string; + /** + * hash type + */ + hash: string = 'sha256'; + /** + * The public key + */ + publicKey: string; + + constructor(id: string, encryptedKey: PrivateKey, address: Address, salt: string) { + this.id = id; + this.encryptedKey = encryptedKey; + this.address = address; + this.salt = salt; + } + + toJson(): object { + return { + id: this.id, + ...this.encryptedKey.serializeJson(), + address: this.address.toBase58(), + salt: this.salt, + ['enc-alg']: 'aes-256-gcm', + hash: this.hash, + publicKey: this.publicKey + }; + } +} + +export class Identity { + /** + * Import identity + * @param label Name of identity + * @param encryptedPrivateKey Encrypted private key + * @param password User's password to decrypt + * @param address Address to decrypt + * @param saltBase64 Salt to decrypt + * @param params Optional params to decrypt + */ + static importIdentity( + label: string, + encryptedPrivateKey: PrivateKey, + password: string, + address: Address, + saltBase64: string, + params?: ScryptParams + ): Identity { + // create identity + const identity = new Identity(); + const salt = Buffer.from(saltBase64, 'base64').toString('hex'); + const privateKey = encryptedPrivateKey.decrypt(password, address, salt, params); + if (!label) { + label = ab2hexstring (generateRandomArray(4)); + } + + // generate did from p + const publicKey = privateKey.getPublicKey(); + identity.dnaid = Address.generateDNAid(publicKey); + identity.label = label; + identity.lock = false; + identity.isDefault = false; + + // control + const control = new ControlData('1', encryptedPrivateKey, Address.fromDNAid(identity.dnaid), saltBase64); + control.publicKey = publicKey.serializeHex(); + identity.controls.push(control); + + return identity; + } + + /** + * Creates Identity object encrypting specified private key. + * + * The identity is not registered on the blockchain. Caller needs to register it. + * + * @param privateKey Private key associated with the identity + * @param keyphrase Password use to encrypt the private key + * @param label Custom label + * @param params Optional scrypt params + */ + static create(privateKey: PrivateKey, keyphrase: string, label: string, params?: ScryptParams) { + const identity = new Identity(); + identity.dnaid = ''; + identity.label = label; + identity.lock = false; + identity.isDefault = false; + + // dnaid + const publicKey = privateKey.getPublicKey(); + identity.dnaid = Address.generateDNAid(publicKey); + const address = Address.fromDNAid(identity.dnaid); + const salt = randomBytes(16); + const encryptedPrivateKey = privateKey.encrypt(keyphrase, address, salt, params); + // start from 1 + const saltBase64 = Buffer.from(salt, 'hex').toString('base64'); + const control = new ControlData('1', encryptedPrivateKey, address, saltBase64); + control.publicKey = publicKey.serializeHex(); + identity.controls.push(control); + + return identity; + } + + static parseJson(json: string): Identity { + return Identity.parseJsonObj(JSON.parse(json)); + } + + /** + * Deserializes JSON object. + * + * Object should be real object, not stringified. + * + * @param obj JSON object + */ + static parseJsonObj(obj: any): Identity { + const id = new Identity(); + id.dnaid = obj.dnaid; + id.label = obj.label; + id.lock = obj.lock; + id.isDefault = obj.isDefault; + id.controls = (obj.controls as any[]).map((c) => ControlData.fromJson(c)); + id.extra = obj.extra; + return id; + } + + dnaid: string; + label: string; + lock: boolean; + isDefault: boolean; + controls: ControlData[] = []; + extra: null; + + addControl(control: ControlData) { + for (const c of this.controls) { + if (c.address.toBase58() === control.address.toBase58()) { + return; + } + } + control.id = (this.controls.length + 1).toString(); + this.controls.push(control); + } + + toJson(): string { + return JSON.stringify(this.toJsonObj()); + } + + /** + * Serializes to JSON object. + * + * Returned object will not be stringified. + * + */ + toJsonObj(): any { + const obj = { + dnaid: this.dnaid, + label: this.label, + lock: this.lock, + isDefault: this.isDefault, + controls: this.controls.map((c) => c.toJson()), + extra: this.extra + }; + return obj; + } + + exportPrivateKey(password: string, params?: ScryptParams) { + const encryptedKey = this.controls[0].encryptedKey; + const address = this.controls[0].address; + const salt = this.controls[0].salt; + return encryptedKey.decrypt(password, address, salt, params); + } + + signTransaction(password: string, tx: Transaction, params?: ScryptParams) { + const pri = this.exportPrivateKey(password, params); + signTransaction(tx, pri, pri.algorithm.defaultSchema); + return tx; + } +} diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..7aba779 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { Account } from './account'; +import { Claim } from './claim'; +import * as CONST from './consts'; +import * as Crypto from './crypto'; +import { Identity } from './identity'; +import * as NeoCore from './neocore'; +import RestClient from './network/rest/restClient'; +import RpcClient from './network/rpc/rpcClient'; +import { WebsocketClient } from './network/websocket/websocketClient'; +import * as scrypt from './scrypt'; +import AbiFunction from './smartcontract/abi/abiFunction'; +import AbiInfo from './smartcontract/abi/abiInfo'; +import { Parameter, ParameterType } from './smartcontract/abi/parameter'; +import Struct from './smartcontract/abi/struct'; +import * as AssetTxBuilder from './smartcontract/nativevm/assetTxBuilder'; +import * as GovernanceTxBuilder from './smartcontract/nativevm/governanceContractTxBuilder'; +import * as IdTxBuilder from './smartcontract/nativevm/idContractTxBuilder'; +import * as Token from './smartcontract/nativevm/token'; +import * as Oep4 from './smartcontract/neovm/oep4TxBuilder'; +import * as Oep5 from './smartcontract/neovm/oep5TxBuilder'; +import * as Oep8 from './smartcontract/neovm/oep8TxBuilder'; +import { DDO, DDOAttribute } from './transaction/ddo'; +import * as ScriptBuilder from './transaction/scriptBuilder'; +import { Transaction } from './transaction/transaction'; +import * as TransactionBuilder from './transaction/transactionBuilder'; +import { Transfer } from './transaction/transfer'; +import { TxSignature } from './transaction/txSignature'; +import * as utils from './utils'; +import { Wallet } from './wallet'; + +class DNA { + Account: any; + Identity: any; + Claim: any; + DDO: any; + DDOAttribute: any; + Transaction: any; + Transfer: any; + TxSignature: any; + TransactionBuilder: any; + AssetTxBuilder: any; + Parameter: any; + ParameterType: any; + AbiFunction: any; + AbiInfo: any; + utils: any; + scrypt: any; + CONST: any; + Wallet: any; + SDK: any; + Token: any; + IdTxBuilder: any; + GovernanceTxBuilder: any; + RestClient: any; + RpcClient: any; + WebsocketClient: any; + Crypto: any; + Struct: any; + ScriptBuilder: any; + NeoCore: any; + Oep4: any; + Oep8: any; + Oep5: any; + + constructor() { + this.Account = Account; + this.Identity = Identity; + this.Claim = Claim; + this.DDO = DDO; + this.DDOAttribute = DDOAttribute; + this.Transaction = Transaction; + this.Transfer = Transfer; + this.TxSignature = TxSignature; + this.TransactionBuilder = TransactionBuilder; + this.AssetTxBuilder = AssetTxBuilder; + this.GovernanceTxBuilder = GovernanceTxBuilder; + this.Parameter = Parameter; + this.ParameterType = ParameterType; + this.AbiFunction = AbiFunction; + this.AbiInfo = AbiInfo; + this.utils = utils; + this.scrypt = scrypt; + this.CONST = CONST; + this.Wallet = Wallet; + this.Token = Token; + this.IdTxBuilder = IdTxBuilder; + this.RestClient = RestClient; + this.RpcClient = RpcClient; + this.WebsocketClient = WebsocketClient; + this.Crypto = Crypto; + this.Struct = Struct; + this.ScriptBuilder = ScriptBuilder; + this.NeoCore = NeoCore; + this.Oep4 = Oep4; + this.Oep8 = Oep8; + this.Oep5 = Oep5; + } + setNode(url: string) { + this.CONST.TEST_NODE = url; + } + + setRpcPort(port: string) { + this.CONST.HTTP_JSON_PORT = port; + } + + setRestPort(port: string) { + this.CONST.HTTP_REST_PORT = port; + } + + setSocketPort(port: string) { + this.CONST.HTTP_WS_PORT = port; + } +} + +export default DNA; + +export { + Account, + Identity, + Claim, + DDO, + DDOAttribute, + Transaction, + Transfer, + TxSignature, + Parameter, + ParameterType, + AbiFunction, + AbiInfo, + TransactionBuilder, + AssetTxBuilder, + GovernanceTxBuilder, + utils, + scrypt, + CONST, + Wallet, + Token, + IdTxBuilder, + RestClient, + RpcClient, + WebsocketClient, + Crypto, + Struct, + ScriptBuilder, + NeoCore, + Oep4, + Oep8, + Oep5 +}; diff --git a/src/merkle.ts b/src/merkle.ts new file mode 100644 index 0000000..ba7d462 --- /dev/null +++ b/src/merkle.ts @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as cryptoJS from 'crypto-js'; +import RestClient from './network/rest/restClient'; + +/* + verify a Merkle Audit Path + + leaf_hash: The hash of the leaf for which the proof was provided. + leaf_index: Index of the leaf in the tree. + proof: A list of SHA-256 hashes representing the Merkle audit path. + tree_size: The size of the tree + root_hash: The root hash of the tree + + Returns: + true when the proof is valid +*/ +export function verifyLeafHashInclusion( + leafHash: string, + leafIndex: number, + proof: string[], + rootHash: string, + treeSize: number +) { + if (treeSize <= leafIndex) { + throw new Error('Wrong params, the tree size is smaller than the leaf index'); + } + + const calculatedRootHash = calculateRootHashFromAuditPath(leafHash, leafIndex, proof, treeSize); + if (calculatedRootHash !== rootHash) { + return false; + } + return true; +} + +export function calculateRootHashFromAuditPath(leafHash: string, leafIndex: number, proof: string[], treeSize: number) { + let calculatedHash = leafHash; + let lastNode = treeSize - 1; + let pos = 0; + const pathLen = proof.length; + + while (lastNode > 0) { + if (pos > pathLen) { + throw new Error('Proof too short'); + } + + if (leafIndex % 2 === 1) { + calculatedHash = hashChildren(proof[pos], calculatedHash); + pos += 1; + } else if (leafIndex < lastNode ) { + calculatedHash = hashChildren(calculatedHash, proof[pos]); + pos += 1; + } + + leafIndex = Math.floor(leafIndex / 2); + lastNode = Math.floor(lastNode / 2); + } + + if (pos < pathLen) { + throw new Error('Proof too long'); + } + + return calculatedHash; +} + +export function hashChildren(left: string, right: string) { + let data = '01' + left; + data += right; + const hex = cryptoJS.enc.Hex.parse(data); + return cryptoJS.SHA256(hex).toString(); +} + +export function getProofNodes(leafIndex: number, treeSize: number, proof: string[]) { + let lastNode = treeSize - 1; + let pos = 0; + const pathLen = proof.length; + const nodes: any[] = []; + + while (lastNode > 0) { + if (pos > pathLen) { + throw new Error('Proof too short'); + } + + const node = { + TargetHash: proof[pos], + Direction: '' + }; + + if (leafIndex % 2 === 1) { + node.Direction = 'Left'; + pos += 1; + } else if (leafIndex < lastNode) { + node.Direction = 'Right'; + pos += 1; + } + + nodes.push(node); + leafIndex = Math.floor(leafIndex / 2); + lastNode = Math.floor(lastNode / 2); + } + + return nodes; +} + +export async function constructClaimProof(txHash: string, contractAddr: string) { + const restClient = new RestClient(); + const res = await restClient.getMerkleProof(txHash); + + // tslint:disable-next-line:no-console + console.log(res.Result); + + const merkleProof = res.Result; + const proof = merkleProof.TargetHashes; + const leafIndex = merkleProof.BlockHeight; + const treeSize = merkleProof.CurBlockHeight; + // const pos = 0; + // const pathLen = proof.length; + + const nodes = getProofNodes(leafIndex, treeSize, proof); + + const claimProof = { + Type: 'MerkleProof', + TxnHash: txHash, + ContractAddr: contractAddr, + BlockHeight: merkleProof.BlockHeight, + MerkleRoot: merkleProof.CurBlockRoot, + Nodes: nodes + }; + + return claimProof; +} + +// "TxnHash": "c89e76ee58ae6ad99cfab829d3bf5bd7e5b9af3e5b38713c9d76ef2dcba2c8e0", +// "MerkleRoot": "bfc2ac895685fbb01e22c61462f15f2a6e3544835731a43ae0cba82255a9f904", +// "Nodes": [{ +// "Direction": "Right", +// "TargetHash": "2fa49b6440104c2de900699d31506845d244cc0c8c36a2fffb019ee7c0c6e2f6" +// }, { +// "Direction": "Left", +// "TargetHash": "fc4990f9758a310e054d166da842dab1ecd15ad9f8f0122ec71946f20ae964a4" +// }] + +export function verifyClaimProof(txHash: string, merkleRoot: string, nodes: any[]) { + let p = txHash; + for (const n of nodes) { + if (n.Direction === 'Right') { + p = hashChildren(p, n.TargetHash); + } else if (n.Direction === 'Left') { + p = hashChildren(n.TargetHash, p); + } + } + if (p === merkleRoot) { + return true; + } else { + return false; + } +} diff --git a/src/neocore/InvocationTransaction.ts b/src/neocore/InvocationTransaction.ts new file mode 100644 index 0000000..ba552fa --- /dev/null +++ b/src/neocore/InvocationTransaction.ts @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { hex2VarBytes } from '../utils'; +import { TxType } from './../transaction/transaction'; +import { num2hexstring } from './../utils'; +import { TransactionNeo } from './TransactionNeo'; + +export class InvocationTransaction extends TransactionNeo { + script: string; + gas: number; + constructor() { + super(); + this.type = TxType.Invoke; + } + + serializeExclusiveData() { + let result = ''; + result += hex2VarBytes(this.script); + result += num2hexstring(this.gas, 8, true); + return result; + } +} diff --git a/src/neocore/NeoRpc.ts b/src/neocore/NeoRpc.ts new file mode 100644 index 0000000..4dc7965 --- /dev/null +++ b/src/neocore/NeoRpc.ts @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import axios from 'axios'; +import { Address } from './../crypto/address'; + +export class NeoRpc { + + static sendRawTransaction(url: string, data: string) { + const req = this.makeRequest('sendrawtransaction', data); + return axios.post(url, req).then((res) => { + return res.data; + }); + } + + static makeRequest(method: string, ...params: any[]) { + const request = { + jsonrpc: '2.0', + method, + params, + id: 1 + }; + + return request; + } + + static getBalance(url: string, contractAddr: Address, address: Address) { + const req = this.makeRequest('getstorage', contractAddr.toHexString(), address.serialize()); + return axios.post(url, req).then((res) => { + return res.data; + }); + } +} diff --git a/src/neocore/Program.ts b/src/neocore/Program.ts new file mode 100644 index 0000000..e80d72d --- /dev/null +++ b/src/neocore/Program.ts @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { PublicKey } from '../crypto/PublicKey'; +import { programFromMultiPubKey, programFromParams, programFromPubKey } from '../transaction/program'; +import { hex2VarBytes, StringReader } from '../utils'; + +export class Program { + static deserialize(hexstring: string) { + const sr = new StringReader(); + const program = new Program(); + program.parameter = sr.readNextBytes(); + program.code = sr.readNextBytes(); + return program; + } + + static programFromParams(sigData: string[]) { + return programFromParams(sigData); + } + + static programFromPubKey(publicKey: PublicKey) { + return programFromPubKey(publicKey); + } + + static programFromMultiPubKey(m: number, pks: PublicKey[]) { + return programFromMultiPubKey(pks, m); + } + + parameter: string; + + code: string; + + serialize() { + let result = ''; + result += hex2VarBytes(this.parameter); + result += hex2VarBytes(this.code); + return result; + } +} diff --git a/src/neocore/SmartContract.ts b/src/neocore/SmartContract.ts new file mode 100644 index 0000000..f3ce3ca --- /dev/null +++ b/src/neocore/SmartContract.ts @@ -0,0 +1,52 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import AbiFunction from '../smartcontract/abi/abiFunction'; +import { serializeAbiFunction } from '../transaction/scriptBuilder'; +import { num2hexstring, randomBytes } from '../utils'; +import { Address } from './../crypto/address'; +import { TransactionAttribute, TransactionAttributeUsage } from './../transaction/txAttribute'; +import { InvocationTransaction } from './InvocationTransaction'; +export class SmartContract { + static makeInvokeTransaction(contractAddr: Address, addr: Address, abiFunction: AbiFunction) { + let params = serializeAbiFunction(abiFunction); + params += num2hexstring(0x67); + params += contractAddr.serialize(); + const tx = this.makeInvocationTransaction(params, addr); + return tx; + } + + static makeInvocationTransaction(params: string, addr: Address) { + const tx = new InvocationTransaction(); + tx.version = 1; + tx.attributes = []; + const attr1 = new TransactionAttribute(); + attr1.usage = TransactionAttributeUsage.Script; + attr1.data = addr.serialize(); + tx.attributes[0] = attr1; + const attr2 = new TransactionAttribute(); + attr2.usage = TransactionAttributeUsage.DescriptionUrl; + attr2.data = randomBytes(16); + tx.attributes[1] = attr2; + tx.inputs = []; + tx.outputs = []; + tx.script = params; + tx.gas = 0; + return tx; + } +} diff --git a/src/neocore/TransactionInput.ts b/src/neocore/TransactionInput.ts new file mode 100644 index 0000000..64566b7 --- /dev/null +++ b/src/neocore/TransactionInput.ts @@ -0,0 +1,61 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { reverseHex } from '../utils'; +import { num2hexstring, StringReader } from './../utils'; + +export class TransactionInput { + + static deserialize(hexstr: string) { + const sr = new StringReader(hexstr); + const input = new TransactionInput(); + input.prevHash = sr.read(20); + input.prevIndex = parseInt(reverseHex(sr.read(2)), 16); + return input; + } + /** + * 32 bytes + */ + prevHash: string; + + prevIndex: number; + + equals(o: any) { + if (o === this) { + return true; + } + if (null === o) { + return false; + } + if (!(o instanceof TransactionInput)) { + return false; + } + return this.prevHash === o.prevHash && this.prevIndex === o.prevIndex; + } + + hashCode() { + return parseInt(reverseHex(this.prevHash) , 16) + this.prevIndex; + } + + serialize() { + let result = ''; + result += this.prevHash; + result += num2hexstring(this.prevIndex, 2, true); + return result; + } +} diff --git a/src/neocore/TransactionNeo.ts b/src/neocore/TransactionNeo.ts new file mode 100644 index 0000000..4180962 --- /dev/null +++ b/src/neocore/TransactionNeo.ts @@ -0,0 +1,132 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as cryptoJS from 'crypto-js'; +import { Signable } from '../crypto/index'; +import { PrivateKey } from '../crypto/PrivateKey'; +import { TxType } from '../transaction/transaction'; +import { SignatureScheme } from './../crypto/SignatureScheme'; +import { TransactionAttribute } from './../transaction/txAttribute'; +import { num2hexstring, num2VarInt } from './../utils'; +import { Program } from './Program'; +import { TransactionInput } from './TransactionInput'; +import { TransactionOutput } from './TransactionOutput'; + +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +export class TransactionNeo implements Signable { + /** + * Transaction type + */ + type: TxType; + + version: number = 0; + + nonce: string; + + attributes: TransactionAttribute[]; + + inputs: TransactionInput[]; + + outputs: TransactionOutput[]; + + scripts: Program[]; + + serialize() { + let result = this.serializeUnsigned(); + result += num2VarInt(this.scripts.length); + for (const s of this.scripts) { + result += s.serialize(); + } + + return result; + + } + + serializeUnsigned() { + let result = ''; + result += num2hexstring(this.type); + result += num2hexstring(this.version); + + result += this.serializeExclusiveData(); + result += num2VarInt(this.attributes.length); + for (const a of this.attributes) { + result += a.serialize(); + } + + result += num2VarInt(this.inputs.length); + for (const i of this.inputs) { + result += i.serialize(); + } + + result += num2VarInt(this.outputs.length); + for (const o of this.outputs) { + result += o.serialize(); + } + return result; + } + + getHash() { + const data = this.serializeUnsigned(); + + const ProgramHexString = cryptoJS.enc.Hex.parse(data); + const ProgramSha256 = cryptoJS.SHA256(ProgramHexString).toString(); + const ProgramSha2562 = cryptoJS.SHA256(cryptoJS.enc.Hex.parse(ProgramSha256)).toString(); + + return ProgramSha2562; + } + + getSignContent() { + return this.getHashData(); + } + + serializeUnsignedData() { + return this.getHashData(); + } + + getHashData() { + return this.serializeUnsigned(); + } + + sign(privateKey: PrivateKey, scheme: SignatureScheme = SignatureScheme.ECDSAwithSHA256) { + const sig = privateKey.sign(this.getHashData(), scheme).serializeHex(); + const signature = sig.substring(2); + return signature; + } + + protected serializeExclusiveData() { + return ''; + } + +} diff --git a/src/neocore/TransactionOutput.ts b/src/neocore/TransactionOutput.ts new file mode 100644 index 0000000..fb5f278 --- /dev/null +++ b/src/neocore/TransactionOutput.ts @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { Address } from './../crypto/address'; +import { num2hexstring, StringReader } from './../utils'; +export class TransactionOutput { + + static deserialize(hexstring: string) { + const sr = new StringReader(hexstring); + const output = new TransactionOutput(); + output.assetId = sr.read(32); + output.value = sr.readLong(); + output.scriptHash = new Address(sr.read(20)); + return output; + } + + /** + * 32 bytes + */ + assetId: string; + + // long + value: number; + + scriptHash: Address; + + serialize() { + let result = ''; + result += this.assetId; + result += num2hexstring(this.value, 8, true); + result += this.scriptHash.serialize(); + return result; + } +} diff --git a/src/neocore/index.ts b/src/neocore/index.ts new file mode 100644 index 0000000..1009510 --- /dev/null +++ b/src/neocore/index.ts @@ -0,0 +1,25 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +export { InvocationTransaction } from './InvocationTransaction'; +export { NeoRpc } from './NeoRpc'; +export { Program } from './Program'; +export { SmartContract } from './SmartContract'; +export { TransactionInput } from './TransactionInput'; +export { TransactionOutput } from './TransactionOutput'; +export { TransactionNeo } from './TransactionNeo'; diff --git a/src/network/rest/restClient.ts b/src/network/rest/restClient.ts new file mode 100644 index 0000000..7010ca1 --- /dev/null +++ b/src/network/rest/restClient.ts @@ -0,0 +1,372 @@ +import { ERROR_CODE } from './../../error'; +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import axios from 'axios'; +import { TEST_DNA_URL } from '../../consts'; +import { Address } from '../../crypto/address'; +import UrlConsts from './urlConsts'; + +/** + * Wrapper class for restful api. + */ +export default class RestClient { + /** + * Url of the blockchain node + */ + url: string; + + /** + * Version of restful api + */ + version: string = 'v1.0.0'; + + /** + * Action name of the request + */ + action: string = 'sendrawtransaction'; + + constructor(url ?: string) { + this.url = url || TEST_DNA_URL.REST_URL; + if (this.url[this.url.length - 1] === '/') { + this.url = this.url.substring(0, this.url.length - 1); + } + } + + /** + * Concat params as the query part + * @param params + */ + concatParams(params: Map) { + let result = ''; + if (params.size === 0) { + return ''; + } + + for (const key of params.keys()) { + let value = params.get(key); + if (value) { + value = encodeURIComponent(value); + } + result += `&${key}=${value}`; + } + + return '?' + result.substr(1); + } + + /** + * Get the current blockchain node url + */ + getUrl() { + return this.url; + } + + /** + * To send raw transaction to blockchian + * @param hexData Hex encoded data + * @param preExec Decides if it is a pre-execute transaction + * @param userId User's id + */ + sendRawTransaction(hexData: string, preExec: boolean = false, userId ?: string): Promise { + const param = new Map(); + + if (userId) { + param.set('userid', userId); + } + + if (preExec) { + param.set('preExec', '1'); + } + + let url = this.url + UrlConsts.Url_send_transaction; + url += this.concatParams(param); + + const body = { + Action : this.action, + Version : this.version, + Data : hexData + }; + + return axios.post(url, body).then((res) => { + return res.data; + }); + } + + /** + * Get raw transaction by transaction hash. + * The result is hex encoded transaction. + * @param txHash Transactin hash.Always use the reversed value of transaction hash to query. + * + * @example + * + * ```typescript + * import { utils, Transaction } from 'DNA-ts-sdk'; + * const txHash = tx.getHash(); // tx is an instance of Transaction + * restClient.getRawTransaction(utils.reverseHex(txHash)).then(res => { + * const tx = Transaction.deserialize(res.Result) + * }) + * + * ```` + */ + getRawTransaction(txHash: string): Promise { + const param = new Map(); + + param.set('raw', '1'); + let url = this.url + UrlConsts.Url_get_transaction + txHash; + url += this.concatParams(param); + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get transaction by transaction hash. + * The result is transaction in json. + * @param txHash Reversed transaction hash + */ + getRawTransactionJson(txHash: string): Promise { + const param = new Map(); + param.set('raw', '0'); + let url = this.url + UrlConsts.Url_get_transaction + txHash; + url += this.concatParams(param); + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** Deprecated + * Get the generation time for each block. + * If the blockchain node runs in vbft, the result is null. + */ + // getGenerateBlockTime(): Promise { + // const url = this.url + UrlConsts.Url_get_generate_block_time; + // return axios.get(url).then((res) => { + // return res.data; + // }); + // } + + /** + * Get the nodes count of the blockchain. + */ + getNodeCount(): Promise { + const url = this.url + UrlConsts.Url_get_node_count; + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get the current height of the blockchain. + */ + getBlockHeight(): Promise { + const url = this.url + UrlConsts.Url_get_block_height; + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get block by block's height or hash + * @param value Block height or block hash + */ + getBlock(value: number | string): Promise { + const params = new Map(); + params.set('raw', '1'); + + let url = ''; + if (typeof value === 'number') { + url = this.url + UrlConsts.Url_get_block_by_height + value; + } else if (typeof value === 'string') { + url = this.url + UrlConsts.Url_get_block_by_hash + value; + } + url += this.concatParams(params); + + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get contract info by code hash.The result is hex encoded string. + * @param codeHash Code hash of contract.The value is reversed contract address. + */ + getContract(codeHash: string): Promise { + const params = new Map(); + params.set('raw', '1'); + + let url = this.url + UrlConsts.Url_get_contract_state + codeHash; + url += this.concatParams(params); + + // console.log('url: '+url); + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get contract info by code hash. The result is json. + * @param codeHash Code hash of contract. + */ + getContractJson(codeHash: string): Promise { + const params = new Map(); + params.set('raw', '0'); + let url = this.url + UrlConsts.Url_get_contract_state + codeHash; + url += this.concatParams(params); + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get smart contract event by Block height or reversed transaction hash. + * If the parameter is block height, the result includes all the transaction event of that block; + * If the parameter is transaction hash, the result is the event of that transaction. + * @param value Block height or reversed transaction hash + */ + getSmartCodeEvent(value: string | number): Promise { + let url = ''; + if (typeof value === 'string') { + url = this.url + UrlConsts.Url_get_smartcodeevent_by_txhash + value; + } else if (typeof value === 'number') { + url = this.url + UrlConsts.Url_get_smartcodeevent_txs_by_height + value; + } + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get the block height by reversed transaction hash. + * @param hash Reversed transaction hash. + */ + getBlockHeightByTxHash(hash: string): Promise { + const url = this.url + UrlConsts.Url_get_block_height_by_txhash + hash; + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get the stored value in smart contract by the code hash and key. + * @param codeHash Code hash of the smart contract + * @param key Key of the stored value + */ + getStorage(codeHash: string, key: string): Promise { + const url = this.url + UrlConsts.Url_get_storage + codeHash + '/' + key; + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get the merkle proof by transaction hash + * @param hash Reversed transaction hash + */ + getMerkleProof(hash: string): Promise { + const url = this.url + UrlConsts.Url_get_merkleproof + hash; + + // tslint:disable-next-line:no-console + console.log('url: ' + url); + + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get balance of some address + * The result contains balance of gas + * @param address Address + */ + getBalance(address: Address): Promise { + const url = this.url + UrlConsts.Url_get_account_balance + address.toBase58(); + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get block info by block's height or hash. + * @param value Block's height or hash + */ + getBlockJson(value: number | string): Promise { + let url = ''; + if (typeof value === 'number') { + url = this.url + UrlConsts.Url_get_block_by_height + value; + } else if (typeof value === 'string') { + url = this.url + UrlConsts.Url_get_block_by_hash + value; + } + + return axios.get(url).then((res) => { + return res.data; + }); + } + + /** + * Get allowance by address + * @param asset Asset type. Only gas . + * @param from Address of allowance sender. + * @param to Address of allowance receiver. + */ + getAllowance(asset: string, from: Address, to: Address): Promise { + asset = asset.toLowerCase(); + if (asset !== 'gas') { + throw new Error(String(ERROR_CODE.INVALID_PARAMS)); + } + const url = this.url + UrlConsts.Url_get_allowance + + asset.toLowerCase() + '/' + from.toBase58() + '/' + to.toBase58(); + return axios.get(url).then((res) => { + return res.data; + }); + } + + getBlockTxsByHeight(height: number): Promise { + const url = this.url + UrlConsts.Url_get_block_txs_by_height + height; + return axios.get(url).then((res) => { + return res.data; + }); + } + + getGasPrice(): Promise { + const url = this.url + UrlConsts.Url_get_gasprice ; + return axios.get(url).then((res) => { + return res.data; + }); + } + + getMempoolTxCount(): Promise { + const url = this.url + UrlConsts.Url_get_mempool_txcount; + return axios.get(url).then((res) => { + return res.data; + }); + } + + getMempoolTxState(hash: string): Promise { + const url = this.url + UrlConsts.Url_get_mempool_txstate + hash; + return axios.get(url).then((res) => { + return res.data; + }); + } + + getVersion(): Promise { + const url = this.url + UrlConsts.Url_get_version; + return axios.get(url).then((res) => { + return res.data; + }); + } +} diff --git a/src/network/rest/urlConsts.ts b/src/network/rest/urlConsts.ts new file mode 100644 index 0000000..9cc53b1 --- /dev/null +++ b/src/network/rest/urlConsts.ts @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +/** + * Restful api + */ +export default { + Url_send_transaction : '/api/v1/transaction', + Url_get_transaction : '/api/v1/transaction/', + Url_get_generate_block_time : '/api/v1/node/generateblocktime', + Url_get_node_count : '/api/v1/node/connectioncount', + Url_get_block_height : '/api/v1/block/height', + Url_get_block_by_height : '/api/v1/block/details/height/', + Url_get_block_by_hash : '/api/v1/block/details/hash/', + Url_get_account_balance : '/api/v1/balance/', + Url_get_contract_state : '/api/v1/contract/', + Url_get_smartcodeevent_txs_by_height : '/api/v1/smartcode/event/transactions/', + Url_get_smartcodeevent_by_txhash : '/api/v1/smartcode/event/txhash/', + Url_get_block_height_by_txhash : '/api/v1/block/height/txhash/', + Url_get_storage : '/api/v1/storage/', + Url_get_merkleproof : '/api/v1/merkleproof/', + Url_get_allowance: '/api/v1/allowance/', + Url_get_block_txs_by_height: '/api/v1/block/transactions/height/', + Url_get_mempool_txcount: '/api/v1/mempool/txcount', + Url_get_mempool_txstate: '/api/v1/mempool/txstate/', + Url_get_version: '/api/v1/version', + Url_get_networkid: '/api/v1/networkid', + Url_get_gasprice: '/api/v1/gasprice' +}; diff --git a/src/network/rpc/rpcClient.ts b/src/network/rpc/rpcClient.ts new file mode 100644 index 0000000..20e76a1 --- /dev/null +++ b/src/network/rpc/rpcClient.ts @@ -0,0 +1,331 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import axios from 'axios'; +import { TEST_DNA_URL } from '../../consts'; +import { Address } from '../../crypto/address'; +import { ERROR_CODE } from '../../error'; + +/** + * Wrapper class for RPC apis. + */ +export default class RpcClient { + /** + * Url of the blockchain node + */ + url: string; + + constructor( url ?: string ) { + this.url = url || TEST_DNA_URL.RPC_URL; + } + + /** + * Get the current blockchain node url. + */ + getUrl() { + return this.url; + } + + /** + * Make request base on method and parameters + * @param method Method's name + * @param params Parameters + */ + makeRequest(method: string, ...params: any[]) { + const request = { + jsonrpc: '2.0', + method, + params, + id: 1 + }; + + return request; + } + + /** + * Get the balance of some address. + * The result contains DNA and ONG. + * @param address Address + */ + getBalance(address: Address): Promise { + const req = this.makeRequest('getbalance', address.toBase58()); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Send ran transaction to blockchain. + * @param data Hex encoded data. + * @param preExec Decides if it is a pre-execute transaction. + */ + sendRawTransaction(data: string, preExec: boolean = false): Promise { + let req; + + if (preExec) { + req = this.makeRequest('sendrawtransaction', data, 1); + } else { + req = this.makeRequest('sendrawtransaction', data); + } + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get raw transaction by transaction hash. + * The result is hex encoded string. + * @param txHash Reversed transaction hash + */ + getRawTransaction(txHash: string): Promise { + const req = this.makeRequest('getrawtransaction', txHash); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get transaction info by transaction hash. + * The result is json. + * @param txHash Reversed transaction hash. + */ + getRawTransactionJson(txHash: string): Promise { + const req = this.makeRequest('getrawtransaction', txHash, 1); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** Deprecated + * Get the generation time for each block. + * If the blockchain node runs in vbft, the result is null cause the time is not fixed. + */ + // getGenerateBlockTime(): Promise { + // const req = this.makeRequest('getgenerateblocktime'); + + // return axios.post(this.url, req).then((res) => { + // return res.data; + // }); + // } + + /** + * Get the nodes count. + */ + getNodeCount(): Promise { + const req = this.makeRequest('getconnectioncount'); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get the current block height. + */ + getBlockHeight(): Promise { + const req = this.makeRequest('getblockcount'); + + return axios.post(this.url, req).then((res) => { + if (res.data && res.data.result) { + return res.data.result - 1; + } else { + return 0; + } + }); + } + + /** + * Get the all blocks count. + */ + getBlockCount(): Promise { + const req = this.makeRequest('getblockcount'); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get block info by block's height or hash. + * The result is json. + * @param value Block's hash or height + */ + getBlockJson(value: string | number): Promise { + const req = this.makeRequest('getblock', value, 1); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get contract info by contract' code hash. + * The result is hex encoded string. + * @param hash Contract's code hash. + */ + getContract(hash: string): Promise { + const req = this.makeRequest('getcontractstate', hash); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get contract info by contract's code hash. + * The result is json. + * @param codeHash Contract's code hash. + */ + getContractJson(codeHash: string): Promise { + const req = this.makeRequest('getcontractstate', codeHash, 1); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get block info by block's height or hash. + * The result is hex encoded string. + * + * @param value Block's height or hash + */ + getBlock(value: string | number): Promise { + const req = this.makeRequest('getblock', value); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get smart contract event. + * If parameter is transaction's hash, the result is the event of that transaction. + * If parameter is block's height, the result is all the events of that block. + * + * @param value Transaction's hash or block's height + */ + getSmartCodeEvent(value: string | number): Promise { + const req = this.makeRequest('getsmartcodeevent', value); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get block height by transaction hash + * @param txHash Reversed transaction hash + */ + getBlockHeightByTxHash(txHash: string): Promise { + const req = this.makeRequest('getblockheightbytxhash', txHash); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get stored value in smart contract by contract's code hash and the key. + * @param codeHash Contract's code hash + * @param key Key of stored value + */ + getStorage(codeHash: string, key: string): Promise { + const req = this.makeRequest('getstorage', codeHash, key); + + // tslint:disable-next-line:no-console + console.log(req); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get merkle proof by transaction hash. + * @param hash Reversed transaction hash + */ + getMerkleProof(hash: string): Promise { + const req = this.makeRequest('getmerkleproof', hash); + + // tslint:disable-next-line:no-console + console.log(this.url); + // tslint:disable-next-line:no-console + console.log(req); + + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + /** + * Get allowanece + * @param asset Asset's type.Only gas supported. + * @param from Address of allowance's sender. + * @param to Address of allowance's receiver. + */ + getAllowance(asset: string, from: Address, to: Address): Promise { + if (asset.toLowerCase() !== 'gas') { + throw ERROR_CODE.INVALID_PARAMS; + } + const req = this.makeRequest('getallowance', asset, from.toBase58(), to.toBase58()); + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + getBlockTxsByHeight(height: number): Promise { + const req = this.makeRequest('getblocktxsbyheight', height); + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + getGasPrice(): Promise { + const req = this.makeRequest('getgasprice'); + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + getMempoolTxCount(): Promise { + const req = this.makeRequest('getmempooltxcount'); + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + getMempoolTxState(txHash: string): Promise { + const req = this.makeRequest('getmempooltxstate', txHash); + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + + getVersion(): Promise { + const req = this.makeRequest('getversion'); + return axios.post(this.url, req).then((res) => { + return res.data; + }); + } + +} diff --git a/src/network/websocket/deferred.ts b/src/network/websocket/deferred.ts new file mode 100644 index 0000000..2466c0f --- /dev/null +++ b/src/network/websocket/deferred.ts @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +// tslint:disable:variable-name +export class Deferred { + private _promise: Promise; + private _resolve: (value?: T | PromiseLike) => void; + private _reject: (reason?: any) => void; + + constructor() { + this._promise = new Promise((resolve, reject) => { + this._resolve = resolve; + this._reject = reject; + }); + } + + get promise(): Promise { + return this._promise; + } + + public resolve = (value?: T | PromiseLike): void => { + this._resolve(value); + } + + public reject = (reason?: any): void => { + this._reject(reason); + } +} diff --git a/src/network/websocket/websocketBuilder.ts b/src/network/websocket/websocketBuilder.ts new file mode 100644 index 0000000..fbad3fd --- /dev/null +++ b/src/network/websocket/websocketBuilder.ts @@ -0,0 +1,287 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { Address } from '../../crypto/address'; + +// const generateReqId = () => { +// return Math.floor(Math.random() * 10e8); +// }; + +export function sendHeartBeat() { + const param = { + Action : 'heartbeat', + Version : 'V1.0.0' + }; + return param; +} + +export function sendSubscribe( + subscribeEvent: boolean = false, + subscribeJsonBlock: boolean = false, + subscribeRawBlock: boolean = false, + subscribeBlockTxHashes: boolean = false +) { + const param = { + Action: 'subscribe', + Version: '1.0.0', + SubscribeEvent: subscribeEvent, // optional + SubscribeJsonBlock: subscribeJsonBlock, // optional + SubscribeRawBlock: subscribeRawBlock, // optional + SubscribeBlockTxHashs: subscribeBlockTxHashes // optional + }; + return param; +} + +export function sendRawTransaction(hexData: string, preExec: boolean = false) { + let param = { + Action: 'sendrawtransaction', + Version: '1.0.0', + Data: hexData + }; + if (preExec) { + param = Object.assign(param, { PreExec : '1' }); + } + return param; +} + +export function getRawTransaction(txHash: string) { + const param = { + Action: 'gettransaction', + Version: '1.0.0', + Hash: txHash, + Raw : '1' + }; + return param; +} + +export function getRawTransactionJson(txHash: string) { + const param = { + Action: 'gettransaction', + Version: '1.0.0', + Hash: txHash, + Raw: '0' + }; + return param; +} + +// export function getGenerateBlockTime() { +// const param = { +// Action: 'getgenerateblocktime', +// Version: '1.0.0' +// }; +// return param; +// } + +export function getNodeCount() { + const param = { + Action: 'getconnectioncount', + Version: '1.0.0' + }; + return param; +} + +export function getBlockHeight() { + const param = { + Action: 'getblockheight', + Version: '1.0.0' + }; + return param; +} + +export function getBlock(value: number | string) { + let param = {}; + if (typeof value === 'number') { + param = { + Action: 'getblockbyheight', + Version: '1.0.0', + Height: value, + Raw: '1' + }; + } else if (typeof value === 'string') { + param = { + Action: 'getblockbyhash', + Version: '1.0.0', + Hash: value, + Raw: '1' + }; + } + return param; +} + +export function getBlockJson(value: number | string) { + let param = {}; + if (typeof value === 'number') { + param = { + Action: 'getblockbyheight', + Version: '1.0.0', + Height: value + }; + } else if (typeof value === 'string') { + param = { + Action: 'getblockbyhash', + Version: '1.0.0', + Hash: value + }; + } + return param; +} + +export function getBalance(address: Address) { + const param = { + Action: 'getbalance', + Version: '1.0.0', + Addr: address.toBase58() + }; + return param; +} + +export function getContract(hash: string) { + const param = { + Action: 'getcontract', + Version: '1.0.0', + Hash: hash, + Raw: '1' + }; + return param; +} + +export function getContractJson(hash: string) { + const param = { + Action: 'getcontract', + Version: '1.0.0', + Hash: hash, + Raw: '0' + }; + return param; +} + +export function getSmartCodeEvent(value: number | string) { + let param = {}; + if (typeof value === 'number') { + param = { + Action: 'getsmartcodeeventbyheight', + Version: '1.0.0', + Height: value + }; + } else if (typeof value === 'string') { + param = { + Action: 'getsmartcodeeventbyhash', + Version: '1.0.0', + Hash: value + }; + } + return param; +} + +export function getBlockHeightByTxHash(hash: string) { + const param = { + Action: 'getblockheightbytxhash', + Version: '1.0.0', + Hash: hash + }; + return param; +} + +export function getStorage(codeHash: string, key: string) { + const param = { + Action: 'getstorage', + Version: '1.0.0', + Hash: codeHash, + Key : key + }; + return param; +} + +export function getMerkleProof(hash: string) { + const param = { + Action: 'getmerkleproof', + Version: '1.0.0', + Hash: hash + }; + return param; +} + +export function getAllowance(asset: string, from: Address, to: Address) { + const param = { + Action: 'getallowance', + Version: '1.0.0', + Asset: asset, + From: from.toBase58(), + To: to.toBase58() + }; + return param; +} + +export function getBlockHash(value: number) { + const param = { + Action: 'getblockhash', + Version: '1.0.0', + Height: value + }; + return param; +} + +export function getBlockTxsByHeight(value: number) { + const param = { + Action: 'getblocktxsbyheight', + Version: '1.0.0', + Height: value + }; + return param; +} + +export function getGasPrice() { + const param = { + Action: 'getgasprice', + Version: '1.0.0' + }; + return param; +} + +export function getMempoolTxCount() { + const param = { + Action: 'getmempooltxcount', + Version: '1.0.0' + }; + return param; +} + +export function getMempoolTxState(txHash: string) { + const param = { + Action: 'getmempooltxstate', + Version: '1.0.0', + Hash: txHash + }; + return param; +} + +export function getVersion() { + const param = { + Action: 'getversion', + Version: '1.0.0' + }; + return param; +} + +export function getNetworkId() { + const param = { + Action: 'getnetworkid', + Version: '1.0.0' + }; + return param; +} diff --git a/src/network/websocket/websocketClient.ts b/src/network/websocket/websocketClient.ts new file mode 100644 index 0000000..54d8eb1 --- /dev/null +++ b/src/network/websocket/websocketClient.ts @@ -0,0 +1,357 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { TEST_DNA_URL } from '../../consts'; +import { Address } from '../../crypto/address'; +import { Deferred } from './deferred'; +import * as Builder from './websocketBuilder'; +import { WebsocketSender } from './websocketSender'; + +/** + * Websocket client. + * + * TODO: correlate request and response with id, so socket can be reused. + */ +export class WebsocketClient { + sender: WebsocketSender; + + autoClose: boolean; + + promises: Map>; + + constructor(url = TEST_DNA_URL.SOCKET_URL, debug = false, autoClose = true) { + this.autoClose = autoClose; + this.promises = new Map(); + this.sender = new WebsocketSender(url, debug); + this.sender.addListener(this.notifyListener.bind(this)); + } + + /** + * Send heart beat request + */ + async sendHeartBeat(): Promise { + const raw = Builder.sendHeartBeat(); + return this.send(raw); + } + + /** + * Send subscribe request + * @param subscribeEvent + * @param subscribeJsonBlock + * @param subscribeRawBlock + * @param subscribeBlockTxHashes + */ + async sendSubscribe( + subscribeEvent = false, + subscribeJsonBlock = false, + subscribeRawBlock = false, + subscribeBlockTxHashes = false + ): Promise { + const raw = Builder.sendSubscribe( + subscribeEvent, + subscribeJsonBlock, + subscribeRawBlock, + subscribeBlockTxHashes + ); + + return this.send(raw); + } + + /** + * Send raw transaction + * @param hexData Hex encoded data + * @param preExec Decides if it is a pre-executed transaction + * @param waitNotify Decides if client waits for notify from blockchain before closing + */ + async sendRawTransaction(hexData: string, preExec = false, waitNotify = false) { + const raw = Builder.sendRawTransaction(hexData, preExec); + const sendResult = await this.send(raw, this.autoClose && !waitNotify); + + if (sendResult.Error !== 0) { + // tslint:disable-next-line:no-console + console.log(sendResult); + throw new Error(JSON.stringify(sendResult)); + } + + if (waitNotify) { + const txHash: string = sendResult.Result; + + const deferred = new Deferred(); + this.promises.set(txHash, deferred); + return deferred.promise; + } else { + return sendResult; + } + } + + /** + * Get raw transaction by transaction hash. + * The result is hex encoded transaction. + * @param txHash Reversed transaction hash + */ + async getRawTransaction(txHash: string): Promise { + const raw = Builder.getRawTransaction(txHash); + return this.send(raw); + } + + /** + * Get transaction info by transaction hash. + * The result is json. + * @param txHash Reversed transaction hash + */ + async getRawTransactionJson(txHash: string): Promise { + const raw = Builder.getRawTransactionJson(txHash); + return this.send(raw); + } + + /** Deprecated + * Get the generation time for each block. + * If the blockchain node runs in vbft, the result is null. + */ + // async getGenerateBlockTime(): Promise { + // const raw = Builder.getGenerateBlockTime(); + // return this.send(raw); + // } + + /** + * Get Nodes count + */ + async getNodeCount(): Promise { + const raw = Builder.getNodeCount(); + return this.send(raw); + } + + /** + * Get current block height + */ + async getBlockHeight(): Promise { + const raw = Builder.getBlockHeight(); + return this.send(raw); + } + + /** + * Get block's info by block's height or hash. + * The result is hex encoded string. + * @param value Block's height or hash + */ + async getBlock(value: number | string): Promise { + const raw = Builder.getBlock(value); + return this.send(raw); + } + + /** + * Get block's info by block's height or hash. + * The result is json. + * @param value Block's height or hash + */ + async getBlockJson(value: number | string): Promise { + const raw = Builder.getBlockJson(value); + return this.send(raw); + } + + /** + * Get the balance of some address. + * The result contains DNA and ONG. + * @param address Address + */ + async getBalance(address: Address): Promise { + const raw = Builder.getBalance(address); + return this.send(raw); + } + + /** + * Get contract info by code hash. + * The result is hex encoded string. + * @param hash Contract's code hash. + */ + async getContract(hash: string): Promise { + const raw = Builder.getContract(hash); + return this.send(raw); + } + + /** + * Get contract's info by code hash + * The result is json. + * @param hash Contract's code hash + */ + async getContractJson(hash: string): Promise { + const raw = Builder.getContractJson(hash); + return this.send(raw); + } + + /** + * Get smart conde event by transaction hash or block's height. + * If parameter is transaction hash, the result is the event of that transaction. + * If parameter is block's height, the result is all the events of that block. + * @param value Reversed transaction hash or block's height + */ + async getSmartCodeEvent(value: number | string): Promise { + const raw = Builder.getSmartCodeEvent(value); + return this.send(raw); + } + + /** + * Get block's height by transaction hash + * @param hash Reversed transaction hash + */ + async getBlockHeightByTxHash(hash: string): Promise { + const raw = Builder.getBlockHeightByTxHash(hash); + return this.send(raw); + } + + /** + * Get stored value in smart contract by contract's code hash and the key. + * @param codeHash Contract's code hash + * @param key Key of stored value + */ + async getStorage(codeHash: string, key: string): Promise { + const raw = Builder.getStorage(codeHash, key); + return this.send(raw); + } + + /** + * Get merkle proof by transaction hash. + * @param hash Reversed transaction hash + */ + async getMerkleProof(hash: string): Promise { + const raw = Builder.getMerkleProof(hash); + return this.send(raw); + } + + /** + * Get allowanece + * @param asset Asset's type.Only DNA and ONG supported. + * @param from Address of allowance's sender. + * @param to Address of allowance's receiver. + */ + async getAllowance(asset: string, from: Address, to: Address) { + const raw = Builder.getAllowance(asset, from, to); + return this.send(raw); + } + + /** + * Get block hash by block height + * @param height Height of the block + */ + async getBlockHash(height: number): Promise { + const raw = Builder.getBlockHash(height); + return this.send(raw); + } + + /** + * Return all transaction hash contained in the block corresponding to this height + * @param height Height of the block + */ + async getBlockTxsByHeight(height: number): Promise { + const raw = Builder.getBlockTxsByHeight(height); + return this.send(raw); + } + + /** + * Return the state of transaction locate in memory + */ + async getGasPrice(): Promise { + const raw = Builder.getGasPrice(); + return this.send(raw); + } + + /** + * Query the transaction count in the memory pool + */ + async getMempoolTxCount(): Promise { + const raw = Builder.getMempoolTxCount(); + return this.send(raw); + } + + /** + * Query the transaction state in the memory pool + */ + async getMempoolTxState(txHash: string): Promise { + const raw = Builder.getMempoolTxState(txHash); + return this.send(raw); + } + + /** + * Get the version information of the node + */ + async getVersion(): Promise { + const raw = Builder.getVersion(); + return this.send(raw); + } + + /** + * Get the network id + */ + async getNetworkId(): Promise { + const raw = Builder.getNetworkId(); + return this.send(raw); + } + + /** + * Adds listener for Notify messages. + * + * Be careful to not set autoClose = true and close the websocket on your own. + * @param listener Listener + */ + addNotifyListener(listener: (result: any) => void) { + this.sender.addListener((result: any) => { + if (result.Action === 'Notify') { + listener(result); + } + }); + } + + /** + * Close the websocket manually. + */ + close() { + this.sender.close(); + } + + /** + * Send msg to blockchain + * @param raw Message to send + * @param close Automaticly close connection if also autoClose is specified + */ + private async send(raw: T, close: boolean = this.autoClose): Promise { + return this.sender.send(raw, close); + } + + private notifyListener(result: any) { + // Fixme: Log message cause Notify message to disappear + if (result.Action === 'Notify' || result.Action === 'Log') { + const txHash: string | undefined = result.Result.TxHash; + + if (txHash !== undefined) { + const promise = this.promises.get(txHash); + + if (promise !== undefined) { + this.promises.delete(txHash); + promise.resolve(result); + } else { + // tslint:disable-next-line:no-console + console.warn('Received Notify event for unknown transaction'); + } + + if (this.autoClose) { + this.sender.close(); + } + } + } + } +} diff --git a/src/network/websocket/websocketSender.ts b/src/network/websocket/websocketSender.ts new file mode 100644 index 0000000..86ff932 --- /dev/null +++ b/src/network/websocket/websocketSender.ts @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import * as Html5WebSocket from '@ont-community/html5-websocket'; +import * as WebSocketAsPromised from 'websocket-as-promised'; +import { TEST_DNA_URL } from '../../consts'; + +/** + * We can import html5-websocket directly, because webpack will use html5-websocket/browser.js + * in browser environment, which does not require 'ws'. + */ + + /** + * Websocket sender for send messages and handle notify. + */ +export class WebsocketSender { + private static generateReqId() { + return Math.floor(Math.random() * 10e8); + } + + debug: boolean; + + private wsp: any; // WebSocketAsPromised + + constructor(url = TEST_DNA_URL.SOCKET_URL, debug = false) { + this.debug = debug; + this.wsp = new WebSocketAsPromised(url, { + createWebSocket: (socketUrl: string) => new Html5WebSocket(socketUrl), + attachRequestId: (data: any, id: number) => ({ Id: id, ...data }), + extractRequestId: (data: any) => data && data.Id, + packMessage: (data: any) => JSON.stringify(data), + unpackMessage: (message: string) => JSON.parse(message) + }); + + this.wsp.onOpen.addListener(() => { + if (this.debug) { + // tslint:disable-next-line:no-console + console.log('connected'); + } + }); + + this.wsp.onClose.addListener(() => { + if (this.debug) { + // tslint:disable-next-line:no-console + console.log('disconnected'); + } + }); + + this.wsp.onSend.addListener((message: any) => { + if (this.debug) { + // tslint:disable-next-line:no-console + console.log('sent: ', message); + } + }); + + this.wsp.onMessage.addListener((message: any) => { + if (this.debug) { + // tslint:disable-next-line:no-console + console.log('received: ', message); + } + }); + + this.wsp.onError.addListener((event: any) => { + if (this.debug) { + // tslint:disable-next-line:no-console + console.log('error: ', event); + } + }); + } + + async send(param: T, close: boolean = true) { + try { + if (!param) { + return; + } + + await this.wsp.open(); + const response = await this.wsp.sendRequest(param, { requestId: WebsocketSender.generateReqId() }); + + return response; + } finally { + if (close) { + await this.wsp.close(); + } + } + } + + addListener(listener: (result: any) => void) { + this.wsp.onUnpackedMessage.addListener(listener); + } + + close() { + this.wsp.close(); + } +} diff --git a/src/scrypt.ts b/src/scrypt.ts new file mode 100644 index 0000000..6c5bb72 --- /dev/null +++ b/src/scrypt.ts @@ -0,0 +1,402 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import * as base58 from 'base-58'; +import { createCipheriv, createDecipheriv } from 'crypto'; +import * as CryptoJS from 'crypto-js'; +import * as asyncScrypt from 'scrypt-async'; +import { DEFAULT_SCRYPT, OEP_FLAG, OEP_HEADER } from './consts'; +import { Address } from './crypto/address'; +import { PublicKey } from './crypto/PublicKey'; +import { ERROR_CODE } from './error'; +import { ab2hexstring, hexstring2ab, hexXor, isHexString, StringReader } from './utils'; + +/** + * Decribtes the structure of params for scrypt + */ +export interface ScryptParams { + cost: number; + blockSize: number; + parallel: number; + size: number; +} + +/** + * Synchronious call to scrypt-async-js. + * + * @param keyphrase Keyphrase to use + * @param addressHash Hex encoded address + * @param params Scrypt params + */ +function scrypt(keyphrase: string, addressHash: string, params: ScryptParams) { + let derived: number[] = []; + + asyncScrypt( + keyphrase.normalize('NFC'), + hexstring2ab(addressHash), + { + N: params.cost, + r: params.blockSize, + p: params.parallel, + dkLen: params.size + }, + (result: string | number[]) => { + derived = result as number[]; + } + ); + return new Buffer(derived); +} + +/** + * Encrypt with aes-ctr + */ +export function encryptWithCtr( + privateKey: string, + publicKeyEncoded: string, + keyphrase: string, + scryptParams: ScryptParams = DEFAULT_SCRYPT +): string { + // let privateKey = PrivateKey.deserializeWIF(wifKey); + // console.log( "privateKey: ", privateKey ); + + // console.log( "publickeyEncode: ", publicKey ); + + const publicKey = PublicKey.deserializeHex(new StringReader(publicKeyEncoded)); + + const address = Address.fromPubKey(publicKey); + // console.log( "address: ", address ); + + const addresshash = address.getB58Checksum(); + // console.log( "addresshash: ", addresshash ); + + // Scrypt + const derived = scrypt(keyphrase, addresshash, scryptParams).toString('hex'); + const derived1 = derived.slice(0, 32); + const derived2 = derived.slice(64); + const iv = CryptoJS.enc.Hex.parse(derived1); + + // console.log('decrypt derived: ' + derived) + // console.log('decrypt iv: ' + iv) + // console.log('decrypt derived2: ' + derived2) + + // AES Encrypt + // let xor = hexXor(privateKey, derived1); + const encrypted = CryptoJS.AES.encrypt( + CryptoJS.enc.Hex.parse(privateKey), + CryptoJS.enc.Hex.parse(derived2), + { mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding, iv } + ); + // console.log( "encrypted: ", encrypted.ciphertext.toString() ); + + // Construct + // let assembled = OEP_HEADER + OEP_FLAG + addresshash + encrypted.ciphertext.toString(); + const assembled = encrypted.ciphertext.toString(); + + // console.log( "enc assembled: ", assembled ); + + // return Bs58check.encode(Buffer.from(assembled, 'hex')); + return new Buffer(assembled, 'hex').toString('base64'); +} + +/** + * Decrypt with aes-ctr + * @param encryptedKey encrypted private key + * @param keyphrase user's password to encrypt private key + * @param saltOrAddress 4 hex encoded bytes salt or Address object + */ +export function decryptWithCtr( + encryptedKey: string, + keyphrase: string, + saltOrAddress: string | Address, + scryptParams: ScryptParams = DEFAULT_SCRYPT +): string { + // let assembled = ab2hexstring(Bs58check.decode(encryptedKey)); + const encrypted = Buffer.from(encryptedKey, 'base64').toString('hex'); + + // tslint:disable-next-line:no-console + // console.log('dec assembled: ', encrypted); + + let salt = ''; + if (typeof saltOrAddress === 'string' && saltOrAddress.length === 8) { + salt = saltOrAddress; + } else if (saltOrAddress instanceof Address) { + salt = saltOrAddress.getB58Checksum(); + } else { + throw ERROR_CODE.INVALID_PARAMS; + } + + // let addressHash = assembled.substr(0, 8); + // console.log( "dec addressHash: ", addressHash ); + + // let encrypted = assembled.substr(8); + // console.log( "encrypted: ", encrypted ); + + // Scrypt + const derived = scrypt(keyphrase, salt, scryptParams).toString('hex'); + const derived1 = derived.slice(0, 32); + const derived2 = derived.slice(64); + // console.log('decrypt derived: ' + derived) + + const iv = CryptoJS.enc.Hex.parse(derived1); + + // AES Decrypt + const ciphertexts = { ciphertext: CryptoJS.enc.Hex.parse(encrypted), salt: '', iv: '' }; + const decrypted = CryptoJS.AES.decrypt( + ciphertexts, + CryptoJS.enc.Hex.parse(derived2), + { mode: CryptoJS.mode.CTR, padding: CryptoJS.pad.NoPadding, iv } + ); + // console.log( "decrypted: ", decrypted.toString() ); + + // Check PrivateKey + // ---------------------------------------------------------- + + // PrivateKey + // let privateKey = hexXor(decrypted.toString(), derived1); + const privateKey = decrypted.toString(); + // console.log( "privateKey: ", privateKey ); + return privateKey; +} + +/** + * Checks if the password supplied to decrypt was correct. + * + * This method was taken out from decrypt, because it needs to create public key from private key + * and it needs to be supplied from outside. + * + * @param saltOrAddress 4 hex encoded bytes salt or Address object + * @param publicKeyEncoded Public key from decrypted key + */ +export function checkCtrDecrypted(saltOrAddress: string | Address, publicKeyEncoded: string): void { + // const assembled = ab2hexstring(Bs58check.decode(encryptedKey)); + // let assembled = Buffer.from(encryptedKey, 'base64').toString('hex') + + // console.log( "assembled: ", assembled ); + + // const addressHash = assembled.substr(0, 8); + // console.log( "addressHash: ", addressHash ); + + // console.log('publicKey', publicKey) + let salt = ''; + if (typeof saltOrAddress === 'string' && saltOrAddress.length === 8) { + salt = saltOrAddress; + } else if (saltOrAddress instanceof Address) { + salt = saltOrAddress.getB58Checksum(); + } else { + throw ERROR_CODE.INVALID_PARAMS; + } + + const publicKey = PublicKey.deserializeHex(new StringReader(publicKeyEncoded)); + + // Address + const address = Address.fromPubKey(publicKey); + // console.log('address 2', address) + + // AddressHash + const saltNew = address.getB58Checksum(); + + if (saltNew !== salt) { + + // tslint:disable-next-line:no-console + console.log('keyphrase error.'); + + throw ERROR_CODE.Decrypto_ERROR; + } + + // WIF + // let wifKey = privateKey.serializeWIF(); + // console.log( "wifKey: ", wifKey ); +} + +/** + * Encrypt with aes-ecb + */ +export function encryptWithEcb( + privateKey: string, + publicKeyEncoded: string, + keyphrase: string, + scryptParams: ScryptParams = DEFAULT_SCRYPT +): string { + const publicKey = PublicKey.deserializeHex(new StringReader(publicKeyEncoded)); + + const address = Address.fromPubKey(publicKey); + // console.log( "address: ", address ); + + const addresshash = address.getB58Checksum(); + // console.log( "addresshash: ", addresshash ); + // Scrypt + const derived = scrypt(keyphrase, addresshash, scryptParams).toString('hex'); + const derived1 = derived.slice(0, 64); + const derived2 = derived.slice(64); + + // AES Encrypt + const xor = hexXor(privateKey, derived1); + const encrypted = CryptoJS.AES.encrypt( + CryptoJS.enc.Hex.parse(xor), + CryptoJS.enc.Hex.parse(derived2), + { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); + // console.log( "encrypted: ", encrypted.ciphertext.toString() ); + // Construct + const assembled = OEP_HEADER + OEP_FLAG + addresshash + encrypted.ciphertext.toString(); + // console.log( "assembled: ", assembled ); + return base58.encode(Buffer.from(assembled, 'hex')); +} + +/** + * Decrypt with aes-ecb + */ +export function decryptWithEcb( + encryptedKey: string, + keyphrase: string, + scryptParams: ScryptParams = DEFAULT_SCRYPT +): string { + const assembled = ab2hexstring(base58.decode(encryptedKey)); + // console.log( "assembled: ", assembled ); + const addressHash = assembled.substr(6, 8); + // console.log( "addressHash: ", addressHash ); + const encrypted = assembled.substr(-64); + // console.log( "encrypted: ", encrypted ); + // Scrypt + const derived = scrypt(keyphrase, addressHash, scryptParams).toString('hex'); + const derived1 = derived.slice(0, 64); + const derived2 = derived.slice(64); + + // AES Decrypt + const ciphertexts = { ciphertext: CryptoJS.enc.Hex.parse(encrypted), salt: '', iv: '' }; + const decrypted = CryptoJS.AES.decrypt( + ciphertexts, + CryptoJS.enc.Hex.parse(derived2), + { mode: CryptoJS.mode.ECB, padding: CryptoJS.pad.NoPadding }); + // console.log( "decrypted: ", decrypted.toString() ); + // Check PrivateKey + // ---------------------------------------------------------- + // PrivateKey + const privateKey = hexXor(decrypted.toString(), derived1); + // console.log( "privateKey: ", privateKey ); + return privateKey; +} + +/** + * Checks if the password supplied to decrypt was correct. + * + * This method was taken out from decrypt, because it needs to create public key from private key + * and it needs to be supplied from outside. + * + * @param encryptedKey Original encrypted key + * @param decryptedKey Decrypted key with decrypt + * @param publicKeyEncoded Public key from decrypted key + */ +export function checkEcbDecrypted(encryptedKey: string, decryptedKey: string, publicKeyEncoded: string): void { + const assembled = ab2hexstring(base58.decode(encryptedKey)); + // console.log( "assembled: ", assembled ); + const addressHash = assembled.substr(6, 8); + + const publicKey = PublicKey.deserializeHex(new StringReader(publicKeyEncoded)); + + // Address + const address = Address.fromPubKey(publicKey); + // console.log('address', address) + // AddressHash + const addressHashNew = address.getB58Checksum(); + + if (addressHashNew !== addressHash) { + // tslint:disable-next-line:no-console + console.log('keyphrase error.'); + throw ERROR_CODE.Decrypto_ERROR; + } +} + +/** + * Encrypt with aes-gcm-256 + * This is the default encryption algorithm for private key + * @param privateKey Private key to encpryt with + * @param address Adderss to encrypt with + * @param salt Salt to encrypt with + * @param keyphrase User's password + * @param scryptParams Optional params to encrypt + */ +export function encryptWithGcm( + privateKey: string, + address: Address, + salt: string, + keyphrase: string, + scryptParams: ScryptParams = DEFAULT_SCRYPT +) { + if (!isHexString(privateKey)) { + throw new Error(ERROR_CODE.INVALID_PARAMS + ', Invalid private key'); + } + const derived = scrypt(keyphrase, salt, scryptParams); + const derived1 = derived.slice(0, 12); + const derived2 = derived.slice(32); + const key = derived2; + const iv = derived1; + const aad = new Buffer(address.toBase58()); + const cipher = createCipheriv('aes-256-gcm', key, iv); + cipher.setAAD(aad); + const plainText = Buffer.from(privateKey, 'hex'); + let ciphertext = cipher.update(plainText); + // ciphertext += cipher.final(); + const final = cipher.final(); + const authTag = cipher.getAuthTag(); + ciphertext = Buffer.concat([ciphertext, final]); + + const result = Buffer.concat([ciphertext, authTag]); + return result.toString('base64'); +} + +/** + * Decrypt with aes-256-gcm + * @param encrypted Encrypted private key + * @param address Address to decrypt with + * @param salt Salt to decrypt with + * @param keyphrase User's password + * @param scryptParams Optioanl params to decrypt with + */ +export function decryptWithGcm( + // ciphertext: string, + // authTag: string, + encrypted: string, + address: Address, + salt: string, + keyphrase: string, + scryptParams: ScryptParams = DEFAULT_SCRYPT +) { + if (salt.length !== 32) { + throw ERROR_CODE.INVALID_PARAMS; + } + const result = Buffer.from(encrypted, 'base64'); + const ciphertext = result.slice(0, result.length - 16); + const authTag = result.slice(result.length - 16); + const derived = scrypt(keyphrase, salt, scryptParams); + const derived1 = derived.slice(0, 12); + const derived2 = derived.slice(32); + const key = derived2; + const iv = derived1; + const aad = new Buffer(address.toBase58()); + // const auth = new Buffer(authTag, 'hex'); + const decipher = createDecipheriv('aes-256-gcm', key, iv); + decipher.setAAD(aad); + decipher.setAuthTag(authTag); + let decrypted = decipher.update(ciphertext).toString('hex'); + + try { + decrypted += decipher.final().toString('hex'); + } catch (err) { + throw ERROR_CODE.Decrypto_ERROR; + } + return decrypted; +} diff --git a/src/smartcontract/abi/abiFunction.ts b/src/smartcontract/abi/abiFunction.ts new file mode 100644 index 0000000..840337d --- /dev/null +++ b/src/smartcontract/abi/abiFunction.ts @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { Parameter } from './parameter'; + +/** + * Describes the Abi function + */ +export default class AbiFunction { + name: string; + returntype: string; + parameters: Parameter[]; + + constructor(name: string, returntype: string, parameters: Parameter[]) { + this.name = name; + this.returntype = returntype; + this.parameters = parameters; + } + + getParameter(name: string): any { + // const p = {} as Parameter; + + for (const v of this.parameters) { + if (v.getName() === name) { + return v; + } + } + return null; + } + + setParamsValue(...args: Parameter[]): void { + for (let i = 0, len = args.length; i < len; i++) { + // tslint:disable-next-line:prefer-for-of + for (let j = 0 ; j < this.parameters.length; j++) { + if (args[i].name === this.parameters[j].getName()) { + this.parameters[j].setValue(args[i]); + } + } + } + // const parameters = []; + // for (let i = 0, len = args.length; i < len; i++) { + // parameters.push(args[i]); + // } + // this.parameters = parameters; + } + + toString(): string { + const json = { + name : this.name, + returntype : this.returntype, + parameters : this.parameters + }; + + return JSON.stringify(json); + } +} diff --git a/src/smartcontract/abi/abiInfo.ts b/src/smartcontract/abi/abiInfo.ts new file mode 100644 index 0000000..ee46777 --- /dev/null +++ b/src/smartcontract/abi/abiInfo.ts @@ -0,0 +1,57 @@ + +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import AbiFunction from './abiFunction'; +import { Parameter } from './parameter'; + +/** + * Decribes the Abi info. + */ +export default class AbiInfo { + static parseJson(json: string): AbiInfo { + const a = new AbiInfo(); + const obj = JSON.parse(json); + a.hash = obj.hash; + a.entrypoint = obj.entrypoint; + a.functions = obj.functions; + + return a; + } + + hash: string; + entrypoint: string; + functions: AbiFunction[] = []; + + getHash(): string { + return this.hash; + } + + getEntryPoint(): string { + return this.entrypoint; + } + + getFunction(name: string): AbiFunction { + for (const v of this.functions) { + if (v.name === name) { + const parameters = v.parameters.map((p: any) => new Parameter(p.name, p.type, '')); + return new AbiFunction(v.name, v.returntype, parameters); + } + } + throw Error('not found'); + } +} diff --git a/src/smartcontract/abi/nativeVmParamsBuilder.ts b/src/smartcontract/abi/nativeVmParamsBuilder.ts new file mode 100644 index 0000000..2c56aad --- /dev/null +++ b/src/smartcontract/abi/nativeVmParamsBuilder.ts @@ -0,0 +1,129 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { BigNumber } from 'bignumber.js'; +import { Address } from '../../crypto/address'; +import opcode from '../../transaction/opcode'; +import { hex2VarBytes, num2hexstring, str2VarBytes } from '../../utils'; +import { pushHexString } from './../../transaction/program'; +import { pushBigNum, pushBool, pushInt } from './../../transaction/scriptBuilder'; +import { Parameter, ParameterType } from './parameter'; +import Struct from './struct'; + +export function buildParams(params: Parameter[]): string { + let result = ''; + for (const p of params) { + const type = p.getType(); + switch (type) { + case ParameterType.ByteArray: + result += hex2VarBytes(p.value); + break; + case ParameterType.Int: + result += num2hexstring(p.value, 4, true); + break; + case ParameterType.String: + result += str2VarBytes(p.value); + break; + case ParameterType.Address: + result += p.value.serialize(); + default: + break; + } + } + return result; +} + +export function createCodeParamScript(obj: any): string { + let result = ''; + // Consider string as hexstr + if (typeof obj === 'string') { + result += pushHexString(obj); + } else if (typeof obj === 'boolean') { + result += pushBool(obj); + } else if (typeof obj === 'number') { + result += pushInt(obj); + } else if (obj instanceof BigNumber) { + result += pushBigNum(obj); + } else if (obj instanceof Address) { + result += pushHexString(obj.serialize()); + } else if (obj instanceof Struct) { + for (const v of obj.list) { + result += createCodeParamScript(v); + result += num2hexstring(opcode.DUPFROMALTSTACK); + result += num2hexstring(opcode.SWAP); + result += num2hexstring(opcode.APPEND); + } + } + return result; +} + +export function buildNativeCodeScript(list: any[]) { + let result = ''; + for (let i = list.length - 1; i >= 0; i--) { + const val = list[i]; + // Consider string as hexstr + if (typeof val === 'string') { + result += pushHexString(val); + } else if (typeof val === 'boolean') { + result += pushBool(val); + } else if (typeof val === 'number') { + result += pushInt(val); + } else if (val instanceof BigNumber) { + result += pushBigNum(val); + } else if (val instanceof Address) { + result += pushHexString(val.serialize()); + } else if (val instanceof Struct) { + result += pushInt(0); + result += num2hexstring(opcode.NEWSTRUCT); + result += num2hexstring(opcode.TOALTSTACK); + for (const v of val.list) { + result += createCodeParamScript(v); + result += num2hexstring(opcode.DUPFROMALTSTACK); + result += num2hexstring(opcode.SWAP); + result += num2hexstring(opcode.APPEND); + } + result += num2hexstring(opcode.FROMALTSTACK); + // } else if (Array.isArray(val) && isTypedArray(val, Struct)) { + // result += pushInt(0); + // result += num2hexstring(opcode.NEWSTRUCT); + // result += num2hexstring(opcode.TOALTSTACK); + // for (const s of val) { + // result += createCodeParamScript(s); + // } + // result += num2hexstring(opcode.FROMALTSTACK); + // result += pushInt(val.length); + // result += num2hexstring(opcode.PACK); + } else if (Array.isArray(val)) { + result += buildNativeCodeScript(val); + result += pushInt(val.length); + result += num2hexstring(opcode.PACK); + } + } + return result; +} + +export function isTypedArray(arr: any[], type: any) { + let result = true; + for (const a of arr) { + if (!(a instanceof type)) { + result = false; + break; + } + } + return result; +} diff --git a/src/smartcontract/abi/parameter.ts b/src/smartcontract/abi/parameter.ts new file mode 100644 index 0000000..885c88e --- /dev/null +++ b/src/smartcontract/abi/parameter.ts @@ -0,0 +1,76 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +export enum ParameterType { + Boolean = 'Boolean', + Integer = 'Integer', + ByteArray = 'ByteArray', + Interface = 'Interface', + Array = 'Array', + Struct = 'Struct', + Map = 'Map', + String = 'String', + Int = 'Integer', + Long = 'Long', // value should be string + IntArray = 'IntArray', + LongArray = 'LongArray', + Address = 'Address' +} + +export enum ParameterTypeVal { + ByteArray = 0x00, + Boolean = 0x01, + Integer = 0x02, + Interface = 0x40, + Array = 0x80, + Struct = 0x81, + Map = 0x82 +} + +/** + * Decribes the parameter. + */ +export class Parameter { + public name: string; + public type: ParameterType; + public value: any; + constructor(name: string, type: ParameterType, value: any) { + this.name = name; + this.type = type; + this.value = value; + } + + getName(): string { + return this.name; + } + + getType(): ParameterType { + return this.type; + } + + getValue(): any { + return this.value; + } + + setValue(value: any): boolean { + if (value.type === this.type && value.name === this.name && value.value != null) { + this.value = value.value; + return true; + } + return false; + } +} diff --git a/src/smartcontract/abi/struct.ts b/src/smartcontract/abi/struct.ts new file mode 100644 index 0000000..b8df93b --- /dev/null +++ b/src/smartcontract/abi/struct.ts @@ -0,0 +1,38 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +/** + * Struct is a special kind of parameter that used in smart contract. + */ +export default class Struct { + list: any[]; + + constructor() { + this.list = []; + } + /** + * Add arguments to struct. + * @param args Array of some kinds of value. + * Boolean, number, string, Address and Struct are supported. + */ + add(...args: any[]) { + for (const a of args) { + this.list.push(a); + } + } +} diff --git a/src/smartcontract/data/attestClaim.avm b/src/smartcontract/data/attestClaim.avm new file mode 100755 index 0000000..0692aa7 --- /dev/null +++ b/src/smartcontract/data/attestClaim.avm @@ -0,0 +1 @@ +5fc56b6c766b00527ac46c766b51527ac4616c766b00c306436f6d6d6974876c766b52527ac46c766b52c3647100616c766b51c3c0539c009c6c766b56527ac46c766b56c3640e00006c766b57527ac46232016c766b51c300c36c766b53527ac46c766b51c351c36c766b54527ac46c766b51c352c36c766b55527ac46c766b53c36c766b54c36c766b55c361527265fc006c766b57527ac462e9006c766b00c3065265766f6b65876c766b58527ac46c766b58c3645d00616c766b51c3c0529c009c6c766b5b527ac46c766b5bc3640e00006c766b57527ac462a8006c766b51c300c36c766b59527ac46c766b51c351c36c766b5a527ac46c766b59c36c766b5ac3617c6528026c766b57527ac46273006c766b00c309476574537461747573876c766b5c527ac46c766b5cc3644900616c766b51c3c0519c009c6c766b5e527ac46c766b5ec3640e00006c766b57527ac4622f006c766b51c300c36c766b5d527ac46c766b5dc361651b046c766b57527ac4620e00006c766b57527ac46203006c766b57c3616c756658c56b6c766b00527ac46c766b51527ac46c766b52527ac46161681953797374656d2e53746f726167652e476574436f6e746578746c766b00c3617c681253797374656d2e53746f726167652e4765746c766b53527ac46c766b53c300a06c766b56527ac46c766b56c364440061616c766b00c309206578697374656421617c084572726f724d736753c1681553797374656d2e52756e74696d652e4e6f7469667961006c766b57527ac462ee006154c56c766b54527ac46c766b54c36c766b00c3007cc46c766b54c351537cc46c766b54c36c766b51c3517cc46c766b54c36c766b52c3527cc46c766b54c361681853797374656d2e52756e74696d652e53657269616c697a656c766b55527ac461681953797374656d2e53746f726167652e476574436f6e746578746c766b00c36c766b55c3615272681253797374656d2e53746f726167652e50757461616c766b51c31320637265617465206e657720636c61696d3a206c766b00c3615272045075736854c1681553797374656d2e52756e74696d652e4e6f7469667961516c766b57527ac46203006c766b57c3616c756659c56b6c766b00527ac46c766b51527ac46161681953797374656d2e53746f726167652e476574436f6e746578746c766b00c3617c681253797374656d2e53746f726167652e4765746c766b52527ac46c766b52c3009c6c766b55527ac46c766b55c364480061616c766b00c30d206e6f74206578697374656421617c084572726f724d736753c1681553797374656d2e52756e74696d652e4e6f7469667961006c766b56527ac462a7016c766b52c361681a53797374656d2e52756e74696d652e446573657269616c697a656c766b53527ac46c766b53c353c3519c009c6c766b57527ac46c766b57c3644b0061616c766b00c31020696e76616c6964207374617475732e617c084572726f724d736753c1681553797374656d2e52756e74696d652e4e6f7469667961006c766b56527ac4621c016c766b53c351c36c766b51c3617c65ac01009c6c766b58527ac46c766b58c364440061616c766b51c30920696e76616c69642e617c084572726f724d736753c1681553797374656d2e52756e74696d652e4e6f7469667961006c766b56527ac462b9006c766b53c300537cc46c766b53c361681853797374656d2e52756e74696d652e53657269616c697a656c766b54527ac461681953797374656d2e53746f726167652e476574436f6e746578746c766b00c36c766b54c3615272681253797374656d2e53746f726167652e50757461616c766b51c30f207265766f6b6520636c61696d3a206c766b00c3615272045075736854c1681553797374656d2e52756e74696d652e4e6f7469667961516c766b56527ac46203006c766b56c3616c756653c56b6c766b00527ac46161681953797374656d2e53746f726167652e476574436f6e746578746c766b00c3617c681253797374656d2e53746f726167652e4765746c766b51527ac4616c766b00c309207374617475733a206c766b51c3615272045075736854c1681553797374656d2e52756e74696d652e4e6f74696679616c766b51c36c766b52527ac46203006c766b52c3616c756657c56b6c766b00527ac46c766b51527ac4616c766b00c3c06c766b51c3c09c009c6c766b52527ac46c766b52c3640f0061006c766b53527ac4627900006c766b54527ac4624800616c766b00c36c766b54c3517f6c766b51c36c766b54c3517f9c009c6c766b55527ac46c766b55c3640e00006c766b53527ac4623800616c766b54c351936c766b54527ac46c766b54c36c766b00c3c09f6c766b56527ac46c766b56c363a3ff516c766b53527ac46203006c766b53c3616c7566 \ No newline at end of file diff --git a/src/smartcontract/data/attestClaim.ts b/src/smartcontract/data/attestClaim.ts new file mode 100755 index 0000000..379a16c --- /dev/null +++ b/src/smartcontract/data/attestClaim.ts @@ -0,0 +1,69 @@ +export default { + hash: '36bb5c053b6b839c8f6b923fe852f91239b9fccc', + entrypoint: 'Main', + functions: [{ + name: 'Main', + parameters: [{ + name: 'operation', + type: 'String' + }, { + name: 'args', + type: 'Array' + }], + returntype: 'Any' + }, { + name: 'Commit', + parameters: [{ + name: 'claimId', + type: 'ByteArray' + }, { + name: 'commiterId', + type: 'ByteArray' + }, { + name: 'ownerId', + type: 'ByteArray' + }], + returntype: 'Boolean' + }, { + name: 'Revoke', + parameters: [{ + name: 'claimId', + type: 'ByteArray' + }, { + name: 'dnaid', + type: 'ByteArray' + }], + returntype: 'Boolean' + }, { + name: 'GetStatus', + parameters: [{ + name: 'claimId', + type: 'ByteArray' + }], + returntype: 'ByteArray' + }], + events: [{ + name: 'ErrorMsg', + parameters: [{ + name: 'arg1', + type: 'ByteArray' + }, { + name: 'arg2', + type: 'String' + }], + returntype: 'Void' + }, { + name: 'Push', + parameters: [{ + name: 'arg1', + type: 'ByteArray' + }, { + name: 'arg2', + type: 'String' + }, { + name: 'arg3', + type: 'ByteArray' + }], + returntype: 'Void' + }] +}; diff --git a/src/smartcontract/data/idContract.abi.ts b/src/smartcontract/data/idContract.abi.ts new file mode 100644 index 0000000..1a5ae66 --- /dev/null +++ b/src/smartcontract/data/idContract.abi.ts @@ -0,0 +1,308 @@ +export default { + hash: 'ff00000000000000000000000000000000000003', + entrypoint: 'Main', + functions: [ + { + name: 'Main', + parameters: [ + { + name: 'operation', + type: 'String' + }, + { + name: 'args', + type: 'Array' + } + ], + returntype: 'Any' + }, + { + name: 'regIDWithPublicKey', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'publicKey', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'regIDWithAttributes', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'publicKey', + type: 'ByteArray' + }, + { + name: 'tuples', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'addKey', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'newPublicKey', + type: 'ByteArray' + }, + { + name: 'sender', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'removeKey', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'oldPublicKey', + type: 'ByteArray' + }, + { + name: 'sender', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'addRecovery', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'recovery', + type: 'ByteArray' + }, + { + name: 'publicKey', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'changeRecovery', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'newRecovery', + type: 'ByteArray' + }, + { + name: 'recovery', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'addAttributes', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'attributes', + type: 'ByteArray' + }, + { + name: 'publicKey', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'removeAttribute', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'path', + type: 'ByteArray' + }, + { + name: 'publicKey', + type: 'ByteArray' + } + ], + returntype: 'Boolean' + }, + { + name: 'getPublicKeys', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + } + ], + returntype: 'ByteArray' + }, + { + name: 'getAttributes', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + } + ], + returntype: 'ByteArray' + }, + { + name: 'GetPublicKeyId', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'publicKey', + type: 'ByteArray' + } + ], + returntype: 'ByteArray' + }, + { + name: 'getKeyState', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'pkId', + type: 'Int' + } + ], + returntype: 'ByteArray' + }, + { + name: 'GetRecovery', + parameters: [ + { + name: 'dnaid', + type: 'ByteArray' + } + ], + returntype: 'ByteArray' + }, + { + name: 'getDDO', + parameters: [ + { + name: 'id', + type: 'ByteArray' + } + ], + returntype: 'ByteArray' + } + ], + events: [ + { + name: 'Register', + parameters: [ + { + name: 'op', + type: 'String' + }, + { + name: 'dnaid', + type: 'ByteArray' + } + ], + returntype: 'Void' + }, + { + name: 'PublicKey', + parameters: [ + { + name: 'op', + type: 'String' + }, + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'publicKey', + type: 'ByteArray' + } + ], + returntype: 'Void' + }, + { + name: 'Attribute', + parameters: [ + { + name: 'op', + type: 'String' + }, + { + name: 'dnaid', + type: 'ByteArray' + }, + { + name: 'attrName', + type: 'ByteArray' + } + ], + returntype: 'Void' + }, + { + name: 'Debug', + parameters: [ + { + name: 'func', + type: 'String' + }, + { + name: 'info', + type: 'ByteArray' + } + ], + returntype: 'Void' + }, + { + name: 'Debug', + parameters: [ + { + name: 'func', + type: 'String' + }, + { + name: 'trace', + type: 'Integer' + } + ], + returntype: 'Void' + } + ] +}; diff --git a/src/smartcontract/nativevm/assetTxBuilder.ts b/src/smartcontract/nativevm/assetTxBuilder.ts new file mode 100644 index 0000000..f7a773b --- /dev/null +++ b/src/smartcontract/nativevm/assetTxBuilder.ts @@ -0,0 +1,349 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import { BigNumber } from 'bignumber.js'; +import BigInt from '../../common/bigInt'; +import { TOKEN_TYPE } from '../../consts'; +import { Address } from '../../crypto'; +import { Transaction } from '../../transaction/transaction'; +import { makeNativeContractTx } from '../../transaction/transactionUtils'; +import { Transfer } from '../../transaction/transfer'; +import { hex2VarBytes, hexstr2str, StringReader } from '../../utils'; +import { buildNativeCodeScript } from '../abi/nativeVmParamsBuilder'; +import Struct from '../abi/struct'; +import { State } from './token'; + +export const GAS_CONTRACT = '0000000000000000000000000000000000000002'; + +/** + * Get the address of native asset contract + * @param tokenType Token type. Can only be DNA or ONG + */ +export function getTokenContract(tokenType: string) { + if (tokenType.toUpperCase() === TOKEN_TYPE.GAS) { + return new Address(GAS_CONTRACT); + } else { + throw new Error('Error token type.'); + } +} + +/** + * Verify amount + * @param amount Amount + */ +export function verifyAmount(amount: number | string) { + const value = new BigNumber(amount); + + if (!value.isInteger() || value.lte(new BigNumber(0))) { + throw new Error('Amount is invalid.'); + } +} + +/** + * Creates transaction to transfer native assets. + * @param tokenType gas + * @param from sender's address + * @param to receiver's address + * @param amount Amount of amount to transfer + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Address to pay for transaction's gas. + */ +export function makeTransferTx( + tokenType: string, + from: Address, + to: Address, + amount: number | string, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transfer { + verifyAmount(amount); + const num = new BigNumber(amount); + const struct = new Struct(); + struct.add(from, to, num); + const list = []; + list.push([struct]); + const contract = getTokenContract(tokenType); + const params = buildNativeCodeScript(list); + const tx: Transfer = makeNativeContractTx('transfer', params, contract, gasPrice, gasLimit) as any; + tx.tokenType = tokenType; + tx.from = from; + tx.to = to; + tx.amount = amount; + tx.method = 'transfer'; + + if (payer) { + tx.payer = payer; + } else { + tx.payer = from; + } + return tx; +} + +/** + * Create transaction for asset transfer approve + * @param tokenType gas + * @param from Sender's address + * @param to receiver's address + * @param amount Amount to approve + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Address of fee payer + */ +export function makeApproveTx( + tokenType: string, + from: Address, + to: Address, + amount: number | string, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + verifyAmount(amount); + const struct = new Struct(); + struct.add(from, to, amount); + const list = []; + list.push(struct); + const contract = getTokenContract(tokenType); + const params = buildNativeCodeScript(list); + const tx: Transfer = makeNativeContractTx('approve', params, contract, gasPrice, gasLimit) as any; + tx.tokenType = tokenType; + tx.from = from; + tx.to = to; + tx.amount = amount; + tx.method = 'approve'; + + if (payer) { + tx.payer = payer; + } else { + tx.payer = from; + } + return tx; +} + +/** + * Create transaction for asset transfer from + * @param tokenType gas + * @param from Sender's address + * @param to receiver's address + * @param amount Amount to approve + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Address of fee payer + */ +export function makeTransferFromTx( + tokenType: string, + sender: Address, + from: Address, + to: Address, + amount: number | string, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + verifyAmount(amount); + const struct = new Struct(); + struct.add(sender, from, to, amount); + const list = []; + list.push(struct); + const contract = getTokenContract(tokenType); + const params = buildNativeCodeScript(list); + const tx: Transfer = makeNativeContractTx('transferFrom', params, contract, gasPrice, gasLimit) as any; + tx.tokenType = tokenType; + tx.from = from; + tx.to = to; + tx.amount = amount; + tx.method = 'transferFrom'; + + if (payer) { + tx.payer = payer; + } else { + tx.payer = from; + } + return tx; +} + +/** + * transfer from multiple senders to one receiver + * this tx needs multiple senders' signature. + * @param tokenType + * @param from array of senders' address + * @param to receiver's address + * @param amounts + */ +export function makeTransferStateTx( + tokenType: string, + states: State[], + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const structs = []; + for (const state of states) { + verifyAmount(state.value); + const s = new Struct(); + s.add(state.from, state.to, new BigNumber(state.value)); + structs.push(s); + } + + const list = []; + list.push(structs); + const params = buildNativeCodeScript(list); + const contract = getTokenContract(tokenType); + const tx = makeNativeContractTx('transfer', params, contract, gasPrice, gasLimit); + if (payer) { + tx.payer = payer; + } + return tx; +} + +/** + * transfer from one sender to multiple receivers + * @param tokenType + * @param from + * @param to + * @param amounts + */ +export function makeTransferToMany( + tokenType: string, + from: Address, + to: Address[], + amounts: string | number [], + gasPrice: string, + gasLimit: string +): Transaction { + + if (to.length !== amounts.length) { + throw new Error('Params error.'); + } + + const structs = []; + for (let i = 0; i < to.length; i++) { + verifyAmount(amounts[i]); + const s = new Struct(); + s.add(from, to[i], new BigNumber(amounts[i])); + structs.push(s); + } + + const list = []; + list.push(structs); + + const contract = getTokenContract(tokenType); + const params = buildNativeCodeScript(list); + const tx: Transfer = makeNativeContractTx('transfer', params, contract, gasPrice, gasLimit) as any; + tx.payer = from; + return tx; +} + +/** + * Creates transaction to query allowance that can be sent from sender to receiver + * @param asset Asset type. Only DNA or ONg. + * @param from Sender's address + * @param to Receiver's address + */ +export function makeQueryAllowanceTx(from: Address, to: Address): Transaction { + const contract = GAS_CONTRACT; + const list = []; + const struct = new Struct(); + struct.add(from, to); + list.push(struct); + const params = buildNativeCodeScript(list); + const tx = makeNativeContractTx('allowance', params, new Address(contract)); + return tx; +} + +/** + * Creates transaction to query balance. + * @param address Address to query balance + */ +export function makeQueryBalanceTx(address: Address): Transaction { + const contract = GAS_CONTRACT; + const params = hex2VarBytes(address.serialize()); + const tx = makeNativeContractTx('balanceOf', params, new Address(contract)); + return tx; +} + +export function deserializeTransferTx(str: string): Transfer { + const tx: Transfer = Transaction.deserialize(str) as any; + const code = tx.payload.serialize(); + const contractIndex1 = code.lastIndexOf('14' + '000000000000000000000000000000000000000'); + const contractIndex2 = code.lastIndexOf('14' + '0000000000000000000000000000000000000002'); + if (contractIndex1 > 0 && code.substr(contractIndex1 + 41, 1) === '2') { + tx.tokenType = 'GAS'; + } else { + throw new Error('Not a transfer tx'); + } + const contractIndex = Math.max(contractIndex1, contractIndex2); + const params = code.substring(0, contractIndex); + const paramsEnd = params.indexOf('6a7cc86c') + 8; + if (params.substr(paramsEnd, 4) === '51c1') { // transfer + const methodStr = params.substring(paramsEnd + 6); + tx.method = hexstr2str(methodStr); + } else { + const methodStr = params.substring(paramsEnd + 2); + tx.method = hexstr2str(methodStr); + } + + if (tx.method === 'transfer') { + const sr = new StringReader(params); + // const codeLength = sr.readNextLen(); + // const bytes = sr.read(4); + sr.pos += 10; + const from = new Address(sr.read(20)); + tx.from = from; + // const bytes2 = sr.read(4); + sr.pos += 8; + const to = new Address(sr.read(20)); + tx.to = to; + // const bytes3 = sr.read(3); + sr.pos += 6; + const numTmp = parseInt(sr.read(1), 16); + if (sr.str.substr(sr.pos, 6) === '6a7cc8') { + tx.amount = numTmp - 80; + } else { + const amount = BigInt.fromHexstr(sr.read(numTmp)).value; + tx.amount = new BigNumber(amount).toString(); + } + } else if (tx.method === 'transferFrom') { + const sr = new StringReader(params); + // const codeLength = sr.readNextLen(); + // const bytes = sr.read(4); + sr.pos += 10; + const from = new Address(sr.read(20)); + tx.from = from; + // const bytes1 = sr.read(4); + // const contract = new Address(sr.read(20)); + // const bytes2 = sr.read(4); + sr.pos += 56; + const to = new Address(sr.read(20)); + tx.to = to; + // const bytes3 = sr.read(3); + sr.pos += 6; + const numTmp = parseInt(sr.read(1), 16); + if (sr.str.substr(sr.pos, 6) === '6a7cc8') { + tx.amount = numTmp - 80; + } else { + const amount = BigInt.fromHexstr(sr.read(numTmp)).value; + tx.amount = new BigNumber(amount).toString(); + } + } else { + throw new Error('Not a transfer tx'); + } + + return tx; +} diff --git a/src/smartcontract/nativevm/authContractTxBuilder.ts b/src/smartcontract/nativevm/authContractTxBuilder.ts new file mode 100644 index 0000000..8372087 --- /dev/null +++ b/src/smartcontract/nativevm/authContractTxBuilder.ts @@ -0,0 +1,269 @@ + +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { Address } from '../../crypto'; +import { makeNativeContractTx } from '../../transaction/transactionUtils'; +import { hex2VarBytes, str2hexstr, varifyPositiveInt } from '../../utils'; +import { buildNativeCodeScript } from '../abi/nativeVmParamsBuilder'; +import Struct from '../abi/struct'; +import { Transaction } from './../../transaction/transaction'; + +/** + * Address of auth contract. + */ +export const AUTH_CONTRACT = '0000000000000000000000000000000000000006'; +const contractAddress = new Address(AUTH_CONTRACT); + +/** + * Creates transaction that initialize the admin of some contract. + * @param adminDNAId Admin's DNA ID + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeInitContractAdminTx( + adminDNAId: string, + payer: Address, + gasPrice: string, + gasLimit: string): Transaction { + if (adminDNAId.substr(0, 3) === 'did') { + adminDNAId = str2hexstr(adminDNAId); + } + const params = hex2VarBytes(adminDNAId); + const tx = makeNativeContractTx('initContractAdmin', params, contractAddress, + gasPrice, gasLimit, payer); + return tx; +} + +/** + * Transfer the authority to new admin + * @param contractAddr Uer's contract address + * @param newAdminDNAid New admin's DNA ID. This id must be registered. + * @param keyNo Original admin's public key id. Use this pk to varify tx. + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeTransferAuthTx( + contractAddr: Address, + newAdminDNAid: string, + keyNo: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + varifyPositiveInt(keyNo); + if (newAdminDNAid.substr(0, 3) === 'did') { + newAdminDNAid = str2hexstr(newAdminDNAid); + } + const struct = new Struct(); + struct.add(contractAddress.serialize(), newAdminDNAid, keyNo); + const list = [struct]; + const params = buildNativeCodeScript(list); + + const tx = makeNativeContractTx('transfer', params, contractAddress, gasPrice, gasLimit, payer); + return tx; +} + +/** + * verify the user's token of target contract + * @param contractAddr user's target contract address + * @param callerDNAId caller's DNA ID.This id must be registered. + * @param funcName the function to call + * @param keyNo publicKey's id, use this pk to varify tx + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeVerifyTokenTx( + contractAddr: Address, + callerDNAId: string, + funcName: string, + keyNo: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + varifyPositiveInt(keyNo); + if (callerDNAId.substr(0, 3) === 'did') { + callerDNAId = str2hexstr(callerDNAId); + } + const struct = new Struct(); + struct.add(contractAddr.serialize(), callerDNAId, str2hexstr(funcName), keyNo); + const params = buildNativeCodeScript([struct]); + + const tx = makeNativeContractTx('verifyToken', params, contractAddress, gasPrice, gasLimit, payer); + return tx; +} + +/** + * assign functions to role. must be called by contract's admin + * @param contractAddr target contract's address + * @param adminDNAId admin's DNA ID.This id must be registered. + * @param role role name + * @param funcNames array of function name + * @param keyNo publicKey's id, use the pk to varify tx + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeAssignFuncsToRoleTx( + contractAddr: Address, + adminDNAId: string, + role: string, + funcNames: string[], + keyNo: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + varifyPositiveInt(keyNo); + if (adminDNAId.substr(0, 3) === 'did') { + adminDNAId = str2hexstr(adminDNAId); + } + const struct = new Struct(); + struct.add(contractAddr.serialize(), adminDNAId, str2hexstr(role), funcNames.length); + for (const f of funcNames) { + struct.add(str2hexstr(f)); + } + struct.add(keyNo); + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx('assignFuncsToRole', params, + contractAddress, gasPrice, gasLimit, payer); + return tx; +} + +/** + * assign role to DNA IDs. must be called by contract's admin + * @param contractAddr target contract's address + * @param adminDNAId admin's DNA ID.This id must be registered. + * @param role role's name + * @param ontIds array of DNA ID + * @param keyNo admin's pk id.use to varify tx. + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeAssignDNAIdsToRoleTx( + contractAddr: Address, + adminDNAId: string, + role: string, + ontIds: string[], + keyNo: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + varifyPositiveInt(keyNo); + if (adminDNAId.substr(0, 3) === 'did') { + adminDNAId = str2hexstr(adminDNAId); + } + const struct = new Struct(); + struct.add(contractAddr.serialize(), adminDNAId, str2hexstr(role), ontIds.length); + for (const i of ontIds) { + if (i.substr(0, 3) === 'did') { + struct.add(str2hexstr(i)); + } else { + struct.add(i); + } + } + struct.add(keyNo); + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx('assignDNAIDsToRole', params, + contractAddress, gasPrice, gasLimit, payer); + return tx; +} + +/** + * delegate role to others. Can't delegate repeatedly。 + * @param contractAddr target contract's address + * @param from DNA ID of user that wants to delegate role.This id must be registered. + * @param to DNA ID of user that will receive role.This id must be registered. + * @param role role name + * @param period time of delegate period in second + * @param level = 1 for now. + * @param keyNo The number of user's publick in the DDO. + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeDelegateRoleTx( + contractAddr: Address, + from: string, + to: string, + role: string, + period: number, + level: number = 1, + keyNo: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + varifyPositiveInt(keyNo); + varifyPositiveInt(period); + if (from.substr(0, 3) === 'did') { + from = str2hexstr(from); + } + if (to.substr(0, 3) === 'did') { + to = str2hexstr(to); + } + const struct = new Struct(); + struct.add(contractAddr.serialize(), from, to, str2hexstr(role), period, level, keyNo); + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx('delegate', params, + contractAddress, gasPrice, gasLimit, payer); + return tx; +} + +/** + * role's owner can withdraw the delegate in advance + * @param contractAddr target contract's address + * @param initiator DNA ID of role's owner.This id must be registered. + * @param delegate DNA ID of role's agent.This id must be registered. + * @param role role's name + * @param keyNo The number of user's public key in the DDO + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeWithdrawRoleTx( + contractAddr: Address, + initiator: string, + delegate: string, + role: string, + keyNo: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + varifyPositiveInt(keyNo); + if (initiator.substr(0, 3) === 'did') { + initiator = str2hexstr(initiator); + } + if (delegate.substr(0, 3) === 'did') { + delegate = str2hexstr(delegate); + } + const struct = new Struct(); + struct.add(contractAddr.serialize(), initiator, delegate, str2hexstr(role), keyNo); + const params = buildNativeCodeScript([struct]) ; + + const tx = makeNativeContractTx('withdraw', params, + contractAddress, gasPrice, gasLimit, payer); + return tx; +} diff --git a/src/smartcontract/nativevm/governanceContractTxBuilder.ts b/src/smartcontract/nativevm/governanceContractTxBuilder.ts new file mode 100644 index 0000000..dd3bc62 --- /dev/null +++ b/src/smartcontract/nativevm/governanceContractTxBuilder.ts @@ -0,0 +1,783 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import BigInt from '../../common/bigInt'; +import { GENESIS_BLOCK_TIMESTAMP } from '../../consts'; +import { Address } from '../../crypto'; +import { ERROR_CODE } from '../../error'; +import RestClient from '../../network/rest/restClient'; +import { Transaction } from '../../transaction/transaction'; +import { makeNativeContractTx } from '../../transaction/transactionUtils'; +import { bigIntFromBytes, calcUnboundOng, hex2VarBytes, + hexstr2str, num2hexstring, str2hexstr, str2VarBytes, StringReader, varifyPositiveInt } from '../../utils'; +import { buildNativeCodeScript } from '../abi/nativeVmParamsBuilder'; +import Struct from '../abi/struct'; + +const GOVERNANCE_CONTRACT = '0000000000000000000000000000000000000007'; +const PEER_ATTRIBUTES = 'peerAttributes'; +const SPLIT_FEE_ADDRESS = 'splitFeeAddress'; +const AUTHORIZE_INFO_POOL = 'voteInfoPool'; +const GLOBAL_PARAM = 'globalParam'; +const TOTAL_STAKE = 'totalStake'; +const VBFT_CONFIG = 'vbftConfig'; +const contractAddress = new Address(GOVERNANCE_CONTRACT); + +/* TODO: Test */ + +// tslint:disable:no-console + +/** + * Register to be candidate node. + * This tx needs signatures from userAddr and payer if these two address are not the same. + * @param dnaid user's DNA ID, must be assigned with the role. + * @param peerPubKey public key of user's peer + * @param userAddr user's address to pledge DNA&ONG. This address must have enough DNA & ONG. + * @param keyNo user's pk id + * @param initPos Initial state + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeRegisterCandidateTx( + dnaid: string, + peerPubKey: string, + keyNo: number, + userAddr: Address, + initPos: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + if (typeof initPos !== 'number') { + throw new Error('Parameter initPos must be number!'); + } + varifyPositiveInt(initPos); + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + const struct = new Struct(); + struct.add(str2hexstr(peerPubKey), userAddr.serialize(), initPos, dnaid, keyNo); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('registerCandidate', params, contractAddress, + gasPrice, gasLimit, payer); +} + +/** + * + * @param userAddr User's address to pledge DNA&ONG. + * @param peerPubKey Public key of user's peer + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeUnregisterCandidateTx( + userAddr: Address, + peerPubKey: string, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubKey), userAddr.serialize()); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('unRegisterCandidate', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * Creates transaction to approve candidate + * @param peerPubKey Public key of user's peer + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeApproveCandidateTx( + peerPubKey: string, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubKey)); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('approveCandidate', params, contractAddress, + gasPrice, gasLimit, payer); +} + +/** + * Creates transaction to reject candidate + * @param peerPubKey Public key of user's peer + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeRejectCandidateTx( + peerPubKey: string, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubKey)); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('rejectCandidate', params, contractAddress, + gasPrice, gasLimit, payer); +} + +/** + * Creates transaction to vote for some peers. + * Can only vote for peers that with status 1 or 2 + * This tx needs signatures from userAddr and payer if these two address are not the same. + * @param userAddr User's address + * @param peerPubKeys Public keys of peers that to be voted + * @param posList Array of token that to vote + * @param payer Address to pay for transaction's gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeVoteForPeerTx( + userAddr: Address, + peerPubKeys: string[], + posList: number[], + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + if (peerPubKeys.length !== posList.length) { + throw ERROR_CODE.INVALID_PARAMS; + } + const struct = new Struct(); + struct.add(userAddr.serialize()); + struct.add(peerPubKeys.length); + for (const p of peerPubKeys) { + struct.add(str2hexstr(p)); + } + struct.add(posList.length); + for (const n of posList) { + struct.add(n); + } + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('voteForPeer', params, contractAddress, + gasPrice, gasLimit, payer); +} + +/** + * User unvotes peer nodes + * @param userAddr user's address + * @param peerPubKeys peer's pks + * @param posList amount of DNA to unvote + * @param payer Address to pay for the gas. + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeUnvoteForPeerTx( + userAddr: Address, + peerPubKeys: string[], + posList: number[], + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + if (peerPubKeys.length !== posList.length) { + throw ERROR_CODE.INVALID_PARAMS; + } + const struct = new Struct(); + struct.add(userAddr.serialize()); + struct.add(peerPubKeys.length); + for (const p of peerPubKeys) { + struct.add(str2hexstr(p)); + } + struct.add(posList.length); + for (const n of posList) { + struct.add(n); + } + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('unVoteForPeer', params, contractAddress, + gasPrice, gasLimit, payer); +} + +/** + * Withdraw the unvote DNA + * Need two signatures if userAddr and payer are not the same + * @param userAddr + * @param peerPubKeys + * @param withdrawList + */ +export function makeWithdrawTx( + userAddr: Address, + peerPubKeys: string[], + withdrawList: number[], + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + if (peerPubKeys.length !== withdrawList.length) { + throw ERROR_CODE.INVALID_PARAMS; + } + const struct = new Struct(); + struct.add(userAddr.serialize()); + struct.add(peerPubKeys.length); + for (const p of peerPubKeys) { + struct.add(str2hexstr(p)); + } + struct.add(withdrawList.length); + for (const w of withdrawList) { + struct.add(w); + } + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('withdraw', params, contractAddress, + gasPrice, gasLimit, payer); +} + +/** Quit node register + * Need two signatures if userAddr and payer are not the same + */ +export function makeQuitNodeTx( + userAddr: Address, + peerPubKey: string, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubKey), userAddr.serialize()); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('quitNode', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * Peer change the status of authorization + * @param peerPubKey Peer's public key + * @param userAddr User's address + * @param maxAuthorize Allowed max amount of stake authorization + * @param payer Payer of the transaction fee + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeChangeAuthorizationTx( + peerPubKey: string, + userAddr: Address, + maxAuthorize: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubKey), userAddr.serialize(), maxAuthorize); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('changeMaxAuthorization', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * Update allocation proportion of peer + * @param peerPubKey + * @param userAddr + * @param peerCost + * @param payer + * @param gasPrice + * @param gasLimit + */ +export function makeSetPeerCostTx( + peerPubKey: string, + userAddr: Address, + peerCost: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubKey), userAddr.serialize(), peerCost); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('setPeerCost', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * Withdraw fee to user's address + * @param userAddr User's address + * @param payer + * @param gasPrice + * @param gasLimit + */ +export function makeWithdrawFeeTx( + userAddr: Address, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(userAddr.serialize()); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('withdrawFee', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * User authorize some peers + * @param userAddr + * @param peerPubKeyList + * @param posList + * @param payer + * @param gasPrice + * @param gasLimit + */ +export function makeAuthorizeForPeerTx( + userAddr: Address, + peerPubKeyList: string[], + posList: number[], + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(userAddr.serialize()); + struct.add(peerPubKeyList.length); + for (const p of peerPubKeyList) { + struct.add(str2hexstr(p)); + } + struct.add(posList.length); + for (const w of posList) { + struct.add(w); + } + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('authorizeForPeer', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * User cancels the authorization of peer + */ +export function makeUnauthorizeForPeerTx( + userAddr: Address, + peerPubKeyList: string[], + posList: number[], + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(userAddr.serialize()); + struct.add(peerPubKeyList.length); + for (const p of peerPubKeyList) { + struct.add(str2hexstr(p)); + } + struct.add(posList.length); + for (const w of posList) { + struct.add(w); + } + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('unAuthorizeForPeer', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * Peer add the init pos + * @param peerPubkey Peer's public key + * @param userAddr Stake wallet address + * @param pos Amount of pos to add + * @param payer Payer of the transaction + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeAddInitPosTx( + peerPubkey: string, + userAddr: Address, + pos: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubkey), userAddr.serialize(), pos); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('addInitPos', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * Peer reduce the init pos + * @param peerPubkey Peer's public key + * @param userAddr Stake wallet address + * @param pos Amount of pos to reduce + * @param payer Payer of the transaction + * @param gasPrice Gas price + * @param gasLimit Gas limit + */ +export function makeReduceInitPosTx( + peerPubkey: string, + userAddr: Address, + pos: number, + payer: Address, + gasPrice: string, + gasLimit: string +): Transaction { + const struct = new Struct(); + struct.add(str2hexstr(peerPubkey), userAddr.serialize(), pos); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('reduceInitPos', params, contractAddress, gasPrice, gasLimit, payer); +} + +export function makeWithdrawPeerUnboundOngTx( + userAddr: Address, + payer: Address, + gasPrice: string, + gasLimit: string +) { + const struct = new Struct(); + struct.add(userAddr.serialize()); + const params = buildNativeCodeScript([struct]); + return makeNativeContractTx('withdrawOng', params, contractAddress, gasPrice, gasLimit, payer); +} + +/** + * If not set ifAuthorize or cost before, query result will be empty. + * @param peerPubKey + * @param url + */ +export async function getAttributes(peerPubKey: string, url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const key = str2hexstr(PEER_ATTRIBUTES) + peerPubKey; + const res = await restClient.getStorage(codeHash, key); + const result = res.Result; + if (result) { + return PeerAttributes.deserialize(new StringReader(result)); + } else { + return new PeerAttributes(); + } +} + +/** + * Get the reward fee of address + * @param address User's address + * @param url Node's restfull url + */ +export async function getSplitFeeAddress(address: Address, url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const key = str2hexstr(SPLIT_FEE_ADDRESS) + address.serialize(); + const res = await restClient.getStorage(codeHash, key); + const result = res.Result; + if (result) { + return SplitFeeAddress.deserialize(new StringReader(result)); + } else { + return new SplitFeeAddress(); + } +} + +/** + * Get authorization of user's address + * @param peerPubKey Peer's public key + * @param address User's address + * @param url Node's restful url + */ +export async function getAuthorizeInfo(peerPubKey: string, address: Address, url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const key = str2hexstr(AUTHORIZE_INFO_POOL) + peerPubKey + address.serialize(); + const res = await restClient.getStorage(codeHash, key); + const result = res.Result; + if (result) { + return AuthorizeInfo.deserialize(new StringReader(result)); + } else { + return new AuthorizeInfo(); + } +} + +/** + * Query the governance view + * @param url Url of restful api + */ +export async function getGovernanceView(url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const key = str2hexstr('governanceView'); + const viewRes = await restClient.getStorage(codeHash, key); + const view = viewRes.Result; + const governanceView = GovernanceView.deserialize(new StringReader(view)); + return governanceView; +} + +/** + * Query all the peer's state. The result is a map. + * @param url Url of blockchain node + */ +export async function getPeerPoolMap(url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const governanceView = await getGovernanceView(url); + const key1 = str2hexstr('peerPool'); + const key2 = num2hexstring(governanceView.view, 4, true); + const keyP = key1 + key2; + const res = await restClient.getStorage(codeHash, keyP); + const sr = new StringReader(res.Result); + const length = sr.readInt(); + const result: any = {}; + for (let i = 0; i < length; i++) { + const p = PeerPoolItem.deserialize(sr); + result[p.peerPubkey] = p; + } + return result; +} + +export async function getGlobalParam(url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const key = str2hexstr(GLOBAL_PARAM); + const res = await restClient.getStorage(codeHash, key); + if (res.Result) { + return GlobalParam.deserialize(new StringReader(res.Result)); + } else { + return new GlobalParam(); + } + +} + +export async function getTotalStake(userAddr: Address, url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const key = str2hexstr(TOTAL_STAKE) + userAddr.serialize(); + const res = await restClient.getStorage(codeHash, key); + if (res.Result) { + return TotalStake.deserialize(new StringReader(res.Result)); + } else { + return new TotalStake(); + } +} + +export async function getPeerUnboundOng(userAddr: Address, url?: string) { + const totalStake = await getTotalStake(userAddr, url); + if (!totalStake.address) { + return 0; + } + const restClient = new RestClient(url); + const blockHeight = (await restClient.getBlockHeight()).Result; + const block = (await restClient.getBlockJson(blockHeight)).Result; + const timeStamp = block.Header.Timestamp - GENESIS_BLOCK_TIMESTAMP; + return calcUnboundOng(totalStake.stake, totalStake.timeOffset, timeStamp); +} + +export async function getConfiguration(url?: string) { + const restClient = new RestClient(url); + const codeHash = contractAddress.toHexString(); + const key = str2hexstr(VBFT_CONFIG); + const res = await restClient.getStorage(codeHash, key); + if (res.Result) { + return Configuration.deserialize(new StringReader(res.Result)); + } else { + return new Configuration(); + } +} + +/** + * Use to store governance state. + */ +export class GovernanceView { + static deserialize(sr: StringReader): GovernanceView { + const g = new GovernanceView(); + g.view = sr.readUint32(); + g.height = sr.readUint32(); + g.txhash = sr.read(64); // uint256 + return g; + } + view: number = 0; + height: number = 0; + txhash: string = ''; + + serialize(): string { + let result = ''; + result += num2hexstring(this.view, 4, true); + result += num2hexstring(this.height, 4, true); + result += hex2VarBytes(this.txhash); + return result; + } +} + +/** + * Describs the peer's state in the pool. + */ +export class PeerPoolItem { + static deserialize(sr: StringReader): PeerPoolItem { + const p = new PeerPoolItem(); + p.index = sr.readInt(); + p.peerPubkey = hexstr2str(sr.readNextBytes()); + p.address = Address.deserialize(sr); + p.status = parseInt(sr.read(1), 16); + p.initPos = sr.readLong(); + p.totalPos = sr.readLong(); + return p; + } + + index: number = 0; + peerPubkey: string = ''; + address: Address; + status: number = 0; + initPos: number = 0; + totalPos: number = 0; + + serialize(): string { + let result = ''; + result += num2hexstring(this.index, 4, true); + result += str2VarBytes(this.peerPubkey); + result += this.address.serialize(); + result += num2hexstring(this.status); + result += num2hexstring(this.initPos, 8, true); + result += num2hexstring(this.totalPos, 8, true); + return result; + } +} + +export class PeerAttributes { + static deserialize(sr: StringReader): PeerAttributes { + const pr = new PeerAttributes(); + pr.peerPubkey = hexstr2str(sr.readNextBytes()); + + pr.maxAuthorize = sr.readLong(); + + pr.t2PeerCost = sr.readLong(); + pr.t1PeerCost = sr.readLong(); + pr.tPeerCost = sr.readLong(); + + if (sr.isEmpty) { + return pr; + } + pr.field1 = sr.readNextBytes(); + pr.field2 = sr.readNextBytes(); + pr.field3 = sr.readNextBytes(); + pr.field4 = sr.readNextBytes(); + + return pr; + } + peerPubkey: string = ''; + maxAuthorize: number = 0; + t2PeerCost: number = 100; // peer cost, active in view T + 2 + t1PeerCost: number = 100; // peer cost, active in view T + 1 + tPeerCost: number = 0; // peer cost, active in view T + field1: string = ''; + field2: string = ''; + field3: string = ''; + field4: string = ''; + + serialize(): string { + return ''; + } +} + +export class SplitFeeAddress { + static deserialize(sr: StringReader) { + const sfa = new SplitFeeAddress(); + sfa.address = Address.deserialize(sr); + sfa.amount = sr.readLong(); + return sfa; + } + + address: Address; + amount: number = 0; +} + +export class AuthorizeInfo { + static deserialize(sr: StringReader) { + const ai = new AuthorizeInfo(); + ai.peerPubkey = hexstr2str(sr.readNextBytes()); + ai.address = Address.deserialize(sr); + ai.consensusPos = sr.readLong(); + ai.freezePos = sr.readLong(); + ai.newPos = sr.readLong(); + ai.withdrawPos = sr.readLong(); + ai.withdrawFreezePos = sr.readLong(); + ai.withdrawUnfreezePos = sr.readLong(); + return ai; + } + + peerPubkey: string = ''; + address: Address; + consensusPos: number = 0; + freezePos: number = 0; + newPos: number = 0; + withdrawPos: number = 0; + withdrawFreezePos: number = 0; + withdrawUnfreezePos: number = 0; +} + +export class GlobalParam { + static deserialize(sr: StringReader) { + const gp = new GlobalParam(); + const feeHexStr = sr.readNextBytes(); + const candidateFeeStr = BigInt.fromHexstr(feeHexStr).value; + gp.candidateFee = Number(candidateFeeStr); + const minStr = BigInt.fromHexstr(sr.readNextBytes()).value; + gp.minInitState = Number(minStr); + const candidateNumStr = BigInt.fromHexstr(sr.readNextBytes()).value; + const candidateNum = Number(candidateNumStr); + gp.candidateNum = candidateNum; + const posLimitStr = BigInt.fromHexstr(sr.readNextBytes()).value; + gp.posLimit = Number(posLimitStr); + const aStr = BigInt.fromHexstr(sr.readNextBytes()).value; + const a = Number(aStr); + const bStr = BigInt.fromHexstr(sr.readNextBytes()).value; + const b = Number(bStr); + const yStr = BigInt.fromHexstr(sr.readNextBytes()).value; + const yita = Number(yStr); + const pStr = BigInt.fromHexstr(sr.readNextBytes()).value; + const penalty = Number(pStr); + gp.A = a; + gp.B = b; + gp.yita = yita; + gp.penalty = penalty; + return gp; + } + + candidateFee: number; + candidateNum: number; + minInitState: number; + posLimit: number; + A: number; + B: number; + yita: number; + penalty: number; +} + +export class TotalStake { + static deserialize(sr: StringReader): TotalStake { + const ts = new TotalStake(); + ts.address = Address.deserialize(sr); + ts.stake = sr.readLong(); + ts.timeOffset = sr.readUint32(); + return ts; + } + address: Address; + stake: number; + timeOffset: number; +} + +export class Configuration { + + static deserialize(sr: StringReader): Configuration { + const config = new Configuration(); + config.N = bigIntFromBytes(sr.readNextBytes()).toInt(); + config.C = bigIntFromBytes(sr.readNextBytes()).toInt(); + config.K = bigIntFromBytes(sr.readNextBytes()).toInt(); + config.L = bigIntFromBytes(sr.readNextBytes()).toInt(); + config.BlockMsgDelay = bigIntFromBytes(sr.readNextBytes()).toInt(); + config.HashMsgDelay = bigIntFromBytes(sr.readNextBytes()).toInt(); + config.PeerHandShakeTimeout = bigIntFromBytes(sr.readNextBytes()).toInt(); + config.MaxBlockChangeView = bigIntFromBytes(sr.readNextBytes()).toInt(); + return config; + } + N: number; + C: number; + K: number; + L: number; + BlockMsgDelay: number; + HashMsgDelay: number; + PeerHandShakeTimeout: number; + MaxBlockChangeView: number; +} diff --git a/src/smartcontract/nativevm/idContractTxBuilder.ts b/src/smartcontract/nativevm/idContractTxBuilder.ts new file mode 100644 index 0000000..301a3b4 --- /dev/null +++ b/src/smartcontract/nativevm/idContractTxBuilder.ts @@ -0,0 +1,477 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import { Address, PublicKey } from '../../crypto'; +import { DDOAttribute } from '../../transaction/ddo'; +import { Transaction } from '../../transaction/transaction'; +import { makeNativeContractTx } from '../../transaction/transactionUtils'; +import { num2hexstring, str2hexstr } from '../../utils'; +import { buildNativeCodeScript } from '../abi/nativeVmParamsBuilder'; +import Struct from '../abi/struct'; + +/** + * Address of DNA ID contract + */ +export const DNAID_CONTRACT = '0000000000000000000000000000000000000003'; + +/** + * Method names in DNA ID contract + */ +const DNAID_METHOD = { + regIDWithPublicKey: 'regIDWithPublicKey', + regIDWithAttributes: 'regIDWithAttributes', + addAttributes: 'addAttributes', + removeAttribute: 'removeAttribute', + getAttributes: 'getAttributes', + getDDO: 'getDDO', + addKey: 'addKey', + removeKey: 'removeKey', + getPublicKeys: 'getPublicKeys', + addRecovery: 'addRecovery', + changeRecovery: 'changeRecovery', + getKeyState: 'getKeyState' +}; + +/** + * Registers Identity. + * + * GAS calculation: gasLimit * gasPrice is equal to the amount of gas consumed. + * + * @param dnaid User's DNA ID + * @param publicKey Public key + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + */ +export function buildRegisterDNAidTx( + dnaid: string, + publicKey: PublicKey, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const method = DNAID_METHOD.regIDWithPublicKey; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + const struct = new Struct(); + struct.add(dnaid, publicKey.serializeHex()); + const list = [struct]; + const params = buildNativeCodeScript(list); + + const tx = makeNativeContractTx( + method, + params, + new Address(DNAID_CONTRACT), + gasPrice, + gasLimit, + payer + ); + + return tx; +} + +/** + * Registers Identity with initial attributes. + * + * @param dnaid User's DNA ID + * @param attributes Array of DDOAttributes + * @param publicKey User's public key + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + */ +export function buildRegIdWithAttributes( + dnaid: string, + attributes: DDOAttribute[], + publicKey: PublicKey, + gasPrice: string, + gasLimit: string, + payer?: Address +) { + const method = DNAID_METHOD.regIDWithAttributes; + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + // let attrs = ''; + // for (const a of attributes) { + // attrs += a.serialize(); + // } + + // const p1 = new Parameter(f.parameters[0].getName(), ParameterType.ByteArray, dnaid); + // const p2 = new Parameter(f.parameters[1].getName(), ParameterType.ByteArray, publicKey.serializeHex()); + // const p3 = new Parameter(f.parameters[2].getName(), ParameterType.ByteArray, attrs); + // f.setParamsValue(p1, p2, p3); + const attrLen = attributes.length; + const struct = new Struct(); + struct.add(dnaid, publicKey.serializeHex(), attrLen); + for (const a of attributes) { + const key = str2hexstr(a.key); + const type = str2hexstr(a.type); + const value = str2hexstr(a.value); + struct.add(key, type, value); + } + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx( + method, + params, + new Address(DNAID_CONTRACT), + gasPrice, + gasLimit, + payer + ); + + return tx; +} + +/** + * Adds attributes to DNA ID. + * + * @param dnaid User's DNA ID + * @param attributes Array of DDOAttributes + * @param publicKey User's public key + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + */ +export function buildAddAttributeTx( + dnaid: string, + attributes: DDOAttribute[], + publicKey: PublicKey, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const method = DNAID_METHOD.addAttributes; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + const struct = new Struct(); + struct.add(dnaid, attributes.length); + for (const a of attributes) { + const key = str2hexstr(a.key); + const type = str2hexstr(a.type); + const value = str2hexstr(a.value); + struct.add(key, type, value); + } + struct.list.push(publicKey.serializeHex()); + const params = buildNativeCodeScript([struct]); + + const tx = makeNativeContractTx( + method, + params, + new Address(DNAID_CONTRACT), + gasPrice, + gasLimit, + payer + ); + return tx; +} + +/** + * Removes attribute from DNA ID. + * + * @param dnaid User's DNA ID + * @param key Key of attribute to remove + * @param publicKey User's public key + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + * + */ +export function buildRemoveAttributeTx( + dnaid: string, + key: string, + publicKey: PublicKey, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const method = DNAID_METHOD.removeAttribute; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + const struct = new Struct(); + struct.add(dnaid, str2hexstr(key), publicKey.serializeHex()); + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx( + method, + params, + new Address(DNAID_CONTRACT), + gasPrice, + gasLimit, + payer + ); + return tx; +} + +/** + * Queries attributes attached to DNA ID. + * + * @param dnaid User's DNA ID + */ +export function buildGetAttributesTx(dnaid: string) { + const method = DNAID_METHOD.getAttributes; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + const struct = new Struct(); + struct.add(dnaid); + const params = buildNativeCodeScript([struct]); + + const tx = makeNativeContractTx(method, params, new Address(DNAID_CONTRACT)); + return tx; +} + +/** + * Queries Description Object of DNA ID(DDO). + * + * @param dnaid User's DNA ID + */ +export function buildGetDDOTx(dnaid: string) { + const method = DNAID_METHOD.getDDO; + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + const struct = new Struct(); + struct.add(dnaid); + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx(method, params, new Address(DNAID_CONTRACT)); + return tx; +} +/** + * Adds a new public key to DNA ID. + * + * @param dnaid User's DNA ID + * @param newPk New public key to be added + * @param userKey User's public key or address + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + */ +export function buildAddControlKeyTx( + dnaid: string, + newPk: PublicKey, + userKey: PublicKey | Address, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const method = DNAID_METHOD.addKey; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + const p1 = dnaid; + const p2 = newPk.serializeHex(); + let p3; + if (userKey instanceof PublicKey) { + p3 = userKey.serializeHex(); + } else if (userKey instanceof Address) { + p3 = userKey.serialize(); + } + const struct = new Struct(); + struct.add(p1, p2, p3); + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx( + method, + params, + new Address(DNAID_CONTRACT), + gasPrice, + gasLimit, + payer + ); + + return tx; +} + +/** + * Revokes a public key from DNA ID. + * + * @param dnaid User's DNA ID + * @param pk2Remove Public key to be removed + * @param sender User's public key or address + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + */ +export function buildRemoveControlKeyTx( + dnaid: string, + pk2Remove: PublicKey, + sender: PublicKey | Address, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const method = DNAID_METHOD.removeKey; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + const p1 = dnaid; + const p2 = pk2Remove.serializeHex(); + let p3; + if (sender instanceof PublicKey) { + p3 = sender.serializeHex(); + } else if (sender instanceof Address) { + p3 = sender.serialize(); + } + const struct = new Struct(); + struct.add(p1, p2, p3); + const params = buildNativeCodeScript([struct]); + + const tx = makeNativeContractTx( + method, + params, + new Address(DNAID_CONTRACT), + gasPrice, + gasLimit, + payer + ); + return tx; +} + +/** + * Queries public keys attached to DNA ID. + * + * @param dnaid User's DNA ID + */ +export function buildGetPublicKeysTx(dnaid: string) { + const method = DNAID_METHOD.getPublicKeys; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + const struct = new Struct(); + struct.add(dnaid); + const params = buildNativeCodeScript([struct]); + + const tx = makeNativeContractTx(method, params, new Address(DNAID_CONTRACT)); + return tx; +} + +/** + * Adds recovery address to DNA ID. + * + * @param dnaid User's DNA ID + * @param recovery Recovery address, must have not be set + * @param publicKey User's public key, must be user's existing public key + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + */ +export function buildAddRecoveryTx( + dnaid: string, + recovery: Address, + publicKey: PublicKey, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const method = DNAID_METHOD.addRecovery; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + const p1 = dnaid; + const p2 = recovery; + const p3 = publicKey.serializeHex(); + const struct = new Struct(); + struct.add(p1, p2, p3); + const params = buildNativeCodeScript([struct]); + const tx = makeNativeContractTx(method, params, new Address(DNAID_CONTRACT), gasPrice, gasLimit, payer); + return tx; +} + +/** + * Changes recovery address of DNA ID. + * + * This contract call must be initiated by the original recovery address. + * + * @param dnaid user's DNA ID + * @param newrecovery New recovery address + * @param oldrecovery Original recoevery address + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer + */ +export function buildChangeRecoveryTx( + dnaid: string, + newrecovery: Address, + oldrecovery: Address, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const method = DNAID_METHOD.changeRecovery; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + const p1 = dnaid; + const p2 = newrecovery; + const p3 = oldrecovery; + const struct = new Struct(); + struct.add(p1, p2, p3); + const params = buildNativeCodeScript([struct]); + + const tx = makeNativeContractTx(method, params, new Address(DNAID_CONTRACT), + gasPrice, gasLimit); + tx.payer = payer || oldrecovery; + return tx; +} + +/** + * Queries the state of the public key associated with DNA ID. + * + * @param dnaid user's DNA ID + * @param pkId User's public key Id + */ +export function buildGetPublicKeyStateTx(dnaid: string, pkId: number) { + const method = DNAID_METHOD.getKeyState; + + if (dnaid.substr(0, 3) === 'did') { + dnaid = str2hexstr(dnaid); + } + + // tslint:disable-next-line:no-console + console.log('did: ' + dnaid); + + const index = num2hexstring(pkId, 4, true); + + // tslint:disable-next-line:no-console + console.log('index: ' + index); + + const struct = new Struct(); + struct.add(dnaid, pkId); + const params = buildNativeCodeScript([struct]); + + const tx = makeNativeContractTx(method, params, new Address(DNAID_CONTRACT)); + return tx; +} diff --git a/src/smartcontract/nativevm/token.ts b/src/smartcontract/nativevm/token.ts new file mode 100644 index 0000000..104b28a --- /dev/null +++ b/src/smartcontract/nativevm/token.ts @@ -0,0 +1,216 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { BigNumber } from 'bignumber.js'; +import BigInt from '../../common/bigInt'; +import { Address } from '../../crypto/address'; +import { ERROR_CODE } from '../../error'; +import { hex2VarBytes, hexstr2str, num2hexstring, str2VarBytes, StringReader } from '../../utils'; + +export class Transfers { + static deserialize(sr: StringReader) { + const t = new Transfers(); + // const version = sr.read(1); + // t.version = version; + const states = []; + const stateLen = sr.readNextLen(); + for (let i = 0; i < stateLen; i++) { + const state = State.deserialize(sr); + states.push(state); + } + t.states = states; + return t; + } + + // byte + // version : string + states: State[] = []; + + constructor() { + // this.version = '00'; + } + + serialize() { + let result = ''; + // result += this.version + result += num2hexstring(this.states.length); + // tslint:disable-next-line:prefer-for-of + for (let i = 0; i < this.states.length; i++) { + result += this.states[i].serialize(); + } + return result; + } +} + +export class TokenTransfer { + static deserialize(sr: StringReader) { + const tf = new TokenTransfer(); + tf.states = []; + const contract = sr.read(20); + tf.contract = contract; + + const len = sr.readNextLen(); + for (let i = 0; i < len; i++) { + const state = State.deserialize(sr); + tf.states.push(state); + } + return tf; + } + + // 20 bytes + contract: string; + states: State[]; + + serialize() { + let result = ''; + result += this.contract; + const len = num2hexstring(this.states.length); + result += len; + // tslint:disable-next-line:prefer-for-of + for (let i = 0 ; i < this.states.length; i++) { + result += this.states[i].serialize(); + } + return result; + } +} + +export class State { + static deserialize(sr: StringReader) { + // const version = sr.read(1); + const from = new Address(sr.readNextBytes()); + const to = new Address(sr.readNextBytes()); + // const value = (new BigNumber(sr.readNextBytes(), 16)).toString(); + // const value = sr.read(8); + const value = BigInt.fromHexstr(sr.readNextBytes()).value; + + return new State(from, to, value.toString()); + } + + // byte + // version : string + // 20 bytes address + from: Address; + to: Address; + value: string | number; + + constructor(from: Address, to: Address, value: string | number) { + const bi = new BigNumber(value); + if (!bi.isInteger() || bi.isNegative()) { + throw ERROR_CODE.INVALID_PARAMS; + } + this.from = from; + this.to = to; + this.value = value; + } + + serialize() { + let result = ''; + // result += this.version + result += hex2VarBytes(this.from.serialize()); + result += hex2VarBytes(this.to.serialize()); + const bi = new BigInt(this.value).toHexstr(); + result += hex2VarBytes(bi); + return result; + } +} + +export class Contract { + static deserialize(sr: StringReader) { + const c = new Contract(); + const version = sr.read(1); + const address = Address.deserialize(sr); + const method = sr.readNextBytes(); + const args = sr.readNextBytes(); + c.version = version; + c.address = address; + c.method = hexstr2str(method); + c.args = args; + return c; + } + + // byte + version: string; + + // 20 bytes + address: Address; + + method: string; + + // byte + args: string; + + constructor() { + this.version = '00'; + } + + serialize() { + let result = ''; + result += this.version; + + result += this.address.serialize(); + + result += str2VarBytes(this.method); + + result += hex2VarBytes(this.args); + + return result; + } +} + +export class TransferFrom { + static deserialize(sr: StringReader): TransferFrom { + // const version = sr.read(1); + const sender = new Address(sr.readNextBytes()); + const from = new Address(sr.readNextBytes()); + const to = new Address(sr.readNextBytes()); + const value = BigInt.fromHexstr(sr.readNextBytes()).value; + const tf = new TransferFrom(sender, from, to, value.toString()); + return tf; + } + + // version : string = '00' + + sender: Address; + + from: Address; + + to: Address; + + value: string; + + constructor(sender: Address, from: Address, to: Address, value: string) { + const bi = new BigNumber(value); + if (!bi.isInteger() || !bi.isNegative()) { + throw new Error(String(ERROR_CODE.INVALID_PARAMS)); + } + this.sender = sender; + this.from = from; + this.to = to; + this.value = value; + } + + serialize(): string { + let result = ''; + // result += this.version + result += hex2VarBytes(this.sender.serialize()); + result += hex2VarBytes(this.from.serialize()); + result += hex2VarBytes(this.to.serialize()); + const biHex = new BigInt(this.value).toHexstr(); + result += hex2VarBytes(biHex); + return result; + } +} diff --git a/src/smartcontract/neovm/attestClaimTxBuilder.ts b/src/smartcontract/neovm/attestClaimTxBuilder.ts new file mode 100644 index 0000000..d94359f --- /dev/null +++ b/src/smartcontract/neovm/attestClaimTxBuilder.ts @@ -0,0 +1,97 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { Address } from '../../crypto'; +import AbiInfo from '../../smartcontract/abi/abiInfo'; +import { Parameter, ParameterType } from '../../smartcontract/abi/parameter'; + +import { makeInvokeTransaction } from '../../transaction/transactionBuilder'; +import { reverseHex, str2hexstr } from '../../utils'; +import { Transaction } from './../../transaction/transaction'; + +import abiJson from '../data/attestClaim'; +const abiInfo = AbiInfo.parseJson(JSON.stringify(abiJson)); +const contractHash = abiInfo.getHash().replace('0x', ''); +const contractAddress = new Address(reverseHex(contractHash)); +/* TODO : Test */ + +/** + * Attests the claim. + * + * @param claimId Unique id of the claim + * @param issuer Issuer's DNA ID + * @param subject Subject's DNA ID + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer's address + */ +export function buildCommitRecordTx(claimId: string, issuer: string, subject: string, + gasPrice: string, gasLimit: string, payer: Address) { + const f = abiInfo.getFunction('Commit'); + if (issuer.substr(0, 3) === 'did') { + issuer = str2hexstr(issuer); + } + if (subject.substr(0, 3) === 'did') { + subject = str2hexstr(issuer); + } + const p1 = new Parameter(f.parameters[0].getName(), ParameterType.ByteArray, str2hexstr(claimId)); + const p2 = new Parameter(f.parameters[1].getName(), ParameterType.ByteArray, issuer); + const p3 = new Parameter(f.parameters[2].getName(), ParameterType.ByteArray, subject); + + let tx = new Transaction(); + tx = makeInvokeTransaction(f.name, [p1, p2, p3], contractAddress, gasPrice, gasLimit, payer); + return tx; +} + +/** + * Revokes the claim. + * + * @param claimId Unique id of the claim + * @param revokerDNAid Revoker's DNA ID + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer's address + */ +export function buildRevokeRecordTx(claimId: string, revokerDNAid: string, + gasPrice: string, gasLimit: string, payer: Address) { + const f = abiInfo.getFunction('Revoke'); + + const name1 = f.parameters[0].getName(); + const type1 = ParameterType.ByteArray; + + if (revokerDNAid.substr(0, 3) === 'did') { + revokerDNAid = str2hexstr(revokerDNAid); + } + + const p1 = new Parameter(name1, type1, str2hexstr(claimId)); + const p2 = new Parameter(f.parameters[1].getName(), ParameterType.ByteArray, revokerDNAid); + + return makeInvokeTransaction(f.name, [p1, p2], contractAddress, gasPrice, gasLimit, payer); +} + +/** + * Queries the state of attest. + * + * @param claimId Unique id of the claim + */ +export function buildGetRecordStatusTx(claimId: string) { + const f = abiInfo.getFunction('GetStatus'); + const p1 = new Parameter(f.parameters[0].getName(), ParameterType.ByteArray, str2hexstr(claimId)); + const tx = makeInvokeTransaction(f.name, [p1], contractAddress); + return tx; +} diff --git a/src/smartcontract/neovm/nep5TxBuilder.ts b/src/smartcontract/neovm/nep5TxBuilder.ts new file mode 100644 index 0000000..6afd47c --- /dev/null +++ b/src/smartcontract/neovm/nep5TxBuilder.ts @@ -0,0 +1,122 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import { Parameter, Transaction } from '../../index'; +import { ParameterType } from '../abi/parameter'; +import { Address } from './../../crypto/address'; +import { makeInvokeTransaction } from './../../transaction/transactionBuilder'; + +const functionNames = { + Init: 'init', + Transfer: 'transfer', + BalanceOf: 'balanceOf', + TotalSupply: 'totalSupply', + Symbol: 'symbol', + Decimals: 'decimals', + Name: 'name' +}; +/** + * Transaction builder for nep-5 contracts + */ +export default class Nep5TxBuilder { + + /** + * Init the nep-5 smart contract + * @param contractAddr Address of contract + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer's address to pay for gas + */ + static init(contractAddr: Address, gasPrice: string, gasLimit: string, payer?: Address): Transaction { + const funcName = functionNames.Init; + return makeInvokeTransaction(funcName, [], contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Make transaction for transfer + * @param contractAddr Address of nep-5 contract + * @param from Sender's address + * @param to Receiver's address + * @param amount Amountof asset to transfer + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer's address to pay for gas + */ + static makeTransferTx( + contractAddr: Address, + from: Address, + to: Address, + amount: number, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const funcName = functionNames.Transfer; + const p1 = new Parameter('from', ParameterType.ByteArray, from.serialize()); + const p2 = new Parameter('to', ParameterType.ByteArray, to.serialize()); + const p3 = new Parameter('value', ParameterType.Integer, amount); + return makeInvokeTransaction(funcName, [p1, p2, p3], contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Query the balance + * @param contractAddr Address of nep-5 contract + * @param address Address to query balance + */ + static queryBalanceOf(contractAddr: Address, address: Address): Transaction { + const funcName = functionNames.BalanceOf; + const p1 = new Parameter('from', ParameterType.ByteArray, address.serialize()); + + return makeInvokeTransaction(funcName, [p1], contractAddr); + } + + /** + * Query the total supply of nep-5 contract + * @param contractAddr Address of nep-5 contract + */ + static queryTotalSupply(contractAddr: Address): Transaction { + const funcName = functionNames.TotalSupply; + return makeInvokeTransaction(funcName, [], contractAddr); + } + + /** + * Query the total supply of nep-5 contract + * @param contractAddr Address of nep-5 contract + */ + static queryDecimals(contractAddr: Address): Transaction { + const funcName = functionNames.Decimals; + return makeInvokeTransaction(funcName, [], contractAddr); + } + + /** + * Query the total supply of nep-5 contract + * @param contractAddr Address of nep-5 contract + */ + static querySymbol(contractAddr: Address): Transaction { + const funcName = functionNames.Symbol; + return makeInvokeTransaction(funcName, [], contractAddr); + } + + /** + * Query the total supply of nep-5 contract + * @param contractAddr Address of nep-5 contract + */ + static queryName(contractAddr: Address): Transaction { + const funcName = functionNames.Name; + return makeInvokeTransaction(funcName, [], contractAddr); + } +} diff --git a/src/smartcontract/neovm/oep4TxBuilder.ts b/src/smartcontract/neovm/oep4TxBuilder.ts new file mode 100644 index 0000000..4ee1ce1 --- /dev/null +++ b/src/smartcontract/neovm/oep4TxBuilder.ts @@ -0,0 +1,236 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import * as Long from 'long'; +import { createCodeParamsScript } from '../../transaction/scriptBuilder'; +import { Transaction } from '../../transaction/transaction'; +import { bigIntToBytes, str2hexstr } from '../../utils'; +import { Parameter, ParameterType } from '../abi/parameter'; +import { Address } from './../../crypto/address'; +import { makeInvokeTransaction } from './../../transaction/transactionBuilder'; + +const functionNames = { + Init: 'init', + Transfer: 'transfer', + TransferMulti: 'transferMulti', + Approve: 'approve', + TransferFromm: 'transferFrom', + Allowance: 'allowance', + BalanceOf: 'balanceOf', + TotalSupply: 'totalSupply', + Symbol: 'symbol', + Decimals: 'decimals', + Name: 'name' +}; + +export const formatBigNumParameter = (amount: string): Parameter => { + // let val = new BigNumber(amount).toString(16); + // if (val.length % 2 === 1) { + // val = '0' + val; + // } + // const valHex = reverseHex(val); + const valHex = bigIntToBytes(Long.fromString(amount)); + const p = new Parameter('value', ParameterType.ByteArray, valHex); + return p; +}; + +export class Oep4State { + from: string; + to: string; + amount: string; + + constructor(from: Address, to: Address, amount: string) { + this.from = from.serialize(); + this.to = to.serialize(); + this.amount = formatBigNumParameter(amount).value; + } +} +/** + * Transaction builder for oep-4 contracts + */ +export class Oep4TxBuilder { + + contractAddr: Address; + + constructor(contractAddr: Address) { + this.contractAddr = contractAddr; + } + + /** + * Init the oep-4 smart contract + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer's address to pay for gas + */ + init(gasPrice: string, gasLimit: string, payer?: Address): Transaction { + const funcName = functionNames.Init; + return makeInvokeTransaction(funcName, [], this.contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Make transaction for transfer + * @param from Sender's address + * @param to Receiver's address + * @param amount Amountof asset to transfer + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer's address to pay for gas + */ + makeTransferTx( + from: Address, + to: Address, + amount: string, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const funcName = functionNames.Transfer; + const p1 = new Parameter('from', ParameterType.ByteArray, from.serialize()); + const p2 = new Parameter('to', ParameterType.ByteArray, to.serialize()); + const p3 = formatBigNumParameter(amount); + return makeInvokeTransaction(funcName, [p1, p2, p3], this.contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Make transaction for multi transfer. + * The transaction needs signatures of each sender in states and the signature of the payer. + * @param states Array of State(sender, receiver, amount) + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer to pay for gas + */ + makeTransferMultiTx( + states: Oep4State[], + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const list = []; + list.push(str2hexstr(functionNames.TransferMulti)); + const temp = []; + for (const state of states) { + temp.push([ + state.from, + state.to, + state.amount + ]); + } + list.push(temp); + const params = createCodeParamsScript(list); + return makeInvokeTransaction('', params, this.contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Make transaction for approve + * @param owner Owner's address + * @param spender Spender's address + * @param amount Amount + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer to pay for gas + */ + makeApproveTx( + owner: Address, + spender: Address, + amount: string, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const funcName = functionNames.Approve; + const params = [ + new Parameter('owner', ParameterType.ByteArray, owner.serialize()), + new Parameter('spender', ParameterType.ByteArray, spender.serialize()), + formatBigNumParameter(amount) + ]; + return makeInvokeTransaction(funcName, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeTransferFromTx( + sender: Address, + from: Address, + to: Address, + amount: string, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const funcName = functionNames.TransferFromm; + const params = [ + new Parameter('owner', ParameterType.ByteArray, sender.serialize()), + new Parameter('from', ParameterType.ByteArray, from.serialize()), + new Parameter('to', ParameterType.ByteArray, to.serialize()), + formatBigNumParameter(amount) + ]; + return makeInvokeTransaction(funcName, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeQueryAllowanceTx( + owner: Address, + spender: Address + ): Transaction { + const funcName = functionNames.Allowance; + const params = [ + new Parameter('owner', ParameterType.ByteArray, owner.serialize()), + new Parameter('spender', ParameterType.ByteArray, spender.serialize()) + ]; + return makeInvokeTransaction(funcName, params, this.contractAddr); + } + + /** + * Query the balance + * @param address Address to query balance + */ + queryBalanceOf(address: Address): Transaction { + const funcName = functionNames.BalanceOf; + const p1 = new Parameter('from', ParameterType.ByteArray, address.serialize()); + + return makeInvokeTransaction(funcName, [p1], this.contractAddr); + } + + /** + * Query the total supply of oep-4 contract + */ + queryTotalSupply(): Transaction { + const funcName = functionNames.TotalSupply; + return makeInvokeTransaction(funcName, [], this.contractAddr); + } + + /** + * Query the total supply of oep-4 contract + */ + queryDecimals(): Transaction { + const funcName = functionNames.Decimals; + return makeInvokeTransaction(funcName, [], this.contractAddr); + } + + /** + * Query the total supply of oep-4 contract + */ + querySymbol(): Transaction { + const funcName = functionNames.Symbol; + return makeInvokeTransaction(funcName, [], this.contractAddr); + } + + /** + * Query the total supply of oep-4 contract + */ + queryName(): Transaction { + const funcName = functionNames.Name; + return makeInvokeTransaction(funcName, [], this.contractAddr); + } +} diff --git a/src/smartcontract/neovm/oep5TxBuilder.ts b/src/smartcontract/neovm/oep5TxBuilder.ts new file mode 100644 index 0000000..195cad7 --- /dev/null +++ b/src/smartcontract/neovm/oep5TxBuilder.ts @@ -0,0 +1,222 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { createCodeParamsScript } from '../../transaction/scriptBuilder'; +import { Transaction } from '../../transaction/transaction'; +import { str2hexstr } from '../../utils'; +import { Address } from './../../crypto/address'; +import { makeInvokeTransaction } from './../../transaction/transactionBuilder'; +import { Parameter, ParameterType } from './../abi/parameter'; + +export class Oep5Param { + public toAcct: string; // hex string + public tokenId: string; // hex string + + public constructor(toAcct: Address, tokenId: string ) { + this.toAcct = toAcct.serialize(); + this.tokenId = tokenId; + } +} + +const FunctionNames = { + Init: 'init', + Name: 'name', + Symbol: 'symbol', + TotalSupply: 'totalSupply', + BalanceOf: 'balanceOf', + OwnerOf: 'ownerOf', + Transfer: 'transfer', + TransferMulti: 'transferMulti', + Approve: 'approve', + ApproveMulti: 'approveMulti', + TakeOwnership: 'takeOwnership', + QueryTokenIDByIndex: 'queryTokenIDByIndex', + QueryTokenByID: 'queryTokenByID', + GetApproved: 'getApproved', + CreateMultiTokens: 'createMultiTokens', + CreateOneToken: 'createOneToken' +}; + +export class Oep5TxBuilder { + contractAddr: Address; + + constructor(contractAddr: Address) { + this.contractAddr = contractAddr; + } + + makeInitTx( + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.Init; + return makeInvokeTransaction(func, [], this.contractAddr, gasPrice, gasLimit, payer); + } + + makeOwnerOfTx( + tokenId: string + ): Transaction { + const func = FunctionNames.OwnerOf; + const params = [ + new Parameter('tokenId', ParameterType.ByteArray, tokenId) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + /** + * Transfer the control to someone else + * @param oep5Param + * @param gasPrice + * @param gasLimit + * @param payer + */ + makeTransferTx( + oep5Param: Oep5Param, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.Transfer; + const params = [ + new Parameter('toAcct', ParameterType.ByteArray, oep5Param.toAcct), + new Parameter('tokenId', ParameterType.ByteArray, oep5Param.tokenId) + ]; + return makeInvokeTransaction(func, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Transfer the control to multi people + */ + makeTransferMultiTx( + oep5Params: Oep5Param[], + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const list = []; + list.push(str2hexstr(FunctionNames.TransferMulti)); + const temp = []; + for (const param of oep5Params) { + temp.push([ + param.toAcct, + param.tokenId + ]); + } + list.push(temp); + const params = createCodeParamsScript(list); + return makeInvokeTransaction('', params, this.contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Approve the token to toAcct address, it can overwrite older approved address + * @param oep5Param + * @param gasPrice + * @param gasLimit + * @param payer + */ + makeApproveTx( + oep5Param: Oep5Param, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.Approve; + const params = [ + new Parameter('toAcct', ParameterType.ByteArray, oep5Param.toAcct), + new Parameter('tokenId', ParameterType.ByteArray, oep5Param.tokenId) + ]; + return makeInvokeTransaction(func, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Take the approved token. + * @param oep5Param + * @param gasPrice + * @param gasLimit + * @param payer + */ + makeTakeOwnershipTx( + oep5Param: Oep5Param, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.TakeOwnership; + const params = [ + new Parameter('toAcct', ParameterType.ByteArray, oep5Param.toAcct), + new Parameter('tokenId', ParameterType.ByteArray, oep5Param.tokenId) + ]; + return makeInvokeTransaction(func, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeQueryBalanceOfTx( + addr: Address + ): Transaction { + const func = FunctionNames.BalanceOf; + const params = [ + new Parameter('addr', ParameterType.ByteArray, addr.serialize()) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryTotalSupplyTx(): Transaction { + const func = FunctionNames.TotalSupply; + return makeInvokeTransaction(func, [], this.contractAddr); + } + + makeQueryTokenIDByIndexTx( + index: number + ): Transaction { + const func = FunctionNames.QueryTokenIDByIndex; + const params = [ + new Parameter('index', ParameterType.Long, index) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryTokenByIDTx( + tokenId: string + ): Transaction { + const func = FunctionNames.QueryTokenByID; + const params = [ + new Parameter('tokenId', ParameterType.ByteArray, tokenId) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeGetApprovedTx( + tokenId: string + ): Transaction { + const func = FunctionNames.GetApproved; + const params = [ + new Parameter('tokenId', ParameterType.ByteArray, tokenId) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryNameTx(): Transaction { + const func = FunctionNames.Name; + return makeInvokeTransaction(func, [], this.contractAddr); + } + + makeQuerySymbolTx(): Transaction { + const func = FunctionNames.Symbol; + return makeInvokeTransaction(func, [], this.contractAddr); + } + +} diff --git a/src/smartcontract/neovm/oep8TxBuilder.ts b/src/smartcontract/neovm/oep8TxBuilder.ts new file mode 100644 index 0000000..83c2169 --- /dev/null +++ b/src/smartcontract/neovm/oep8TxBuilder.ts @@ -0,0 +1,325 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import { BigNumber } from 'bignumber.js'; +import { createCodeParamsScript } from '../../transaction/scriptBuilder'; +import { Transaction } from '../../transaction/transaction'; +import { str2hexstr } from '../../utils'; +import { Address } from './../../crypto/address'; +import { makeInvokeTransaction } from './../../transaction/transactionBuilder'; +import { num2hexstring } from './../../utils'; +import { Parameter, ParameterType } from './../abi/parameter'; + +export class Oep8State { + public from: string; + public to: string; + public tokenId: string; + public value: BigNumber; + + public constructor(from: Address, to: Address, tokenId: number, value: string) { + this.from = from.serialize(); + this.to = to.serialize(); + this.tokenId = num2hexstring(tokenId); + this.value = new BigNumber(value); + } +} + +export class TransferFrom { + spender: string; + from: string; + to: string; + tokenId: string; + value: BigNumber; + constructor(spender: Address, from: Address, to: Address, tokenId: number, value: string) { + this.spender = spender.serialize(); + this.from = from.serialize(); + this.to = to.serialize(); + this.tokenId = num2hexstring(tokenId); + this.value = new BigNumber(value); + } +} + +const FunctionNames = { + Name: 'name', + Symbol: 'symbol', + TotalSupply: 'totalSupply', + BalanceOf: 'balanceOf', + Transfer: 'transfer', + TransferMulti: 'transferMulti', + Approve: 'approve', + ApproveMulti: 'approveMulti', + Allowance: 'allowance', + TransferFrom: 'transferFrom', + TransferFromMulti: 'transferFromMulti', + Compound: 'compound', + Concatkey: 'concatkey', + Init: 'init', + CreateMultiKindsPumpkin: 'createMultiKindsPumpkin', + CheckTokenPrefix: 'checkTokenPrefix', + BalancesOf: 'balancesOf', + TotalBalanceOf: 'totalBalanceOf', + CheckTokenId: 'checkTokenId' +}; + +export class Oep8TxBuilder { + contractAddr: Address; + + constructor(contractAddr: Address) { + this.contractAddr = contractAddr; + } + + makeInitTx( + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.Init; + return makeInvokeTransaction(func, [], this.contractAddr, gasPrice, gasLimit, payer); + } + + makeTransferTx( + sendAddr: Address, + recvAddr: Address, + tokenId: number, + amount: string, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.Transfer; + const params = [ + new Parameter('sender', ParameterType.ByteArray, sendAddr.serialize()), + new Parameter('recv', ParameterType.ByteArray, recvAddr.serialize()), + new Parameter('tokenId', ParameterType.ByteArray, tokenId), + new Parameter('amount', ParameterType.Long, amount) + ]; + return makeInvokeTransaction(func, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeTransferMultiTx( + states: Oep8State[], + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const list = []; + list.push(str2hexstr(FunctionNames.TransferMulti)); + const temp = []; + for (const state of states) { + temp.push([ + state.from, + state.to, + state.tokenId, + state.value + ]); + } + list.push(temp); + const params = createCodeParamsScript(list); + return makeInvokeTransaction('', params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeApproveTx( + owner: Address, + spender: Address, + tokenId: number, + amount: string, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.Approve; + const params = [ + new Parameter('owner', ParameterType.ByteArray, owner.serialize()), + new Parameter('spender', ParameterType.ByteArray, spender.serialize()), + new Parameter('tokenId', ParameterType.ByteArray, num2hexstring(tokenId)), + new Parameter('amount', ParameterType.Long, amount) + ]; + return makeInvokeTransaction(func, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeApproveMulti( + states: Oep8State[], + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.ApproveMulti; + const list = []; + list.push(str2hexstr(func)); + const temp = []; + for (const state of states) { + temp.push([ + state.from, + state.to, + state.tokenId, + state.value + ]); + } + list.push(temp); + const params = createCodeParamsScript(list); + return makeInvokeTransaction('', params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeTransferFromMulti( + states: TransferFrom[], + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.TransferFromMulti; + const list = []; + list.push(str2hexstr(func)); + const temp = []; + for (const state of states) { + temp.push([ + state.spender, + state.from, + state.to, + state.tokenId, + state.value + ]); + } + list.push(temp); + const params = createCodeParamsScript(list); + return makeInvokeTransaction('', params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeTransferFromTx( + sender: Address, + from: Address, + to: Address, + tokenId: number, + amount: string, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.TransferFrom; + const params = [ + new Parameter('sender', ParameterType.ByteArray, sender.serialize()), + new Parameter('from', ParameterType.ByteArray, from.serialize()), + new Parameter('to', ParameterType.ByteArray, to.serialize()), + new Parameter('tokenId', ParameterType.ByteArray, num2hexstring(tokenId)), + new Parameter('amount', ParameterType.Long, amount) + ]; + return makeInvokeTransaction(func, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + /** + * Compound tokens + * @param account User's address + * @param compoundNum 0 - compound all tokens that can be compounded; 1 - compound 1 token of each type. + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Payer to pay for gas + */ + makeCompoundTx( + account: Address, + compoundNum: number, + gasPrice: string, + gasLimit: string, + payer: Address + ): Transaction { + const func = FunctionNames.Compound; + const params = [ + new Parameter('account', ParameterType.ByteArray, account.serialize()), + new Parameter('compoundNum', ParameterType.Integer, compoundNum) + ]; + return makeInvokeTransaction(func, params, this.contractAddr, gasPrice, gasLimit, payer); + } + + makeQueryAllowanceTx( + owner: Address, + spender: Address, + tokenId: number + ): Transaction { + const func = FunctionNames.Allowance; + const params = [ + new Parameter('owner', ParameterType.ByteArray, owner.serialize()), + new Parameter('spender', ParameterType.ByteArray, spender.serialize()), + new Parameter('tokenId', ParameterType.ByteArray, num2hexstring(tokenId)) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryBalanceOfTx( + addr: Address, + tokenId: number + ): Transaction { + const func = FunctionNames.BalanceOf; + const params = [ + new Parameter('addr', ParameterType.ByteArray, addr.serialize()), + new Parameter('tokenId', ParameterType.ByteArray, num2hexstring(tokenId)) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryTotalSupplyTx( + tokenId: number + ): Transaction { + const func = FunctionNames.TotalSupply; + const params = [ + new Parameter('tokenId', ParameterType.ByteArray, num2hexstring(tokenId)) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryNameTx( + tokenId: number + ): Transaction { + const func = FunctionNames.Name; + const params = [ + new Parameter('tokenId', ParameterType.ByteArray, num2hexstring(tokenId)) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryDecimalsTx(): Transaction { + const func = FunctionNames.Symbol; + return makeInvokeTransaction(func, [], this.contractAddr); + } + + makeQuerySymbolTx( + tokenId: number + ): Transaction { + const func = FunctionNames.Symbol; + const params = [ + new Parameter('tokenId', ParameterType.ByteArray, num2hexstring(tokenId)) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryBalancesTx( + account: Address + ): Transaction { + const func = FunctionNames.BalancesOf; + const params = [ + new Parameter('account', ParameterType.ByteArray, account.serialize()) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } + + makeQueryTotalBalanceTx( + account: Address + ): Transaction { + const func = FunctionNames.TotalBalanceOf; + const params = [ + new Parameter('account', ParameterType.ByteArray, account.serialize()) + ]; + return makeInvokeTransaction(func, params, this.contractAddr); + } +} diff --git a/src/transaction/ddo.ts b/src/transaction/ddo.ts new file mode 100644 index 0000000..f40febc --- /dev/null +++ b/src/transaction/ddo.ts @@ -0,0 +1,145 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { PublicKey } from '../crypto'; +import { hexstr2str, str2VarBytes, StringReader } from '../utils'; + +/** + * Public key representation with recorded id from blockchain. + * + */ +export class PublicKeyWithId { + /** + * Deserialize from hex string to PublicKeyWithId + * @param hexstr + */ + static deserialize(hexstr: string): PublicKeyWithId[] { + const sr = new StringReader(hexstr); + + const result: PublicKeyWithId[] = []; + while (!sr.isEmpty()) { + const index = sr.readUint32(); + const data = sr.readNextBytes(); + const p = new PublicKeyWithId(); + p.id = index; + p.pk = PublicKey.deserializeHex(new StringReader(data)); + result.push(p); + } + return result; + } + + /** + * Id of the public key. + * + * Only numeric part is recorded. Full PublicKeyId will be constucted as follows: + * #keys- + */ + id: number; + pk: PublicKey; +} + +/** + * Description attribute of DNA ID + */ +export class DDOAttribute { + static deserialize(hexstr: string) { + const sr = new StringReader(hexstr); + + const result: DDOAttribute[] = []; + while (!sr.isEmpty()) { + const key = hexstr2str(sr.readNextBytes()); + const type = hexstr2str(sr.readNextBytes()); + const value = hexstr2str(sr.readNextBytes()); + const d = new DDOAttribute(); + d.key = key; + d.type = type; + d.value = value; + result.push(d); + } + + return result; + } + + /** + * Key of the attribute + */ + key: string; + /** + * Type of the attribute + */ + type: string; + /** + * Value of the attribute + */ + value: string; + + /** + * Serialize DDO to hex string + */ + serialize(): string { + let result = ''; + result += str2VarBytes(this.key); + result += str2VarBytes(this.type); + result += str2VarBytes(this.value); + return result; + } +} + +/** + * Description object of DNA ID + */ +export class DDO { + /** + * Deserialize from hex string to DDO + * @param hexstr Hex encoded string + */ + static deserialize(hexstr: string): DDO { + const ss = new StringReader(hexstr); + + const ddo = new DDO(); + const pkLen = ss.readNextLen(); + + if (pkLen > 0) { + ddo.publicKeys = PublicKeyWithId.deserialize(ss.read(pkLen)); + } + + const attrLen = ss.readNextLen(); + if (attrLen > 0) { + ddo.attributes = DDOAttribute.deserialize(ss.read(attrLen)); + } + + const recoveryLen = ss.readNextLen(); + if (recoveryLen > 0) { + ddo.recovery = ss.read(recoveryLen); + } + return ddo; + } + + /** + * Array of public keys + */ + publicKeys: PublicKeyWithId[] = []; + /** + * Array of attributes + */ + attributes: DDOAttribute[] = []; + /** + * Recovery of DDO + */ + recovery: string = ''; +} diff --git a/src/transaction/opcode.ts b/src/transaction/opcode.ts new file mode 100644 index 0000000..8e997fa --- /dev/null +++ b/src/transaction/opcode.ts @@ -0,0 +1,155 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +enum OPCODE { + // Constants + PUSH0 = 0x00, // An empty array of bytes is pushed onto the stack. + PUSHF = PUSH0, + PUSHBYTES1 = 0x01, // 0x01-0x4B The next bytes is data to be pushed onto the stack + PUSHBYTES75 = 0x4B, + PUSHDATA1 = 0x4C, // The next byte contains the number of bytes to be pushed onto the stack. + PUSHDATA2 = 0x4D, // The next two bytes contain the number of bytes to be pushed onto the stack. + PUSHDATA4 = 0x4E, // The next four bytes contain the number of bytes to be pushed onto the stack. + PUSHM1 = 0x4F, // The number -1 is pushed onto the stack. + PUSH1 = 0x51, // The number 1 is pushed onto the stack. + PUSHT = PUSH1, + PUSH2 = 0x52, // The number 2 is pushed onto the stack. + PUSH3 = 0x53, // The number 3 is pushed onto the stack. + PUSH4 = 0x54, // The number 4 is pushed onto the stack. + PUSH5 = 0x55, // The number 5 is pushed onto the stack. + PUSH6 = 0x56, // The number 6 is pushed onto the stack. + PUSH7 = 0x57, // The number 7 is pushed onto the stack. + PUSH8 = 0x58, // The number 8 is pushed onto the stack. + PUSH9 = 0x59, // The number 9 is pushed onto the stack. + PUSH10 = 0x5A, // The number 10 is pushed onto the stack. + PUSH11 = 0x5B, // The number 11 is pushed onto the stack. + PUSH12 = 0x5C, // The number 12 is pushed onto the stack. + PUSH13 = 0x5D, // The number 13 is pushed onto the stack. + PUSH14 = 0x5E, // The number 14 is pushed onto the stack. + PUSH15 = 0x5F, // The number 15 is pushed onto the stack. + PUSH16 = 0x60, // The number 16 is pushed onto the stack. + + // Flow control + NOP = 0x61, // Does nothing. + JMP = 0x62, + JMPIF = 0x63, + JMPIFNOT = 0x64, + CALL = 0x65, + RET = 0x66, + APPCALL = 0x67, + SYSCALL = 0x68, + TAILCALL = 0x69, + DUPFROMALTSTACK = 0x6A, + + // Stack + TOALTSTACK = 0x6B, // Puts the input onto the top of the alt stack. Removes it from the main stack. + FROMALTSTACK = 0x6C, // Puts the input onto the top of the main stack. Removes it from the alt stack. + XDROP = 0x6D, + XSWAP = 0x72, + XTUCK = 0x73, + DEPTH = 0x74, // Puts the number of stack items onto the stack. + DROP = 0x75, // Removes the top stack item. + DUP = 0x76, // Duplicates the top stack item. + NIP = 0x77, // Removes the second-to-top stack item. + OVER = 0x78, // Copies the second-to-top stack item to the top. + PICK = 0x79, // The item n back in the stack is copied to the top. + ROLL = 0x7A, // The item n back in the stack is moved to the top. + ROT = 0x7B, // The top three items on the stack are rotated to the left. + SWAP = 0x7C, // The top two items on the stack are swapped. + TUCK = 0x7D, // The item at the top of the stack is copied and inserted before the second-to-top item. + + // Splice + CAT = 0x7E, // Concatenates two strings. + SUBSTR = 0x7F, // Returns a section of a string. + LEFT = 0x80, // Keeps only characters left of the specified point in a string. + RIGHT = 0x81, // Keeps only characters right of the specified point in a string. + SIZE = 0x82, // Returns the length of the input string. + + // Bitwise logic + INVERT = 0x83, // Flips all of the bits in the input. + AND = 0x84, // Boolean and between each bit in the inputs. + OR = 0x85, // Boolean or between each bit in the inputs. + XOR = 0x86, // Boolean exclusive or between each bit in the inputs. + EQUAL = 0x87, // Returns 1 if the inputs are exactly equal, 0 otherwise. + // EQUALVERIFY = 0x88, // Same as EQUAL, but runs VERIFY afterward. + // RESERVED1 = 0x89, // Transaction is invalid unless occuring in an unexecuted IF branch + // RESERVED2 = 0x8A, // Transaction is invalid unless occuring in an unexecuted IF branch + + // Arithmetic + // Note: Arithmetic inputs are limited to signed 32-bit integers, but may overflow their output. + INC = 0x8B, // 1 is added to the input. + DEC = 0x8C, // 1 is subtracted from the input. + // SAL = 0x8D, // The input is multiplied by 2. + // SAR = 0x8E, // The input is divided by 2. + NEGATE = 0x8F, // The sign of the input is flipped. + ABS = 0x90, // The input is made positive. + NOT = 0x91, // If the input is 0 or 1, it is flipped. Otherwise the output will be 0. + NZ = 0x92, // Returns 0 if the input is 0. 1 otherwise. + ADD = 0x93, // a is added to b. + SUB = 0x94, // b is subtracted from a. + MUL = 0x95, // a is multiplied by b. + DIV = 0x96, // a is divided by b. + MOD = 0x97, // Returns the remainder after dividing a by b. + SHL = 0x98, // Shifts a left b bits, preserving sign. + SHR = 0x99, // Shifts a right b bits, preserving sign. + BOOLAND = 0x9A, // If both a and b are not 0, the output is 1. Otherwise 0. + BOOLOR = 0x9B, // If a or b is not 0, the output is 1. Otherwise 0. + NUMEQUAL = 0x9C, // Returns 1 if the numbers are equal, 0 otherwise. + NUMNOTEQUAL = 0x9E, // Returns 1 if the numbers are not equal, 0 otherwise. + LT = 0x9F, // Returns 1 if a is less than b, 0 otherwise. + GT = 0xA0, // Returns 1 if a is greater than b, 0 otherwise. + LTE = 0xA1, // Returns 1 if a is less than or equal to b, 0 otherwise. + GTE = 0xA2, // Returns 1 if a is greater than or equal to b, 0 otherwise. + MIN = 0xA3, // Returns the smaller of a and b. + MAX = 0xA4, // Returns the larger of a and b. + WITHIN = 0xA5, // Returns 1 if x is within the specified range (left-inclusive), 0 otherwise. + + // Crypto + // RIPEMD160 = 0xA6, // The input is hashed using RIPEMD-160. + SHA1 = 0xA7, // The input is hashed using SHA-1. + SHA256 = 0xA8, // The input is hashed using SHA-256. + HASH160 = 0xA9, + HASH256 = 0xAA, + // tslint:disable-next-line:max-line-length + CHECKSIG = 0xAC, // The entire transaction's outputs inputs and script (from the most recently-executed CODESEPARATOR to the end) are hashed. The signature used by CHECKSIG must be a valid signature for this hash and public key. If it is 1 is returned 0 otherwise. + // tslint:disable-next-line:max-line-length + CHECKMULTISIG = 0xAE, // For each signature and public key pair CHECKSIG is executed. If more public keys than signatures are listed some key/sig pairs can fail. All signatures need to match a public key. If all signatures are valid 1 is returned 0 otherwise. Due to a bug one extra unused value is removed from the stack. + + // Array + // tslint:disable:indent + ARRAYSIZE = 0xC0, + PACK = 0xC1, + UNPACK = 0xC2, + PICKITEM = 0xC3, + SETITEM = 0xC4, + NEWARRAY = 0xC5, + NEWSTRUCT = 0xC6, + NEWMAP = 0xC7, + APPEND = 0xC8, + REVERSE = 0xC9, + REMOVE = 0xCA, + HASKEY = 0xCB, + KEYS = 0xCC, + VALUES = 0xCD, + + // Exception + THROW = 0xF0, + THROWIFNOT = 0xF1 +} + +export default OPCODE; diff --git a/src/transaction/payload/deployCode.ts b/src/transaction/payload/deployCode.ts new file mode 100644 index 0000000..a0e0650 --- /dev/null +++ b/src/transaction/payload/deployCode.ts @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { + hex2VarBytes, + hexstr2str, + str2VarBytes, + StringReader +} from '../../utils'; +import { num2hexstring } from './../../utils'; +import Payload from './payload'; + +export enum VmType { + NEOVM_TYPE = 1, + WASMVM_TYPE = 3 +} + +/** + * Describes the payload of deploy code + */ +export default class DeployCode extends Payload { + /** + * Hex encoded contract content + */ + code: string; + + /** + * Decides if the contract need storage(Deprecated) + * Change to VmType to support wasm vm + */ + // needStorage: boolean; + vmType: VmType; + /** + * Name of the smart contract + */ + name: string; + /** + * Version of the contract + */ + version: string; + /** + * Author of the contract + */ + author: string; + /** + * Email of the author + */ + email: string; + /** + * Description of the contract + */ + description: string; + + /** + * Serialize deploy code to hex string + */ + serialize(): string { + let result = ''; + + // result += this.code.serialize(); + result += hex2VarBytes(this.code); + + result += num2hexstring(this.vmType); + + result += str2VarBytes(this.name); + + result += str2VarBytes(this.version); + + result += str2VarBytes(this.author); + + result += str2VarBytes(this.email); + + result += str2VarBytes(this.description); + + return result; + } + + /** + * Deserialize deploy code + * @param sr + */ + deserialize(sr: StringReader): void { + + // const code = VmCode.deserialize(sr); + const code = sr.readNextBytes(); + this.code = code; + + const type = sr.readUint8(); + this.vmType = type; + + const name = sr.readNextBytes(); + this.name = hexstr2str(name); + + const codeVersion = sr.readNextBytes(); + this.version = hexstr2str(codeVersion); + + const author = sr.readNextBytes(); + this.author = hexstr2str(author); + + const email = sr.readNextBytes(); + this.email = hexstr2str(email); + + const description = sr.readNextBytes(); + this.description = hexstr2str(description); + } +} diff --git a/src/transaction/payload/invokeCode.ts b/src/transaction/payload/invokeCode.ts new file mode 100644 index 0000000..ed02e2d --- /dev/null +++ b/src/transaction/payload/invokeCode.ts @@ -0,0 +1,144 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { hex2VarBytes, StringReader } from '../../utils'; +import Payload from './payload'; + +export default class InvokeCode extends Payload { + // the length is of bytes 20 + /* + scriptHash : string + parameters : Array = [] + functionName : string + */ + + /** + * Hex encoed string + */ + code: string; + + constructor() { + super(); + // this.gasLimit = new Fixed64() + } + +/* serialize() : string { + let payloadLength + let paramsLength = num2hexstring( 0x50 + this.parameters.length) //start from '0x50' + const paramsEnd = 'c1' + let funcNameHex = str2hexstr(this.functionName) + const funcNameLength = num2hexstring(funcNameHex.length/2) + + let params = [] + for(let i = this.parameters.length-1; i > -1; i--) { + let p = this.parameters[i] + let hexP = p.getValue() + let hexPLength = num2VarInt( hexP.length / 2) + let opcode = '' + if( hexP.length/2 < OPCODE.PUSHBYTES75) { + + } else if (hexP.length / 2 < 0x100) { + opcode = num2VarInt( OPCODE.PUSHDATA1 ) + } else if( hexP.length/2 < 0x1000 ) { + opcode = num2hexstring( OPCODE.PUSHDATA2, 2, true) + } else { + opcode = num2hexstring( OPCODE.PUSHDATA4, 4, true) + } + params.push ({ + hexPLength, + hexP, + opcode + }) + } + + let result = '' + //scripthash + // result += this.scriptHash + //params + for(let v of params) { + if(v.opcode) { + result += v.opcode + } + result += v.hexPLength + result += v.hexP + } + result += paramsLength + //end + result += paramsEnd + //function + result += funcNameLength + result += funcNameHex + let totalParamsLength = num2VarInt(result.length / 2) + //result = this.scriptHash + totalParamsLength + result + + console.log('invode serialze: '+ result) + + return result + } */ + + serialize() { + let result = ''; + // if(this.gasLimit) { + // result += this.gasLimit.serialize() + // } + // result += this.code.serialize(); + result += hex2VarBytes(this.code); + return result; + } + + /* deserialize(ss : StringReader) : void { + //scriptHash, fixed langth + this.scriptHash = ss.read(20) + //payload total lenght + const payloadLen = ss.readNextLen() + + //read params start + let params = [] + let nextByte = ss.readNextLen() + //params's length start from 0x50 + while(nextByte < 0x50) { + let p = ss.read(nextByte) + params.push(p) + nextByte = ss.readNextLen() + } + //params end + let end = ss.read(1) + console.log('end :' + end) + if(end === 'c1') { + for(let i=0; i< params.length; i++) { + //TODO can only get value + this.parameters.push(new Parameter('','',params[i])) + } + } + //function name + let funNameLen = ss.readNextLen() + let func = ss.read(funNameLen) + func = hexstr2str(func) + //payload end + this.functionName = func + + } */ + + deserialize(sr: StringReader) { + // let gasLimit = Fixed64.deserialize(sr); + // const code = VmCode.deserialize(sr); + const code = sr.readNextBytes(); + // this.gasLimit = gasLimit; + this.code = code; + return this; + } +} diff --git a/src/transaction/payload/payload.ts b/src/transaction/payload/payload.ts new file mode 100644 index 0000000..cc559c3 --- /dev/null +++ b/src/transaction/payload/payload.ts @@ -0,0 +1,23 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +export default abstract class Payload { + abstract serialize(): string; + + // static can not use with abstract + abstract deserialize(ss: any): void; +} diff --git a/src/transaction/program.ts b/src/transaction/program.ts new file mode 100644 index 0000000..f264953 --- /dev/null +++ b/src/transaction/program.ts @@ -0,0 +1,263 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as elliptic from 'elliptic'; +import { sm2 } from 'sm.js'; +import BigInt from '../common/bigInt'; +import { KeyType } from '../crypto/KeyType'; +import { PublicKey } from '../crypto/PublicKey'; +import { ERROR_CODE } from '../error'; +import { num2hexstring, StringReader } from './../utils'; +import opcode from './opcode'; +// The sorting rules is as follows: +// 1. if keys have different types, then sorted by the KeyType value. +// 2. else, +// 2.1. ECDSA or SM2: +// 2.1.1. if on different curves, then sorted by the curve label. +// 2.1.2. else if x values are different, then sorted by x. +// 2.1.3. else sorted by y. +// 2.2. EdDSA: sorted by the byte sequence directly. +export function comparePublicKeys(a: PublicKey, b: PublicKey) { + if (a.algorithm !== b.algorithm) { + return a.algorithm.hex - b.algorithm.hex; + } + switch (a.algorithm) { + case KeyType.ECDSA: + const ec = new elliptic.ec(a.parameters.curve.preset); + const paKey = ec.keyFromPublic(a.key, 'hex', true); + const pbKey = ec.keyFromPublic(b.key, 'hex', true); + const pa = paKey.getPublic(); + const pb = pbKey.getPublic(); + if (pa.getX() !== pb.getX()) { + return pa.getX() - pb.getX(); + } else { + return pa.getY() - pb.getY(); + } + case KeyType.SM2: + const pka = new sm2.SM2KeyPair(); + const pkb = new sm2.SM2KeyPair(); + pka._pubFromString(a.key); + pkb._pubFromString(b.key); + if (pka.getX().toString() !== pkb.getX().toString()) { + return Number(pka.getX().toString()) - Number(pkb.getX().toString()); + } else { + return Number(pka.getY().toString()) - Number(pkb.getY().toString()); + } + case KeyType.EDDSA: + return Number(a.key) - Number(b.key); + default: + return 0; + } +} + +export function pushOpCode(op: opcode): string { + return num2hexstring(op); +} + +export function pushPubKey(pk: PublicKey): string { + const pkStr = pk.serializeHex(); + return pushBytes(pkStr); +} + +export function pushBigInt(num: number): string { + if (num === -1) { + return num2hexstring(opcode.PUSHM1); + } + if (num === 0) { + return num2hexstring(opcode.PUSH0); + } + if (num > 0 && num <= 16) { + return num2hexstring(opcode.PUSH1 - 1 + num); + } + return num2hexstring(num, 8, true); +} + +export function pushNum(num: number): string { + if ( num === 0 ) { + return pushOpCode(opcode.PUSH0); + } else if ( num <= 16 ) { + return num2hexstring(num - 1 + opcode.PUSH1); + } + const bint = new BigInt(num.toString()); + return pushBytes(bint.toHexstr()); +} + +export function pushBytes(hexstr: string): string { + let result = ''; + if (hexstr.length === 0) { + throw new Error('pushBytes error, hexstr is empty.'); + } + const len = hexstr.length / 2; + if (len <= opcode.PUSHBYTES75 + 1 - opcode.PUSHBYTES1 ) { + result += num2hexstring(len + opcode.PUSHBYTES1 - 1); + } else if (len < 0x100) { + result += num2hexstring(opcode.PUSHDATA1); + result += num2hexstring(len); + } else if (len < 0x10000) { + result += num2hexstring(opcode.PUSHDATA2); + result += num2hexstring(len, 2, true); + } else if (len < 0x100000000) { + result += num2hexstring(opcode.PUSHDATA4); + result += num2hexstring(len, 4, true); + } else { + throw ERROR_CODE.INVALID_PARAMS; + } + result += hexstr; + return result; +} + +export function programFromPubKey(pk: PublicKey): string { + let result = ''; + result += pushPubKey(pk); + result += pushOpCode(opcode.CHECKSIG); + return result; +} + +export function programFromMultiPubKey(pubkeys: PublicKey[], m: number): string { + const n = pubkeys.length; + if (!(1 <= m && m <= n && n <= 1024)) { + throw new Error('Wrong multi-sig param'); + } + // const pkStrList = pubkeys.map( (p) => p.serializeHex()); + // pkStrList.sort(); + + pubkeys.sort(comparePublicKeys); + + let result = ''; + result += pushNum(m); + + for (const pk of pubkeys) { + result += pushBytes(pk.serializeHex()); + } + result += pushNum(n); + result += pushOpCode(opcode.CHECKMULTISIG); + return result; +} + +export function programFromParams(sigs: string[]): string { + let result = ''; + sigs.sort(); + for ( const s of sigs) { + result += pushBytes(s); + } + return result; +} + +export function readOpcode(sr: StringReader) { + return parseInt(sr.read(1), 16); +} + +export function readNum(sr: StringReader) { + let code; + try { + code = readOpcode(sr); + } catch (err) { + return 0; + } + let num = code - opcode.PUSH1 + 1; + if (code === opcode.PUSH0) { + readOpcode(sr); + return 0; + } else if (1 <= num && num <= 16) { + readOpcode(sr); + return num; + } + const bint = BigInt.fromHexstr(sr.readNextBytes()); + num = parseInt(bint.value.toString(), 10); + return num; +} + +export function readBytes(sr: StringReader) { + const code = readOpcode(sr); + let keylen; + if (code === opcode.PUSHDATA4) { + keylen = sr.readUint32(); + } else if (code === opcode.PUSHDATA2) { + keylen = sr.readUint16(); + } else if (code === opcode.PUSHDATA1) { + keylen = sr.readUint8(); + } else if (code <= opcode.PUSHBYTES75 && code >= opcode.PUSHBYTES1) { + keylen = code - opcode.PUSHBYTES1 + 1; + } else { + throw new Error('unexpected opcode: ' + code); + } + return sr.read(keylen); +} + +export function readPubKey(sr: StringReader) { + const pkStr = sr.readNextBytes(); + return PublicKey.deserializeHex(new StringReader(pkStr)); +} + +export function getParamsFromProgram(hexstr: string): string[] { + const sigs = []; + const sr = new StringReader(hexstr); + while (!sr.isEmpty()) { + sigs.push(readBytes(sr)); + } + return sigs; +} + +export class ProgramInfo { + M: number; + pubKeys: PublicKey[]; +} +export function getProgramInfo(hexstr: string): ProgramInfo { + const info = new ProgramInfo(); + const end = parseInt(hexstr.substr(-2, 2), 16); + if (end === opcode.CHECKSIG) { + const sr = new StringReader(hexstr); + const pk = readPubKey(sr); + info.M = 1; + info.pubKeys = [pk]; + return info; + } else if (end === opcode.CHECKMULTISIG) { + const sr = new StringReader(hexstr); + const m = parseInt(sr.read(1), 16) - opcode.PUSH1 + 1; + const n = parseInt(hexstr.substr(-4, 2), 16) - opcode.PUSH1 + 1; + info.M = m; + info.pubKeys = []; + for (let i = 0; i < n; i++) { + const key = readPubKey(sr); + info.pubKeys.push(key); + } + // const n = readNum(sr); + return info; + } else { + throw new Error('Unsupported program.'); + } +} + +export const pushHexString = (param: string) => { + let result = ''; + const len = param.length / 2; + if (len <= opcode.PUSHBYTES75) { + result += num2hexstring(len); + } else if (len < 0x100) { + result += num2hexstring(opcode.PUSHDATA1); + result += num2hexstring(len); + } else if (len < 0x10000) { + result += num2hexstring(opcode.PUSHDATA2); + result += num2hexstring(len, 2, true); + } else { + result += num2hexstring(opcode.PUSHDATA4); + result += num2hexstring(len, 4, true); + } + result += param; + return result; +}; diff --git a/src/transaction/scriptBuilder.ts b/src/transaction/scriptBuilder.ts new file mode 100644 index 0000000..e22f0ce --- /dev/null +++ b/src/transaction/scriptBuilder.ts @@ -0,0 +1,449 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { BigNumber } from 'bignumber.js'; +import BigInt from '../common/bigInt'; +import { I128, I128FromBigInt, I128FromInt } from '../common/int128'; +import { Address } from '../crypto'; +import { ERROR_CODE } from '../error'; +import AbiFunction from '../smartcontract/abi/abiFunction'; +import { Parameter, ParameterType, ParameterTypeVal } from '../smartcontract/abi/parameter'; +import Struct from '../smartcontract/abi/struct'; +import { + // tslint:disable-next-line:max-line-length + ab2hexstring, bigIntFromBytes, hexstr2str, isHexString, num2hexstring, num2VarInt, str2hexstr, StringReader +} from '../utils'; +import opcode from './opcode'; +import { pushHexString } from './program'; + +export const pushBool = (param: boolean) => { + let result = ''; + if (param) { + result += num2hexstring(opcode.PUSHT); + } else { + result += num2hexstring(opcode.PUSHF); + } + return result; +}; + +export const pushInt = (param: number, ledgerCompatible: boolean = true) => { + let result = ''; + if (param === -1) { + result = num2hexstring(opcode.PUSHM1); + } else if (param === 0) { + result = num2hexstring(opcode.PUSH0); + } else if (param > 0 && param < 16) { + const num = opcode.PUSH1 - 1 + param; + result = num2hexstring(num); + } else { + const biHex = new BigInt(param.toString(), ledgerCompatible).toHexstr(); + result = pushHexString(biHex); + } + + return result; +}; + +export const pushBigNum = (param: BigNumber, ledgerCompatible: boolean = true) => { + let result = ''; + if (param.isEqualTo(-1)) { + result = num2hexstring(opcode.PUSHM1); + } else if (param.isEqualTo(0)) { + result = num2hexstring(opcode.PUSH0); + } else if (param.isGreaterThan(0) && param.isLessThan(16)) { + const num = opcode.PUSH1 - 1 + param.toNumber(); + result = num2hexstring(num); + } else { + const biHex = new BigInt(param.toString(), ledgerCompatible).toHexstr(); + result = pushHexString(biHex); + } + return result; +}; + +export const getStructBytes = (val: Struct) => { + let result = ''; + result += num2hexstring(ParameterTypeVal.Struct); + result += num2hexstring(val.list.length); // val is array-like + for (const v of val.list) { + if (typeof v === 'string') {// consider as hex string + result += num2hexstring(ParameterTypeVal.ByteArray); + result += pushHexString(v); + } else if (typeof v === 'number') { + result += num2hexstring(ParameterTypeVal.ByteArray); + result += pushHexString(num2VarInt(v)); + } else { + throw ERROR_CODE.INVALID_PARAMS; + } + } + return result; +}; + +export const getMapBytes = (val: Map) => { + let result = ''; + result += num2hexstring(ParameterTypeVal.Map); + result += num2hexstring(val.size); + for (const k of val.keys()) { + result += num2hexstring(ParameterTypeVal.ByteArray); + result += pushHexString(str2hexstr(k)); + const p = val.get(k); + if (p && p.getType() === ParameterType.ByteArray) { + result += num2hexstring(ParameterTypeVal.ByteArray); + result += pushHexString(p.getValue()); + } else if (p && p.getType() === ParameterType.String) { + result += num2hexstring(ParameterTypeVal.ByteArray); + result += pushHexString(str2hexstr(p.getValue())); + } else if (p && p.getType() === ParameterType.Integer) { + result += num2hexstring(ParameterTypeVal.Integer); + result += pushHexString(num2VarInt(p.getValue())); + } else if (p && p.getType() === ParameterType.Long) { + result += num2hexstring(ParameterTypeVal.Integer); + result += pushHexString(num2VarInt(p.getValue())); + } else { + throw ERROR_CODE.INVALID_PARAMS; + } + } + return result; +}; + +export const pushMap = (val: Map, ledgerCompatible: boolean) => { + let result = ''; + result += num2hexstring(opcode.NEWMAP); + result += num2hexstring(opcode.TOALTSTACK); + for (const k of val.keys()) { + result += num2hexstring(opcode.DUPFROMALTSTACK); + result += pushHexString(str2hexstr(k)); + result += pushParam(val.get(k), ledgerCompatible); + result += num2hexstring(opcode.SETITEM); + } + result += num2hexstring(opcode.FROMALTSTACK); + return result; +}; + +export const pushParam = (p: any, ledgerCompatible: boolean) => { + if (!p) { + throw Error('Parameter can not be undefined'); + } + let result = ''; + if (p.type === ParameterType.ByteArray) { + result += pushHexString(p.value); + } else if (p.type === ParameterType.Address) { + result += pushHexString(p.value.serialize()); + } else if (p.type === ParameterType.String) { + result += pushHexString(str2hexstr(p.value)); + } else if (p.type === ParameterType.Boolean) { + result += pushBool(Boolean(p.value)); + result += num2hexstring(opcode.PUSH0); + result += num2hexstring(opcode.BOOLOR); + } else if (p.type === ParameterType.Map) { + result += pushMap(convertMap(p), ledgerCompatible); + } else if (p instanceof Map) { + result += pushMap(p, ledgerCompatible); + } else if (p.type === ParameterType.Array) { + for (let i = p.value.length - 1; i > -1; i--) { + result += pushParam(p.value[i], ledgerCompatible); + } + result += pushInt(p.value.length, ledgerCompatible); + result += num2hexstring(opcode.PACK); + } else if (p.type === ParameterType.Integer) { + result += pushInt(p.value, ledgerCompatible); + result += num2hexstring(opcode.PUSH0); + result += num2hexstring(opcode.ADD); + } else if (p.type === ParameterType.Long) { + result += pushBigNum(new BigNumber(p.value), ledgerCompatible); + result += num2hexstring(opcode.PUSH0); + result += num2hexstring(opcode.ADD); + } else { + throw Error('Invalid parameter type: ' + JSON.stringify(p)); + } + return result; +}; + +export const serializeAbiFunction = (abiFunction: AbiFunction, ledgerCompatible: boolean = true) => { + const list = []; + list.push(str2hexstr(abiFunction.name)); + const tmp = []; + for (const p of abiFunction.parameters) { + if (p.getType() === ParameterType.String) { + tmp.push(str2hexstr(p.getValue())); + } else if (p.getType() === ParameterType.Long) { + tmp.push(new BigNumber(p.getValue())); + } else if (p.getType() === ParameterType.Map) { + tmp.push(convertMap(p)); + } else if (p.getType() === ParameterType.Address) { + tmp.push(p.getValue().serialize()); + } else { + tmp.push(p.getValue()); + } + } + if (list.length > 0) { + list.push(tmp); + } + const result = createCodeParamsScript(list, ledgerCompatible); + return result; +}; + +export function convertArray(list: Parameter[]): any { + const tmp = []; + for (const p of list) { + if (p.getType && p.getType() === ParameterType.String) { + tmp.push(str2hexstr(p.getValue())); + } else if (p.getType && p.getType() === ParameterType.Long) { + tmp.push(new BigNumber(p.getValue())); + } else if (p.getType && p.getType() === ParameterType.Array) { + tmp.push(convertArray(p.value)); + } else if (p.getType && p.getType() === ParameterType.Map) { + tmp.push(convertMap(p)); + } else if (p.getType && p.getType() === ParameterType.Address) { + tmp.push(p.getValue().serialize()); + } else { + tmp.push(p.getValue ? p.getValue() : p); + } + } + return tmp; +} + +export function convertMap(p: Parameter): any { + const map = new Map(); + for (const k of Object.keys(p.value)) { + const pVal = p.value[k]; + // map.set(k, pVal); + if (pVal.type && pVal.type === ParameterType.Map) { + map.set(k, convertMap(pVal)); + } else { + map.set(k, pVal); + } + } + return map; +} + +/** + * To deserialize the value return from smart contract invoke. + * @param hexstr + */ +export function deserializeItem(sr: StringReader): any { + const t = parseInt(sr.read(1), 16); + if ( t === ParameterTypeVal.ByteArray) { + return sr.readNextBytes(); + } else if (t === ParameterTypeVal.Boolean) { + return sr.readBoolean(); + } else if (t === ParameterTypeVal.Integer) { + const v = bigIntFromBytes(sr.readNextBytes()).toNumber(); + return v; + } else if (t === ParameterTypeVal.Array || t === ParameterTypeVal.Struct ) { + const length = sr.readNextLen(); + const list = []; + for (let i = length; i > 0; i--) { + const ele = deserializeItem(sr); + list.push(ele); + } + return list; + } else if (t === ParameterTypeVal.Map ) { + const length = sr.readNextLen(); + const map = new Map(); + for (let i = length; i > 0; i--) { + const key = hexstr2str(deserializeItem(sr)); + const value = deserializeItem(sr); + map.set(key, value); + } + return map; + } else { + throw Error('Invalid parameter type: ' + t); + } +} + +export const createCodeParamsScript = (list: any[], ledgerCompatible: boolean = true) => { + let result = ''; + for (let i = list.length - 1; i >= 0; i--) { + const val = list[i]; + if (typeof val === 'string') { + result += pushHexString(val); + } else if (typeof val === 'number') { + result += pushInt(val, ledgerCompatible); + } else if (typeof val === 'boolean') { + result += pushBool(val); + } else if (val instanceof BigNumber) { + result += pushBigNum(val, ledgerCompatible); + } else if (val instanceof Map) { + result += pushMap(val, ledgerCompatible); + // const mapBytes = getMapBytes(val); + // result += pushHexString(mapBytes); + } else if (val instanceof Struct) { + const structBytes = getStructBytes(val); + result += pushHexString(structBytes); + } else if (val instanceof Array) { + result += createCodeParamsScript(convertArray(val), ledgerCompatible); + result += pushInt(val.length, ledgerCompatible); + result += num2hexstring(opcode.PACK); + } + } + return result; +}; + +// deprecated +export const buildSmartContractParam = (functionName: string, params: Parameter[]) => { + let result = ''; + for (let i = params.length - 1; i > -1; i--) { + const type = params[i].getType(); + switch (type) { + case ParameterType.Boolean: + result += pushBool(params[i].getValue()); + break; + + case ParameterType.Integer: + result += pushInt(params[i].getValue()); + break; + + case ParameterType.String: + const value = str2hexstr(params[i].getValue()); + result += pushHexString(value); + break; + + case ParameterType.ByteArray: + result += pushHexString(params[i].getValue()); + break; + + case ParameterType.Map: + const mapBytes = getMapBytes(params[i].getValue()); + result += pushHexString(mapBytes); + break; + + case ParameterType.Struct: + const structBytes = getStructBytes(params[i].getValue()); + result += pushHexString(structBytes); + break; + // case ParameterType.Array: + // result += buildSmartContractParam(params[i].getValue()); + // result += pushInt(params[i].getValue().length); + // result += num2hexstring(opcode.PACK); + // break; + default: + throw new Error('Unsupported param type: ' + JSON.stringify(params[i])); + } + } + + result += pushInt(params.length); + result += num2hexstring(opcode.PACK); + + result += pushHexString(str2hexstr(functionName)); + + return result; +}; + +export function buildWasmContractParam(params: Parameter[]): string { + let result = ''; + + for (const p of params) { + const type = p.getType(); + + switch (type) { + case ParameterType.String: + result += writeString(p.value); + break; + case ParameterType.Int: + result += I128FromInt(p.value).serialize(); + break; + case ParameterType.Long: + result += I128FromBigInt(p.value).serialize(); + break; + case ParameterType.ByteArray: + result += writeVarBytes(p.value); + break; + case ParameterType.Address: + result += writeAddress(p.value); + break; + case ParameterType.Boolean: + result += writeBool(p.value); + break; + case ParameterType.Array: + result += writeVarUint(p.value.length); + result += buildWasmContractParam(p.value); + break; + default: + throw new Error(`Not a supported type: ${p.type}`); + } + } + + return result; +} + +export function writeUint16(data: number): string { + return num2hexstring(data, 2, true); +} + +export function writeUint32(data: number): string { + return num2hexstring(data, 4, true); +} + +export function writeUint64(data: number): string { + return num2hexstring(data, 8, true); +} + +// data is hexstring; +export function writeVarBytes(data: string): string { + if (!isHexString(data)) { + throw new Error('[writeVarBytes] The param is not hex string.'); + } + let result = ''; + result += num2VarInt(data.length / 2); + result += data; + return result; +} + +export function writeString(data: string): string { + return writeVarBytes(str2hexstr(data)); +} + +export function writeAddress(data: Address): string { + return data.serialize(); +} + +export function writeI128(data: I128): string { + return data.serialize(); +} + +export function writeBool(data: boolean): string { + if (data) { + return '01'; + } else { + return '00'; + } +} + +export function writeVarUint(data: number): string { + const buf = []; + if (data < 0xFD) { + buf[0] = data; + } else if (data <= 0xFFFF) { + buf[0] = 0xFD; + putLittleEndianUint(buf, 1, 2, data); + } else if (data <= 0xFFFFFFFF) { + buf[0] = 0xFE; + putLittleEndianUint(buf, 1, 4, data); + } else { + buf[0] = 0xFF; + putLittleEndianUint(buf, 1, 8, data); + } + return ab2hexstring(buf); +} + +function putLittleEndianUint(buf: number[], start: number, size: number, data: number) { + buf[start] = data; + for (let i = start + 1; i <= size; i++) { + data = data >> (8 * (i - 1)); + buf[i] = data & 0xFF; + } +} diff --git a/src/transaction/transaction.ts b/src/transaction/transaction.ts new file mode 100644 index 0000000..cdb1459 --- /dev/null +++ b/src/transaction/transaction.ts @@ -0,0 +1,255 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import * as cryptoJS from 'crypto-js'; +import Fixed64 from '../common/fixed64'; +import { Address } from '../crypto/address'; +import { Signable } from '../crypto/signable'; +import { ab2hexstring, generateRandomArray, num2hexstring, StringReader } from '../utils'; +import DeployCode from './payload/deployCode'; +import InvokeCode from './payload/invokeCode'; +import Payload from './payload/payload'; +import { TransactionAttribute } from './txAttribute'; +import { TxSignature } from './txSignature'; + +export enum TxType { + BookKeeper = 0x02, + Claim = 0x03, + Deploy = 0xd0, + Invoke = 0xd1, + Enrollment = 0x04, + Vote = 0x05, + InvokeWasm = 0xd2 +} + +export const TxName = { + BookKeeper: 'BookKeeper', + Claim: 'Claim', + Deploy: 'Deploy', + Invoke: 'Invoke', + Enrollment: 'Enrollment', + Vote: 'Vote' +}; + +/** + * @deprecated. Transaction fee. + */ +export class Fee { + static deserialize(sr: StringReader): Fee { + const fee = new Fee(); + const amount = Fixed64.deserialize(sr); + const payer = sr.read(20); + fee.amount = amount; + fee.payer = new Address(payer); + return fee; + } + + amount: Fixed64; + + // 20 bytes address + payer: Address; + + serialize(): string { + let result = ''; + result += this.amount.serialize(); + result += this.payer.serialize(); + return result; + } +} + +export class Transaction implements Signable { + static deserialize(hexstring: string): Transaction { + const tx = new Transaction(); + + // console.log(' hexstring' + hexstring) + const ss = new StringReader(hexstring); + + tx.version = parseInt(ss.read(1), 16); + tx.type = parseInt(ss.read(1), 16); + tx.nonce = ss.read(4); + tx.gasPrice = Fixed64.deserialize(ss); + tx.gasLimit = Fixed64.deserialize(ss); + tx.payer = new Address(ss.read(20)); + let payload; + + switch (tx.type) { + case TxType.Invoke : + payload = new InvokeCode(); + break; + case TxType.Deploy: + payload = new DeployCode(); + break; + default : + payload = new InvokeCode(); + } + payload.deserialize(ss); + tx.payload = payload; + tx.txAttributes = []; + tx.sigs = []; + + const attributeLength = ss.readNextLen(); + for (let i = 0; i < attributeLength; i++) { + const txAttribute = new TransactionAttribute(); + txAttribute.deserialize(ss); + tx.txAttributes.push(txAttribute); + } + + const sigLength = ss.readNextLen(); + for (let i = 0; i < sigLength; i++) { + tx.sigs.push(TxSignature.deserialize(ss)); + } + + return tx; + } + + /** + * Transaction type + */ + type: TxType = 0xd1; + + /** + * Version of transaction + */ + version: number = 0x00; + + /** + * Payload of transaction + */ + payload: Payload; + + /** + * Random hex string. 4 bytes. + */ + nonce: string; + + /** + * @deprecated + */ + txAttributes: TransactionAttribute[] = []; + + /** + * Gas price + */ + gasPrice: Fixed64; + + /** + * Gas limit + */ + gasLimit: Fixed64; + + /** + * Address to pay for gas + */ + payer: Address; + + /** + * Array of signatures + */ + sigs: TxSignature[] = []; + + constructor() { + this.nonce = ab2hexstring(generateRandomArray(4)); + this.gasPrice = new Fixed64(); + + // const limit = num2hexstring(DEFAULT_GAS_LIMIT, 8, true); + + this.gasLimit = new Fixed64(); + this.payer = new Address('0000000000000000000000000000000000000000'); + } + + /** + * Serialize transaction to hex string + * The result is used to send to blockchain. + */ + serialize(): string { + const unsigned = this.serializeUnsignedData(); + const signed = this.serializeSignedData(); + + return unsigned + signed; + } + + /** + * Serialize transaction data exclueds signatures + */ + serializeUnsignedData() { + let result = ''; + result += num2hexstring(this.version); + result += num2hexstring(this.type); + + // nonce 4bytes + result += this.nonce; + result += this.gasPrice.serialize(); + result += this.gasLimit.serialize(); + result += this.payer.serialize(); + result += this.payload.serialize(); + + // serialize transaction attributes + result += num2hexstring(this.txAttributes.length); + // tslint:disable-next-line:prefer-for-of + for (let i = 0; i < this.txAttributes.length; i++) { + result += this.txAttributes[i].serialize(); + } + // result += num2hexstring(this.fee.length) + // for (let i=0 ; i< this.fee.length; i++) { + // result += this.fee[i].amount.serialize() + // result += this.fee[i].payer.serialize() + // } + + // if(this.networkFee) { + // result += this.networkFee.serialize() + // } + + return result; + } + + /** + * Serialize signatures + */ + serializeSignedData() { + let result = ''; + // programs + result += num2hexstring(this.sigs.length); + // tslint:disable-next-line:prefer-for-of + for (let i = 0; i < this.sigs.length; i++) { + result += this.sigs[i].serialize(); + } + + return result; + } + + /** + * Get the signable content + */ + getSignContent() { + const data = this.serializeUnsignedData(); + + const ProgramHexString = cryptoJS.enc.Hex.parse(data); + const ProgramSha256 = cryptoJS.SHA256(ProgramHexString).toString(); + const ProgramSha2562 = cryptoJS.SHA256(cryptoJS.enc.Hex.parse(ProgramSha256)).toString(); + + return ProgramSha2562; + } + + /** + * Get the hash of transaction + * @deprecated Use getSignContent instead + */ + getHash() { + return this.getSignContent(); + } +} diff --git a/src/transaction/transactionBuilder.ts b/src/transaction/transactionBuilder.ts new file mode 100644 index 0000000..91e2ef8 --- /dev/null +++ b/src/transaction/transactionBuilder.ts @@ -0,0 +1,534 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import Fixed64 from '../common/fixed64'; +import { REST_API, TX_MAX_SIG_SIZE } from '../consts'; +import { Address, PrivateKey, SignatureScheme } from '../crypto'; +import { PublicKey } from '../crypto/PublicKey'; +import { ERROR_CODE } from '../error'; +import AbiFunction from '../smartcontract/abi/abiFunction'; +import { Parameter } from '../smartcontract/abi/parameter'; + +import { + num2hexstring, + reverseHex, + str2hexstr +} from '../utils'; +import { ParameterType } from './../smartcontract/abi/parameter'; +import opcode from './opcode'; +import DeployCode from './payload/deployCode'; +import InvokeCode from './payload/invokeCode'; +import { comparePublicKeys } from './program'; +import { buildWasmContractParam, createCodeParamsScript, serializeAbiFunction, writeVarBytes } from './scriptBuilder'; +import { Transaction, TxType } from './transaction'; + +import { makeTransferTx } from '../smartcontract/nativevm/assetTxBuilder'; +import { buildGetDDOTx, buildRegisterDNAidTx } from '../smartcontract/nativevm/idContractTxBuilder'; +import { VmType } from './payload/deployCode'; +import { TxSignature } from './txSignature'; + +// tslint:disable-next-line:variable-name +export const Default_params = { + Action: 'sendrawtransaction', + Version: '1.0.0', + Type: '', + Op: 'test' +}; + +/** + * Signs the transaction object. + * + * If there is already a signature, the new one will replace existing. + * If the signature schema is not provided, default schema for Private key type is used. + * + * @param tx Transaction to sign + * @param privateKey Private key to sign with + * @param schema Signature Schema to use + */ +export const signTransaction = (tx: Transaction, privateKey: PrivateKey, schema?: SignatureScheme) => { + const signature = TxSignature.create(tx, privateKey, schema); + + tx.sigs = [signature]; +}; + +/** + * Signs the transaction object asynchroniously. + * + * If there is already a signature, the new one will replace existing. + * If the signature schema is not provided, default schema for Private key type is used. + * + * @param tx Transaction to sign + * @param privateKey Private key to sign with + * @param schema Signature Schema to use + */ +export const signTransactionAsync = async (tx: Transaction, privateKey: PrivateKey, schema?: SignatureScheme) => { + const signature = await TxSignature.createAsync(tx, privateKey, schema); + + tx.sigs = [signature]; +}; + +/** + * Signs the transaction object. + * + * If there is already a signature, the new one will be added to the end. + * If the signature schema is not provided, default schema for Private key type is used. + * + * @param tx Transaction to sign + * @param privateKey Private key to sign with + * @param schema Signature Schema to use + */ +export const addSign = (tx: Transaction, privateKey: PrivateKey, schema?: SignatureScheme) => { + const signature = TxSignature.create(tx, privateKey, schema); + + tx.sigs.push(signature); +}; + +const equalPks = (pks1: PublicKey[], pks2: PublicKey[]): boolean => { + if (pks1 === pks2) { + return true; + } + pks1.sort(comparePublicKeys); + pks2.sort(comparePublicKeys); + if (pks1.length !== pks2.length) { + return false; + } + for (let i = 0; i < pks1.length ; i++) { + if (pks1[i].key !== pks2[i].key) { + return false; + } + } + return true; +}; + +/** + * Signs the transaction with multiple signatures with multi-sign keys. + * + * If there is already a signature, the new ones will be added to the end. + * If the signature schema is not provided, default schema for Private key type is used. + * + * @param tx Transaction to sign + * @param M m of the (m ,n) multi sign address threshold + * @param pubKeys Array of Public keys of (m,n) multi sign address, the number is n + * @param privateKey Private key to sign the tx. + * @param scheme Signature scheme to use + */ +export const signTx = (tx: Transaction, M: number, pubKeys: PublicKey[], + privateKey: PrivateKey, scheme?: SignatureScheme) => { + + if (tx.sigs.length === 0) { + tx.sigs = []; + } else { + if (tx.sigs.length > TX_MAX_SIG_SIZE || M > pubKeys.length || M <= 0 || pubKeys.length === 0) { + throw ERROR_CODE.INVALID_PARAMS; + } + // tslint:disable-next-line:prefer-for-of + for (let i = 0; i < tx.sigs.length; i++) { + if (equalPks(tx.sigs[i].pubKeys, pubKeys)) { + if (tx.sigs[i].sigData.length + 1 > pubKeys.length) { + throw new Error('Too many sigData'); + } + const signData = privateKey.sign(tx, scheme).serializeHex(); + tx.sigs[i].sigData.push(signData); + return; + } + } + } + const sig = new TxSignature(); + sig.M = M; + sig.pubKeys = pubKeys; + sig.sigData = [privateKey.sign(tx, scheme).serializeHex()]; + tx.sigs.push(sig); +}; + +/** + * Creates transaction to inovke smart contract + * @param funcName Function name of smart contract + * @param params Array of Parameters or serialized parameters + * @param contractAddr Address of contract + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Address to pay for gas + */ +export const makeInvokeTransaction = ( + funcName: string, + params: Parameter[] | string, + contractAddr: Address, + gasPrice?: string, + gasLimit?: string, + payer?: Address, + ledgerCompatible: boolean = true +) => { + const tx = new Transaction(); + tx.type = TxType.Invoke; + + let args = ''; + if (typeof params === 'string') { + args = params; + } else { + const abiFunc = new AbiFunction(funcName, '', params); + args = serializeAbiFunction(abiFunc, ledgerCompatible); + } + + let code = args + num2hexstring(opcode.APPCALL); + code += contractAddr.serialize(); + + const payload = new InvokeCode(); + payload.code = code; + tx.payload = payload; + + if (gasLimit) { + tx.gasLimit = new Fixed64(gasLimit); + } + if (gasPrice) { + tx.gasPrice = new Fixed64(gasPrice); + } + if (payer) { + tx.payer = payer; + } + return tx; +}; + +export function buildWasmVmInvokeCode(contractaddress: Address, params: Parameter[]): string { + let result = ''; + result += contractaddress.serialize(); + const args = buildWasmContractParam(params); + result += writeVarBytes(args); + return result; +} + +/** + * Creates transaction to inovke wasm vm smart contract + * @param funcName Function name of smart contract + * @param params Array of Parameters or serialized parameters + * @param contractAddress Address of contract + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Address to pay for gas + */ +export function makeWasmVmInvokeTransaction( + funcName: string, + params: Parameter[], + contractAddress: Address, + gasPrice: string, + gasLimit: string, + payer?: Address +): Transaction { + const tx = new Transaction(); + tx.type = TxType.InvokeWasm; + + const paramFunc = new Parameter('method', ParameterType.String, funcName); + const paramsAll = [paramFunc, ...params]; + const code = buildWasmVmInvokeCode(contractAddress, paramsAll); + const payload = new InvokeCode(); + payload.code = code; + tx.payload = payload; + + if (gasLimit) { + tx.gasLimit = new Fixed64(gasLimit); + } + if (gasPrice) { + tx.gasPrice = new Fixed64(gasPrice); + } + if (payer) { + tx.payer = payer; + } + return tx; +} + +/** + * Creates transaction to deploy smart contract + * @param code Avm code of contract to deploy + * @param name Name of contract + * @param codeVersion version of contract + * @param author Author of contract + * @param email Email of author + * @param desp Description of contract + * @param vmType Decides the vm type + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Address to pay for gas + */ +export function makeDeployCodeTransaction( + code: string, + name: string= '', + codeVersion: string= '1.0', + author: string= '', + email: string= '', + desp: string= '', vmType: VmType | boolean, gasPrice: string, gasLimit: string, payer?: Address) { + const dc = new DeployCode(); + dc.author = author; + // const vmCode = new VmCode(); + // vmCode.code = code; + // vmCode.vmType = vmType; + // dc.code = vmCode; + dc.code = code; + dc.version = codeVersion; + dc.description = desp; + dc.email = email; + dc.name = name; + if (typeof vmType === 'boolean') { // to be compatible with old api + dc.vmType = VmType.NEOVM_TYPE; + } else { + dc.vmType = vmType; + } + + const tx = new Transaction(); + tx.version = 0x00; + + tx.payload = dc; + + tx.type = TxType.Deploy; + // gas + // if (DEFAULT_GAS_LIMIT === Number(0)) { + // tx.gasPrice = new Fixed64(); + // } else { + // const price = new BigNumber(gas).multipliedBy(1e9).dividedBy(new BigNumber(DEFAULT_GAS_LIMIT)).toString(); + // tx.gasPrice = new Fixed64(price); + // } + tx.gasLimit = new Fixed64(gasLimit); + tx.gasPrice = new Fixed64(gasPrice); + if (payer) { + tx.payer = payer; + } + + return tx; + +} + +/** + * @deprecated + * Creates params from transaction to send with websocket + * @param tx Transactio to send + * @param isPreExec Decides if it is pre-execute transaction + */ +export function buildTxParam(tx: Transaction, isPreExec: boolean = false) { + const op = isPreExec ? { PreExec: '1'} : {}; + const serialized = tx.serialize(); + + return JSON.stringify(Object.assign({}, Default_params, { Data: serialized }, op)); +} + +/** + * @deprecated + * Creates params from transaction to send with rpc + * @param tx Transaction + * @param method Method name + */ +export function buildRpcParam(tx: Transaction, method?: string) { + const param = tx.serialize(); + const result = { + jsonrpc: '2.0', + method: method || 'sendrawtransaction', + params: [param], + id: 10 + }; + return result; +} + +/** + * @deprecated + * Creates params from transaction to send with restful + * @param tx Transaction + */ +export function buildRestfulParam(tx: Transaction) { + const param = tx.serialize(); + return { + Action : 'sendrawtransaction', + Version : '1.0.0', + Data : param + }; +} + +/** + * @deprecated + * @param url Url of blochchain node + * @param preExec Decides if is a pre-execute request + */ +export function sendRawTxRestfulUrl(url: string, preExec: boolean = false) { + if (url.charAt(url.length - 1) === '/') { + url = url.substring(0, url.length - 1); + } + + let restUrl = url + REST_API.sendRawTx; + if (preExec) { + restUrl += '?preExec=1'; + } + + return restUrl; +} + +export function transferStringParameter(value: string): Parameter { + const strs = value.split(':'); + if (strs.length < 2) { + throw new Error('Invalid parameter. ' + value); + } + const pType = value.substring(0, value.indexOf(':')); + const pVal = value.substring(value.indexOf(':') + 1); + const p = new Parameter('', pType as ParameterType, pVal); + if (p.type === ParameterType.Address) { + p.type = ParameterType.ByteArray; + p.value = new Address(p.value).serialize(); + } + return p; +} + +export function transformMapParameter(value: any) { + const map: any = {}; + for (const k of Object.keys(value)) { + const v = value[k]; + if (typeof v === 'number') { + map[k] = new Parameter('', ParameterType.Integer, v); + } else if (typeof v === 'boolean') { + map[k] = new Parameter('', ParameterType.Boolean, v); + } else if (Array.isArray(v)) { + map[k] = new Parameter('', ParameterType.Array, transformArrayParameter(v)); + } else if (typeof v === 'object') { + map[k] = new Parameter('', ParameterType.Map, transformMapParameter(v)); + } else if (typeof v === 'string') { + map[k] = transferStringParameter(v); + } + } + return map; +} + +export function transformArrayParameter(val: any) { + const list = []; + for (const v of val) { + let p = new Parameter('', ParameterType.ByteArray, v); + if (typeof v === 'number') { + p.type = ParameterType.Integer; + } else if (typeof v === 'boolean') { + p.type = ParameterType.Boolean; + } else if (Array.isArray(v)) { + p.type = ParameterType.Array; + p.value = transformArrayParameter(v); + } else if (typeof v === 'object') { + p.type = ParameterType.Map; + p.value = transformMapParameter(v); + } else if (typeof v === 'string') { + p = transferStringParameter(v); + } + list.push(p); + } + return list; +} + +export function transformParameter(arg: any) { + const name = arg.name; + const value = arg.value; + let p = new Parameter(name, ParameterType.ByteArray, value); + if (typeof value === 'number') { + p.type = ParameterType.Integer; + p.value = Number(value); + } else if (typeof value === 'boolean') { + p.type = ParameterType.Boolean; + p.value = Boolean(value); + } else if (Array.isArray(value)) { + p.type = ParameterType.Array; + p.value = transformArrayParameter(value); + } else if (typeof value === 'object') { + p.type = ParameterType.Map; + p.value = transformMapParameter(value); + } else if (typeof value === 'string') { + p = transferStringParameter(value); + } + return p; +} + +export function buildParamsByJson(json: any) { + const paramsList = []; + const functions = json.functions; + for (const obj of functions) { + const { operation, args } = obj; + const list = []; + list.push(str2hexstr(operation)); + const temp = []; + for (const arg of args) { + temp.push(transformParameter(arg)); + } + list.push(temp); + paramsList.push(list); + } + return paramsList; +} + +export function makeTransactionsByJson(json: any, ledgerCompatible: boolean = true) { + if (!json) { + throw new Error('Invalid parameter. Expect JSON object'); + } + if (!json.action || + (json.action !== 'invoke' && + json.action !== 'invokeRead' && + json.action !== 'invokePasswordFree')) { + throw new Error('Invalid parameter. The action type must be "invoke or invokeRead"'); + } + if (!json.params || !json.params.invokeConfig) { + throw new Error('Invalid parameter. The params can not be empty.'); + } + const invokeConfig = json.params.invokeConfig; + // tslint:disable-next-line:prefer-const + let { payer, gasPrice, gasLimit, contractHash } = invokeConfig; + if (!contractHash) { + throw new Error('Invalid parameter. The contractHash can not be empty.'); + } + const contractAddr = new Address(reverseHex(contractHash)); + payer = payer ? new Address(payer) : null; + gasPrice = gasPrice + '' || '500'; + gasLimit = gasLimit + '' || '200000'; + const txList = []; + if (contractHash.indexOf('00000000000000000000000000000000000000') > -1) { // native contract + const tx = buildNativeTxFromJson(invokeConfig); + txList.push(tx); + } else { + const parameters = buildParamsByJson(invokeConfig); + for (const list of parameters) { + const params = createCodeParamsScript(list, ledgerCompatible); + const tx = makeInvokeTransaction('', params, contractAddr, gasPrice, gasLimit, payer, ledgerCompatible); + txList.push(tx); + } + } + + return txList; +} + +export function buildNativeTxFromJson(json: any) { + const funcArgs = json.functions[0]; + const args = funcArgs.args; + if (json.contractHash.indexOf('02') > -1 || json.contractHash.indexOf('01') > -1) { // DNA ONG contract + const tokenType = json.contractHash.indexOf('02') > -1 ? 'ONG' : 'DNA'; + if (funcArgs.operation === 'transfer') { + const from = new Address(args[0].value.split(':')[1]); + const to = new Address(args[1].value.split(':')[1]); + const amount = args[2].value.split(':')[1] + ''; // convert to string + const payer = new Address(json.payer); + const tx = makeTransferTx(tokenType, from, to, amount, json.gasPrice, json.gasLimit, payer); + return tx; + } + } else if (json.contractHash.indexOf('03') > -1) { // DNA ID contract + if (funcArgs.operation === 'regIDWithPublicKey') { + const dnaid = args[0].value.substr(args[0].value.indexOf(':') + 1); + const pk = new PublicKey(args[1].value.split(':')[1]); + const payer = new Address(json.payer); + const tx = buildRegisterDNAidTx(dnaid, pk, json.gasPrice, json.gasLimit, payer); + return tx; + } else if (funcArgs.operation === 'getDDO') { + const dnaid = args[0].value.substr(args[0].value.indexOf(':') + 1); + const tx = buildGetDDOTx(dnaid); + return tx; + } + } +} diff --git a/src/transaction/transactionUtils.ts b/src/transaction/transactionUtils.ts new file mode 100644 index 0000000..e9d666a --- /dev/null +++ b/src/transaction/transactionUtils.ts @@ -0,0 +1,59 @@ + +import Fixed64 from '../common/fixed64'; +import { NATIVE_INVOKE_NAME, VERSION_CONTRACT_GAS } from '../consts'; +import { Address } from '../crypto'; +import { num2hexstring, str2hexstr } from '../utils'; +import OPCODE from './opcode'; +import InvokeCode from './payload/invokeCode'; +import { pushHexString } from './program'; +import { pushInt } from './scriptBuilder'; +import { Transaction, TxType } from './transaction'; +import { Transfer } from './transfer'; + +/** + * Creates transaction to invoke native contract + * @param funcName Function name of contract to call + * @param params Parameters serialized in hex string + * @param contractAddr Adderss of contract + * @param gasPrice Gas price + * @param gasLimit Gas limit + * @param payer Address to pay for transaction gas + */ +export function makeNativeContractTx( + funcName: string, + params: string, + contractAddr: Address, + gasPrice?: string, + gasLimit?: string, + payer?: Address +) { + let code = ''; + code += params; + code += pushHexString(str2hexstr(funcName)); + code += pushHexString(contractAddr.serialize()); + code += pushInt(VERSION_CONTRACT_GAS); + code += num2hexstring(OPCODE.SYSCALL); + code += pushHexString(str2hexstr(NATIVE_INVOKE_NAME)); + const payload = new InvokeCode(); + payload.code = code; + + let tx: Transaction; + if (funcName === 'transfer' || funcName === 'transferFrom') { + tx = new Transfer(); + } else { + tx = new Transaction(); + } + + tx.type = TxType.Invoke; + tx.payload = payload; + if (gasLimit) { + tx.gasLimit = new Fixed64(gasLimit); + } + if (gasPrice) { + tx.gasPrice = new Fixed64(gasPrice); + } + if (payer) { + tx.payer = payer; + } + return tx; +} diff --git a/src/transaction/transfer.ts b/src/transaction/transfer.ts new file mode 100644 index 0000000..469c770 --- /dev/null +++ b/src/transaction/transfer.ts @@ -0,0 +1,27 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { Address } from '../crypto/address'; +import { Transaction } from './transaction'; + +export class Transfer extends Transaction { + amount: number | string; + tokenType: string; + from: Address; + to: Address; + method: string; +} diff --git a/src/transaction/txAttribute.ts b/src/transaction/txAttribute.ts new file mode 100644 index 0000000..400176b --- /dev/null +++ b/src/transaction/txAttribute.ts @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { ERROR_CODE } from '../error'; +import { hex2VarBytes, num2hexstring, StringReader } from '../utils'; + +export enum TransactionAttributeUsage { + Nonce = 0x00, + Script = 0x20, + DescriptionUrl = 0x81, + Description = 0x90 +} + +/** + * @deprecated + * TransactionAttribute + * @property {number} usage - Identifying byte + * @property {string} data - Data + */ +export class TransactionAttribute { + usage: TransactionAttributeUsage; + // hexstring + data: string; + + serialize(): string { + let result = ''; + result += num2hexstring(this.usage); + if (this.usage === TransactionAttributeUsage.Script) { + result += this.data; + } else if (this.usage === TransactionAttributeUsage.DescriptionUrl + || this.usage === TransactionAttributeUsage.Description + || this.usage === TransactionAttributeUsage.Nonce) { + result += hex2VarBytes(this.data); + } else { + throw ERROR_CODE.INVALID_PARAMS; + } + + return result; + } + + deserialize(ss: StringReader): void { + // usage + const usage = parseInt(ss.read(1), 16); + // nonce + // const nonce = ss.read(8); + // get hash with publicKey; + const dataLen = ss.readNextLen(); + const data = ss.read(dataLen); + this.usage = usage; + // this.nonce = nonce; + this.data = data; + } +} diff --git a/src/transaction/txSender.ts b/src/transaction/txSender.ts new file mode 100644 index 0000000..a0d46ce --- /dev/null +++ b/src/transaction/txSender.ts @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import * as Html5WebSocket from '@ont-community/html5-websocket'; +import { TEST_DNA_URL } from '../consts'; + +/** + * We can import html5-websocket directly, because webpack will use html5-websocket/browser.js + * in browser environment, which does not require 'ws'. + */ + +/** + * @deprecated Use WebsocketClient instead. + */ +export default class TxSender { + SOCKET_URL: string; + + constructor(socketUrl ?: string) { + this.SOCKET_URL = socketUrl || TEST_DNA_URL.SOCKET_URL; + } + + sendTxWithSocket(param: string, callback: (err: any, res: any, socket: any) => any) { + if (!param) { + return; + } + + const socket = new Html5WebSocket(this.SOCKET_URL); + socket.onopen = () => { + // console.log('connected') + socket.send(param); + }; + socket.onmessage = (event: any) => { + let res; + if (typeof event.data === 'string') { + res = JSON.parse(event.data); + } else { + res = event.data; + } + + // pass socket to let caller decide when to close the it. + if (callback) { + callback(null, res, socket); + } + }; + socket.onerror = (err: any) => { + // no server or server is stopped + // tslint:disable-next-line:no-console + console.log(err); + callback(err, null, null); + socket.close(); + }; + } +} diff --git a/src/transaction/txSignature.ts b/src/transaction/txSignature.ts new file mode 100644 index 0000000..af975fc --- /dev/null +++ b/src/transaction/txSignature.ts @@ -0,0 +1,147 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { PrivateKey, PublicKey, Signable, SignatureScheme } from '../crypto'; +import { hex2VarBytes, StringReader } from '../utils'; +import { getParamsFromProgram, getProgramInfo, + programFromMultiPubKey, programFromParams, programFromPubKey } from './program'; + +/** + * Signature generated by signing transaction hash with Private Keys. + */ +export class TxSignature { + + /** + * Deserializes hex representation to Transaction Signature + * + * @param sr Hex string reader + */ + static deserialize(sr: StringReader) { + const sig = new TxSignature(); + // sig.pubKeys = []; + // const pubKeyLength = sr.readNextLen(); + + // for (let i = 0; i < pubKeyLength; i++) { + // const serializedLength = sr.readNextLen(); + // const pk = PublicKey.deserializeHex(sr, serializedLength); + // sig.pubKeys.push(pk); + // } + + // sig.M = sr.readNextLen(); + // sig.sigData = []; + + // const dataLength = sr.readNextLen(); + // for (let i = 0; i < dataLength; i++) { + // const data = sr.readNextBytes(); + // sig.sigData.push(data); + // } + const invocationScript = sr.readNextBytes(); + const verificationScript = sr.readNextBytes(); + const sigData = getParamsFromProgram(invocationScript); + const info = getProgramInfo(verificationScript); + sig.M = info.M; + sig.pubKeys = info.pubKeys; + sig.sigData = sigData; + return sig; + } + + /** + * Creates Transaction signature of hash with supplied private key and scheme. + * + * If the signature schemas is not provided, the default schemes for the key types are used. + * + * @param hash hash of the transaction or signable transaction + * @param privateKey Private key to use + * @param scheme Signature scheme to use + */ + static create(hash: string | Signable, privateKey: PrivateKey, scheme?: SignatureScheme) { + const signature = new TxSignature(); + + signature.M = 1; + signature.pubKeys = [privateKey.getPublicKey()]; + signature.sigData = [privateKey.sign(hash, scheme).serializeHex()]; + + return signature; + } + + /** + * Creates Transaction signature of hash with supplied private key and scheme asynchroniously. + * + * If the signature schemas is not provided, the default schemes for the key types are used. + * + * @param hash hash of the transaction or signable transaction + * @param privateKey Private key to use + * @param scheme Signature scheme to use + */ + static async createAsync(hash: string | Signable, privateKey: PrivateKey, scheme?: SignatureScheme) { + const signature = new TxSignature(); + + signature.M = 1; + signature.pubKeys = [privateKey.getPublicKey()]; + signature.sigData = [(await privateKey.signAsync(hash, scheme)).serializeHex()]; + + return signature; + } + + /** + * Public keys used to create this signature. + */ + pubKeys: PublicKey[]; + + // Cardinality of the signature + M: number; + + // Signature values + sigData: string[]; + + /** + * Serializes signature to Hex representation. + * + */ + serialize(): string { + let result = ''; + // result += num2hexstring(this.pubKeys.length); + + // // tslint:disable-next-line:prefer-for-of + // for (let i = 0; i < this.pubKeys.length; i++) { + // const serialized = this.pubKeys[i].serializeHex(); + // result += num2hexstring(serialized.length / 2); + // result += serialized; + // } + + // result += num2hexstring(this.M); + + // result += num2hexstring(this.sigData.length); + + // // tslint:disable-next-line:prefer-for-of + // for (let i = 0; i < this.sigData.length; i++) { + // result += hex2VarBytes(this.sigData[i]); + // } + const invocationScript = programFromParams(this.sigData); + let verificationScript = ''; + if (this.pubKeys.length === 0) { + throw new Error('No pubkeys in sig'); + } else if (this.pubKeys.length === 1) { + verificationScript = programFromPubKey(this.pubKeys[0]); + } else { + verificationScript = programFromMultiPubKey(this.pubKeys, this.M); + } + result += hex2VarBytes(invocationScript); + result += hex2VarBytes(verificationScript); + return result; + } +} diff --git a/src/transaction/vmcode.ts b/src/transaction/vmcode.ts new file mode 100644 index 0000000..55de7f1 --- /dev/null +++ b/src/transaction/vmcode.ts @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { hex2VarBytes, num2hexstring, StringReader } from '../utils'; + +export enum VmType { + NativeVM = 0xFF, + NEOVM = 0x80, + WASMVM = 0x90 +} + +/** + * @deprecated + */ +export class VmCode { + static deserialize(sr: StringReader): any { + const vmcode = new VmCode(); + const type = parseInt(sr.read(1), 16); + const code = sr.readNextBytes(); + vmcode.vmType = type; + vmcode.code = code; + return vmcode; + } + + vmType: VmType; + code: string; + + serialize() { + let result = ''; + result += num2hexstring(this.vmType); + result += hex2VarBytes(this.code); + return result; + } +} diff --git a/src/utils.ts b/src/utils.ts new file mode 100644 index 0000000..cf95bad --- /dev/null +++ b/src/utils.ts @@ -0,0 +1,558 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import axios from 'axios'; +import * as bip39 from 'bip39'; +import * as cryptoJS from 'crypto-js'; +import * as Long from 'long'; +import * as secureRandom from 'secure-random'; +import { DNA_TOTAL_SUPPLY, UNBOUND_GENERATION_AMOUNT, UNBOUND_TIME_INTERVAL } from './consts'; +import { ERROR_CODE } from './error'; +/** + * Turn hex string into array buffer + * @param str hex string + */ +export function hexstring2ab(str: string): number[] { + const result = []; + + while (str.length >= 2) { + result.push(parseInt(str.substring(0, 2), 16)); + str = str.substring(2, str.length); + } + + return result; +} + +/** + * Turn array buffer into hex string + * @param arr Array like value + */ +export function ab2hexstring(arr: any): string { + let result: string = ''; + const uint8Arr: Uint8Array = new Uint8Array(arr); + for (let i = 0; i < uint8Arr.byteLength; i++) { + let str = uint8Arr[i].toString(16); + str = str.length === 0 + ? '00' + : str.length === 1 + ? '0' + str + : str; + result += str; + } + return result; +} + +/** + * Turn ArrayBuffer or array-like oject into normal string + * @param buf + */ +export function ab2str(buf: ArrayBuffer | number[]): string { + return String.fromCharCode.apply(null, new Uint8Array(buf)); +} + +/** + * Turn normal string into ArrayBuffer + * @param str Normal string + */ +export function str2ab(str: string) { + const buf = new ArrayBuffer(str.length); // 每个字符占用1个字节 + const bufView = new Uint8Array(buf); + for (let i = 0, strLen = str.length; i < strLen; i++) { + bufView[i] = str.charCodeAt(i); + } + return buf; +} + +/** + * Turn normal string into hex string + * @param str Normal string + */ +export function str2hexstr(str: string) { + return ab2hexstring(str2ab(str)); +} + +/** + * Turn hex string into normal string + * @param str Hex string + */ +export function hexstr2str(str: string) { + return ab2str(hexstring2ab(str)); +} + +/** + * return the (length of bytes) + bytes + * @param hex Hex string + */ +export function hex2VarBytes(hex: string) { + let result = ''; + result += num2VarInt(hex.length / 2); + result += hex; + return result; +} + +/** + * return the length of string(bytes) + string(bytes) + * @param str Normal string + */ +export function str2VarBytes(str: string) { + let result = ''; + const hex = str2hexstr(str); + const hexLen = num2VarInt(hex.length / 2); + result += hexLen; + result += hex; + return result; +} + +/** + * return the byte of boolean value + * @param v + */ +export function bool2VarByte(v: boolean) { + return v ? '01' : '00'; +} + +/** + * Do xor operation with two strings + * @param str1 Hex string + * @param str2 Hex string + */ +export function hexXor(str1: string, str2: string): string { + if (str1.length !== str2.length) { + throw new Error('strings are disparate lengths'); + } + if (str1.length % 2 !== 0) { + throw new Error('strings must be hex'); + } + + const result = new ArrayBuffer(str1.length / 2); + const result8 = new Uint8Array(result); + for (let i = 0; i < str1.length; i += 2) { + // tslint:disable-next-line:no-bitwise + result8[i / 2] = (parseInt(str1.substr(i, 2), 16) ^ parseInt(str2.substr(i, 2), 16)); + } + return ab2hexstring(result); +} + +/** + * Converts a number to a big endian hexstring of a suitable size, optionally little endian + * @param {number} num + * @param {number} size - The required size in bytes, eg 1 for Uint8, 2 for Uint16. Defaults to 1. + * @param {boolean} littleEndian - Encode the hex in little endian form + * @return {string} + */ +export const num2hexstring = (num: number, size = 1, littleEndian = false) => { + if (num < 0) { + throw new RangeError('num must be >=0'); + } + if (size % 1 !== 0) { + throw new Error('size must be a whole integer'); + } + if (!Number.isSafeInteger(num)) { + throw new RangeError(`num (${num}) must be a safe integer`); + } + + size = size * 2; + let hexstring = num.toString(16); + hexstring = hexstring.length % size === 0 ? hexstring : ('0'.repeat(size) + hexstring).substring(hexstring.length); + if (littleEndian) { + hexstring = reverseHex(hexstring); + } + return hexstring; +}; + +/** + * Converts a number to a hex + * @param {number} num - The number + * @returns {string} hexstring of the variable Int. + */ +export const num2VarInt = (num: number) => { + if (num < 0xfd) { + return num2hexstring(num); + } else if (num <= 0xffff) { + // uint16 + return 'fd' + num2hexstring(num, 2, true); + } else if (num <= 0xffffffff) { + // uint32 + return 'fe' + num2hexstring(num, 4, true); + } else { + // uint64 + return 'ff' + num2hexstring(num, 8, true); + } +}; + +/** + * Reverses a hex string, 2 chars as 1 byte + * @example + * reverseHex('abcdef') = 'efcdab' + * @param {string} hex - HEX string + * @return {string} reversed hex string. + */ +export const reverseHex = (hex: string) => { + if (hex.length % 2 !== 0) { + throw new Error(`Incorrect Length: ${hex}`); + } + let out = ''; + for (let i = hex.length - 2; i >= 0; i -= 2) { + out += hex.substr(i, 2); + } + return out; +}; + +export function bigIntFromBytes(bytes: string): Long { + const buff = Buffer.from(bytes, 'hex'); + let data = Array.from(buff.subarray(0)); + const b = data[data.length - 1]; + + if (b >> 7 === 1) { + data = data.concat(Array(8 - data.length).fill(255)); + } + return Long.fromBytesLE(data); +} + +export function bigIntToBytes(value: Long) { + let data = value.toBytesLE(); + const negData = value.neg().toBytesLE(); + let stop; + if (value.isNegative()) { + stop = 255; + } else { + stop = 0; + } + let b = stop; + let pos = 0; + for (let i = data.length - 1; i >= 0; i--) { + if (data[i] !== stop) { + b = value.isNegative() ? negData[i] : data[i]; + pos = i + 1; + break; + } + } + data = data.slice(0, pos); + + if (b >> 7 === 1) { + data.push(value.isNegative() ? 255 : 0); + } + return new Buffer(data).toString('hex'); +} + +/** + * @class StringReader + * @classdesc A string helper used to read given string as bytes.2 chars as one byte. + * @param {string} str - The string to read. + */ +export class StringReader { + str: string; + pos: number; + size: number; + constructor(str = '') { + if (str.length % 2 !== 0) { + throw new Error('Param\'s length is not even.'); + } + this.str = str; + this.pos = 0; + this.size = this.str.length / 2; + } + + /** + * Checks if reached the end of the string. + */ + isEmpty() { + return this.pos >= this.str.length; + } + + /** + * Reads some bytes. + * @param {number} bytes - Number of bytes to read + */ + read(bytes: number) { + if (this.isEmpty()) { + throw new Error('StringReader reached the end.'); + } + const out = this.str.substr(this.pos, bytes * 2); + this.pos += bytes * 2; + return out; + } + + unreadBytes(bytes: number) { + if ((this.pos - bytes * 2) < 0) { + throw new Error('Can not unread too many bytes.'); + } + this.pos -= bytes * 2; + return; + } + + /** + * Reads string terminated by NULL. + */ + readNullTerminated(): string { + const index = this.str.indexOf('00', this.pos); + if (index === -1) { + throw new Error('No ending NULL found'); + } + + const out = this.str.substring(this.pos, index); + this.pos = index + 2; + return out; + } + + readNextByte() { + return this.read(1); + } + + /** + * First, read one byte as the length of bytes to read. Then read the following bytes. + */ + readNextBytes() { + const bytesToRead = this.readNextLen(); + if (bytesToRead === 0) { + return ''; + } + + return this.read(bytesToRead); + } + + /** + * Reads one byte as int, which may indicates the length of following bytes to read. + * @returns {number} + */ + readNextLen() { + let len = parseInt(this.read(1), 16); + + if (len === 0xfd) { + len = parseInt(reverseHex(this.read(2)), 16); + } else if (len === 0xfe) { + len = parseInt(reverseHex(this.read(4)), 16); + } else if (len === 0xff) { + len = parseInt(reverseHex(this.read(8)), 16); + } + + return len; + } + + readVarUint() { + return this.readNextLen(); + } + + /** + * Read Uint8 + */ + readUint8() { + return parseInt(reverseHex(this.read(1)), 16); + } + + /** + * read 2 bytes as uint16 in littleEndian + */ + readUint16() { + return parseInt(reverseHex(this.read(2)), 16); + } + + /** + * Read 4 bytes as uint32 in littleEndian + */ + readUint32() { + return parseInt(reverseHex(this.read(4)), 16); + } + + /** + * Read 8 bytes as uint64 in littleEndian + */ + readUint64() { + return parseInt(reverseHex(this.read(8)), 16); + } + + /** + * Read 4 bytes as int in littleEndian + */ + readInt() { + return parseInt(reverseHex(this.read(4)), 16); + } + + /** + * Read 8 bytes as long in littleEndian + */ + readLong() { + return parseInt(reverseHex(this.read(8)), 16); + } + + readBoolean() { + return parseInt(this.read(1), 16) !== 0; + } +} + +export class EventEmitter { + handlers: any = {}; + + // register event type and handler + on(type: string, handler: () => void) { + if (typeof this.handlers[type] === 'undefined') { + this.handlers[type] = []; + } + this.handlers[type].push(handler); + } + + /** + * trigger event + * @param { string } type + * @param { any } event , is the parameter + */ + trigger(type: string, event?: any) { + if (this.handlers[type] instanceof Array) { + const handlers = this.handlers[type]; + for (let i = 0, len = handlers.length; i < len; i++) { + handlers[i](event); + } + } + } + + // remove event listener + off(type: string) { + delete this.handlers[type]; + } +} + +export const axiosPost = (url: string, params: any) => { + return axios.post(url, params).then((res: any) => { + // tslint:disable-next-line:no-console + console.log('axios res:' + res); + return res; + }).catch((err: any) => { + // tslint:disable-next-line:no-console + console.log('axios res:' + JSON.stringify(err)); + + return err; + }); +}; + +/** + * Gets current time in unix timestamp format. + */ +export function now(): number { + return Math.floor(Date.now() / 1000); +} + +/** + * Computes sha-256 hash from hex encoded data. + * + * @param data Hex encoded data + */ +export function sha256(data: string) { + const hex = cryptoJS.enc.Hex.parse(data); + const sha = cryptoJS.SHA256(hex).toString(); + return sha; +} + +/** + * Computes ripemd-160 hash from hex encoded data. + * + * @param data Hex encoded data + */ +export function ripemd160(data: string) { + const hex = cryptoJS.enc.Hex.parse(data); + const ripemd = cryptoJS.RIPEMD160(hex).toString(); + return ripemd; +} + +/** + * Computes ripemd-160 hash of sha-256 hash from hex encoded data. + * + * @param data Hex encoded data + */ +export function hash160(SignatureScript: string): string { + return ripemd160(sha256(SignatureScript)); +} + +/** + * Generates random ArrayBuffer of specified length. + * + * @param len Length of the array to generate + */ +export function generateRandomArray(len: number): ArrayBuffer { + return secureRandom(len); +} + +/** + * Generates random ArrayBuffer of specified length encoded as hex string + * + * @param len Length of the array to generate + */ +export function randomBytes(len: number) { + return ab2hexstring(generateRandomArray(len)); +} + +export function generateMnemonic(size: number = 16): string { + const random = ab2hexstring(generateRandomArray(size)); + return bip39.entropyToMnemonic(random); +} + +export function parseMnemonic(str: string) { + return bip39.mnemonicToEntropy(str); +} + +export function varifyPositiveInt(v: number) { + if (!/^[1-9]\d*$/.test(v.toString())) { + throw ERROR_CODE.INVALID_PARAMS; + } + return; +} + +export function isBase64(str: string): boolean { + return Buffer.from(str, 'base64').toString('base64') === str; +} + +export function isHexString(str: string): boolean { + const regexp = /^[0-9a-fA-F]+$/; + return regexp.test(str) && (str.length % 2 === 0); +} + +export function unboundDeadline() { + let count = 0; + for (const m of UNBOUND_GENERATION_AMOUNT) { + count += m; + } + count *= UNBOUND_TIME_INTERVAL; + const numInterval = UNBOUND_GENERATION_AMOUNT.length; + if (UNBOUND_GENERATION_AMOUNT[numInterval - 1] !== 1 || + !((count - UNBOUND_TIME_INTERVAL < DNA_TOTAL_SUPPLY) && DNA_TOTAL_SUPPLY <= count)) { + throw new Error('incompatible constants setting'); + } + return UNBOUND_TIME_INTERVAL * numInterval - (count - DNA_TOTAL_SUPPLY); +} + +export function calcUnboundOng(balance: number, startOffset: number, endOffset: number) { + let amount = 0; + if (startOffset >= endOffset) { + return 0; + } + const UNBOUND_DEADLINE = unboundDeadline(); + if (startOffset < UNBOUND_DEADLINE) { + let ustart = Math.floor(startOffset / UNBOUND_TIME_INTERVAL); + let istart = startOffset % UNBOUND_TIME_INTERVAL; + if (endOffset >= UNBOUND_DEADLINE) { + endOffset = UNBOUND_DEADLINE; + } + const uend = Math.floor(endOffset / UNBOUND_TIME_INTERVAL); + const iend = endOffset % UNBOUND_TIME_INTERVAL; + while (ustart < uend) { + amount += (UNBOUND_TIME_INTERVAL - istart) * UNBOUND_GENERATION_AMOUNT[ustart]; + ustart++; + istart = 0; + } + amount += (iend - istart) * UNBOUND_GENERATION_AMOUNT[ustart]; + } + return amount * balance; +} diff --git a/src/wallet.ts b/src/wallet.ts new file mode 100644 index 0000000..647a547 --- /dev/null +++ b/src/wallet.ts @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import { Account } from './account'; +import { DEFAULT_SCRYPT } from './consts'; +import { Identity } from './identity'; + +/** + * Class to manage Accounts and Identity + */ +export class Wallet { + + static parseJson(json: string): Wallet { + return Wallet.parseJsonObj(JSON.parse(json)); + } + + /** + * Deserializes JSON object. + * + * Object should be real object, not stringified. + * + * @param obj JSON object + */ + static parseJsonObj(obj: any): Wallet { + const wallet = new Wallet(); + wallet.name = obj.name; + wallet.defaultDNAid = obj.defaultDNAid; + wallet.defaultAccountAddress = obj.defaultAccountAddress; + wallet.createTime = obj.createTime; + wallet.version = obj.version; + wallet.scrypt = obj.scrypt; + wallet.identities = obj.identities && (obj.identities as any[]).map((i) => Identity.parseJsonObj(i)); + wallet.accounts = obj.accounts && (obj.accounts as any[]).map((a) => Account.parseJsonObj(a)); + wallet.extra = obj.extra; + return wallet; + } + + static fromWalletFile(obj: any): Wallet { + const wallet = Wallet.parseJsonObj(obj); + return wallet; + } + + /** + * @example + * ```typescript + * + * import { Wallet } from 'DNA-ts-sdk'; + * const wallet = Wallet.create('test'); + * ``` + * + * @param name Wallet's name + */ + static create(name: string): Wallet { + const wallet = new Wallet(); + wallet.name = name; + + // createtime + wallet.createTime = (new Date()).toISOString(); + wallet.version = '1.0'; + wallet.scrypt = { + n: DEFAULT_SCRYPT.cost, + r: DEFAULT_SCRYPT.blockSize, + p: DEFAULT_SCRYPT.parallel, + dkLen: DEFAULT_SCRYPT.size + }; + + return wallet; + } + + name: string; + defaultDNAid: string = ''; + defaultAccountAddress: string = ''; + createTime: string; + version: string; + scrypt: { + n: number; + r: number; + p: number; + dkLen: number; + }; + identities: Identity[] = []; + accounts: Account[] = []; + extra: null; + + addAccount(account: Account): void { + for (const ac of this.accounts) { + if (ac.address.toBase58() === account.address.toBase58()) { + return; + } + } + this.accounts.push(account); + } + + addIdentity(identity: Identity): void { + for (const item of this.identities) { + if (item.dnaid === identity.dnaid) { + return; + } + } + this.identities.push(identity); + } + + setDefaultAccount(address: string): void { + this.defaultAccountAddress = address; + } + + setDefaultIdentity(dnaid: string): void { + this.defaultDNAid = dnaid; + } + + toJson(): string { + return JSON.stringify(this.toJsonObj()); + } + + /** + * Serializes to JSON object. + * + * Returned object will not be stringified. + * + */ + toJsonObj(): any { + const obj = { + name: this.name, + defaultDNAid: this.defaultDNAid, + defaultAccountAddress: this.defaultAccountAddress, + createTime: this.createTime, + version: this.version, + scrypt: this.scrypt, + identities: this.identities.map((i) => i.toJsonObj()), + accounts: this.accounts.map((a) => a.toJsonObj()), + extra: null + }; + + return obj; + } + + signatureData(): string { + return ''; + } + + /* + *generate a wallet file that is compatible with cli wallet. + */ + toWalletFile(): any { + const obj = this.toJsonObj(); + return obj; + } +} diff --git a/test/abiInfo.test.ts b/test/abiInfo.test.ts new file mode 100644 index 0000000..ab79c08 --- /dev/null +++ b/test/abiInfo.test.ts @@ -0,0 +1,72 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import AbiFunction from '../src/smartcontract/abi/abiFunction'; +import AbiInfo from '../src/smartcontract/abi/abiInfo'; +import { Parameter, ParameterType } from '../src/smartcontract/abi/parameter'; +import { PublicKey } from './../src/crypto/PublicKey'; + +import json from '../src/smartcontract/data/idContract.abi'; +import { Transaction } from '../src/transaction/transaction'; +import { VmType } from './../src/transaction/vmcode'; + +import { Address } from '../src/crypto'; +import { makeInvokeTransaction } from '../src/transaction/transactionBuilder'; +import { num2hexstring, reverseHex, str2hexstr } from '../src/utils'; + +describe('test AbiInfo', () => { + + // tslint:disable-next-line:one-variable-per-declaration + let a: AbiInfo, + f: AbiFunction, + tx: Transaction, + serialized: string; + + a = AbiInfo.parseJson(JSON.stringify(json)); + f = a.getFunction('regIDWithPublicKey'); + test('test read json', () => { + + expect(f.parameters.length).toEqual(2); + + const ontidhex = str2hexstr('did:dna:TQLASLtT6pWbThcSCYU1biVqhMnzhTgLFq'); + const p1 = new Parameter('dnaid', ParameterType.ByteArray, ontidhex); + // tslint:disable-next-line:max-line-length + const p2 = new Parameter('publicKey', ParameterType.ByteArray, '039fbb47841f7338c0c654addd6225995642b5b6d492413563f7f8755ba83c0ecd'); + + f.setParamsValue(p1, p2); + + // tslint:disable-next-line:no-console + console.log(f); + + }); + + // tslint:disable-next-line:indent + test('test getFunction throws error if not found', () => { + expect(() => a.getFunction('not_a_function')).toThrowError('not found'); + }); + + test('test make invokecode tx', () => { + tx = makeInvokeTransaction(f.name, f.parameters, new Address(a.getHash()), '0'); + // tslint:disable-next-line:no-console + console.log(tx); + + serialized = tx.serialize(); + // tslint:disable-next-line:no-console + console.log('serialize: ' + serialized); + expect(serialized).toBeDefined(); + }); +}); diff --git a/test/account.test.ts b/test/account.test.ts new file mode 100644 index 0000000..618ecbb --- /dev/null +++ b/test/account.test.ts @@ -0,0 +1,90 @@ + +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { BigNumber } from 'bignumber.js'; +import { sm2, SM2KeyPair } from 'sm.js'; +import { Account } from '../src/account'; +import { Address, PublicKey } from '../src/crypto'; +import { PrivateKey } from '../src/crypto'; +import { CurveLabel } from '../src/crypto/CurveLabel'; +import { KeyParameters } from '../src/crypto/Key'; +import { ERROR_CODE } from '../src/error'; +import * as utils from '../src/utils'; +import { KeyType } from './../src/crypto/KeyType'; + +describe('test account', () => { + + // tslint:disable-next-line:one-variable-per-declaration + let privateKey: PrivateKey, + accountDataStr: string, + account: Account, + encryptedPrivateKey: PrivateKey; + + beforeAll(() => { + privateKey = PrivateKey.random(); + // console.log(privateKey.serializeJson()) + // console.log(privateKey.serializeWIF()); + }); + + test('test create', () => { + account = Account.create(privateKey, '123456', 'mickey'); + encryptedPrivateKey = account.encryptedKey; + accountDataStr = account.toJson(); + // tslint:disable-next-line:no-console + console.log('account: ' + accountDataStr); + expect(accountDataStr).toBeDefined(); + // tslint:disable:no-console + console.log('address: ' + account.address.toBase58()); + console.log('privateKey: ' + privateKey); + console.log('addressU160: ' + account.address.serialize()); + + const pub = '120202d3d048aca7bdee582a611d0b8acc45642950dc6167aee63abbdcd1a5781c6319'; + console.log('Address: ' + Address.fromPubKey(new PublicKey(pub)).toBase58()); + }); + test('test import account with correct password', () => { + let a: Account; + try { + a = Account.importAccount('mickey', encryptedPrivateKey, '123456', account.address, account.salt); + } catch (err) { + console.log(err); + } + const pri = a.exportPrivateKey('123456'); + expect(pri.key).toEqual(privateKey.key); + expect(a.label).toBe('mickey'); + + }); + test('test import with incorrect password', () => { + try { + const a = Account.importAccount('mickey', encryptedPrivateKey, '1234567', account.address, account.salt); + } catch (err) { + expect(err).toEqual(ERROR_CODE.Decrypto_ERROR); + } + + }); + + test('create_sm2', () => { + const keyParameter = new KeyParameters(CurveLabel.SM2P256V1); + const pri = PrivateKey.random(KeyType.SM2, keyParameter); + const acc = Account.create(pri, '123456', 'sm2Account'); + console.log('addr: ' + acc.address.toBase58()); + const accJson = acc.toJsonObj(); + console.log(accJson); + expect(accJson.algorithm).toEqual('SM2'); + }); +}); diff --git a/test/anonymous.test.ts b/test/anonymous.test.ts new file mode 100644 index 0000000..8010498 --- /dev/null +++ b/test/anonymous.test.ts @@ -0,0 +1,108 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { Issuer, User } from '../src/crypto'; + +describe('test Anonymous Crendential', () => { + + const curve = 'BN254'; + const AttributeName = ['24', 'master', 'male', 'handsome']; + const Disclosure = [1, 0, 1, 0]; + + const I = new Issuer(curve); + const U = new User(curve); + const V = new User(curve); + + beforeAll(() => { + // privateKey = PrivateKey.random(); + // // console.log(privateKey.serializeJson()) + // console.log(privateKey.serializeWIF()); + }); + + test('test create', () => { + + /* issuer setup */ + // tslint:disable:no-console + console.log('I.GenerateSk()'); + I.GenerateSk(); + console.log('I.GenerateKeyPair()'); + I.GenerateKeyPair(); + console.log('I.SetAttributeSet(AttributeName)'); + I.SetAttributeSet(AttributeName); + + console.log('I.GetPk()'); + const ipk = I.GetPk(); + console.log('I.Publish(I.ipk)'); + + console.log('U.SetIpk(I.ipk)'); + U.SetIpk(ipk); + console.log('U.GenerateSk()'); + U.GenerateSk(); + + /* issuer generate a random nonce number */ + console.log('I.GenerateNonce()'); + const nonce = I.GenerateNonce(); + console.log('I.send(nonce)'); + + /* user */ + console.log('U.GenerateCrendentialRequest(nonce)'); + const CR = U.GenerateCrendentialRequest(nonce); + console.log('U.send(CrendentialRequest)'); + + console.log('I.pk.VerifyCredentialRequest(CR)'); + const v = I.VerifyCredentialRequest(CR); // verify pi + console.log(v); + expect(v).toBe(true); + + console.log('I.Sign(CR.Nym, CR.attrs)'); + const Cred = I.Sign(CR.Nym, CR.attrs); + console.log('I.send(Credential)'); + + console.log('U.VerifyBBSplus(Credential), or call it verify issuer\'s reality'); + const uv = U.VerifyBBSplus(Cred); + console.log(uv); + expect(uv).toBe(true); + + console.log('U.SetCred(Credential)'); + U.SetCredential(Cred); + + /* + * @inputs + * D: Disclosure of attributes. + * Nonce: a non-sense string for fresh. + * @output + */ + console.log('U.prove(Credential)'); + const proof = U.Prove(Disclosure); + + /* U ---> V */ + console.log('U.send(proof)'); + + console.log('V.SetIpk(I.ipk)'); + V.SetIpk(ipk); + + console.log('V.Verify(U.proof, U.Disclosure, U.attrs)'); + const r = V.Verify(proof, Disclosure, U.attrs); + console.log(r); + + expect(r).toBe(true); + + console.log('BINGO~'); + + }); +}); diff --git a/test/attest.test.ts b/test/attest.test.ts new file mode 100644 index 0000000..9a0a28e --- /dev/null +++ b/test/attest.test.ts @@ -0,0 +1,125 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import * as uuid from 'uuid'; +import { Claim, RevocationType } from '../src/claim/claim'; +import { Address, KeyType, PrivateKey, Signature } from '../src/crypto'; +import { Identity } from '../src/identity'; +import { now } from '../src/utils'; +import { Account } from './../src/account'; + +describe('test attest claim', () => { + const sockUrl = 'ws://polaris1.ont.io:20335'; + const restUrl = 'http://polaris1.ont.io:20334'; + + const privateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b95'); + const publicKey = privateKey.getPublicKey(); + const account = Account.create(privateKey, '123456', ''); + const identity = Identity.create(privateKey, '123456', ''); + const dnaid = identity.dnaid; + const address = account.address; + + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + + const gasPrice = '500'; + const gasLimit = '30000'; + + function randomClaim(): Claim { + return new Claim({ + issuer: dnaid, + subject: dnaid, + issuedAt: now() + }, undefined); + } + + function claimWithId(id: string): Claim { + return new Claim({ + messageId: id, + issuer: dnaid, + subject: dnaid, + issuedAt: now() + }, undefined); + } + + test('test attest new', async () => { + const claim = randomClaim(); + const result = await claim.attest(sockUrl, gasPrice, gasLimit, account.address, privateKey); + + expect(result).toBeTruthy(); + }, 10000); + + test('test attest existing', async () => { + const claim = claimWithId('4df086e3-713d-489d-96fe-8c1bb08ce3eb'); + const result = await claim.attest(sockUrl, gasPrice, gasLimit, account.address, privateKey); + + expect(result).toBeFalsy(); + }, 10000); + + test('test revoke existing', async () => { + const claim = randomClaim(); + + const resultAttest = await claim.attest(sockUrl, gasPrice, gasLimit, account.address, privateKey); + expect(resultAttest).toBeTruthy(); + + const resultRevoke = await claim.revoke(sockUrl, gasPrice, gasLimit, account.address, privateKey); + expect(resultRevoke).toBeTruthy(); + }, 20000); + + test('test revoke non existing', async () => { + const claim = randomClaim(); + const resultRevoke = await claim.revoke(sockUrl, gasPrice, gasLimit, account.address, privateKey); + + expect(resultRevoke).toBeFalsy(); + }, 10000); + + test('test getStatus ATTESTED', async () => { + const claim = claimWithId('4df086e3-713d-489d-96fe-8c1bb08ce3eb'); + const result = await claim.getStatus(restUrl); + + expect(result).toBeTruthy(); + }, 10000); + + test('test getStatus ATTESTED by different attester', async () => { + const claim = claimWithId('4df086e3-713d-489d-96fe-8c1bb08ce3eb'); + claim.metadata.issuer = 'did:dna:TVgarJ2yuWDqXk5WjUwHZEgFqJZUKDNX1C'; + const result = await claim.getStatus(restUrl); + + expect(result).toBeFalsy(); + }, 10000); + + test('test getStatus NOT FOUND', async () => { + const claim = randomClaim(); + const result = await claim.getStatus(restUrl); + + expect(result).toBeFalsy(); + }, 10000); + + test('test revoke existing and status', async () => { + const claim = randomClaim(); + + const resultAttest = await claim.attest(sockUrl, gasPrice, gasLimit, account.address, privateKey); + expect(resultAttest).toBeTruthy(); + + const resultRevoke = await claim.revoke(sockUrl, gasPrice, gasLimit, account.address, privateKey); + expect(resultRevoke).toBeTruthy(); + + const result = await claim.getStatus(restUrl); + expect(result).toBeFalsy(); + }, 20000); +}); diff --git a/test/bip44.test.ts b/test/bip44.test.ts new file mode 100644 index 0000000..13867fd --- /dev/null +++ b/test/bip44.test.ts @@ -0,0 +1,62 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import * as bip39 from 'bip39'; +import { Address, PrivateKey } from '../src/crypto'; +// tslint:disable-next-line:no-var-requires +const HDKey = require('@ont-community/hdkey-secp256r1'); + +// tslint:disable:no-console +describe('test bip44', () => { + test('test_24', () => { + // tslint:disable-next-line:max-line-length + const mnemonic = 'hill ready family useful detect bacon visit canoe recall circle topple claw sheriff universe robust lounge cluster duty vast excuse weasel grunt junk actor'; + + const seed = bip39.mnemonicToSeedHex(mnemonic); + console.log('seed:', seed); + + const hdkey = HDKey.fromMasterSeed(Buffer.from(seed, 'hex')); + console.log('root:', hdkey.privateExtendedKey); + + // tslint:disable-next-line:quotemark + const path = "m/44'/1024'/0'/0/0"; + + const leaf = hdkey.derive(path); + console.log('leaf:', leaf.privateExtendedKey); + + const privateKey = new PrivateKey(Buffer.from(leaf.privateKey).toString('hex')); + console.log('private key:', privateKey.key); + + console.log('WIF key:', privateKey.serializeWIF()); + + const publicKey = privateKey.getPublicKey(); + console.log('public key:', publicKey.key); + + const address = Address.fromPubKey(publicKey); + console.log('address', address.toBase58()); + + expect(address.toBase58()).toBe('AM57cppabEf4JeBXXGAPvRSLmYpqTmQ3sS'); + }); + + test('derive_pri', () => { + const seed = '7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'; + const hdk = HDKey.fromMasterSeed(Buffer.from(seed, 'hex')); + const path = 'm/44\'/1024\'/0\'/0/0'; + const derive = hdk.derive(path); + console.log(Buffer.from(derive.privateKey).toString('hex')); + }); +}); diff --git a/test/claim.test.ts b/test/claim.test.ts new file mode 100644 index 0000000..6504ea3 --- /dev/null +++ b/test/claim.test.ts @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { Account } from '../src/account'; +import { Claim, RevocationType } from '../src/claim/claim'; +import { Address, PrivateKey } from '../src/crypto'; +import { Identity } from '../src/identity'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { buildRegisterDNAidTx } from '../src/smartcontract/nativevm/idContractTxBuilder'; +import { addSign, signTransaction } from '../src/transaction/transactionBuilder'; + +describe('test claim', () => { + const restUrl = 'http://polaris1.ont.io:20334'; + + const privateKey = PrivateKey.random(); + const publicKey = privateKey.getPublicKey(); + const account = Account.create(privateKey, '123456', ''); + const identity = Identity.create(privateKey, '123456', ''); + const dnaid = identity.dnaid; + const address = account.address; + const publicKeyId = dnaid + '#keys-1'; + + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + + let serialized: string; + let signed: string; + + // tslint:disable:no-console + console.log('did:' + dnaid); + /** + * Registers new DNA ID to create transaction with Events and new block + */ + beforeAll(async () => { + const tx = buildRegisterDNAidTx(dnaid, publicKey, '500', '30000'); + tx.payer = adminAddress; + signTransaction(tx, adminPrivateKey); + addSign(tx, privateKey); + + const client = new WebsocketClient(); + await client.sendRawTransaction(tx.serialize(), false, true); + }, 10000); + + test('test serialization', () => { + const claim = new Claim({ + messageId: '1', + issuer: dnaid, + subject: dnaid, + issuedAt: 1525800823 + }, undefined, false); + claim.version = '0.7.0'; + claim.context = 'https://example.com/template/v1'; + claim.content = { + Name: 'Bob Dylan', + Age: '22' + }; + claim.revocation = { + type: RevocationType.AttestContract, + addr: '8055b362904715fd84536e754868f4c8d27ca3f6' + }; + + serialized = claim.serialize(); + + expect(serialized).toBeDefined(); + + }); + + test('test deserialization', async () => { + const msg = Claim.deserialize(serialized); + + expect(msg.metadata.messageId).toEqual('1'); + expect(msg.metadata.issuer).toEqual(dnaid); + expect(msg.metadata.subject).toEqual(dnaid); + expect(msg.metadata.issuedAt).toEqual(1525800823); + expect(msg.signature).toBeUndefined(); + expect(msg.version).toEqual('0.7.0'); + expect(msg.context).toEqual('https://example.com/template/v1'); + expect(msg.content.Name).toEqual('Bob Dylan'); + expect(msg.content.Age).toEqual('22'); + expect(msg.revocation.type).toEqual(RevocationType.AttestContract); + expect(msg.revocation.addr).toEqual('8055b362904715fd84536e754868f4c8d27ca3f6'); + expect(msg.revocation.url).toBeUndefined(); + }); + + test('test signature', async () => { + const claim = new Claim({ + messageId: '1', + issuer: dnaid, + subject: dnaid, + issuedAt: 1525800823 + }, undefined, false); + claim.version = '0.7.0'; + claim.context = 'https://example.com/template/v1'; + claim.content = { + Name: 'Bob Dylan', + Age: '22' + }; + claim.revocation = { + type: RevocationType.AttestContract, + addr: '8055b362904715fd84536e754868f4c8d27ca3f6' + }; + + await claim.sign(restUrl, publicKeyId, privateKey); + + signed = claim.serialize(); + + expect(claim.signature).toBeDefined(); + }); + + test('test verify', async () => { + const msg = Claim.deserialize(signed); + + const result = await msg.verify(restUrl, false); + + expect(result).toBeTruthy(); + }); + + test('test verify with missing attest', async () => { + const msg = Claim.deserialize(signed); + + const result = await msg.verify(restUrl, true); + + expect(result).toBeFalsy(); + }); + test('claim', async () => { + const restUrl = 'http://polaris1.ont.io:20334'; + const dnaid = 'did:dna:AN88DMMBZr5X9ChpMHX3LqRvQHqGxk2c3r'; + const publicKeyId = dnaid + '#keys-1'; + const privateKey = new PrivateKey('4a8d6d61060998cf83acef4d6e7976d538b16ddeaa59a96752a4a7c0f7ec4860'); + const claim = new Claim({ + messageId: '1', + issuer: dnaid, + subject: dnaid, + issuedAt: 1525800823 + }, undefined, false); + claim.version = '0.7.0'; + claim.context = 'https://example.com/template/v1'; + claim.content = { + Name: 'Bob Dylan', + Age: '22' + }; + claim.revocation = { + type: RevocationType.AttestContract, + addr: '8055b362904715fd84536e754868f4c8d27ca3f6' + }; + await claim.sign(restUrl, publicKeyId, privateKey); + const socketUrl = 'ws://polaris1.ont.io:20335'; + const res = await claim.attest(socketUrl, '500', '20000', adminAddress, adminPrivateKey); + console.log(res); + + const signed = claim.serialize(); + + const msg = Claim.deserialize(signed); + const result = await msg.verify(restUrl, false); + + console.log('Info: ', signed, result, claim); + }); +}); diff --git a/test/core.test.ts b/test/core.test.ts new file mode 100644 index 0000000..5d9d6e6 --- /dev/null +++ b/test/core.test.ts @@ -0,0 +1,77 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import * as bip39 from 'bip39'; +import { Claim, Metadata } from '../src/claim'; +import { Address, CurveLabel, KeyParameters, KeyType, PrivateKey, PublicKey } from '../src/crypto'; +import * as utils from '../src/utils'; +import { Signature } from './../src/crypto/Signature'; +import { SignatureScheme } from './../src/crypto/SignatureScheme'; +import { randomBytes, sha256, StringReader } from './../src/utils'; +// tslint:disable : no-console +describe('test core', () => { + + let privateKey: PrivateKey; + let wifKey: string; + + beforeAll(() => { + privateKey = PrivateKey.random(); + }); + + test('test getWIFFromPrivateKey', () => { + const pri = new PrivateKey('e467a2a9c9f56b012c71cf2270df42843a9d7ff181934068b4a62bcdd570e8be'); + wifKey = pri.serializeWIF(); + // expect(wifKey).toBeDefined(); + expect(wifKey).toEqual('L4shZ7B4NFQw2eqKncuUViJdFRq6uk1QUb6HjiuedxN4Q2CaRQKW'); + }); + + test('test getPrivateKeyFromWIF', () => { + const wif = 'L4shZ7B4NFQw2eqKncuUViJdFRq6uk1QUb6HjiuedxN4Q2CaRQKW'; + const key = PrivateKey.deserializeWIF(wif); + expect(key.key).toEqual('e467a2a9c9f56b012c71cf2270df42843a9d7ff181934068b4a62bcdd570e8be'); + }); + + test('get public key', () => { + const pk = privateKey.getPublicKey().serializeHex(); + console.log('get pk: ' + pk); + expect(pk).toBeDefined(); + }); + + test('encrypt private key', () => { + // tslint:disable-next-line:no-shadowed-variable + const privateKey = new PrivateKey('b02304dcb35bc9a055147f07b2a3291db4ac52f664ec38b436470c98db4200d9'); + const address = Address.fromPubKey(privateKey.getPublicKey()); + const encrypt = privateKey.encrypt('123456', address, randomBytes(16)); + console.log('encrypt: ' + encrypt.key); + }); + + test('sign and verify', () => { + // tslint:disable-next-line:no-shadowed-variable + const privateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b95'); + const data = 'helloworld'; + const msg = utils.str2hexstr('helloworld'); + console.log('msg: ' + msg); + const signed = privateKey.sign(msg); + console.log('signed: ' + signed.serializeHex()); + console.log('base64: ' + new Buffer(signed.serializeHex(), 'hex').toString('base64')); + const pk = privateKey.getPublicKey(); + console.log('pub: ' + pk.serializeHex()); + const verifyResult = pk.verify(msg, signed); + console.log('verifyResult: ' + verifyResult); + expect(verifyResult).toBeTruthy(); + }); +}); diff --git a/test/ddo.test.ts b/test/ddo.test.ts new file mode 100644 index 0000000..fbac405 --- /dev/null +++ b/test/ddo.test.ts @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { DDO } from '../src/transaction/ddo'; + +// tslint:disable:max-line-length +const hexstring = + // "000000260100000021039392ba7df4a7badc4cc498be257202f9bbb89c887502e9bcb96a6636ee050ba80000001c010000001700000004436572740000000b06537472696e6761626364" +// '2801000000231202022f71daef10803ece19f96b2cdb348d22bf7871c178b41f35a4f3772a8359b7d20000'; +'28010000002312020204120443e93e67083ab49a4e90e0cde41ac45835f1c8c3e13e4f5a689cd8aff10f01130568656c6c6f06737472696e6700'; +// "5001000000231202022f71daef10803ece19f96b2cdb348d22bf7871c178b41f35a4f3772a8359b7d202000000231202035096277bd28ee25aad489a83ca91cfda1f59f2668f95869e3f7de0af0f07fc5cc446636c61696d3a62356138376265613932643532353235623665626133623637303539356366386239636262353165393732663563626666343939643438363737646465653861044a534f4e777b2254797065223a224a534f4e222c2256616c7565223a7b22436f6e74657874223a22636c61696d3a73746166665f61757468656e7469636174696f6e38222c22497373756572223a226469643a6f6e743a545675463646483150736b7a574a4146685741466731374e5369744d4445424e6f61227d7d1401052e34559b0def95c23f2d4fd86391bb37e27d" +describe('test ddo', () => { + test('test ddo deserialize', () => { + const ddo = DDO.deserialize(hexstring); + // tslint:disable-next-line:no-console + console.log(JSON.stringify(ddo)); + }); +}); diff --git a/test/deployCodeTx.test.ts b/test/deployCodeTx.test.ts new file mode 100644 index 0000000..512e64d --- /dev/null +++ b/test/deployCodeTx.test.ts @@ -0,0 +1,115 @@ +import { VmType } from './../src/transaction/payload/deployCode'; +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import DeployCode from '../src/transaction/payload/deployCode'; +import { Transaction, TxType } from '../src/transaction/transaction'; + +import { buildRestfulParam, buildRpcParam, buildTxParam, Default_params, makeDeployCodeTransaction, + makeInvokeTransaction, sendRawTxRestfulUrl, signTransaction + } from '../src/transaction/transactionBuilder'; +import { ab2hexstring, ab2str, num2hexstring , reverseHex, str2hexstr } from '../src/utils'; + +import axios from 'axios'; +import { MAIN_NODE, MAIN_DNA_URL, DNA_NETWORK, TEST_NODE, TEST_DNA_URL } from '../src/consts'; +import AbiFunction from '../src/smartcontract/abi/abiFunction'; +import AbiInfo from '../src/smartcontract/abi/abiInfo'; +import { Parameter } from '../src/smartcontract/abi/parameter'; +import TxSender from '../src/transaction/txSender'; + +import { Address } from '../src/crypto'; +import { RestClient, WebsocketClient } from '../src/index'; +import json from '../src/smartcontract/data/idContract.abi'; +import { VmCode } from '../src/transaction/vmcode'; +import { Account } from './../src/account'; +import { PrivateKey } from './../src/crypto/PrivateKey'; +// tslint:disable-next-line:no-var-requires +const fs = require('fs'); + +describe('test deploy contract', () => { + + const privateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b93'); + const account = Account.create(privateKey, '123456', 'test'); + console.log(account.address.toBase58()); + + const dnaid = '6469643a6f6e743a5452616a31684377615135336264525450635a78596950415a364d61376a6351564b'; + + const abiInfo = AbiInfo.parseJson(JSON.stringify(json)); + + const txSender = new TxSender(TEST_DNA_URL.SOCKET_URL); + + // tslint:disable-next-line:max-line-length + const attestClaimAvmCode = '013fc56b6a00527ac46a51527ac46a00c3046e616d659c640900655d076c7566616a00c30568656c6c6f9c642a00536a52527ac46a51c3c0519e640700006c7566616a51c300c36a53527ac46a53c3651a076c7566616a00c3097465737448656c6c6f9c646c006a51c3c0559e640700006c7566616a51c300c36a54527ac46a51c351c36a55527ac46a51c352c36a56527ac46a51c353c36a57527ac46a51c354c36a58527ac46a54c36a55c36a56c36a57c36a58c35479517956727551727553795279557275527275651c066c7566616a00c308746573744c6973749c6424006a51c3c0519e640700006c7566616a51c300c36a59527ac46a59c365b1056c7566616a00c30e746573744c697374416e645374729c6451006a51c351c176c9681553797374656d2e52756e74696d652e4e6f74696679616a51c3c0529e640700006c7566616a51c300c36a59527ac46a51c351c36a57527ac46a59c36a57c37c65f1046c7566616a00c30e746573745374727563744c6973749c6431006a51c3681553797374656d2e52756e74696d652e4e6f74696679616a51c300c36a5a527ac46a5ac36570046c7566616a00c314746573745374727563744c697374416e645374729c6432006a51c3c0529e640700006c7566616a51c300c36a5a527ac46a51c351c36a57527ac46a5ac36a57c37c65fa036c7566616a00c307746573744d61709c6416006a51c300c36a53527ac46a53c3655b036c7566616a00c30a746573744765744d61709c6424006a51c3c0519e640700006c7566616a51c300c36a5b527ac46a5bc365b1026c7566616a00c30c746573744d6170496e4d61709c6416006a51c300c36a53527ac46a53c365c2016c7566616a00c30f746573744765744d6170496e4d61709c6424006a51c3c0519e640700006c7566616a51c300c36a5b527ac46a5bc365e3006c7566616a00c30d7472616e736665724d756c74699c6416006a51c300c36a5c527ac46a5cc3650b006c756661006c756659c56b6a00527ac4006a52527ac46a00c3c06a53527ac4616a52c36a53c39f6473006a00c36a52c3c36a51527ac46a52c351936a52527ac46a51c3c0539e6420001b7472616e736665724d756c746920706172616d73206572726f722ef0616a51c300c36a51c351c36a51c352c35272652900009c64a2ff157472616e736665724d756c7469206661696c65642ef06288ff616161516c756656c56b6a00527ac46a51527ac46a52527ac4516c756657c56b6a00527ac4681953797374656d2e53746f726167652e476574436f6e7465787461086d61705f6b6579327c681253797374656d2e53746f726167652e476574616a51527ac40f746573744765744d6170496e4d61706a51c352c176c9681553797374656d2e52756e74696d652e4e6f74696679616a51c3681a53797374656d2e52756e74696d652e446573657269616c697a65616a52527ac46a52c36a00c3c36c756659c56b6a00527ac46a00c36a51527ac46a51c3681853797374656d2e52756e74696d652e53657269616c697a65616a52527ac4076d6170496e666f6a52c352c176c9681553797374656d2e52756e74696d652e4e6f74696679616a51c3036b6579c3681853797374656d2e52756e74696d652e53657269616c697a65616a53527ac4681953797374656d2e53746f726167652e476574436f6e7465787461086d61705f6b6579326a53c35272681253797374656d2e53746f726167652e507574616a52c36c756656c56b6a00527ac4681953797374656d2e53746f726167652e476574436f6e7465787461076d61705f6b65797c681253797374656d2e53746f726167652e476574616a51527ac46a51c3681a53797374656d2e52756e74696d652e446573657269616c697a65616a52527ac46a52c36a00c3c36c756657c56b6a00527ac46a00c36a51527ac46a51c3681853797374656d2e52756e74696d652e53657269616c697a65616a52527ac4681953797374656d2e53746f726167652e476574436f6e7465787461076d61705f6b65796a52c35272681253797374656d2e53746f726167652e507574616a51c3036b6579c36c756658c56b6a00527ac46a51527ac400c176c96a52527ac46a52c36a00c3c86a52c36a51c3c86a52c36c756655c56b6a00527ac40e746573745374727563744c6973746a00c352c176c9681553797374656d2e52756e74696d652e4e6f74696679616a00c36c756659c56b6a00527ac46a51527ac40e746573744c697374416e645374726a00c36a51c353c176c9681553797374656d2e52756e74696d652e4e6f746966796100c176c96a52527ac46a52c36a00c3c86a52c36a51c3c86a52c36c756655c56b6a00527ac40b746573744d73674c6973746a00c352c176c9681553797374656d2e52756e74696d652e4e6f74696679616a00c36c75665fc56b6a00527ac46a51527ac46a52527ac46a53527ac46a54527ac4097465737448656c6c6f6a00c36a51c36a52c36a53c36a54c356c176c9681553797374656d2e52756e74696d652e4e6f746966796100c176c96a55527ac46a55c36a00c3c86a55c36a51c3c86a55c36a52c3c86a55c36a53c3c86a55c36a54c3c86a55c36c756654c56b6a00527ac46a00c36c756653c56b046e616d656c7566'; + + // const url = 'http://polaris1.ont.io:20334'; + const url = 'http://127.0.0.1:20334'; + const restClient = new RestClient(url); + const socketClient = new WebsocketClient('http://127.0.0.1:20335'); + test('test_deploy_with_avm_code', async () => { + + const tx = makeDeployCodeTransaction(attestClaimAvmCode, + 'name', '1.0', 'alice', 'testmail', 'desc', true, '500', '30000000'); + tx.payer = account.address; + signTransaction(tx, privateKey); + const result = await restClient.sendRawTransaction(tx.serialize()); + // tslint:disable:no-console + console.log(result); + expect(result.Error).toEqual(0); + }, 10000); + + test('get_contract', async () => { + const contract = Address.fromVmCode(attestClaimAvmCode); + const codeHash = contract.toHexString(); + // tslint:disable:no-console + console.log('contract address: ' + contract.serialize()); + console.log('codeHash: ' + codeHash); + const result = await restClient.getContract(codeHash); + console.log(result); + expect(result.Result).toBeTruthy(); + }, 10000); + + test('getContract', async () => { + const restClient = new RestClient(MAIN_DNA_URL.REST_URL); + const hash = '36bb5c053b6b839c8f6b923fe852f91239b9fccc'; + const contract = reverseHex(hash); + const res = await restClient.getContract(hash); + console.log(res); + }); + + test('run_name', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'name'; + const params = []; + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await socketClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + }); + + test('run_list', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testList'; + const params = []; + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await socketClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + }); +}); diff --git a/test/ecdsa.crypto.test.ts b/test/ecdsa.crypto.test.ts new file mode 100644 index 0000000..261c91c --- /dev/null +++ b/test/ecdsa.crypto.test.ts @@ -0,0 +1,59 @@ +import { Address } from '../src/crypto'; +import { PrivateKey } from '../src/crypto/PrivateKey'; +import { Signature } from '../src/crypto/Signature'; +import { str2hexstr } from '../src/utils'; +import { SignatureScheme } from './../src/crypto/SignatureScheme'; + +describe('test sign and verify with ECDSAwithSHA256', () => { + test('test sign and verify', () => { + const pri = new PrivateKey('0fdbd5d046997da9959b1931c727c96d83dff19e8ec0244952c1e72d1cdb5bf4'); + const content = 'helloworld'; + const msg = str2hexstr(content); + const signature = pri.sign(msg, SignatureScheme.ECDSAwithSHA256); + console.log('hex: ' + signature.serializeHex()); + console.log('pk: ' + pri.getPublicKey().key); + + const pub = pri.getPublicKey(); + const result = pub.verify(msg, signature); + expect(result).toBeTruthy(); + }); + + test('test verify signature generated by Java SDK', () => { + // tslint:disable-next-line:max-line-length + const content = 'deviceCode=device79dd02d40eb6422bb1f7924c2a6b06af&nonce=1042961893&dnaid=did:dna:AVRKWDig5TorzjCS5xphjgMnmdsT7KgsGD×tamp=1535970123'; + const hexStr = str2hexstr(content); + + const pri = new PrivateKey('0fdbd5d046997da9959b1931c727c96d83dff19e8ec0244952c1e72d1cdb5bf4'); + const pub = pri.getPublicKey(); + + // Signature from Java sdk in base64 + // tslint:disable-next-line:max-line-length + const msg = new Buffer('AYUi0ZgY7ZGN9Msr42prWjsghbcQ6yGaRL34RSUwQr949JMXuhrbjWCYIO3UV1FbFbNKG0YZByYHkffu800pNMw=', 'base64').toString('hex'); + const sig = Signature.deserializeHex(msg); + + const result = pub.verify(hexStr, sig); + expect(result).toBeTruthy(); + }); + + test('tt', () => { + const pri4 = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b98'); + const pub4 = pri4.getPublicKey(); + const address = Address.fromPubKey(pub4).toBase58(); + const ontid4 = 'did:dna:' + address; + + console.log('did: ' + ontid4); + const req = { + timestamp: 1535336885, + dnaid: address, + nonce: 45348391, + deviceCode: 'deviceCOde', + sig: '' + }; + const msg = 'deviceCode=' + req.deviceCode + '&nonce=' + req.nonce + + '&dnaid=' + req.dnaid + '×tamp=' + req.timestamp; + const hexMsg = str2hexstr(msg); + const sig = pri4.sign(hexMsg).serializeHex(); + req.sig = sig; + console.log(req); + }); +}); diff --git a/test/ecies.test.ts b/test/ecies.test.ts new file mode 100644 index 0000000..f30bdd8 --- /dev/null +++ b/test/ecies.test.ts @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +// tslint:disable:variable-name +// tslint:disable:no-empty +import { Ecies } from '../src/crypto'; + +describe('test ECIES', () => { + const test_case = [ + '', + '12345', + 'hello world', + 'qwertyuiopasdfghjklzxcvbnm1234567890', + '一去二三里', + 'Attack!' + ]; + + const python_sdk_case = { + priv: + '9a31d585431ce0aa0aab1f0a432142e98a92afccb7bcbcaff53f758df82acdb3', + pub: + '021401156f187ec23ce631a489c3fa17f292171009c6c3162ef642406d3d09c74d', + cipher: { + iv: '577b04f22c6edcc67c0a864a8d9ba4ee', + out: + '0468d87653b57c6e39a66442d7b64fbae5d3fd49ce81858b8107cf' + + 'ddf0152a7e9c4a04fe6207891b64af9036674a7723f22c002a7b12443bcc12f8b2b6ad1bafc4', + msgCipher: 'fed0f33ba2d90062d6dc9310ad65d4ac' + }, + msg: 'Attack!' + }; + + const java_sdk_case = { + priv: + '9a31d585431ce0aa0aab1f0a432142e98a92afccb7bcbcaff53f758df82acdb3', + pub: + '021401156f187ec23ce631a489c3fa17f292171009c6c3162ef642406d3d09c74d', + cipher: { + iv: 'f88305e04df4bdc491ca6ff65d222386', + out: + '0480a0e5157874371c32cdb01e7e0938d155eaed8f50eecbc6d39b71685d5c' + + '69cbb3f5b5c497d2e34ab47f105f85fc39edf0588d32b7e87403d65ff1e181800590', + msgCipher: '8e7f8f37c16a712f7360c5eebcb0b01a' + }, + msg: '1234567890' + }; + + const curvename = 'p256'; + + beforeAll(() => {}); + + test('test kdf()', () => { + const supposed_output = [ + // java sdk & python sdk + '27704664b7e8ba3c36199f581fa3023f49fd90af918444e2d9477e82565f868a', + '5dbee0a29283512256238cd05870a61c81ccea8a245c8973abc0618df4d3471f' + ]; + const seed = Buffer.from('0102', 'hex'); + const bitlen = 512; + const ins = new Ecies(curvename); + const key = ins.kdf2(seed, bitlen, ins.digestSize, ins.hashAlg); + + expect(key[0].toString('hex') === supposed_output[0]).toBeTruthy(); + expect(key[1].toString('hex') === supposed_output[1]).toBeTruthy(); + }); + + test('test enc() then dec()', () => { + for (const msg of test_case) { + const insA = new Ecies(curvename); + const insB = new Ecies(curvename); + insA.generateKeyPair(); + insB.generateKeyPair(); + + const keyB = insB.getKeyPair(); + + // tslint:disable:no-console + // console.log(keyB.pub); + + const cipher = insA.enc(keyB.pub, Buffer.from(msg, 'utf8'), 32); + + const plainBuffer = insB.dec( + cipher.msgCipher, + cipher.out, + cipher.iv, + 32 + ); + + const plain = plainBuffer.toString('utf8'); + + expect(plain === msg).toBeTruthy(); + } + }); + + test('test decrypt cipher from python sdk', () => { + const insA = new Ecies(curvename); + const insB = new Ecies(curvename); + insA.generateKeyPair(); + + insB.setKeyPair(python_sdk_case.priv); + + expect(insB.getKeyPair().pub === python_sdk_case.pub).toBeTruthy(); + + const plainBuffer = insB.dec( + python_sdk_case.cipher.msgCipher, + python_sdk_case.cipher.out, + python_sdk_case.cipher.iv, + 32 + ); + + const plain = plainBuffer.toString('utf8'); + + expect(plain === python_sdk_case.msg).toBeTruthy(); + }); + test('test decrypt cipher from java sdk', () => { + const insA = new Ecies(curvename); + const insB = new Ecies(curvename); + insA.generateKeyPair(); + + insB.setKeyPair(java_sdk_case.priv); + + expect(insB.getKeyPair().pub === java_sdk_case.pub).toBeTruthy(); + + const plainBuffer = insB.dec( + java_sdk_case.cipher.msgCipher, + java_sdk_case.cipher.out, + java_sdk_case.cipher.iv, + 32 + ); + + const plain = plainBuffer.toString('utf8'); + + expect(plain === java_sdk_case.msg).toBeTruthy(); + }); +}); diff --git a/test/governanceAuthorization.ts b/test/governanceAuthorization.ts new file mode 100644 index 0000000..823dc7f --- /dev/null +++ b/test/governanceAuthorization.ts @@ -0,0 +1,220 @@ +import { Address } from '../src/crypto/address'; +import { PrivateKey } from '../src/crypto/PrivateKey'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { PublicKey } from './../src/crypto/PublicKey'; +import { ParameterType } from './../src/smartcontract/abi/parameter'; + +import { RestClient } from '../src/index'; +import { Parameter } from '../src/smartcontract/abi/parameter'; +import { getAttributes, getAuthorizeInfo, getGlobalParam, getGovernanceView, + getPeerPoolMap, getPeerUnboundOng, getSplitFeeAddress, getTotalStake, + makeAuthorizeForPeerTx, makeChangeAuthorizationTx, makeSetPeerCostTx, + makeUnauthorizeForPeerTx, makeWithdrawFeeTx, makeWithdrawPeerUnboundOngTx, makeWithdrawTx, getConfiguration +} from '../src/smartcontract/nativevm/governanceContractTxBuilder'; +import { makeInvokeTransaction, signTransaction } from '../src/transaction/transactionBuilder'; +import { calcUnboundOng, reverseHex, StringReader } from '../src/utils'; +import { Key } from './../src/crypto/Key'; + +describe('test governance authorization', () => { + const socketClient = new WebsocketClient('ws://139.219.128.220:20335'); + const nodeUrl = 'http://139.219.128.220:20334'; + const restClient = new RestClient(nodeUrl); + const gasPrice = '0'; + const gasLimit = '20000'; + const stake1 = { + dnaid: 'did:dna:AJTMXN8LQEFv3yg8cYKWGWPbkz9KEB36EM', + ontidPass: '920410', + peerPubkey: '02f4c0a18ae38a65b070820e3e51583fd3aea06fee2dc4c03328e4b4115c622567', + address: 'AHqbLqY8wCXFcEGK5cKZzQig2bAfxTrpnL', + addrPass: '123456' + }; + const stake1Account = { 'address': 'AHqbLqY8wCXFcEGK5cKZzQig2bAfxTrpnL', 'label': 'wwww', 'lock': false, 'algorithm': 'ECDSA', 'parameters': { curve: 'P-256' }, 'key': 'p6+xORnKA3uWYOpLECWJ5tCMmxeK/0ZD2m7mOO10i+nx6KuPBtnsCe9tls0J68+f', 'enc-alg': 'aes-256-gcm', 'salt': '1b8neI2vZr8rUVEbmRCzWQ==', 'isDefault': true, 'publicKey': '02f2a7a368f515a40e1c9a626d29df2b845e73aaec742a20ca968a8fe542a674e9', 'signatureScheme': 'SHA256withECDSA' }; + + const stake2 = { + dnaid: 'did:dna:AUEKhXNsoAT27HJwwqFGbpRy8QLHUMBMPz', + ontidPass: '111111', + peerPubkey: '03f6149b3a982c046912731d6374305e2bc8e278fa90892f6f20a8ee85c1d5443f', + address: 'ANYR5cPbKfSeHJXHrK1fP6q5uzqXsg1MmF', + addrPass: '123456' + }; + const stake2Account = { 'address': 'ANYR5cPbKfSeHJXHrK1fP6q5uzqXsg1MmF', 'label': 'qqqq', 'lock': false, 'algorithm': 'ECDSA', 'parameters': { curve: 'P-256' }, 'key': 'CjO1FcDRCq/aT7kcWZAsv3mOLxtDnJ+enFdLHKhLLLHI8JK9ivuL2e1RXfSWy0gZ', 'enc-alg': 'aes-256-gcm', 'salt': 'pztdtlWov/o2GKH4SSU3nQ==', 'isDefault': true, 'publicKey': '02f4c0a18ae38a65b070820e3e51583fd3aea06fee2dc4c03328e4b4115c622567', 'signatureScheme': 'SHA256withECDSA' }; + + const account1 = { 'address': 'AaMHKcpRUuFbhDtrc2raf6K2629LkLWEfL', 'label': 'testHex64', 'lock': false, 'algorithm': 'ECDSA', 'parameters': { curve: 'P-256' }, 'key': 'FCmwz1ukdUkhqnJThCYAgxf6Xx2oZ/PSBPi/wl4w32IR+RMrMzwDrIGNbNBhnd1c', 'enc-alg': 'aes-256-gcm', 'salt': 'ku63qE/TwEAlEyTxJTSHkg==', 'isDefault': true, 'publicKey': '02301589d59d6b78ca23dcc0f674a5210a4745d8e42d5b42ee1c4e720d3e05f4b3', 'signatureScheme': 'SHA256withECDSA' }; + const account2 = { 'address': 'ATfw74wvyQGSxbA7EZNXYN9wj74GNnTtXT', 'label': '托尔斯泰', 'lock': false, 'algorithm': 'ECDSA', 'parameters': { curve: 'P-256' }, 'key': '6B1j4kkclNgJMBYiYJ74Ogh0PJ4f7UA8alAVk58kkotMC7u/VVjKJ9159RMO/C9Y', 'enc-alg': 'aes-256-gcm', 'salt': 'rhZrBuUgGM5iMGX/nmuz+Q==', 'isDefault': true, 'publicKey': '02815af6fc10ec59ac387287265d6a9cb963b8c6fb446ae4ba3e00eb479d83a6c8', 'signatureScheme': 'SHA256withECDSA' }; + const account3 = { 'address': 'AGVbH7fK28bcybSxetR3juPdKEXKX4cJsa', 'label': '22e2a02d', 'lock': false, 'algorithm': 'ECDSA', 'parameters': { curve: 'P-256' }, 'key': 'TtYFBPz+kCsqIySh4O/KYqpUMoRVwIs/mps16srolzD/ZFP/rjsmChE/Z2hZ7tEE', 'enc-alg': 'aes-256-gcm', 'salt': '28fI51NGeRPWLzdTDYJaUQ==', 'isDefault': true, 'publicKey': '0303ed30d674e8076143e451cf69a126f77ac2c3d6c264087cdc69235e623f3020', 'signatureScheme': 'SHA256withECDSA' }; + const account4 = { 'address': 'AaCoH9veFJcrbrq9JriMgybf6d1dnLdEcJ', 'label': 'etwtwew', 'lock': false, 'algorithm': 'ECDSA', 'parameters': { curve: 'P-256' }, 'key': 'PodanUwt2gheR1v8jPSyVPgWIHxrL3hDXQBeSMotI+XNcwNV/D+zypufMXzVhEsV', 'enc-alg': 'aes-256-gcm', 'salt': 'EhIF6MNP+u4Wzs/W18LHZQ==', 'isDefault': true, 'publicKey': '03f4aff6e979ef03f6147769ebcb5839844d9dc69e1929431eb510154bca205026', 'signatureScheme': 'SHA256withECDSA' }; + + const posAmount = 500; + + const getPrivatekey = (account, password) => { + let pri; + const params = { + cost: 16384, // 除以2时间减半 + blockSize: 8, + parallel: 8, + size: 64 + }; + const enc = new PrivateKey(account.key); + const address = new Address(account.address); + try { + pri = enc.decrypt(password, address, account.salt, params); + } catch (err) { + pri = null; + } + return pri; + }; + test('changeAuthorization', async () => { + const stake = stake2; + const pk = stake.peerPubkey; + const address = new Address(stake.address); + const maxAuthorize = 500; + const tx = makeChangeAuthorizationTx(pk, address, maxAuthorize, address, gasPrice, gasLimit); + const pri = getPrivatekey(stake2Account, stake.addrPass); + signTransaction(tx, pri); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + }, 10000); + + test('setPeerCost', async () => { + const stake = stake2; + const pk = stake.peerPubkey; + const address = new Address(stake.address); + const peerCost = 50; + const tx = makeSetPeerCostTx(pk, address, peerCost, address, gasPrice, gasLimit); + const pri = getPrivatekey(stake2Account, stake.addrPass); + signTransaction(tx, pri); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + }, 10000); + + test('withdrawFee', async () => { + const account = account4; + const address = new Address(account.address); + const tx = makeWithdrawFeeTx(address, address, gasPrice, gasLimit); + const pri = getPrivatekey(account, '123456'); + signTransaction(tx, pri); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + }, 10000); + + test('authorizePeer', async () => { + const account = account1; + const address = new Address(account.address); + const peerPubkeyList = [stake2.peerPubkey]; + const posList = [posAmount]; + const tx = makeAuthorizeForPeerTx(address, peerPubkeyList, posList, address, gasPrice, gasLimit); + const pri = getPrivatekey(account, '123456'); + signTransaction(tx, pri); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + // const res = await restClient.sendRawTransaction(tx.serialize()); + // console.log(res); + }, 10000); + + test('unAuthorizeForPeer', async () => { + const account = account1; + const address = new Address(account.address); + const peerPubkeyList = [stake1.peerPubkey]; + const posList = [1000]; + const tx = makeUnauthorizeForPeerTx(address, peerPubkeyList, posList, address, gasPrice, gasLimit); + const pri = getPrivatekey(account, '123456'); + signTransaction(tx, pri); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + }, 10000); + + test('DNAwithdraw', async () => { + const account = account1; + const address = new Address(account.address); + const peerPubkeyList = [stake1.peerPubkey]; + const withdrawList = [1500]; + const tx = makeWithdrawTx(address, peerPubkeyList, withdrawList, address, gasPrice, gasLimit); + const pri = getPrivatekey(account, '123456'); + signTransaction(tx, pri); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + }); + + test('getAttributes', async () => { + const pk = '032f6464df7c42b5a80953680165a23cb98453a1fcb5770f233664909847faf36f'; + const url = 'http://dappnode1.ont.io:20334'; + const res = await getAttributes(pk, url); + console.log(res); + }, 10000); + + test('getSplitFeeAddress', async () => { + const address = new Address(stake1.address); + const res = await getSplitFeeAddress(address, nodeUrl); + console.log(res); + }, 10000); + + test('getPeerPoolMap', async () => { + const nodeUrl = 'http://polaris1.ont.io:20334'; + const res = await getPeerPoolMap(nodeUrl); + console.log(res); + // const pk = '032f6464df7c42b5a80953680165a23cb98453a1fcb5770f233664909847faf36f'; + // console.log(res[pk]); + }, 10000); + + test('getAuthorizeInfo', async () => { + // const pk = stake2.peerPubkey; + const pk = '032f6464df7c42b5a80953680165a23cb98453a1fcb5770f233664909847faf36f'; + // const userAddr = new Address(account4.address); + const userAddr = new Address('ALaDrS5ZwMKZgTS3a8okgDDz84k3ttfP4x'); + const nodeUrl = 'http://dappnode1.ont.io:20334'; + const res = await getAuthorizeInfo(pk, userAddr, nodeUrl); + console.log(res); + }, 10000); + + test('testPass', () => { + const pk = '033d9aea7fb2f72bb3b1db9e2416f32f313b5489b626d34fb576440c7220995e11'; + const address = Address.fromPubKey(new PublicKey(pk)).toBase58(); + expect(address).toEqual('AUg53MTnZ8x8awYvbgV8zhxxsrCgG3jqjc'); + }); + + test('getGovernanceView', async () => { + const view = await getGovernanceView(nodeUrl); + console.log(view); + }, 1000); + + test('getGlobalParam', async () => { + const view = await getGlobalParam(nodeUrl); + console.log(view); + }, 1000); + + test('getTotalStake', async () => { + const addr = new Address('AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve'); + const nodeUrl = 'http://polaris1.ont.io:20334'; + const ts = await getTotalStake(addr, nodeUrl); + console.log(ts); + }); + + test('getUnboundOng', async () => { + const addr = new Address(stake1.address); + const unbound = await getPeerUnboundOng(addr, nodeUrl); + console.log(unbound); + }); + + test('withdrawOng', async () => { + const addr = new Address(stake2.address); + const tx = await makeWithdrawPeerUnboundOngTx(addr, addr, gasPrice, gasLimit); + const pri = getPrivatekey(stake2Account, '123456'); + signTransaction(tx, pri); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + }); + + test('getConfiguration', async () => { + const url = 'http://dappnode1.ont.io:20334'; + const config = await getConfiguration(url); + console.log(config); + }); + +}); diff --git a/test/hdkey.test.ts b/test/hdkey.test.ts new file mode 100644 index 0000000..d0baff7 --- /dev/null +++ b/test/hdkey.test.ts @@ -0,0 +1,36 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import * as bip39 from 'bip39'; +// tslint:disable-next-line:no-var-requires +const HDKey = require('@ont-community/hdkey-secp256r1'); + +// tslint:disable:quotemark +describe('hd key tests', () => { + test('simple test', () => { + const seed = '000102030405060708090a0b0c0d0e0f'; + + const hdkey = HDKey.fromMasterSeed(Buffer.from(seed, 'hex')); + const pubStr = hdkey.derive("m/0/0/176").publicKey.toString('hex'); + + const hdkey2 = HDKey.fromExtendedKey(hdkey.publicExtendedKey); + const pubStr2 = hdkey2.derive("m/0/0/176").publicKey.toString('hex'); + + expect(pubStr2).toBe(pubStr); + }); +}); diff --git a/test/idContract.test.ts b/test/idContract.test.ts new file mode 100644 index 0000000..f2fe83f --- /dev/null +++ b/test/idContract.test.ts @@ -0,0 +1,253 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +// tslint:disable:max-line-length +import axios from 'axios'; +import { GetStatusResponse } from '../src/claim/claim'; +import { MAIN_DNA_URL, TEST_DNA_URL } from '../src/consts'; +import { DEFAULT_ALGORITHM, DNA_NETWORK, TEST_NODE } from '../src/consts'; +import { Address, CurveLabel, KeyParameters, KeyType, PrivateKey, PublicKey } from '../src/crypto'; +import { Identity } from '../src/identity'; +import { RestClient } from '../src/index'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import AbiFunction from '../src/smartcontract/abi/abiFunction'; +import AbiInfo from '../src/smartcontract/abi/abiInfo'; +import { Parameter, ParameterType } from '../src/smartcontract/abi/parameter'; +import json2 from '../src/smartcontract/data/idContract.abi'; +import { buildAddAttributeTx, buildAddControlKeyTx, buildAddRecoveryTx, + buildChangeRecoveryTx, buildGetAttributesTx, buildGetDDOTx, buildGetPublicKeyStateTx, + buildGetPublicKeysTx, buildRegIdWithAttributes, buildRegisterDNAidTx, buildRemoveAttributeTx, buildRemoveControlKeyTx +} from '../src/smartcontract/nativevm/idContractTxBuilder'; +import { State } from '../src/smartcontract/nativevm/token'; +import { buildCommitRecordTx, buildGetRecordStatusTx, buildRevokeRecordTx } from '../src/smartcontract/neovm/attestClaimTxBuilder'; +import { DDO, DDOAttribute, PublicKeyWithId } from '../src/transaction/ddo'; +import InvokeCode from '../src/transaction/payload/invokeCode'; +import { Transaction } from '../src/transaction/transaction'; +import { addSign , buildRestfulParam, + buildRpcParam, buildTxParam, makeInvokeTransaction, sendRawTxRestfulUrl } from '../src/transaction/transactionBuilder'; +import TxSender from '../src/transaction/txSender'; +import { VmType } from '../src/transaction/vmcode'; +import { ab2hexstring, hexstr2str, str2hexstr, StringReader } from '../src/utils'; +import { Account } from '../src/account'; +import { signTransaction, signTx } from '../src/transaction/transactionBuilder'; + +describe('test DNA ID contract', () => { + + const gasPrice = '500'; + const gasLimit = '20000'; + const socketClient = new WebsocketClient('ws://127.0.0.1:20335'); + + const restClient = new RestClient('http://127.0.0.1:20334'); + + let privateKey: PrivateKey; + let publicKey: PublicKey; + // tslint:disable-next-line:prefer-const + let pk2: PublicKey; + let dnaid: string; + // tslint:disable:prefer-const + let oldrecovery: string; + let newrecovery: string; + let pkId: string; + + let abiInfo: AbiInfo; + let identity: Identity; + + abiInfo = AbiInfo.parseJson(JSON.stringify(json2)); + // privateKey = PrivateKey.random() + // console.log('privatekey: ' + privateKey) + // console.log('publick key: ' + publicKey) + // tslint:disable:no-console + + privateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b95'); + const account = Account.create(privateKey, '123456', ''); + console.log('account: ' + account.address.toBase58()); + publicKey = privateKey.getPublicKey(); + console.log('pk: ' + publicKey.key); + // dnaid = 'did:dna:AUG62qrHboRc4oNn8SvJ31ha6BkwLPKvvG'; + dnaid = 'did:dna:' + account.address.toBase58(); + + const pri2 = new PrivateKey('cd19cfe79112f1339749adcb3491595753ea54687e78925cb5e01a6451244406'); + const account2 = Account.create(pri2, '123456', ''); + const pub2 = pri2.getPublicKey(); + const dnaid2 = 'did:dna:ALnvzTMkbanffAKzQwxJ3EGoBqYuR6WqcG'; + console.log('address2: ' + account2.address.toBase58()); + + const pri3 = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const account3 = Account.create(pri3, '123456', ''); + const pub3 = pri3.getPublicKey(); + const dnaid3 = Address.generateDNAid(pub3); + console.log('pk3:' + pri3.getPublicKey().serializeHex()); + console.log('address3: ' + account3.address.toBase58()); + + const pri4 = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b98'); + const account4 = Account.create(pri4, '123456', ''); + const pub4 = pri4.getPublicKey(); + const dnaid4 = Address.generateDNAid(pub4); + console.log('pk4:' + pri4.getPublicKey().serializeHex()); + console.log('address4: ' + account4.address.toBase58()); + + const pri5 = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b99'); + const account5 = Account.create(pri5, '123456', ''); + const pub5 = pri5.getPublicKey(); + const dnaid5 = Address.generateDNAid(pub5); + console.log('address5: ' + account5.address.toBase58()); + + test('testRegisterDNAid', async () => { + + const tx = buildRegisterDNAidTx(dnaid, publicKey, gasPrice, gasLimit, account.address); + console.log(tx.serialize()); + signTransaction(tx, privateKey); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + + test('testDDOTx', async () => { + const tx = buildGetDDOTx(dnaid); + const response = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(response); + const ddo = DDO.deserialize(response.Result.Result); + console.log(ddo); + }, 10000); + + test('testRegIdWithAttributes', async () => { + // tslint:disable-next-line:no-shadowed-variable + const dnaid = Address.generateDNAid(pub2); + const attr = new DDOAttribute(); + attr.key = 'hello'; + attr.type = 'string', + attr.value = 'world'; + const tx = buildRegIdWithAttributes(dnaid, [attr], pub2, gasPrice, gasLimit); + tx.payer = account2.address; + signTransaction(tx, pri2); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + + test('testAddAttribute', async () => { + // tslint:disable-next-line:one-variable-per-declaration + const claimId = 'claim:b5a87bea92d52525b6eba3b670595cf8b9cbb51e972f5cbff499d48677ddee8a', + context = 'claim:staff_authentication8', + issuer = 'did:dna:TVuF6FH1PskzWJAFhWAFg17NSitMDEBNoa'; + // let key = str2hexstr(claimId) + + const type = 'JSON'; + const data = { + Type : 'JSON', + Value : { + Context: context, + Issuer: issuer + } + }; + const value = JSON.stringify(data); + + const attr = new DDOAttribute(); + attr.key = claimId; + attr.type = type; + attr.value = value; + const did = dnaid5; + const tx = buildAddAttributeTx(did, [attr], pub5, gasPrice, gasLimit); + tx.payer = account2.address; + signTransaction(tx, pri2); + addSign(tx, pri5); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + + test('testRemoveAttribute', async () => { + const claimId = 'claim:b5a87bea92d52525b6eba3b670595cf8b9cbb51e972f5cbff499d48677ddee8a'; + // const key = str2hexstr(claimId); + // let key = str2hexstr('Claim:twitter'); + let key = claimId; + + console.log('removeAttr key: ' + key); + const tx = buildRemoveAttributeTx(dnaid, claimId, pub5, gasPrice, gasLimit); + tx.payer = account5.address; + signTransaction(tx, pri5); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + + test('testGetAttributs', async () => { + const tx = buildGetAttributesTx(dnaid5); + tx.payer = account.address; + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const attr = DDOAttribute.deserialize(res.Result.Result); + console.log(attr); + expect(attr).toBeTruthy(); + }, 10000); + + test('testGetPublicKeyState', async () => { + const tx = buildGetPublicKeyStateTx(dnaid5, 2); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const result = res.Result.Result; + console.log(hexstr2str(result)); + expect(hexstr2str(result)).toEqual('in use'); + }, 10000); + + test('testAddPK', async () => { + const tx = buildAddControlKeyTx(dnaid5, pub4, pub5, gasPrice, gasLimit); + tx.payer = account5.address; + signTransaction(tx, pri5); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + + test('testGetPublicKeys', async () => { + const tx = buildGetPublicKeysTx(dnaid5); + // tx.payer = account.address; + // signTransaction(tx, privateKey); + // let param = buildTxParam(tx) + // sendTx(param) + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const r = PublicKeyWithId.deserialize(res.Result.Result); + console.log('pkWithId: ' + JSON.stringify(r)); + }, 10000); + + test('testRemovePK', async () => { + const tx = buildRemoveControlKeyTx(dnaid, pub4, pub5, gasPrice, gasLimit); + tx.payer = account5.address; + signTransaction(tx, pri5); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + + test('testAddRecovery', async () => { + const tx = buildAddRecoveryTx(dnaid5, account3.address, pub5, gasPrice, gasLimit); + tx.payer = account5.address; + signTransaction(tx, pri5); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + + test('testChangeRecovery', async () => { + const tx = buildChangeRecoveryTx(dnaid5, account2.address, account3.address, gasPrice, gasLimit); + tx.payer = account3.address; + signTransaction(tx, pri3); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Error).toEqual(0); + }, 10000); + +}); diff --git a/test/identity.test.ts b/test/identity.test.ts new file mode 100644 index 0000000..45570af --- /dev/null +++ b/test/identity.test.ts @@ -0,0 +1,100 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import axios from 'axios'; +import { Address, PrivateKey } from '../src/crypto'; +import { ERROR_CODE } from '../src/error'; +import { Identity } from '../src/identity'; + +describe('test identity', () => { + + // tslint:disable-next-line:one-variable-per-declaration + let privateKey: PrivateKey, + identityDataStr: string, + identity: Identity, + encryptedPrivateKey: PrivateKey, + address: Address; + + beforeAll(() => { + privateKey = PrivateKey.random(); + }); + + test('test create', () => { + identity = Identity.create(privateKey, '123456', 'mickey'); + address = identity.controls[0].address; + encryptedPrivateKey = identity.controls[0].encryptedKey; + identityDataStr = identity.toJson(); + console.log(identityDataStr); + const itemp = Identity.parseJson(identityDataStr); + expect(itemp).toBeDefined(); + expect(identityDataStr).toBeDefined(); + const pri = identity.exportPrivateKey('123456'); + expect(pri.key).toEqual(privateKey.key); + }); + + test('test import with correct password', () => { + // tslint:disable:no-console + console.log('encryptedkey: ' + encryptedPrivateKey.key); + let a: Identity; + + try { + a = Identity.importIdentity('mickey', encryptedPrivateKey, '123456', address, identity.controls[0].salt); + } catch (err) { + console.log(err); + } + expect(a.label).toBe('mickey'); + }); + + test('test import with incorrect password', () => { + try { + const a = Identity.importIdentity('', encryptedPrivateKey, '123457', address, identity.controls[0].salt); + } catch (err) { + console.log(err); + expect(err).toEqual(ERROR_CODE.Decrypto_ERROR); + } + }); + + test('test_userAgent_devicecode', async () => { + const pri = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b95'); + const a = Identity.create(pri, '123456', ''); + // const encrypt = new PrivateKey('xLdlFLuWMUcHZagEAiFZEiCwm1eQYbSEONIwxxL4qPk='); + // const pri = encrypt.decrypt('111111', new Address('TA8z22MRYHcFRKJznJWWGFz5brXBsmMTJZ')); + // a.create(pri, '123456', 'test'); + const data = { + OwnerDNAId : a.dnaid + }; + const msg = JSON.stringify(data); + const pkId = a.dnaid + '#key-1'; + console.log('msg: ' + msg); + const sig = pri.sign(msg, undefined, pkId); + const body = { + OwnerDNAId: a.dnaid, + Signature : sig.serializePgp() + }; + console.log('value: ' + body.Signature.Value); + + console.log('pk: ' + pri.getPublicKey().serializeHex()); + console.log(JSON.stringify(body)); + // const userAgent = 'http://192.168.50.121:9099/api/v1/ontpass/devicecode/gain'; + // const res = await axios.post(userAgent, body).then( (res) => { + // console.log(res.data); + // return res.data; + // }); + }); + +}); diff --git a/test/merkle.test.ts b/test/merkle.test.ts new file mode 100644 index 0000000..5ed0403 --- /dev/null +++ b/test/merkle.test.ts @@ -0,0 +1,96 @@ +import { Account } from '../src/account'; +import { PrivateKey } from '../src/crypto'; +import { Identity } from '../src/identity'; +import { constructClaimProof, getProofNodes, verifyClaimProof, verifyLeafHashInclusion } from '../src/merkle'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { buildRegisterDNAidTx } from '../src/smartcontract/nativevm/idContractTxBuilder'; +import { signTransaction } from '../src/transaction/transactionBuilder'; + +// tslint:disable:no-console + +describe('test merkle proofs', () => { + let txHash: string; + + const privateKey = PrivateKey.random(); + const publicKey = privateKey.getPublicKey(); + const account = Account.create(privateKey, '123456', ''); + const identity = Identity.create(privateKey, '123456', ''); + const dnaid = identity.dnaid; + const address = account.address; + + /** + * Registers new DNA ID to create transaction + */ + beforeAll(async () => { + const tx = buildRegisterDNAidTx(dnaid, publicKey, '0', '30000'); + tx.payer = account.address; + signTransaction(tx, privateKey); + + const client = new WebsocketClient(); + const result = await client.sendRawTransaction(tx.serialize(), false, true); + txHash = result.Result.TxHash; + }, 10000); + + test('test verify leaf in tree', () => { + const merkle = { + Type: 'MerkleProof', + TransactionsRoot: 'dafd3426157505e944b79341692fc671a08ff6a49df8bae0316589f8aeb662e8', + BlockHeight: 987, + CurBlockRoot: '013f7e94417caddd5d4cb2b188986950095fc1156337280a0202eb60f97a7202', + CurBlockHeight: 1334, + TargetHashes: + ['fc58cd3c287a212d6ff4dbb4b7ac6a3758bb7c5aba90de7e7c25e73ecfc2e314', + '8f6b07cb220cff1b7675a572df40355156593afc942e8025383fd299b020efae', + '8f855e903d197c6b950fb1d06af5b62ad77e833ae6cacdd2d26461bb4db5dd84', + '21a9fb67d89ec41ec1f72a2219bea14a5e0598bafa0ee034560831c3591ac791', + '812af7a5a48d503da1d8a567955d28e81e667a229048b1384b00af6091ca2f28', + '9710423e9b37ec7533db32d96e4ce915ba3070067f0d07b761b98882b727b42d', + 'e693cb5ccd21c3a4e3109444dba90d48e50d998817f5ea30bd8b5e80f5b51908', + 'f80b3101f4ba67f8a122d196c292b1fdd12fa376576eb2ec9a39558bc0d050a5', + 'e16f24631135b44b22540392b3d326cedbc2b0009b65251fa9bfc4bf3afe9c99', + '3067fe25fa3af8c7e8b4b68714ccf38498a987d1e4dd51f8e87c00c204d5d26d', + 'e7bc56e79d77391f9a4c1065b1c769087b403fa707d7d924536bdad88f6c162e'] + }; + const leafHash = merkle.TransactionsRoot; + const leafIndex = merkle.BlockHeight; + const proof = merkle.TargetHashes; + const rootHash = merkle.CurBlockRoot; + const treeSize = merkle.CurBlockHeight; + const result = verifyLeafHashInclusion(leafHash, leafIndex, proof, rootHash, treeSize); + console.log(result); + expect(result).toBeTruthy(); + }); + + test('test verifyMerkleProof with wrong contractAddr', async () => { + const contractAddr = '1234567890'; + const claimProof = await constructClaimProof(txHash, contractAddr); + console.log(claimProof); + const result = verifyClaimProof(claimProof.TxnHash, claimProof.MerkleRoot, claimProof.Nodes); + console.log(result); + expect(result).toBeFalsy(); + }); + + test('test getProofNodes', () => { + const merkle = { TransactionsRoot: '9376dc41a98a52cdaeac04e43033102ba5167ef914c929093bf316d4c23cc89d', + Type: 'MerkleProof', CurBlockRoot: 'b70494ad2d446004cd2cb4a5746829192402dfcbbc0300c0f6ee67c40ad94971', + CurBlockHeight: 3975, BlockHeight: 3807, + TargetHashes: ['f1c52b64834de776dd75899b7a737586649262ef2f6b7a2e2403ad2f6806a563', + '763cf365f5d54763eddf7d790a8f238f42c84efe6083fc3d0dcdbda1bba42e1d', + 'a4d84c9eae6877f0f8dbd4e7dd16cac5662def94ec5a1560b635c06277c1157e', + 'f53a8ef0da3764781d2e1fb910ee24e060b49bb48c49d264624149c802a9c051', + 'c17bffb1d0d6cc6156835250fdb6560a0c55085c1c252ace0ebad99b49dc8904', + 'c72bad737b03a3f1474439415670fef914d51329364846b5c0de9430bda2fdce', + '286700b35b38d66aedd53f4f0f6ecfd9647825160cb11d1159695977a827413b', + 'bac6b66302d3ce0ba7921d09b498b8fdbed97c92c8cec01b6bc7d4e1093664f9', + 'e279ddafd7c0e24f5e11fad048863f2464c53185ee28aec2aa7625b1351bc3c0', + '2efe9edb28594bf2c40d23b256db86a9b47617e738f6f1989a1a88c86417342c', + '8498af2fc96c62427b2992ece3842cabe69ccc8d2b7df1b634ea6263c3b9b35b', + '73fc0e4d1163018bf721ce2d31bb42004d7f4604d6896443c2d38ece602e3909'] }; + const leafIndex = merkle.BlockHeight; + const treeSize = merkle.CurBlockHeight; + const proof = merkle.TargetHashes; + const proofNodes = getProofNodes(leafIndex, treeSize, proof); + console.log(proofNodes); + expect(proofNodes.length).toBeGreaterThan(0); + }); +}); diff --git a/test/oep4.test.ts b/test/oep4.test.ts new file mode 100644 index 0000000..6bee376 --- /dev/null +++ b/test/oep4.test.ts @@ -0,0 +1,181 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { BigNumber } from 'bignumber.js'; +import { Account } from '../src'; +import RestClient from '../src/network/rest/restClient'; +import { Address } from './../src/crypto/address'; +import { PrivateKey } from './../src/crypto/PrivateKey'; +import { WebsocketClient } from './../src/network/websocket/websocketClient'; +import { Oep4State, Oep4TxBuilder } from './../src/smartcontract/neovm/oep4TxBuilder'; +import { addSign, signTransaction } from './../src/transaction/transactionBuilder'; +import { hexstr2str, reverseHex } from './../src/utils'; + +describe('test oep4', () => { + const private1 = new PrivateKey('5f2fe68215476abb9852cfa7da31ef00aa1468782d5ca809da5c4e1390b8ee45'); + const private2 = new PrivateKey('49855b16636e70f100cc5f4f42bc20a6535d7414fb8845e7310f8dd065a97221'); + const private3 = new PrivateKey('1094e90dd7c4fdfd849c14798d725ac351ae0d924b29a279a9ffa77d5737bd96'); + + const address1 = new Address('AQf4Mzu1YJrhz9f3aRkkwSm9n3qhXGSh4p'); + const address2 = new Address('AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX'); + const address3 = new Address('AVXf5w8WD2y6jV1Lzi36oSKYNif1C7Surc'); + + const codeHash = '78ac3965410c552609b691bbfe30469110c71485'; + + const contractAddr = new Address(reverseHex(codeHash)); + const oep4 = new Oep4TxBuilder(contractAddr); + const gasPrice = '500'; + const gasLimit = '200000'; + // const url = TEST_DNA_URL.REST_URL; + const url = 'http://polaris2.ont.io:'; + const restClient = new RestClient(url + '20334'); + const socketClient = new WebsocketClient(url + '20335'); + + test('init', async () => { + const tx = oep4.init(gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); + + test('getBalance', async () => { + const tx = oep4.queryBalanceOf(address1); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const val = res.Result.Result ? parseInt(reverseHex(res.Result.Result), 16) : 0; + // tslint:disable-next-line:no-console + console.log(val); + expect(val).toBeGreaterThan(0); + }); + + test('1_test_transfer', async () => { + const tx = oep4.makeTransferTx(address1, address2, '10000', gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }, 10000); + + test('test_totalSupply', async () => { + const tx = oep4.queryTotalSupply(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + const val = parseInt(reverseHex(res.Result.Result), 16); + // tslint:disable-next-line:no-console + expect(val).toBeGreaterThan(0); + }, 10000); + + test('test_name', async () => { + const tx = oep4.queryName(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log('res: ' + JSON.stringify(res)); + if (!res.Result.Result) { + return; + } + const val = hexstr2str(res.Result.Result); + console.log(val); + // tslint:disable-next-line:no-console + expect(val).toBeDefined(); + }, 10000); + + test('test_symbol', async () => { + const tx = oep4.querySymbol(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const val = hexstr2str(res.Result.Result); + // tslint:disable-next-line:no-console + console.log(val); + expect(val).toBeDefined(); + }); + + test('test_decimals', async () => { + const tx = oep4.queryDecimals(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + const val = res.Result; + console.log(val); + if (val.Result) { + console.log('decimal:' + parseInt(val.Result, 16)); + } + // tslint:disable-next-line:no-console + expect(val).toBeTruthy(); + }, 10000); + + test('test_approve', async () => { + const tx = oep4.makeApproveTx(address1, address3, '10000', gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); + + test('test_queryAllowance', async () => { + const tx = oep4.makeQueryAllowanceTx(address1, address3); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + const val = res.Result.Result ? parseInt(reverseHex(res.Result.Result), 16) : 0; + console.log(val); + // tslint:disable-next-line:no-console + expect(val).toEqual(10000); + }); + + test('test_transferFrom', async () => { + const tx = oep4.makeTransferFromTx(address3, address1, address3, '10000', gasPrice, gasLimit, address3); + signTransaction(tx, private3); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); + + test('test_transferMulti', async () => { + const state1 = new Oep4State(address1, address2, '200'); + const state2 = new Oep4State(address1, address3, '300'); + const tx = oep4.makeTransferMultiTx([state1, state2], gasPrice, gasLimit, address2); + signTransaction(tx, private2); + addSign(tx, private1); + // addSign(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); + + test('bigDecimal_oep4_transfer', async () => { + const newOep4 = new Oep4TxBuilder(new Address(reverseHex('55e02438c938f6f4eb15a9cb315b26d0169b7fd7'))); + const tx = newOep4.makeTransferTx(address1, address2, + '65530', gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + const notify = response.Result.Notify.find((item) => item.ContractAddress !== '0200000000000000000000000000000000000000'); + if (notify) { + const val = new BigNumber(reverseHex(notify.States[3]), 16).toString(); + console.log('val: ', val); + } + + const tx2 = newOep4.queryBalanceOf(address2); + const res = await restClient.sendRawTransaction(tx2.serialize(), true); + console.log('balance after transfer: ', res.Result); + const val2 = res.Result.Result ? new BigNumber(reverseHex(res.Result.Result), 16).toString() : 0; + console.log('balance : ', val2); + }, 10000); +}); diff --git a/test/oep5.test.ts b/test/oep5.test.ts new file mode 100644 index 0000000..70c85bb --- /dev/null +++ b/test/oep5.test.ts @@ -0,0 +1,204 @@ +import RestClient from '../src/network/rest/restClient'; +import { Address } from './../src/crypto/address'; +import { PrivateKey } from './../src/crypto/PrivateKey'; +import { WebsocketClient } from './../src/network/websocket/websocketClient'; +import { Oep5Param, Oep5TxBuilder } from './../src/smartcontract/neovm/oep5TxBuilder'; + +import { addSign, signTransaction } from './../src/transaction/transactionBuilder'; +import { hexstr2str, reverseHex } from './../src/utils'; +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +describe('test oep5', () => { + const private1 = new PrivateKey('5f2fe68215476abb9852cfa7da31ef00aa1468782d5ca809da5c4e1390b8ee45'); + const private2 = new PrivateKey('49855b16636e70f100cc5f4f42bc20a6535d7414fb8845e7310f8dd065a97221'); + const private3 = new PrivateKey('1094e90dd7c4fdfd849c14798d725ac351ae0d924b29a279a9ffa77d5737bd96'); + + const address1 = new Address('AQf4Mzu1YJrhz9f3aRkkwSm9n3qhXGSh4p'); + const address2 = new Address('AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX'); + const address3 = new Address('AVXf5w8WD2y6jV1Lzi36oSKYNif1C7Surc'); + + const codeHash = '93ce027f647dd2bd99545b089a77aca0f9ddb155'; + + const contractAddr = new Address(reverseHex(codeHash)); + const oep5 = new Oep5TxBuilder(contractAddr); + const gasPrice = '500'; + const gasLimit = '281571'; + // const url = TEST_DNA_URL.REST_URL; + const url = 'http://polaris1.ont.io:'; + const restClient = new RestClient(url + '20334'); + const socketClient = new WebsocketClient(url + '20335'); + let tokenId1 = ''; + let tokenId2 = ''; + let tokenId3 = ''; + let tokenId4 = ''; + + beforeAll(async () => { + const tx1 = oep5.makeQueryTokenIDByIndexTx(1); + const res1 = await restClient.sendRawTransaction(tx1.serialize(), true); + tokenId1 = res1.Result.Result; + + const tx2 = oep5.makeQueryTokenIDByIndexTx(2); + const res2 = await restClient.sendRawTransaction(tx2.serialize(), true); + tokenId2 = res2.Result.Result; + + const tx3 = oep5.makeQueryTokenIDByIndexTx(3); + const res3 = await restClient.sendRawTransaction(tx3.serialize(), true); + tokenId3 = res3.Result.Result; + + const tx4 = oep5.makeQueryTokenIDByIndexTx(4); + const res4 = await restClient.sendRawTransaction(tx4.serialize(), true); + tokenId4 = res4.Result.Result; + }); + + test('init', async () => { + const tx = oep5.makeInitTx(gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); + + test('getBalance', async () => { + const tx = oep5.makeQueryBalanceOfTx(address2); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + const val = res.Result.Result ? parseInt(reverseHex(res.Result.Result), 16) : 0; + // tslint:disable-next-line:no-console + console.log(val); + expect(val).toBeGreaterThan(0); + }); + + test('queryTokenID_1_ByIndex', async () => { + const tx = oep5.makeQueryTokenIDByIndexTx(1); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + tokenId1 = res.Result.Result; + console.log(tokenId1); + // tslint:disable-next-line:no-console + expect(tokenId1).toBeDefined(); + }); + + test('queryTokenID_2_ByIndex', async () => { + const tx = oep5.makeQueryTokenIDByIndexTx(2); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + tokenId2 = res.Result.Result; + // tslint:disable-next-line:no-console + expect(tokenId2).toBeDefined(); + }); + test('queryTokenID_3_ByIndex', async () => { + const tx = oep5.makeQueryTokenIDByIndexTx(3); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + tokenId3 = res.Result.Result; + // tslint:disable-next-line:no-console + expect(tokenId3).toBeDefined(); + }); + + test('transfer', async () => { + console.log(tokenId1); + const oep5Param = new Oep5Param(address2, tokenId1); + const tx = oep5.makeTransferTx(oep5Param, gasPrice, gasLimit, address2); + signTransaction(tx, private2); // payer's signature + addSign(tx, private1); // add owner's signature if payer and owner are not the same + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }, 10000); + + test('test_totalSupply', async () => { + const tx = oep5.makeQueryTotalSupplyTx(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + const val = parseInt(reverseHex(res.Result.Result), 16); + // tslint:disable-next-line:no-console + expect(val).toBeGreaterThan(0); + }, 10000); + + test('test_name', async () => { + const tx = oep5.makeQueryNameTx(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const val = hexstr2str(res.Result.Result); + console.log(val); + // tslint:disable-next-line:no-console + expect(val).toBeDefined(); + }, 10000); + + test('test_symbol', async () => { + const tx = oep5.makeQuerySymbolTx(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const val = hexstr2str(res.Result.Result); + // tslint:disable-next-line:no-console + console.log(val); + expect(val).toBeDefined(); + }); + + test('test_ownerOf', async () => { + const tx = oep5.makeOwnerOfTx(tokenId3); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + const address = new Address(res.Result.Result).toBase58(); + console.log(address); + // tslint:disable-next-line:no-console + expect(res).toBeTruthy(); + }, 10000); + + test('test_approve', async () => { + const tx = oep5.makeApproveTx(new Oep5Param(address3, tokenId3), gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); + + test('test_getApproved', async () => { + const tx = oep5.makeGetApprovedTx(tokenId3); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + const address = new Address(res.Result.Result).toBase58(); + console.log(address); + // tslint:disable-next-line:no-console + expect(res).toBeTruthy(); + }, 10000); + + test('test_takeOwnership', async () => { + const tx = oep5.makeTakeOwnershipTx(new Oep5Param(address3, tokenId3), gasPrice, gasLimit, address3); + signTransaction(tx, private3); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Result.State).toEqual(1); + }); + + test('test_transferMulti', async () => { + const param1 = new Oep5Param(address2, tokenId2); + const param2 = new Oep5Param(address2, tokenId4); + console.log(tokenId1); + console.log(tokenId4); + const tx = oep5.makeTransferMultiTx([param1, param2], gasPrice, gasLimit, address1); + signTransaction(tx, private1); + // addSign(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); +}); diff --git a/test/oep8.test.ts b/test/oep8.test.ts new file mode 100644 index 0000000..8465d92 --- /dev/null +++ b/test/oep8.test.ts @@ -0,0 +1,245 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { BigNumber } from 'bignumber.js'; +import { Account } from '../src/account'; +import { TEST_DNA_URL } from '../src/consts'; +import { PrivateKey } from '../src/crypto/PrivateKey'; +import { RestClient, WebsocketClient } from '../src/index'; +import { Oep8TxBuilder } from '../src/smartcontract/neovm/oep8TxBuilder'; +import { addSign, signTransaction } from '../src/transaction/transactionBuilder'; +import { hexstr2str, reverseHex } from '../src/utils'; +import { Result } from './../src/claim/attestNotifyEvent'; +import { Address } from './../src/crypto/address'; +import { Oep8State, TransferFrom } from './../src/smartcontract/neovm/oep8TxBuilder'; + +describe('test oep8', () => { + const private1 = new PrivateKey('5f2fe68215476abb9852cfa7da31ef00aa1468782d5ca809da5c4e1390b8ee45'); + const private2 = new PrivateKey('49855b16636e70f100cc5f4f42bc20a6535d7414fb8845e7310f8dd065a97221'); + const private3 = new PrivateKey('1094e90dd7c4fdfd849c14798d725ac351ae0d924b29a279a9ffa77d5737bd96'); + + // const account1 = Account.create(private1, '123456', 'Account1'); // AQf4Mzu1YJrhz9f3aRkkwSm9n3qhXGSh4p + // const account2 = Account.create(private2, '123456', 'Account2'); // AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX + // const account3 = Account.create(private3, '123456', 'Account3'); // AVXf5w8WD2y6jV1Lzi36oSKYNif1C7Surc + const address1 = new Address('AQf4Mzu1YJrhz9f3aRkkwSm9n3qhXGSh4p'); + const address2 = new Address('AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX'); + const address3 = new Address('AVXf5w8WD2y6jV1Lzi36oSKYNif1C7Surc'); + // console.log(account1.address.toBase58()); + // console.log(account2.address.toBase58()); + // console.log(account3.address.toBase58()); + + const codeHash = 'b2ae73193b07043e75de65edd4ad74b0fa6148b3'; + + const contractAddr = new Address(reverseHex(codeHash)); + const oep8 = new Oep8TxBuilder(contractAddr); + const gasPrice = '500'; + const gasLimit = '200000'; + // const url = TEST_DNA_URL.REST_URL; + const url = 'http://127.0.0.1:'; + const restClient = new RestClient(); + const socketClient = new WebsocketClient(); + // tokenId is from 1 to 7; + const tokenIds = [1, 2, 3, 4, 5, 6, 7]; + + test('test_init', async () => { + const tx = oep8.makeInitTx(gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }); + + test('test_query_Balance', async () => { + const tx = oep8.makeQueryBalanceOfTx(address1, 1); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + if (!res.Result.Result) { // balance is 0 + const balance = 0; + expect(balance).toEqual(0); + console.log(balance); + return; + } + const val = parseInt(reverseHex(res.Result.Result), 16); + console.log(val); + // tslint:disable-next-line:no-console + expect(val).toBeGreaterThan(0); + }, 10000); + + test('test_queryBalances', async () => { + const tx = oep8.makeQueryBalancesTx(address1); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + if (res.Result.Result) { // balance is 0 + const vals = res.Result.Result.map((v) => v ? parseInt(reverseHex(v), 16) : 0); + console.log('Token Ids: ["1", "2", "3", "4", "5", "6", "7", "8"]'); + console.log('Balances: ' + vals); + expect(vals[0]).toBeGreaterThan(0); + } + // tslint:disable-next-line:no-console + }, 10000); + + test('test_totalBalance', async () => { + const tx = oep8.makeQueryTotalBalanceTx(address2); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + if (!res.Result.Result) { // balance is 0 + const balance = 0; + expect(balance).toEqual(0); + console.log(balance); + return; + } + const val = parseInt(reverseHex(res.Result.Result), 16); + console.log(val); + // tslint:disable-next-line:no-console + expect(val).toBeGreaterThan(0); + }, 10000); + + test('test_makeTransfer', async () => { + const tx = oep8.makeTransferTx(address1, address2, 1, '1', gasPrice, gasLimit, address2); + signTransaction(tx, private2); + addSign(tx, private1); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }, 10000); + + test('test_totalSupply', async () => { + const tx = oep8.makeQueryTotalSupplyTx(1); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + const val = parseInt(reverseHex(res.Result.Result), 16); + // tslint:disable-next-line:no-console + expect(val).toBeGreaterThan(0); + }, 10000); + + test('test_name', async () => { + const tx = oep8.makeQueryNameTx(1); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const val = hexstr2str(res.Result.Result); + console.log(val); + // tslint:disable-next-line:no-console + expect(val).toBeDefined(); + }, 10000); + + test('test_symbol', async () => { + const tx = oep8.makeQuerySymbolTx(1); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + const val = hexstr2str(res.Result.Result); + // tslint:disable-next-line:no-console + console.log(val); + expect(val).not.toBeNull(); + }); + + test('test_decimals', async () => { + const tx = oep8.makeQueryDecimalsTx(); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + const val = res.Result; + console.log(val); + // tslint:disable-next-line:no-console + expect(val).toBeTruthy(); + }, 10000); + + // Amount to approve can not exceed balance. + test('test_approve', async () => { + const tx = oep8.makeApproveTx(address1, address3, 1, '10', gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Result.State).toEqual(1); + }); + + test('test_queryAllowance', async () => { + const tx = oep8.makeQueryAllowanceTx(address1, address3, 4); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + // const val = parseInt(reverseHex(res.Result.Result), 16); + const val = new BigNumber(reverseHex(res.Result.Result), 16).toString(); + console.log(val); + expect(res).toBeDefined(); // it will change after transferFrom + }); + + test('test_transferFrom_error', async () => { + const tx = oep8.makeTransferFromTx(address3, address1, address3, 1, '15', gasPrice, gasLimit, address3); + signTransaction(tx, private3); + let res; + res = await restClient.sendRawTransaction(tx.serialize(), false); + console.log(JSON.stringify(res)); + expect(res.Error).toEqual(-1); + }); + + test('test_transferFrom_right', async () => { + const tx = oep8.makeTransferFromTx(address3, address1, address3, 1, '9', gasPrice, gasLimit, address3); + signTransaction(tx, private3); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(res); + expect(res.Result.State).toEqual(1); + }); + + test('test_transferMulti', async () => { + const state1 = new Oep8State(address1, address2, 3, '3'); + const state2 = new Oep8State(address1, address3, 3, '4'); + const tx = oep8.makeTransferMultiTx([state1, state2], gasPrice, gasLimit, address3); + signTransaction(tx, private3); + addSign(tx, private1); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(JSON.stringify(res)); + expect(res.Result.State).toEqual(1); + }); + + test('test_approveMulti', async () => { + const state1 = new Oep8State(address1, address2, 4, '4'); + const state2 = new Oep8State(address1, address3, 4, '5'); + const tx = oep8.makeApproveMulti([state1, state2], gasPrice, gasLimit, address2); + signTransaction(tx, private2); // payer's signature + addSign(tx, private1); // sender's signature + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(JSON.stringify(res)); + expect(res.Result.State).toEqual(1); + }); + + test('test_transferFromMulti', async () => { + const tf1 = new TransferFrom(address2, address1, address2, 4, '4'); + const tf2 = new TransferFrom(address3, address1, address3, 4, '5'); + const tx = oep8.makeTransferFromMulti([tf1, tf2], gasPrice, gasLimit, address3); + signTransaction(tx, private3); + addSign(tx, private2); // spender1 + addSign(tx, private2); // spender2 + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(JSON.stringify(res)); + expect(res.Result.State).toEqual(1); + }); + + test('test_compound', async () => { + const tx = oep8.makeCompoundTx(address1, 100000, gasPrice, gasLimit, address1); + signTransaction(tx, private1); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(JSON.stringify(res)); + /* +{"Action":"Notify","Desc":"SUCCESS","Error":0,"Result":{"TxHash":"1a2186eac5bdf214706c71cf3e889a1141c3fd76a70d261e5de2e931554e3482","State":1,"GasConsumed":0,"Notify":[{"Contra +ctAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98","States":["7472616e73666572","aa6e06c79f864152ab7f3139074aad822ffea855","00","01","04"]},{"ContractAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98","States":["7472616e73666572","aa6e06c79f864152ab7f3139074aad822ffea855","00","02","04"]},{"ContractAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98","States":["7472616e73666572","aa6e06c79f864152ab7f3139074aad822ffea855","00","03","04"]},{"ContractAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98","States":["7472616e73666572","aa6e06c79f864152ab7f3139074aad822ffea855","00","04","04"]},{"ContractAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98","States":["7472616e73666572","aa6e06c79f864152ab7f3139074aad822ffea855","00","05","04"]},{"ContractAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98","States":["7472616e73666572","aa6e06c79f864152ab7f3139074aad822ffea855","00","06","04"]},{"ContractAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98","States":["7472616e73666572","aa6e06c79f864152ab7f3139074aad822ffea855","00","07","04"]},{"ContractAddress":"c411141fa6ec39a34aac291dbec5c1622eb5ae98", +"States":["7472616e73666572","00","aa6e06c79f864152ab7f3139074aad822ffea855","08","04"]}]},"Version":"1.0.0"} + */ + expect(res.Result.State).toEqual(1); + const compoundResult = res.Result.Notify[7]; + const compoundedNum = compoundResult.States[4] ? parseInt(compoundResult.States[4], 16) : 0; + expect(compoundedNum).toBeGreaterThan(0); + }); +}); diff --git a/test/pri.test.ts b/test/pri.test.ts new file mode 100644 index 0000000..1514d0f --- /dev/null +++ b/test/pri.test.ts @@ -0,0 +1,37 @@ +import { PrivateKey } from '../src/crypto/PrivateKey'; +import { str2hexstr } from '../src/utils'; +import { Account } from './../src/account'; +import { Address } from './../src/crypto/address'; +import { PublicKey } from './../src/crypto/PublicKey'; + +describe('private', () => { + + function createDec() { + const params = { + cost: 16384, // 除以2时间减半 + blockSize: 8, + parallel: 8, + size: 64 + }; + const password = '$Pass1234'; + const pri = PrivateKey.random(); + const account = Account.create(pri, password, '', params); + const accountObj = account.toJsonObj(); + const enc = new PrivateKey(accountObj.key); + const addr = new Address(accountObj.address); + let pri2; + try { + pri2 = enc.decrypt(password, addr, accountObj.salt, params); + } catch (err) { + console.log('Found: '); + console.log('Pri1: ' + pri.key); + console.log('Pri2: ' + pri2.key); + throw Error('Found'); + } + } + test('500', () => { + for (let i = 1; i <= 1000; i++ ) { + createDec(); + } + }); +}); diff --git a/test/restClient.test.ts b/test/restClient.test.ts new file mode 100644 index 0000000..2bf729d --- /dev/null +++ b/test/restClient.test.ts @@ -0,0 +1,207 @@ +import { Account } from '../src/account'; +import { PrivateKey } from '../src/crypto'; +import { Address } from '../src/crypto/address'; +import { Identity } from '../src/identity'; +import RestClient from '../src/network/rest/restClient'; +import RpcClient from '../src/network/rpc/rpcClient'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { buildGetDDOTx, buildRegisterDNAidTx } from '../src/smartcontract/nativevm/idContractTxBuilder'; +import { signTransaction } from '../src/transaction/transactionBuilder'; +import { addSign } from './../src/transaction/transactionBuilder'; + +// tslint:disable:no-console +describe('test restClient', () => { + const rest = new RestClient('http://127.0.0.1:20334'); + + const codeHash = '36bb5c053b6b839c8f6b923fe852f91239b9fccc'; + + let txHash: string; + let blockHash: string; + let height: number = 10000; + + const privateKey = PrivateKey.random(); + const publicKey = privateKey.getPublicKey(); + const account = Account.create(privateKey, '123456', ''); + const identity = Identity.create(privateKey, '123456', ''); + const dnaid = identity.dnaid; + const address = account.address; + + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + + /** + * Registers new DNA ID to create transaction with Events and new block + */ + beforeAll(async () => { + const tx = buildRegisterDNAidTx(dnaid, publicKey, '500', '30000'); + tx.payer = adminAddress; + signTransaction(tx, adminPrivateKey); + addSign(tx, privateKey); + + const client = new WebsocketClient('ws://127.0.0.1:20335'); + const result = await client.sendRawTransaction(tx.serialize(), false, true); + txHash = result.Result.TxHash; + }, 5000); + + test('test sendRawTransaction', async () => { + const tx = buildGetDDOTx(dnaid); + const res = await rest.sendRawTransaction(tx.serialize(), true); + console.log(res); + expect(res.Result).toBeDefined(); + }); + + test('test getRawTransaction', async () => { + const res = await rest.getRawTransaction(txHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test getRawTransactionJson', async () => { + const res = await rest.getRawTransactionJson(txHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + // test('test GenerateBlockTime', async () => { + // const res = await rest.getGenerateBlockTime(); + // console.log(res); + // // expect(res.Result).toBeTruthy(); + // expect(res.Result).toBeFalsy(); + // }); + + test('test getNodeCount', async () => { + const res = await rest.getNodeCount(); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + /** + * Gets current block height to be used by following tests. + */ + test('1getBlockHeight', async () => { + const response = await rest.getBlockHeight(); + console.log(response); + expect(response).toBeDefined(); + expect(response.Result).toBeDefined(); + height = response.Result; + const rpc = new RpcClient(); + const res = await rpc.getBlockHeight(); + console.log(res); + }); + + test('test getBlock by height', async () => { + const res = await rest.getBlock(height); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + /** + * Gets block hash to be used by following tests. + */ + test('test getBlockJson by height', async () => { + const res = await rest.getBlockJson(height); + console.log(res); + expect(res.Result).toBeTruthy(); + expect(res.Result.Hash).toBeDefined(); + blockHash = res.Result.Hash; + }); + + test('test getBlock by hash', async () => { + const res = await rest.getBlock(blockHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test getBlockJson by hash', async () => { + const res = await rest.getBlockJson(blockHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test getBalance', async () => { + const res = await rest.getBalance(address); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test getContract', async () => { + const res = await rest.getContract(codeHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test getContractJson', async () => { + const res = await rest.getContractJson(codeHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test smartCodeEvent by hash', async () => { + const res = await rest.getSmartCodeEvent(txHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test smartCodeEvent by height', async () => { + const res = await rest.getSmartCodeEvent(height); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test('test getBlockHeightByTxHash', async () => { + const res = await rest.getBlockHeightByTxHash(txHash); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + test.skip('test getStorage', async () => { + const key = '2a6469643a6f6e743a5443375a6b556a62694e36794b61415433687735567a714c713138587538635a4a5702'; + const res = await rest.getStorage(codeHash, key); + console.log(res); + expect(res.Result).toBeTruthy(); + }); + + // wait for update this api in testnet + test('test getMerkleProof', async () => { + const res = await rest.getMerkleProof(txHash); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getBlockTxsByHeight', async () => { + const res = await rest.getBlockTxsByHeight(height); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getGasPrice', async () => { + const res = await rest.getGasPrice(); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getGrangOng', async () => { + const res = await rest.getGrangOng(adminAddress); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getMempoolTxCount', async () => { + const res = await rest.getMempoolTxCount(); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getMempoolTxState', async () => { + const txHash = '6f3c0da62e83c126c7e3b2381d5fd6d2513026afcabea295f0a8dd8bcca2a7ad'; + const res = await rest.getMempoolTxState(txHash); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getVersion', async () => { + const res = await rest.getVersion(); + console.log(res); + expect(res).toBeDefined(); + }); +}); diff --git a/test/rpcClient.test.ts b/test/rpcClient.test.ts new file mode 100644 index 0000000..38cd7fb --- /dev/null +++ b/test/rpcClient.test.ts @@ -0,0 +1,197 @@ +import { Account } from '../src/account'; +import { PrivateKey } from '../src/crypto'; +import { Address } from '../src/crypto/address'; +import { Identity } from '../src/identity'; +import RpcClient from '../src/network/rpc/rpcClient'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { buildGetDDOTx, buildRegisterDNAidTx } from '../src/smartcontract/nativevm/idContractTxBuilder'; +import { signTransaction } from '../src/transaction/transactionBuilder'; +import { addSign } from './../src/transaction/transactionBuilder'; + +// tslint:disable:no-console +describe('test rpc client', () => { + const rpcClient = new RpcClient('http://127.0.0.1:20336'); + + const codeHash = '36bb5c053b6b839c8f6b923fe852f91239b9fccc'; + + let txHash: string; + let blockHash: string; + let height: number; + + const privateKey = PrivateKey.random(); + const publicKey = privateKey.getPublicKey(); + const account = Account.create(privateKey, '123456', ''); + const identity = Identity.create(privateKey, '123456', ''); + const dnaid = identity.dnaid; + const address = account.address; + + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + + /** + * Registers new DNA ID to create transaction with Events and new block + */ + beforeAll(async () => { + const tx = buildRegisterDNAidTx(dnaid, publicKey, '500', '30000'); + tx.payer = adminAddress; + signTransaction(tx, adminPrivateKey); + addSign(tx, privateKey); + + const client = new WebsocketClient('ws://127.0.0.1:20335'); + const result = await client.sendRawTransaction(tx.serialize(), false, true); + txHash = result.Result.TxHash; + }, 10000); + + /** + * Gets current block height to be used by following tests. + */ + test('test getBlockHeight', async () => { + const res = await rpcClient.getBlockHeight(); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + expect(res.result).toBeDefined(); + height = res.result - 1; + }); + + /** + * Gets block hash to be used by following tests. + */ + test('test getBlockJson by height', async () => { + const res = await rpcClient.getBlockJson(height); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + expect(res.result).toBeTruthy(); + expect(res.result.Hash).toBeDefined(); + blockHash = res.result.Hash; + }); + + test('test getBlock by height', async () => { + const res = await rpcClient.getBlock(height); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test sendRawTransaction', async () => { + const tx = buildGetDDOTx(dnaid); + const res = await rpcClient.sendRawTransaction(tx.serialize(), true); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getRawTransaction', async () => { + const res = await rpcClient.getRawTransaction(txHash); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getRawTransactionJson', async () => { + const res = await rpcClient.getRawTransactionJson(txHash); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + // test('test getGenerateBlockTime', async () => { + // const res = await rpcClient.getGenerateBlockTime(); + // expect(res.desc).toEqual('SUCCESS'); + // }); + + test('test getNodeCount', async () => { + const res = await rpcClient.getNodeCount(); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getBlockJson', async () => { + const res = await rpcClient.getBlockJson(blockHash); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getBalance', async () => { + const res = await rpcClient.getBalance(address); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getContract', async () => { + const res = await rpcClient.getContract(codeHash); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getContractJson', async () => { + const res = await rpcClient.getContractJson(codeHash); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getBlock by hash', async () => { + const res = await rpcClient.getBlock(blockHash); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getBlockCount', async () => { + const res = await rpcClient.getBlockCount(); + console.log(res); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getSmartCodeEvent by height', async () => { + const res = await rpcClient.getSmartCodeEvent(height); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getSmartCodeEvent by hash', async () => { + const res = await rpcClient.getSmartCodeEvent(txHash); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getBlockHeightByTxHash', async () => { + const res = await rpcClient.getBlockHeightByTxHash(txHash); + expect(res.desc).toEqual('SUCCESS'); + }); + + test('test getStorage', async () => { + const key = '2a6469643a6f6e743a5443375a6b556a62694e36794b61415433687735567a714c713138587538635a4a5702'; + const res = await rpcClient.getStorage(codeHash, key); + console.log('getStorage'); + console.log(res); + expect(res.result).toBeDefined(); + }); + + // wait for update this api in testnet + /* test('test getMerkleProof', async () => { + let hash = '8893c8648d8dfad8f99274e1bdd3abb3cd47ba87cb54543c0594ac9cf7110888' + let res = await rpcClient.getMerkleProof(hash) + expect(res.desc).toEqual('SUCCESS') + }) */ + + test('test_getBlockTxsByHeight', async () => { + const res = await rpcClient.getBlockTxsByHeight(height); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getGasPrice', async () => { + const res = await rpcClient.getGasPrice(); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getMempoolTxCount', async () => { + const res = await rpcClient.getMempoolTxCount(); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getMempoolTxState', async () => { + // const txHash = '6f3c0da62e83c126c7e3b2381d5fd6d2513026afcabea295f0a8dd8bcca2a7ad'; + const res = await rpcClient.getMempoolTxState(txHash); + console.log(res); + expect(res).toBeDefined(); + }); + + test('test_getVersion', async () => { + const res = await rpcClient.getVersion(); + console.log(res); + expect(res).toBeDefined(); + }); +}); diff --git a/test/scParams.test.ts b/test/scParams.test.ts new file mode 100644 index 0000000..647c85d --- /dev/null +++ b/test/scParams.test.ts @@ -0,0 +1,172 @@ +import BigNumber from 'bignumber.js'; +import * as Long from 'long'; +import { PrivateKey } from '../src/crypto/PrivateKey'; +import { RestClient, Struct } from '../src/index'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { createCodeParamsScript, deserializeItem } from '../src/transaction/scriptBuilder'; +import { bigIntFromBytes, bigIntToBytes, hexstr2str, hexstring2ab, num2hexstring, reverseHex, str2hexstr, StringReader } from '../src/utils'; +import { Account } from './../src/account'; +import { Address } from './../src/crypto/address'; +import { Parameter, ParameterType } from './../src/smartcontract/abi/parameter'; +import { makeInvokeTransaction, signTransaction } from './../src/transaction/transactionBuilder'; +import { reverseHex } from './../src/utils'; + +describe('test smarct contract params', () => { + const socketClient = new WebsocketClient('ws://127.0.0.1:20335'); + const restClient = new RestClient('http://127.0.0.1:20334'); + + const privateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b93'); + const account = Account.create(privateKey, '123456', 'test'); + console.log(account.address.toBase58()); + test('test_params_Array', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testHello'; + + const params = [ + new Parameter('op', ParameterType.String, 'test'), + new Parameter('args', ParameterType.Array, + [ + new Parameter('arg1', ParameterType.Boolean, false), + new Parameter('arg2', ParameterType.Integer, 3), + // new Parameter('arg3', ParameterType.ByteArray, account.address.serialize()), + new Parameter('arg3', ParameterType.Address, account.address), + new Parameter('arg4', ParameterType.String, 'arg4') + ] + ) + ]; + + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(JSON.stringify(res)); + }, 10000); + + test('test_list', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testList'; + + const params = [ + new Parameter('args', ParameterType.Array, + [ + new Parameter('arg1', ParameterType.String, 'test') + ] + ) + ]; + console.log(JSON.stringify(params)); + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await socketClient.sendRawTransaction(tx.serialize(), false, true); + console.log(JSON.stringify(res)); + }, 10000); + + test('testMap', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testMap'; + + const params = [ + new Parameter('args', ParameterType.Map, + { key : new Parameter('', ParameterType.String, 'test'), + key2: new Parameter('', ParameterType.String, 'test') + } + ) + ]; + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await restClient.sendRawTransaction(tx.serialize(), false); + console.log(JSON.stringify(res)); + }, 10000); + + test('testGetmap', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testGetMap'; + + const params = [ + new Parameter('args', ParameterType.String, 'key') + ]; + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + const val = hexstr2str(res.Result.Result); + expect(val).toEqual('test'); + }, 10000); + + test('testMapInMap', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testMapInMap'; + + const params = [ + new Parameter('args', ParameterType.Map, + { + key: new Parameter('', ParameterType.String, 'hello2'), + key2: new Parameter('', ParameterType.ByteArray, 'aabb'), + key3: new Parameter('', ParameterType.Integer, 100), + key4: new Parameter('', ParameterType.Boolean, true), + key5: new Parameter('', ParameterType.Array, [ + new Parameter('', ParameterType.String, 'hello'), + new Parameter('', ParameterType.Integer, 100) + ]), + key6: new Parameter('', ParameterType.Map, { + key: new Parameter('', ParameterType.String, 'hello2'), + key1: new Parameter('', ParameterType.Boolean, true), + key3: new Parameter('', ParameterType.Integer, 100) + }) + } + + ) + ]; + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await socketClient.sendRawTransaction(tx.serialize(), false); + console.log(JSON.stringify(res)); + }, 10000); + + test('testMapInNestedMap', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testMapInMap'; + + const params = [ + new Parameter('', ParameterType.Map, { + key: new Parameter('name', ParameterType.Map, + { + key: new Parameter('', ParameterType.String, 'Hello') + } + ) + }) + ]; + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await restClient.sendRawTransaction(tx.serialize(), false); + console.log(JSON.stringify(res)); + }, 10000); + + test('testGetMapInMap', async () => { + const contract = reverseHex('eb7f5d8314b8c71532420bd675408b52e5805c9e'); + const contractAddr = new Address(contract); + const method = 'testGetMapInMap'; + + const params = [ + new Parameter('', ParameterType.String, 'key') + ]; + const tx = makeInvokeTransaction(method, params, contractAddr, '500', '20000', account.address); + signTransaction(tx, privateKey); + const res = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(res)); + const val = hexstr2str(res.Result.Result); + expect(val).toEqual('Hello'); + }) + + test('deserialize_item', () => { + const hex = '820600036b6579000668656c6c6f3200046b6579320002aabb00046b65793302016400046b657934010100046b6579358002000568656c6c6f02016400046b657936820300036b6579000668656c6c6f3200046b657931010100046b657933020164'; + const sr = new StringReader(hex); + const val = deserializeItem(sr); + expect(val.get('key5').length).toEqual; + console.log(val); + }); +}); + diff --git a/test/scrypt.test.ts b/test/scrypt.test.ts new file mode 100644 index 0000000..8a77e11 --- /dev/null +++ b/test/scrypt.test.ts @@ -0,0 +1,120 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ +import * as CryptoJS from 'crypto-js'; +import * as secureRandom from 'secure-random'; +import { Account } from '../src/account'; +import { Address, CurveLabel, KeyParameters, KeyType , PrivateKey } from '../src/crypto'; +import { ERROR_CODE } from '../src/error'; +import { utils } from '../src/index'; +import * as scrypt from '../src/scrypt'; +import { ab2hexstring, isBase64, str2hexstr } from '../src/utils'; +import { PublicKey } from './../src/crypto/PublicKey'; + +describe('test scrypt', () => { + test('test_encryptCtr', () => { + // const privateKey = PrivateKey.random(); + const privateKey = new PrivateKey('40b6b5a45bc3ba6bd4f49b0c6b024d5c6851db4cdf1a99c2c7adad9675170b07'); + const publicKey = privateKey.getPublicKey().serializeHex(); + const address = Address.fromPubKey(privateKey.getPublicKey()); + // tslint:disable-next-line:no-console + console.log('add: ' + address.toBase58()); + + const encrypt = scrypt.encryptWithCtr(privateKey.key, publicKey, '123456'); + // tslint:disable-next-line:no-console + console.log('encrypt: ' + encrypt); + expect(encrypt).toBeDefined(); + const decrypt = scrypt.decryptWithCtr(encrypt, '123456', address); + expect(decrypt).toEqual(privateKey.key); + }); + + test('test_enc_mnemonic', () => { + const salt = ab2hexstring(secureRandom(16)); + const mnemonic = 'doll remember harbor resource desert curious fatigue nature arrest fix nation rhythm'; + const mnemonicHex = utils.str2hexstr(mnemonic); + // generate privateKey + const password = '123456'; + const privateKey = PrivateKey.generateFromMnemonic(mnemonic); + const pub = privateKey.getPublicKey(); + const address = Address.fromPubKey(pub); + const encMne = scrypt.encryptWithGcm( + mnemonicHex, address, salt, password); + const decMneHex = scrypt.decryptWithGcm(encMne, address, salt, '123456'); + // tslint:disable:no-console + console.log('privateKey: ' + privateKey.key); + console.log('encMne: ' + encMne); + + const decMne = utils.hexstr2str(decMneHex); + console.log('decMne: ' + decMne); + expect(decMne).toEqual(mnemonic); + + // tslint:disable-next-line:no-console + console.log('encMen: ' + encMne); + }); + + test('test_encWithEcb', () => { + const pri = new PrivateKey('40b6b5a45bc3ba6bd4f49b0c6b024d5c6851db4cdf1a99c2c7adad9675170b07'); + const pub = pri.getPublicKey(); + + const enc = scrypt.encryptWithEcb(pri.key, pub.serializeHex(), '123456'); + + const dec = scrypt.decryptWithEcb(enc, '123456'); + expect(dec).toEqual(pri.key); + const decPri = new PrivateKey(dec); + const decPub = decPri.getPublicKey(); + scrypt.checkEcbDecrypted(enc, dec, decPub.serializeHex()); + + }); + + test('test_gcm', () => { + const salt = ab2hexstring(secureRandom(16)); + const pri = new PrivateKey('40b6b5a45bc3ba6bd4f49b0c6b024d5c6851db4cdf1a99c2c7adad9675170b07'); + const pub = pri.getPublicKey(); + const address = Address.fromPubKey(pub); + + const enc = scrypt.encryptWithGcm(pri.key, address, salt, '123456'); + console.log('enc: ' + JSON.stringify(enc)); + + const dec = scrypt.decryptWithGcm(enc, address, salt, '123456'); + console.log('dec: ' + dec); + expect(dec).toEqual(pri.key); + + }); + + test('test_isBase64', () => { + const salt = 'q0uJFA3mLo0g0VMH9r1fFA=='; + expect(isBase64(salt)).toBeTruthy(); + const str = '123'; + expect(isBase64(str)).toBeFalsy(); + }); + + test('test_scrypt', () => { + const pri = new PrivateKey('6717c0df45159d5b5ef383521e5d8ed8857a02cdbbfdefeeeb624f9418b0895e'); + // const key = 'dRiHlKa16kKGuWEYWhXUxvHcPlLiJcorAN3ocZ9fQ8p832p4OdIIiy+kR6eImjYd' + const salt = Buffer.from('sJwpxe1zDsBt9hI2iA2zKQ==', 'base64').toString('hex'); + const address = new Address('AakBoSAJapitE4sMPmW7bs8tfT4YqPeZEU'); + const encrypt = pri.encrypt('11111111', address, salt); + console.log('encrypt: ' + encrypt); + const params = { + + }; + + // const key = 'dRiHlKa16kKGuWEYWhXUxvHcPlLiJcorAN3ocZ9fQ8p832p4OdIIiy+kR6eImjYd' + // const decrypt = scrypt.decryptWithGcm(key, address, salt, '11111111'); + // console.log('decrypt: ' + decrypt); + }); +}); diff --git a/test/sm.crypto.test.ts b/test/sm.crypto.test.ts new file mode 100644 index 0000000..c07d6f4 --- /dev/null +++ b/test/sm.crypto.test.ts @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { sm2 } from 'sm.js'; +import { CurveLabel, KeyParameters, KeyType, PrivateKey, PublicKey, Signature, SignatureScheme } from '../src/crypto'; +import { Address } from '../src/crypto/address'; +import { ab2hexstring, ab2str, str2ab, str2hexstr } from '../src/utils'; + +describe('SM2 and SM3 cryptographics functions tests', () => { + test('test SM3 hash', () => { + const key: PrivateKey = PrivateKey.random(KeyType.SM2); + + const msg = 'test'; + const encoded = str2hexstr(msg); + + const hash = key.computeHash(encoded, SignatureScheme.SM2withSM3); + + expect(hash).toEqual('55e12e91650d2fec56ec74e1d3e4ddbfce2ef3a65890c2a19ecf88a307e76a23'); + }); + + test('test SM2 sign and verify', () => { + const msg = 'test'; + const encoded = str2hexstr(msg); + + const pk = 'ab80a7ad086249c01e65c4d9bb6ce18de259dcfc218cd49f2455c539e9112ca3'; + const privateKey = new PrivateKey(pk, KeyType.SM2, new KeyParameters(CurveLabel.SM2P256V1)); + + const signature = privateKey.sign(encoded, SignatureScheme.SM2withSM3); + // tslint:disable-next-line:no-console + console.log('signature', signature.value); + + const publicKey = privateKey.getPublicKey(); + + const result = publicKey.verify(encoded, signature); + expect(result).toBeTruthy(); + }); + + test('test SM2 verify java SDK generated signature', () => { + const msg = 'test'; + const encoded = str2hexstr(msg); + + const signature = new Signature( + SignatureScheme.SM2withSM3, + // tslint:disable-next-line:max-line-length + '3132333435363738313233343536373800bc1d431f932afb7b809627f051c1b5c10ee22e470aea4623c3281231dd513779ca1171f4f3bbf414f089e8c963f715b3376007008206a2b9ebb252dd6883dbce' + ); + + const publicKey = new PublicKey( + '031220580679fda524f575ac48b39b9f74cb0a97993df4fac5798b04c702d07a39', + KeyType.SM2, + new KeyParameters(CurveLabel.SM2P256V1) + ); + + const result = publicKey.verify(encoded, signature); + expect(result).toBeTruthy(); + }); + + test('verifySSS', () => { + const signature = Signature.deserializeHex('01cf157a48216bfcd455a97a39c0ad65bd1b27d1da07965b19848146045c9f2e5a12f905a5ee0923412d589e615a5d6954c58cade367dce67fcf13eaa82c12e87a'); + const msg = str2hexstr('sss'); + const pk = new PublicKey('035384561673e76c7e3003e705e4aa7aee67714c8b68d62dd1fb3221f48c5d3da0'); + const result = pk.verify(msg, signature); + console.log(result); + }); +}); diff --git a/test/smartcontract_abi_parameter.test.ts b/test/smartcontract_abi_parameter.test.ts new file mode 100644 index 0000000..043e73e --- /dev/null +++ b/test/smartcontract_abi_parameter.test.ts @@ -0,0 +1,52 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { Parameter, ParameterType } from '../src/smartcontract/abi/parameter'; + +describe('test smartcontract.abi.parameter', () => { + test('test setValue with 0', () => { + const p = new Parameter('test', ParameterType.Integer, 123); + const result = p.setValue({ + name: 'test', + type: ParameterType.Integer, + value: 0 + }); + expect(result).toBeTruthy(); + expect(p.getValue()).toEqual(0); + }); + test('test setValue with false', () => { + const p = new Parameter('test', ParameterType.Boolean, true); + const result = p.setValue({ + name: 'test', + type: ParameterType.Boolean, + value: false + }); + expect(result).toBeTruthy(); + expect(p.getValue()).toEqual(false); + }); + test('test setValue with null', () => { + const p = new Parameter('test', ParameterType.Integer, 123); + const result = p.setValue({ + name: 'test', + type: ParameterType.Integer, + value: null + }); + expect(result).toBeFalsy(); + expect(p.getValue()).toEqual(123); + }); +}); diff --git a/test/transactionBuilder.test.ts b/test/transactionBuilder.test.ts new file mode 100644 index 0000000..6967ea1 --- /dev/null +++ b/test/transactionBuilder.test.ts @@ -0,0 +1,265 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ +import { DDO } from '../src'; +import { Address, PrivateKey } from '../src/crypto'; +import RestClient from '../src/network/rest/restClient'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { Parameter, ParameterType } from '../src/smartcontract/abi/parameter'; +import { Transaction } from '../src/transaction/transaction'; +import { makeInvokeTransaction, makeTransactionsByJson } from '../src/transaction/transactionBuilder'; +import { signTransaction } from '../src/transaction/transactionBuilder'; +import { reverseHex } from '../src/utils'; + +describe('test AbiInfo', () => { + + test('makeTransactionByJson', async () => { + const private2 = new PrivateKey('49855b16636e70f100cc5f4f42bc20a6535d7414fb8845e7310f8dd065a97221'); + const address2 = new Address('AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX'); + const restClient = new RestClient(); + const json = { + action: 'invoke', + params: { + login: true, + message: 'invoke smart contract test', + invokeConfig: { + contractHash: 'cd948340ffcf11d4f5494140c93885583110f3e9', + functions: [{ + operation: 'transferNativeAsset', + args: [{ + name: 'arg0', + value: 'String:ont' + }, { + name: 'arg1', + value: 'Address:AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX' + }, { + name: 'arg2', + value: 'Address:AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ' + }, { + name: 'arg3', + value: 1000000000 + }] + }], + gasLimit: 20000, + gasPrice: 500, + payer: 'AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX' + } + } + }; + const txs = makeTransactionsByJson(json); + signTransaction(txs[0], private2); + + const raw = '00d16009495df401000000000000204e000000000000aa6e06c79f864152ab7f3139074aad822ffea8555e0400ca9a3b14fa88f5244be19659bbd24477caeeacac7cbf781b14aa6e06c79f864152ab7f3139074aad822ffea855036f6e7454c1137472616e736665724e6174697665417373657467e9f31031588538c9404149f5d411cfff408394cd0001414043443452de4b5374af440118b0a0c9f25fc31324ea23e9c5754fa335cfac776a795893d3accb6386a8d54ef616b2c9ead411704e3328a3e124584be8b174e5de232102df6f28e327352a44720f2b384e55034c1a7f54ba31785aa3a338f613a5b7cc26ac'; + const expectedTx = Transaction.deserialize(raw); + const match = txs[0].payload.code === expectedTx.payload.code; + expect(match).toEqual(false); + + const res = await restClient.sendRawTransaction(txs[0].serialize(), false); + console.log(res); + }); + + test('makeTransactionByJsonLedgerIncompatible', async () => { + const private2 = new PrivateKey('49855b16636e70f100cc5f4f42bc20a6535d7414fb8845e7310f8dd065a97221'); + const address2 = new Address('AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX'); + const restClient = new RestClient(); + const json = { + action: 'invoke', + params: { + login: true, + message: 'invoke smart contract test', + invokeConfig: { + contractHash: 'cd948340ffcf11d4f5494140c93885583110f3e9', + functions: [{ + operation: 'transferNativeAsset', + args: [{ + name: 'arg0', + value: 'String:ont' + }, { + name: 'arg1', + value: 'Address:AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX' + }, { + name: 'arg2', + value: 'Address:AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ' + }, { + name: 'arg3', + value: 1000000000 + }] + }], + gasLimit: 20000, + gasPrice: 500, + payer: 'AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX' + } + } + }; + const txs = makeTransactionsByJson(json, false); + signTransaction(txs[0], private2); + + const raw = '00d16009495df401000000000000204e000000000000aa6e06c79f864152ab7f3139074aad822ffea8555e0400ca9a3b14fa88f5244be19659bbd24477caeeacac7cbf781b14aa6e06c79f864152ab7f3139074aad822ffea855036f6e7454c1137472616e736665724e6174697665417373657467e9f31031588538c9404149f5d411cfff408394cd0001414043443452de4b5374af440118b0a0c9f25fc31324ea23e9c5754fa335cfac776a795893d3accb6386a8d54ef616b2c9ead411704e3328a3e124584be8b174e5de232102df6f28e327352a44720f2b384e55034c1a7f54ba31785aa3a338f613a5b7cc26ac'; + const expectedTx = Transaction.deserialize(raw); + const match = txs[0].payload.code === expectedTx.payload.code; + expect(match).toEqual(true); + + const res = await restClient.sendRawTransaction(txs[0].serialize(), false); + console.log(res); + }); + + test('makeInvokeTransaction', async () => { + const privateKey = new PrivateKey('49855b16636e70f100cc5f4f42bc20a6535d7414fb8845e7310f8dd065a97221'); + const address = 'AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX'; + + const addressParam1 = new Address(address); + const addressParam2 = new Address('AecaeSEBkt5GcBCxwz1F41TvdjX3dnKBkJ'); + + const param = new Parameter('arg0', ParameterType.String, 'ont'); + const param2 = new Parameter('arg1', ParameterType.ByteArray, addressParam1.serialize()); + const param3 = new Parameter('arg2', ParameterType.ByteArray, addressParam2.serialize()); + const param4 = new Parameter('arg3', ParameterType.Integer, 1000000000); + + const args = [param, param2, param3, param4]; + + const contractHash = 'cd948340ffcf11d4f5494140c93885583110f3e9'; + const contractAddr = new Address(reverseHex(contractHash)); + + const tx = makeInvokeTransaction('transferNativeAsset', args, contractAddr, 500, 20000, addressParam1); + const tx2 = makeInvokeTransaction('transferNativeAsset', args, contractAddr, 500, 20000, addressParam1, false); + + signTransaction(tx, privateKey); + signTransaction(tx2, privateKey); + + const raw = '00d16009495df401000000000000204e000000000000aa6e06c79f864152ab7f3139074aad822ffea8555e0400ca9a3b14fa88f5244be19659bbd24477caeeacac7cbf781b14aa6e06c79f864152ab7f3139074aad822ffea855036f6e7454c1137472616e736665724e6174697665417373657467e9f31031588538c9404149f5d411cfff408394cd0001414043443452de4b5374af440118b0a0c9f25fc31324ea23e9c5754fa335cfac776a795893d3accb6386a8d54ef616b2c9ead411704e3328a3e124584be8b174e5de232102df6f28e327352a44720f2b384e55034c1a7f54ba31785aa3a338f613a5b7cc26ac'; + const expectedTx = Transaction.deserialize(raw); + const match = tx.payload.code === expectedTx.payload.code; + expect(match).toEqual(false); + + const match2 = tx2.payload.code === expectedTx.payload.code; + expect(match2).toEqual(true); + }); + + test('makeTxFromJSON_transferONG', async () => { + const socketClient = new WebsocketClient('ws://polaris1.ont.io:20335'); + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + // tslint:disable:align + const json = { + action: 'invoke', + version: 'v1.0.0', + id: '10ba038e-48da-487b-96e8-8d3b99b6d18a', + params: { + invokeConfig: { + contractHash: '0200000000000000000000000000000000000000', + functions: [{ + operation: 'transfer', + args: [{ + name: 'arg0-from', + value: 'Address:AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz' + }, + { + name: 'arg1-to', + value: 'Address:AXK2KtCfcJnSMyRzSwTuwTKgNrtx5aXfFX' + }, + { + name: 'arg2-amount', + value: 'Long:1000000000' + } + ] + }], + payer: 'AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz', + gasLimit: 20000, + gasPrice: 500 + } + } + }; + const txs = makeTransactionsByJson(json); + signTransaction(txs[0], adminPrivateKey); + const res = await socketClient.sendRawTransaction(txs[0].serialize(), false); + console.log(res); + expect(res.Error).toEqual(0); + }); + + test('makeTxFromJSON_regDNAid', async () => { + const socketClient = new WebsocketClient('ws://polaris1.ont.io:20335'); + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + const pk = adminPrivateKey.getPublicKey().key; + // tslint:disable:align + const json = { + action: 'invoke', + version: 'v1.0.0', + id: '10ba038e-48da-487b-96e8-8d3b99b6d18a', + params: { + invokeConfig: { + contractHash: '0300000000000000000000000000000000000000', + functions: [{ + operation: 'regIDWithPublicKey', + args: [{ + name: 'arg0-dnaid', + value: 'String:did:dna:AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz' + }, + { + name: 'arg1-publickey', + value: 'ByteArray:' + pk + } + ] + }], + payer: 'AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz', + gasLimit: 20000, + gasPrice: 500 + } + } + }; + const txs = makeTransactionsByJson(json); + signTransaction(txs[0], adminPrivateKey); + const res = await socketClient.sendRawTransaction(txs[0].serialize(), false); + console.log(res); + expect(res.Error).toEqual(0); + }); + + test('makeTxFromJSON_getDDO', async () => { + const restClient = new RestClient(); + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + const pk = adminPrivateKey.getPublicKey().key; + // tslint:disable:align + const json = { + action: 'invoke', + version: 'v1.0.0', + id: '10ba038e-48da-487b-96e8-8d3b99b6d18a', + params: { + invokeConfig: { + contractHash: '0300000000000000000000000000000000000000', + functions: [{ + operation: 'getDDO', + args: [{ + name: 'arg0-dnaid', + value: 'String:did:dna:AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz' + } + ] + }], + payer: 'AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz', + gasLimit: 20000, + gasPrice: 500 + } + } + }; + const txs = makeTransactionsByJson(json); + const res = await restClient.sendRawTransaction(txs[0].serialize(), true); + const ddo = DDO.deserialize(res.Result.Result); + console.log(ddo); + expect(res.Error).toEqual(0); + }); + +}); diff --git a/test/transfer.sign.test.ts b/test/transfer.sign.test.ts new file mode 100644 index 0000000..494e909 --- /dev/null +++ b/test/transfer.sign.test.ts @@ -0,0 +1,49 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { Address, PrivateKey, Signature, SignatureScheme } from '../src/crypto'; +import { makeTransferTx } from '../src/smartcontract/nativevm/assetTxBuilder'; +import { signTransaction } from './../src/transaction/transactionBuilder'; + +// tslint:disable:no-console +// tslint:disable:max-line-length +// tslint:disable:quotemark +describe('test transfer sign', () => { + test('test canonical sign', async () => { + const mnemonics = 'immune annual decorate major humble surprise dismiss trend edit suit alert uncover release transfer suit torch small timber lock mind tomorrow north lend diet'; + const privateKey = PrivateKey.generateFromMnemonic(mnemonics, "m/44'/888'/0'/0/0"); + const publicKey = privateKey.getPublicKey(); + const address = Address.fromPubKey(publicKey); + + const from = new Address('AGn8JFPGM5S4jkWhTC89Xtz1Y76sPz29Rc'); + const to = new Address('AcyLq3tokVpkMBMLALVMWRdVJ83TTgBUwU'); + const tx = makeTransferTx('ONG', from, to, 12000000, '500', '30000'); + tx.nonce = 'eb1c7f7f'; + signTransaction(tx, privateKey); + + console.log(tx); + console.log('hash', tx.getHash()); + console.log('key ', privateKey.key); + console.log('pub ', publicKey.key); + console.log('sig ', tx.sigs[0].sigData[0]); + + // if canonical mode is not set, the result will be + // 017da1b8268e1272d7471eef58fa0884108073c09d5efdae0143da5d281019682ea5ea9d0d289b7b15fc861c01418fda56642be628560fe4d7ccdede930e620b5d + expect(tx.sigs[0].sigData[0]).toBe('017da1b8268e1272d7471eef58fa0884108073c09d5efdae0143da5d281019682e5a1562f1d76484eb0379e3febe7025a958bb14855107b9ad26daec2fee0119f4'); + }, 10000); +}); diff --git a/test/transfer.test.ts b/test/transfer.test.ts new file mode 100644 index 0000000..40f2e12 --- /dev/null +++ b/test/transfer.test.ts @@ -0,0 +1,206 @@ +/* +* Copyright (C) 2018 The DNA Authors +* This file is part of The DNA library. +* +* The DNA is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* The DNA is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with The DNA. If not, see . +*/ + +import { Address, CurveLabel, KeyParameters, KeyType, PrivateKey } from '../src/crypto'; +import { PublicKey } from '../src/crypto/PublicKey'; +import { SignatureScheme } from '../src/crypto/SignatureScheme'; +import RestClient from '../src/network/rest/restClient'; +import { makeApproveTx, makeTransferFromTx, makeTransferTx } from '../src/smartcontract/nativevm/assetTxBuilder'; +import { State } from '../src/smartcontract/nativevm/token'; +import { comparePublicKeys } from '../src/transaction/program'; +import { addSign } from '../src/transaction/transactionBuilder'; +// tslint:disable-next-line:max-line-length +import { reverseHex } from '../src/utils'; +import { WebsocketClient } from './../src/network/websocket/websocketClient'; +import { signTransaction, signTx } from './../src/transaction/transactionBuilder'; + +describe('test transfer asset', () => { + const socketClient = new WebsocketClient('ws://127.0.0.1:20335'); + const restClient = new RestClient('http://127.0.0.1:20334'); + const gasLimit = '20000'; + const gasPrice = '500'; + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b93'); + const adminAddress = new Address('AJkkLbouowk6teTaxz1F2DYKfJh24PVk3r'); + const toPrivateKey = new PrivateKey('cd19cfe79112f1339749adcb3491595753ea54687e78925cb5e01a6451244406'); + const toAddress = new Address('AU9TioM24rXk5E3tUGrv8jwgBA1aZVVKDW'); + const sm2Account = { + 'address': 'ATk57i8rMXFSBpHAdX3UQ4TNe48BBrfCoc', + 'label': 'sm2Account', + 'lock': false, + 'algorithm': 'SM2', + 'parameters': { curve: 'sm2p256v1' }, + 'key': 'jQUCWPZZN1tN0ghtsYHuLZoBGdFfUaRaofKSHEYctMIKLdN3Otv52Oi9d3ujNW2p', + 'enc-alg': 'aes-256-gcm', + 'salt': 'jn+zIuiOC5lrn+vrySF1Lw==', + 'isDefault': false, + 'publicKey': '1314031220580679fda524f575ac48b39b9f74cb0a97993df4fac5798b04c702d07a39', + 'signatureScheme': 'SM3withSM2' + }; + + const sleep = (time: number) => new Promise((resolve, reject) => { + setTimeout(() => { + resolve(); + }, time); + }); + + test('test_transfer_asset_GAS', async () => { + const from = adminAddress; + const to = new Address('AVDEiCVQzm7EffYH6vBQNXKYXR7RdVGNsA'); + const tx = makeTransferTx('GAS', from, to, 0.01 * 1e9, gasPrice, gasLimit); + console.log(tx.serializeUnsignedData()); + signTransaction(tx, adminPrivateKey); + const response = await socketClient.sendRawTransaction(tx.serialize(), false, true); + // tslint:disable:no-console + console.log(JSON.stringify(response)); + expect(response.Result.State).toEqual(1); + }, 10000); + + test('test_get_balance', async () => { + const to = new Address('AJkkLbouowk6teTaxz1F2DYKfJh24PVk3r'); + const result = await restClient.getBalance(to); + console.log(result); + expect(result).toBeTruthy(); + }, 10000); + + test('transfer with multi assign address', async () => { + // tslint:disable:max-line-length + const w = [{ name: 'MyWallet', version: '1.1', scrypt: { p: 8, n: 16384, r: 8, dkLen: 64 }, identities: null, accounts: [{ 'address': 'AXmQDzzvpEtPkNwBEFsREzApTTDZFW6frD', 'enc-alg': 'aes-256-gcm', 'key': 'YfOr9im4rOciy3cV7JkVo9QCfrRT4IGLa/CZKUJfL29pM6Zi1oVEM67+8MezMIro', 'algorithm': 'ECDSA', 'salt': 'RCIo60eCJAwzkTYmIfp3GA==', 'parameters': { curve: 'P-256' }, 'label': '', 'publicKey': '037c9e6c6a446b6b296f89b722cbf686b81e0a122444ef05f0f87096777663284b', 'signatureScheme': 'SHA256withECDSA', 'isDefault': true, 'lock': false }], extra: '' }, + { name: 'MyWallet', version: '1.1', scrypt: { p: 8, n: 16384, r: 8, dkLen: 64 }, identities: null, accounts: [{ 'address': 'AY5W6p4jHeZG2jjW6nS1p4KDUhcqLkU6jz', 'enc-alg': 'aes-256-gcm', 'key': 'gpgMejEHzawuXG+ghLkZ8/cQsOJcs4BsFgFjSaqE7SC8zob8hqc6cDNhJI/NBkk+', 'algorithm': 'ECDSA', 'salt': 'tuLGZOimilSnypT91WrenQ==', 'parameters': { curve: 'P-256' }, 'label': '', 'publicKey': '03dff4c63267ae5e23da44ace1bc47d0da1eb8d36fd71181dcccf0e872cb7b31fa', 'signatureScheme': 'SHA256withECDSA', 'isDefault': true, 'lock': false }], extra: '' }, + { name: 'MyWallet', version: '1.1', scrypt: { p: 8, n: 16384, r: 8, dkLen: 64 }, identities: null, accounts: [{ 'address': 'ALZVrZrFqoSvqyi38n7mpPoeDp7DMtZ9b6', 'enc-alg': 'aes-256-gcm', 'key': 'guffI05Eafq9F0j3/eQxHWGo1VN/xpeIkXysEPeH51C2YHYCNnCWTWAdqDB7lonl', 'algorithm': 'ECDSA', 'salt': 'oZPg+5YotRWStVsRMYlhfg==', 'parameters': { curve: 'P-256' }, 'label': '', 'publicKey': '0205bc592aa9121428c4144fcd669ece1fa73fee440616c75624967f83fb881050', 'signatureScheme': 'SHA256withECDSA', 'isDefault': true, 'lock': false }], extra: '' }, + { name: 'MyWallet', version: '1.1', scrypt: { p: 8, n: 16384, r: 8, dkLen: 64 }, identities: null, accounts: [{ 'address': 'AMogjmLf2QohTcGST7niV75ekZfj44SKme', 'enc-alg': 'aes-256-gcm', 'key': 'fAknSuXzMMC0nJ2+YuTpTLs6Hl5Dc0c2zHZBd2Q7vCuv8Wt97uYz1IU0t+AtrWts', 'algorithm': 'ECDSA', 'salt': '0BVIiUf46rb/e5dVZIwfrg==', 'parameters': { curve: 'P-256' }, 'label': '', 'publicKey': '030a34dcb075d144df1f65757b85acaf053395bb47b019970607d2d1cdd222525c', 'signatureScheme': 'SHA256withECDSA', 'isDefault': true, 'lock': false }], extra: '' }, + { name: 'MyWallet', version: '1.1', scrypt: { p: 8, n: 16384, r: 8, dkLen: 64 }, identities: null, accounts: [{ 'address': 'AZzQTkZvjy7ih9gjvwU8KYiZZyNoy6jE9p', 'enc-alg': 'aes-256-gcm', 'key': 'IufXVQfrL3LI7g2Q7dmmsdoF7BdoI/vHIsXAxd4qkqlkGBYj3pcWHoQgdCF+iVOv', 'algorithm': 'ECDSA', 'salt': 'zUtzh0B4UW0wokzL+ILdeg==', 'parameters': { curve: 'P-256' }, 'label': '', 'publicKey': '021844159f97d81da71da52f84e8451ee573c83b296ff2446387b292e44fba5c98', 'signatureScheme': 'SHA256withECDSA', 'isDefault': true, 'lock': false }], extra: '' }, + { name: 'MyWallet', version: '1.1', scrypt: { p: 8, n: 16384, r: 8, dkLen: 64 }, identities: null, accounts: [{ 'address': 'AKEqQKmxCsjWJz8LPGryXzb6nN5fkK1WDY', 'enc-alg': 'aes-256-gcm', 'key': 'PYEJ1c79aR7bxdzvBlj3lUMLp0VLKQHwSe+/OS1++1qa++gBMJJmJWJXUP5ZNhUs', 'algorithm': 'ECDSA', 'salt': 'uJhjsfcouCGZQUdHO2TZZQ==', 'parameters': { curve: 'P-256' }, 'label': '', 'publicKey': '020cc76feb375d6ea8ec9ff653bab18b6bbc815610cecc76e702b43d356f885835', 'signatureScheme': 'SHA256withECDSA', 'isDefault': true, 'lock': false }], extra: '' }, + { name: 'MyWallet', version: '1.1', scrypt: { p: 8, n: 16384, r: 8, dkLen: 64 }, identities: null, accounts: [{ 'address': 'AQNpGWz4oHHFBejtBbakeR43DHfen7cm8L', 'enc-alg': 'aes-256-gcm', 'key': 'ZG/SfHRArUkopwhQS1MW+a0fvQvyN1NnwonU0oZH8y1bGqo5T+dQz3rz1qsXqFI2', 'algorithm': 'ECDSA', 'salt': '6qiU9bgK/+1T2V8l14mszg==', 'parameters': { curve: 'P-256' }, 'label': '', 'publicKey': '03aa4d52b200fd91ca12deff46505c4608a0f66d28d9ae68a342c8a8c1266de0f9', 'signatureScheme': 'SHA256withECDSA', 'isDefault': true, 'lock': false }], extra: '' } + ]; + const params = { + cost: 16384, + blockSize: 8, + parallel: 8, + size: 64 + }; + const pks = []; + const pris = []; + for (const v of w) { + pks.push(new PublicKey(v.accounts[0].publicKey)); + const p = new PrivateKey(v.accounts[0].key); + pris.push(p.decrypt('1', new Address(v.accounts[0].address), v.accounts[0].salt, params)); + } + + const mulAddr = Address.fromMultiPubKeys(2, [pks[0], pks[1]]); + console.log('mulAddr: ' + mulAddr.toBase58()); + const tx = makeTransferTx('gas', mulAddr, + new Address('AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve'), 1 * 1e9, gasPrice, gasLimit, mulAddr); + const multiPri = [pris[0], pris[1]]; + for (const p of multiPri) { + signTx(tx, 2, [pks[0], pks[1]], p); + } + console.log('tx:' + JSON.stringify(tx)); + const result = await socketClient.sendRawTransaction(tx.serialize()); + console.log(result); + + // const mulAddr = Address.fromMultiPubKeys(5, pks); + // console.log('mulAddr: ' + mulAddr.toBase58()); + // // console.log('pris: ' + JSON.stringify(pris)); + // const payer = mulAddr; + // const tx = makeTransferTx('DNA', mulAddr, + // new Address('AazEvfQPcQ2GEFFPLF1ZLwQ7K5jDn81hve'), 100, gasPrice, gasLimit, payer); + // const multiPri = [pris[0], pris[1], pris[2], pris[3], pris[4]]; + // for (const p of multiPri) { + // signTx(tx, 5, pks, p); + // } + // console.log('tx:' + JSON.stringify(tx)); + // const result = await restClient.sendRawTransaction(tx.serialize()); + // console.log(result); + // expect(result.Error).toEqual(0); + }, 10000); + + test('get_allowance', async () => { + const from = adminAddress; + const to = toAddress; + const res = await restClient.getAllowance('gas', from, to); + console.log(res); + }, 10000); + + test('send_approve_transferFrom', async () => { + const res1 = await restClient.getAllowance('gas', adminAddress, toAddress); + const allowance1 = Number(res1.Result); + console.log('allowance1: ' + allowance1); + + const tx1 = makeApproveTx('gas', adminAddress, toAddress, 10 * 1e9, '500', '20000', adminAddress); + signTransaction(tx1, adminPrivateKey); + const res2 = await socketClient.sendRawTransaction(tx1.serialize(), false); + console.log(res2); + await sleep(6000); + + const res3 = await restClient.getAllowance('gas', adminAddress, toAddress); + const allowance2 = Number(res3.Result); + console.log('allowance2: ' + allowance2); + expect(allowance2 - allowance1).toEqual(10 * 1e9); + + const res4 = await restClient.getBalance(adminAddress); + const res5 = await restClient.getBalance(toAddress); + const adminBalance1 = Number(res4.Result.gas); + const toBalance1 = Number(res5.Result.gas); + console.log(`adminBalance1: ${adminBalance1}, toBalance1: ${toBalance1}`); + + const tx = makeTransferFromTx('gas', toAddress, adminAddress, toAddress, 10 * 1e9, '500', '20000', adminAddress); + signTransaction(tx, toPrivateKey); + addSign(tx, adminPrivateKey); + const res6 = await socketClient.sendRawTransaction(tx.serialize(), false); + await sleep(6000); + + const res7 = await restClient.getBalance(adminAddress); + const res8 = await restClient.getBalance(toAddress); + const adminBalance2 = Number(res7.Result.gas); + const toBalance2 = Number(res8.Result.gas); + console.log(`adminBalance2: ${adminBalance2}, toBalance2: ${toBalance2}`); + expect(adminBalance1 - adminBalance2).toEqual(10 * 1e9); + expect(toBalance2 - toBalance1).toEqual(10 * 1e9); + + const res9 = await restClient.getAllowance('gas', adminAddress, toAddress); + const allowance3 = Number(res9.Result); + console.log('allowance3: ' + allowance3); + expect(allowance3).toEqual(allowance1); + + }, 20 * 1000); + + test('send_transferFrom', async () => { + const tx = makeTransferFromTx('gas', toAddress, adminAddress, toAddress, 10 * 1e9, '500', '20000', adminAddress); + // Here we need the signatures of sender and payer. We can only sign once here if the sender is the same as the payer. + signTransaction(tx, toPrivateKey); + addSign(tx, adminPrivateKey); + const res = await socketClient.sendRawTransaction(tx.serialize(), false); + console.log(res); + }); + + test('sort_pk', () => { + const pk1 = new PublicKey('03a3c7a40461238a210d306ce4a79db69800449173e47b9e2fa92b7815d7517872'); + const pk2 = new PublicKey('023c5b6e0e4fe8647d1065ecd09c60d251e1e168999202423e3be5d174866f9349'); + const pks = [pk1, pk2]; + console.log(pks); + const add1 = Address.fromMultiPubKeys(2, [pk1, pk2]); + console.log('add1: ' + add1.toBase58()); + pks.sort(comparePublicKeys); + console.log(pks); + const add2 = Address.fromMultiPubKeys(2, [pk2, pk1]); + console.log('add2: ' + add2.toBase58()); + }); + + + +}); diff --git a/test/transferParse.test.ts b/test/transferParse.test.ts new file mode 100644 index 0000000..c775ed4 --- /dev/null +++ b/test/transferParse.test.ts @@ -0,0 +1,54 @@ +import { Signature } from '../src/crypto'; +import { Address } from '../src/crypto/address'; +import { deserializeTransferTx, + makeTransferTx } from '../src/smartcontract/nativevm/assetTxBuilder'; +import opcode from '../src/transaction/opcode'; +import { addSign, signTransaction } from '../src/transaction/transactionBuilder'; +import { num2hexstring, str2hexstr, StringReader } from '../src/utils'; +import { PrivateKey } from './../src/crypto/PrivateKey'; +import { PublicKey } from './../src/crypto/PublicKey'; +import { WebsocketClient } from './../src/network/websocket/websocketClient'; +import { Transaction } from './../src/transaction/transaction'; + +describe('parse transfer tx', () => { + const from = new Address('AJAhnApxyMTBTHhfpizua48EEFUxGg558x'); + const to = new Address('ALFZykMAYibLoj66jcBdbpTnrBCyczf4CL'); + test('transfer 15 gas', () => { + const tx = makeTransferTx('gas', from, to, 15, '500', '20000', from); + const transfer = deserializeTransferTx(tx.serialize()); + expect(transfer.amount).toEqual(15); + expect(transfer.from.toBase58()).toEqual('AJAhnApxyMTBTHhfpizua48EEFUxGg558x'); + expect(transfer.to.toBase58()).toEqual('ALFZykMAYibLoj66jcBdbpTnrBCyczf4CL'); + expect(transfer.tokenType).toEqual('GAS'); + // console.log(tx); + }); + + test('transfer 10000 GAS', () => { + const tx = makeTransferTx('GAS', from, to, 10000, '500', '20000', from); + const transfer = deserializeTransferTx(tx.serialize()); + expect(transfer.amount).toEqual(10000); + expect(transfer.from.toBase58()).toEqual('AJAhnApxyMTBTHhfpizua48EEFUxGg558x'); + expect(transfer.to.toBase58()).toEqual('ALFZykMAYibLoj66jcBdbpTnrBCyczf4CL'); + expect(transfer.tokenType).toEqual('GAS'); + // console.log(tx); + }); + + test('hex', () => { + const res = Buffer.from('AZ+qwfuOR6zlBfXbYr4N/TKzjUMKExB0bZsSN1MaDGR+aMpmwpDOYiMefCdDMVQzKkvy05+cW4EJmBycFuB/FdI=', 'base64').toString('hex'); + console.log(res); + }); + + test('sig', () => { + const sigData = '01c6985632e146fc51d08773101830fe0e2d006f7377589e2a4d00fd986901d91628b3494401046e9f47c440a6b503b65b8a7e2b4d4bbc48aad54954bafe5cc1d3'; + const pk = new PublicKey('02f64df7d4cf8c604f2662ed1b9614986b803070c68bcfe09418f06776114d7ced'); + const pri = new PrivateKey('09dc431f249e9f0bacbfb525f631518bee8629167f62b5c79e55fa6fd39aea0c'); + const pk2 = pri.getPublicKey(); + console.log('pk2: ' + pk2.key); + console.log('address: ' + Address.fromPubKey(pk2).toBase58()); + + const sig = Signature.deserializeHex(sigData); + const res = pk.verify('505c316ac990aaab268ce5f402a02198a686531d2af5d1eace055ed2d21a9962', sig); + console.log('veeify: ' + res); + }); + +}); diff --git a/test/wallet.test.ts b/test/wallet.test.ts new file mode 100644 index 0000000..c3981e5 --- /dev/null +++ b/test/wallet.test.ts @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2018 The DNA Authors + * This file is part of The DNA library. + * + * The DNA is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * The DNA is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with The DNA. If not, see . + */ + +import { Account } from '../src/account'; +import { PrivateKey } from '../src/crypto'; +import { Address } from '../src/crypto/address'; +import { Identity } from '../src/identity'; +import * as scrypt from '../src/scrypt'; +import * as utils from '../src/utils'; +import { Wallet } from '../src/wallet'; + +// tslint:disable:no-console +describe('test wallet', () => { + // tslint:disable-next-line:one-variable-per-declaration + let wallet: Wallet, + walletDataStr: string; + beforeAll(() => { + console.log(Wallet); + const privateKey = PrivateKey.random(); + wallet = Wallet.create('mickey'); + walletDataStr = wallet.toJson(); + }); + + it('test create wallet with name and password', () => { + expect(walletDataStr).toBeDefined(); + }); + + it('test add identity', () => { + const privateKey = PrivateKey.random(); + + const identity = Identity.create(privateKey, '123456', 'mickey'); + wallet.addIdentity(identity); + expect(wallet.identities.length).toEqual(1); + }); + + it('test add account', () => { + const privateKey = PrivateKey.random(); + const ac = Account.create(privateKey, '123456', 'mickey'); + wallet.addAccount(ac); + const privateKey2 = PrivateKey.random(); + + const identity = Identity.create(privateKey2, '123456', 'mickey'); + wallet.addIdentity(identity); + expect(wallet.accounts.length).toEqual(1); + }); + + it('test parse json', () => { + // tslint:disable-next-line:max-line-length + const jsonStr = '{"name":"MyWallet","version":"1.1","scrypt":{"p":8,"n":16384,"r":8,"dkLen":64},"accounts":[{"address":"AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ","enc-alg":"aes-256-gcm","key":"VWLK6ToY2oLNIP+wCQJqDmvTeTO0zgnJeinOR11F9ZK3JcV4LJ5HOpTAUju5sZ4A","algorithm":"ECDSA","salt":"dg2t+nlEDEvhP52epby/gw==","parameters":{"curve":"P-256"},"label":"","publicKey":"03f631f975560afc7bf47902064838826ec67794ddcdbcc6f0a9c7b91fc8502583","signatureScheme":"SHA256withECDSA","isDefault":true,"lock":false}]}'; + const wallet = Wallet.parseJson(jsonStr); + expect(wallet.accounts.length).toEqual(1); + expect(wallet.identities).toBeUndefined(); + }); +}); diff --git a/test/wasm/helloworld.wasm b/test/wasm/helloworld.wasm new file mode 100644 index 0000000000000000000000000000000000000000..a13a1ea0a70a0c82de96f95d70b5d803b91f7b09 GIT binary patch literal 15242 zcmb_j4Qymrb-wRse&3Au?GIVAyJ_w`w#D1*uE+Lx#x?|ex7kfLKP=EBgi^Ym^~|n4 z_Kw%%v6D2LwIQ@gN&=yvib|!WYNSLJsZ@!oP$D&zQi)PPQAGu6BN3@o1+}VzM5U;d zrr&q&d*iX!8xo3lXWo7Ho_p^3Kj+>zPt{j0I!Y<$?p-t9`ue)FKI6)_kDGNhS!phwKU;4!I?a_83%<`HnXNA_Haj~H zt#&%icK2-e{<-?fobrfne>^K5I=8qqyRbQ0u%qpz?)>=&RE87cu9dm^=y+9S*%hz6 z(p~D*FEr0Knv2bD(?Z8ACqtcPy`gfPv)5uy2JY+3V~X21GCS9tT{wH+e78*wh1Pfu zSm->kmBDx!q5kY#bN<3y*Ge{~w$tpccG{Mtz^;6$-kzUD&uynuc`xH-vZ;K=4KkTb zHj{O6uauY1<4&bg%5j`bA(blT2H3=(m%&%YadRoha~&_2O1Ur}KjmC}mKK_7PcCwlae_nB?;1D1^6pc&+`9X=kU-8%9rp$)35UInMS#sRz*Z&u)$URw9+BNHU6dmn`dn4y$ z(bZ1q1X>wYbwiEOs$0Otsk&KozN}jK&bGpRS{+j}#yN!v%6wn7hFn!bbI5I!98(D2 z5_unIcHTMwadsTOECvvcQ;gk^ZP%CoH!0p8x!L&QDO9eqL$U8w0_+AjCRe)~C zJh$NzUK+*=KUfS%Y>%$%dUWkV_baLuIY&HI@-2~(%bV1-CJ1O6)DkSp=+xyXRr6-h zk=FiYozj`Rp1oZ2<}iPda7N9NVbWj#M!w1^ z*VzUn_ra6J>x9#9C8*F~e=!wvYC>>D{U}QV^bxryRL#RZFCdttg%H1aUbO(O9jM2` zvm@IQ4rPK?N4%MuHw{?f3FByfOUT=Ad3re^1PwC)Lfkh=2&Mo3BIG*C=|4%vUfVE5 z%855WX73)`u)Vx_`XlJwZ5y_CcOh-Ld6YvmAT)#OjmMSquuW9>;u>13B9;X%6t_TkOr+hV9K35R4r2T@IunUZqa_ z=xg8jlfV4JcfS0u>V3s@V4nP_8xE=kGL6D_Bw(@({Xv%h9)l&orv zH2ej!JLE1_-61Rn7Vte}zl_f{t@FWp9opR7cDH{XOgqG4QkFS%^bk=ZeMtTZh6r5% zDI*G^Q1(uw4y=B&4gS*+g3ge8hjCg}mC_!PNyhT*B|L99mS+Pwgf~!GG0n^>?sPAH zgQ>*pxK@%}7}Q7b=ApuMT*;&j2_m<>;ZV zfoqtvt?&Z}bf9xBv)(Gv&V!cDx6ogL(*tHo0lm(_IwCmI9H!iGXE7!8$RZ%Bh2eS& zzGooX&9g^c1sb} zg!Z4NJ7-}L4*W0sQ)CVS*=Pc)0GPBT* z0%ldOc?@9;pO_XFjJhTK1tt=#ca2~UNV4(tTn7(mY&-jnvRW z(d|xa&pdpk75T=ccY4p3Qb?f|#pbv62R!9qGeF}uZWw77h*+Pe;dr8HEks@7c79jw`updYi$?jDeCY{{45EQc z1v7k81_?vb3elR7Ru-)?#s*vF>rc2O<#VxiwD?1;5l3tU^q+X`HSeyX<4&V#4TV}l zI6^dspvb$GHbg$iT3HO^f8*hI$!60vhago0&iB*8f%R#`5h~04BnG_684x@J1PsM{ zIRQ45#d3)AzZAS1a&o7w$|P3%vB4lMXz6BFqY9x<1}ILX!mZ;57pu! zL?MzwD_EBzhRo4N!4@#|nU6!FFdKFs#tafhNwejPh|#LL8n@Y&dFtaL)dz)IN|QAB zFfwOBONxdqU?ZcQ(+K9Cak>#Y@XtAYkh{oRDQisf7=gmKlw6S$nPTzwc1hek6~HLz z2brKX*cH&6V0Drqe`Zc!dQ+VKhvoEPoT@-E_Mb#gGApqZ9G?as5OXU^Y5z3nM)*06 zu*cvkVHGuQ7Ir}2rqC563K)u2(V?xCpilv8o9?{}wS!Jc?nhC}s`VdZBYwHxi(>aF zK%5YDY%P%Dy$9d`$P|Ya5iuj~YZ;%*`=-)j+09lc-C_#<39m*kWTkKY5HLr3{xmJE z0%*Qj`-}(o;(~Z^2WGs=8Mg|+5CF8azN*l){`dl$a7chY&nEnpD}V8K#fox}2nfd6 zi=?lc6K^;fdp*3CfzEfbq2Oo z!r76zA2!Ic(;BM%#&Y{ub%DxsDFZAnbP1HtJ>nYJUwE9STA>_1P{vTCG=q(03Qo*CiSQFbTN%cDSBp1Lo($9b za7CDwBp0@jZdj~I7raICUfhM<5nG5zG~};8LIjA#!xARa9D^{#$I?Iyc4^=)(gPhJ z{AC1=OuPsD9{3)!Ykc-m*_|)+qNazaiBw5-LDfXz^`fTNi<+K|nx1*}QGg<;+NkNF zVWTEmv~qUP%Qdd7N12JfoOQBPI8&jlW)6cx&TI(PfQC=dNZ zmyEnw+8Dm1WGw7fs_5%1Rqg@+MhL~H2qFxoz%6ceJBphlAmAP|t@CHZePFrqf~cT~ z!d88P$%pkhv}9PHhKEUpL;LWM%SC|>dm)(87IJYy$>kuGR6@3_x+B>h^dEA~e(EV1 z_zaNHG&BbkSAfj7vxJs>Vo1Kd#vaYK>F4o0RE_ zCCG3kQfCN2YQyOeezRukGx+M9PGjRl7a$!PrwwV5 zoA?U8q&qh5q9-~=)o7l2-0niY4)sH{A|{VHlQnaI8VLV~5v)Y0(2W}&g|S1zNLkwo ze6WJFXjJg`E^-_KPP{RpI!Y=r287rR6luW3xKZG3h?)%?@ad3j5s}NxyO#mhnNkDH zxhB2V>nKV`Va@DXHZK#RfGwUwQ|Ox!G>uWClKujNwsUf_L$omR_Yx}!4t2v z5S;#CeG%1z1=|YX0VQ{qCtmxTZx7#tcv-KtGg;EOAmC9TITBQyg^AgT~L>-PTnH}>gH?p^42u0Ch06J1R+{+g01qamN z3pI3jjQfZ(G9d27oXYVjnxN*PaTzs}EXRfMBm-+ODJfe@U^nk*Y~%~Fg(pRa1U<_r zDg0%bzB@dJGg(2-9YF=a5D3c%$K)8wEWGXR#5 zW5UxC!iws|H(vam@BHD9|M?#tSr7g;g%Vgi3CeetBRuy+F&it=UzWVdJrZ&qPp0hi zW1jSu@-Wq`&Ld;Ps~MtBwNT9DSxMw^qzlF7yvP8%$EOqG%2Q5&2(IN-a=Q7E2sr96P-ycZUV_GZaf|yeXAx~aWwMjsd z<3LHwhfp)xVhja5&WVIY9%wO*m+hWplVKr=wazw@au8)dNm(ID9+E+HB#EaFY~gg< z3g4aXBPtdp1h^AXl(P>>2yH!)54oUS%1uYGL#=>2WFN>3mXrsPVE|lbX&(u15GzW= zm}evbIV$n7VcM!(M6?}NvJVN8m2v`e?Ugb**INne z#9>1PIK&E4ZfW76K@WzEqi8|Oe>me5#5ZsnXAK1tK|IcIgi%B6Y@i<-b88UL5fro~@&FrDk_5m!aX?i$O201v;@&cC zgMvK`0J7Wy5f`E~%RRCGotNP0Lb42-+J%R|;ic$-3p|uaf(X`PT;o=_KZxYz6eCY{ zBV?>Wri>gCPGqMJtw|8^D1AI@b1ccA`}Ko}6mN7mNN+QUD8UY0u#a&b?jO6hT_ABq zke}alYX(i^`%nQNrij@5@TM&#+CJ%xA+X0Nz`uirExD7b&8m^k#dSejTrHv~-#qfL z)gt##a?qj3fwUN*S@TJuh;Cabs^B0N1wQk`CtQ<4)akR8;Lq^8FIIc}X%PC?$k~6ErDsX8hPETH0tG_@J*enV82hO9F}K{olyBqSGx^g8 zZ_W!;%XAlm~%!lN48U8s}xk5!&E$*!AMd0ySd`8 z3lQ*FcPGy^>5Bc}_wDb*JM*a{?!;e1_yA6S`e^K?kF7SC9>z z+agk=!83h4%UbApQi^*c0AYD3%@2PyO2ZC$^oLt^OSlwdX`V-+l;Z^{N)Gz0t){sX z>BCXNks^=jz$boO$H$Ac#$qi}7Sv2UGa zhf{LFi!EYIhy#AG>ybUqhxmB7%A=-@jmyh1@8laBC*&d7-r=Ew+3-n%6MV(T;V$h- z7~uIgsAEt}i_bCV;SrfsSaJf&JWIw=fjG+m_L$D|=E|}tzz+Htyu8ev423SC5dfpHnv3%Y=GX}o2fgU;|U33q}Fdk0L)5fqqUCWOJL0tRYVAXx&X zK#T`sFjvMS>;x=r*b}&<7+R#US*sAo;e75?Wrv2ml(5Hqfae1Vxg^$MQIbJDLTbb& zU=b{k#n2c5uuIZe0P8OB9qygmOR;3yC~L*;pL0MC?hJs92u3rC5$h z)gQ~vqNTjz>h<78WZ_!2=bPRh#s-D7!>48 zQ-Nwg;mMm6TOb%3Z@-3b_O#Y!fI$5W722`1M+?KZ?( zc%lcRqJ*VNW$uW;CNJ2{P(U&f0+fdyG9TOX0#}AJEwK8>56qw43tQjVaD%7z%9{}l zJ@fwN%IacwYHGE8U#EU)=*Wy-YU_Gi&z$UZX7pNpakZ)PN+~D)1i0c&i{5(}{cjoc zzlO2(&5JE>DQtO}VRp-F7|C7l&5JFsL?kzSaUyBk_bcoR81~JKx#r^HQWtND%+^<$ ztL>H5OP7{9-DX4AXYs;GyCmcHEp-+f!z-QH;l=rL$2%+P-!_!m3*P=4*SFw0iO&E& zd5ymh$+xr~jPSljH1%K5lux9PK5hQ^-ldFZs*(Gsga|a zmr?dN@4wWX1vT-|SoF}*9`Xk_vGnANaoyM7FYawa{nEb%)~!m}Hh+tbu7zNWwzeU- zN_p2nlBiBzbLp4WO1CrLzA#lkH+xjaZM+ZiQ?Sq&c1E&I+;148HK{j*^BS~SLnMZ{ zH5G}~MGy6K{b6a@ZyMG!4=aUZ81>krO6|w>6<4VguCw(^_1XFE1A1w#**U+sbRYW4 zA5-cS$KaH-*#bWN*%LoSd}z13@Tu$bOP!1LZWmJ3-A;YJtLHCXT5Mi~s_XOxZC?eV zZ?tu@(^=}M5cBv)eTx)iz(;Pm3u{(TmsX;eWp9Sq2NWX;Z9$fk1AJ-!<^X*3Se!aBX)l28~ zxuw;1V`WNr=b9R?i0SzitOgR<73sa+StU{WTjjg zsf<>}DwWE3rCO;~CMuKTS4XO&)v;=&I$o_-Yt@PB zWUX8qsg2ggYL(h}ty-(qCTf!t<%yAr(TTB%%Eb6Yb)q&gF)=v_5+||zBv4Oc+9bM^ z`r>aXm4*!d3fBnNn;%nZ5ZC<(z_bO+aw42gy?voc4eOP~`PnArWnZJy|AYD00e;VK zTYE_GTp#1H@D>|hrt5T9biHdO+l0J%Q@$Vb*D(J^T>ltX#>C%*l6alLJ@KD|!O=#N z`+IOdgnRzQp>>=7ldN;*63uUW*3mQXS!y@qtkaKRNx;Q^)FT%ES3v_@L``X>UW(~^ z0_#&w{ZsKuAo3fgBA>y$RWd)h4gw#hsYAHZ2Fd)?={6GIeBzJc4=Q6J6a9z(TmBY2ZveN8`f1R(-FE$%fdQ`vjCRpzIQK&?r;N{r@earvHHbEwK9Bsw%)n0Gz|3fh*J-U`^+vin#V!M1FP-hvr89`!8*^? z8t3ZeiTY^0GSVDA_dvI~)M+$3$3~8i9Uo16PUQ6JHrhURP1-73Xe%TB^z-!CHRnxi znKy@dr9N4F@|yETs#_+;%EF79OS8kB`h92DnzP`bxz<(B0Vhfv^#fcPZ zJ2SM{Jm1wf-K0Bw-SNl_qAPo*^vn$Mt8}srYk^NyfTMu|VZLpnV7=YYD@&^#IFY!< zik_>lHFabD{P`x|5sm$7CGn$sW8V7hOeV%rZXfXT&%uZOLSJD_r!Uji_<1Wn2k<$F M&mnyHw;lff0J;m`a{vGU literal 0 HcmV?d00001 diff --git a/test/wasm/wasmContract.test.ts b/test/wasm/wasmContract.test.ts new file mode 100644 index 0000000..1193016 --- /dev/null +++ b/test/wasm/wasmContract.test.ts @@ -0,0 +1,217 @@ +import { RestClient } from '../../src'; +import BigInt from '../../src/common/bigInt'; +import { PrivateKey } from '../../src/crypto'; +import { + makeDeployCodeTransaction, makeWasmVmInvokeTransaction, signTransaction +} from '../../src/transaction/transactionBuilder'; +import { hexstr2str } from '../../src/utils'; +import { Account } from './../../src/account'; +import { I128, I128FromBigInt, I128FromInt, maxBigU128, maxI128, minI128 } from './../../src/common/int128'; +import { Address } from './../../src/crypto/address'; +import { WebsocketClient } from './../../src/network/websocket/websocketClient'; +import { Parameter, ParameterType } from './../../src/smartcontract/abi/parameter'; +import { VmType } from './../../src/transaction/payload/deployCode'; +import { reverseHex } from './../../src/utils'; +// tslint:disable-next-line:no-var-requires +const fs = require('fs'); + +describe('test deploy contract', () => { + const privateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b93'); + const account = Account.create(privateKey, '123456', 'test'); + // tslint:disable:no-console + console.log(account.address.toBase58()); + + const contractCode = fs.readFileSync(__dirname + '/helloworld.wasm').toString('hex'); + const restClient = new RestClient(); + const wsClient = new WebsocketClient(); + + test('deployWasmContract', async () => { + + // console.log(code); + // tslint:disable-next-line:max-line-length + const tx = makeDeployCodeTransaction(contractCode, 'wasmContract', '1.0', 'alice', 'testmail', 'desc', VmType.WASMVM_TYPE, '500', '30000000'); + tx.payer = account.address; + signTransaction(tx, privateKey); + const result = await restClient.sendRawTransaction(tx.serialize()); + console.log(result); + expect(result.Error).toEqual(0); + }); + + test('get_contract', async () => { + const contract = Address.fromVmCode(contractCode); + const codeHash = contract.toHexString(); + // tslint:disable:no-console + console.log('contract address: ' + contract.serialize()); + console.log('codeHash: ' + codeHash); + const rest = new RestClient('http://13.57.184.209:20334'); + const result = await restClient.getContractJson('d26bd5624d5fd809fdccd865cffaac766c61b6a0'); + console.log(result); + expect(result.Result).toBeTruthy(); + }, 10000); + + test('invokeAdd', async () => { + const contractAddress = new Address('5daf0ec53b21abfab6459c7ba7f760c376e18ebf'); + const params = [ + // new Parameter('param1', ParameterType.Long, '-1'), + // new Parameter('param2', ParameterType.Long, '2') + new Parameter('param1', ParameterType.Integer, -1), + new Parameter('param2', ParameterType.Integer, 2) + ]; + const tx = makeWasmVmInvokeTransaction('add', params, contractAddress, '500', '20000', account.address); + console.log(tx.payload.serialize()); + signTransaction(tx, privateKey); + const result = await wsClient.sendRawTransaction(tx.serialize(), true); + console.log(result); + expect(result.Error).toEqual(0); + }, 10000); + + test('invokeNotify', async () => { + const contractAddress = new Address('5daf0ec53b21abfab6459c7ba7f760c376e18ebf'); + const tx = makeWasmVmInvokeTransaction('notify', [], contractAddress, '500', '20000', account.address); + console.log(tx.payload.serialize()); + signTransaction(tx, privateKey); + const result = await wsClient.sendRawTransaction(tx.serialize(), true); + console.log(JSON.stringify(result)); + console.log(hexstr2str(result.Result)); + expect(result.Error).toEqual(0); + }, 10000); + + test('invokePre', async () => { + const methods = ['timestamp', 'block_height', 'self_address', 'caller_address', 'entry_address', + 'current_txhash', 'current_blockhash']; + const contractAddress = new Address('5daf0ec53b21abfab6459c7ba7f760c376e18ebf'); + for (const method of methods) { + const params = []; + const tx = makeWasmVmInvokeTransaction(method, params, contractAddress, '500', '20000', account.address); + signTransaction(tx, privateKey); + const result = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(result); + expect(result.Error).toEqual(0); + } + + }, 10000); + + test('invokeStorageWrite', async () => { + const contractAddress = new Address('5daf0ec53b21abfab6459c7ba7f760c376e18ebf'); + const params = [ + new Parameter('param1', ParameterType.String, 'abc'), + new Parameter('param2', ParameterType.String, '123') + ]; + const tx = makeWasmVmInvokeTransaction('storage_write', params, contractAddress, + '500', '20000', account.address); + signTransaction(tx, privateKey); + const result = await wsClient.sendRawTransaction(tx.serialize(), false); + console.log(result); + expect(result.Error).toEqual(0); + }, 10000); + + test('invokeStorageRead', async () => { + const contractAddress = new Address('5daf0ec53b21abfab6459c7ba7f760c376e18ebf'); + const params = [ + new Parameter('param1', ParameterType.String, 'abc') + ]; + const tx = makeWasmVmInvokeTransaction('storage_read', params, contractAddress, + '500', '20000', account.address); + signTransaction(tx, privateKey); + const result = await restClient.sendRawTransaction(tx.serialize(), true); + console.log(result); + console.log(hexstr2str(result.Result.Result)); + expect(result.Error).toEqual(0); + }, 10000); + + test('invokeStorageDelete', async () => { + const contractAddress = new Address('5daf0ec53b21abfab6459c7ba7f760c376e18ebf'); + const params = [ + new Parameter('param1', ParameterType.String, 'abc') + ]; + const tx = makeWasmVmInvokeTransaction('storage_delete', params, contractAddress, + '500', '20000', account.address); + signTransaction(tx, privateKey); + const result = await wsClient.sendRawTransaction(tx.serialize(), false); + console.log(result); + expect(result.Error).toEqual(0); + }, 10000); + + test('balanceOf', async () => { + const contractAddress = new Address(reverseHex('44d451cb5ef516eac96c5a1bd32b51f1385e4931')); + const params = [ + // tslint:disable-next-line:max-line-length + // wasm 合约Address类型的值不能传对应ByteArray的值 + new Parameter('param1', ParameterType.Address, new Address('AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ') + ]; + // 没有decimal 方法? + const tx = makeWasmVmInvokeTransaction('decimal', params, contractAddress, + '500', '20000', account.address); + console.log(tx.payload.serialize()); + signTransaction(tx, privateKey); + const wsClient = new WebsocketClient('ws://13.57.184.209:20335'); + const result = await wsClient.sendRawTransaction(tx.serialize(), true); + console.log(result); + console.log(hexstr2str(result.Result.Result)); + expect(result.Error).toEqual(0); + }, 10000); + + test('transfer', async () => { + const contractAddress = new Address(reverseHex('44d451cb5ef516eac96c5a1bd32b51f1385e4931')); + const params = [ + new Parameter('param1', ParameterType.Address, new Address('AJkkLbouowk6teTaxz1F2DYKfJh24PVk3r')), + new Parameter('param1', ParameterType.Address, new Address('AUr5QUfeBADq6BMY6Tp5yuMsUNGpsD7nLZ')), + new Parameter('param1', ParameterType.Long, '10') + ]; + const tx = makeWasmVmInvokeTransaction('transfer', params, contractAddress, + '500', '300000', account.address); + console.log(tx.payload.serialize()); + signTransaction(tx, privateKey); + const wsClient = new WebsocketClient('ws://13.57.184.209:20335'); + const result = await wsClient.sendRawTransaction(tx.serialize(), false); + console.log(JSON.stringify(result)); + if (result.Result && result.Result.Result) { + console.log(hexstr2str(result.Result.Result)); + } + expect(result.Error).toEqual(0); + }, 10000); + test('smartCodeEvent', async () => { + const rest = new RestClient('http://13.57.184.209:20334'); + const res = await rest.getSmartCodeEvent('377617131b99c4472e174e53b939234df278a23e705cfafacce5702dcd0f2c4e'); + console.log(JSON.stringify(res)); + expect(res.Result).toBeTruthy(); + }); + test('i128', async () => { + const i128 = I128FromBigInt('9007199254740993'); + console.log(i128.serialize()); + expect(i128.serialize()).toEqual('01000000000020000000000000000000'); + }); + + test('max128', () => { + console.log(maxI128.toString(16)); + }); + + test('transformNumber', () => { + const data = { + 'minI128': '00000000000000000000000000000080', + 'maxI128': 'ffffffffffffffffffffffffffffff7f', + '-2': 'feffffffffffffffffffffffffffffff', + '-1': 'ffffffffffffffffffffffffffffffff', + '0': '00000000000000000000000000000000', + '1': '01000000000000000000000000000000', + '2': '02000000000000000000000000000000' + }; + const bmin = minI128.toString(); + const bminI128 = I128FromBigInt(bmin).serialize(); + expect(bminI128).toEqual(data.minI128); + const bmax = maxI128.toString(); + const bmaxI128 = I128FromBigInt(bmax).serialize(); + expect(bmaxI128).toEqual(data.maxI128); + expect(I128FromInt(-2).serialize()).toEqual(data['-2']); + expect(I128FromInt(-1).serialize()).toEqual(data['-1']); + expect(I128FromInt(0).serialize()).toEqual(data['0']); + expect(I128FromInt(1).serialize()).toEqual(data['1']); + expect(I128FromInt(2).serialize()).toEqual(data['2']); + console.log(I128FromInt(-2).serialize()); + console.log(I128FromInt(-1).serialize()); + console.log(I128FromInt(0).serialize()); + console.log(I128FromInt(1).serialize()); + console.log(I128FromInt(2).serialize()); + + }); +}); diff --git a/test/wasm/wasm_demo_optimized.wasm b/test/wasm/wasm_demo_optimized.wasm new file mode 100644 index 0000000000000000000000000000000000000000..6c805520dc1f20ba4969fad5711e8cf8f9d97b16 GIT binary patch literal 19987 zcmdsH8w`LQ#z%SUP@(IQpd88gu`CdK`|OU8=$HkM48mL=P?r8;iK<#H(P zklZC_hm`12+?7bl^siVJj8s5XR7so2O{-Q--9klzT4`KVK-+*p-9$xI#7K=m0h)kq z1XO=GbwA&8-^|WZVj{Oi3v`z|@4ox)J@?%6`<(lR!Tid}FbIP1+zp50)z#H-^>AdL zp_&1I;c9R=;RzR>1cwW1>mi*NE^v*x*brTUz`*2Fcp6>MSfE{C!i5V4-~vCv;Uc%{ zh^~YKadYYH4a-ZN#pQ<=9&IihfB3P*&Qfz_C5ZH7i+{4Xbm~m!;S>xNu^w#l z4<2cD9=3-;(g$dzv)rD4r1|h;?Zr+rDCo(sAK!g)w0WY*qhjA0-AC=_{L!GK2Q@#Z z-RzucFZr=m-*sw!X>q~#aBo;*-2 zL)UC=Evl9(VR3Qk?DFwuuzBFNFv!B{2S#>&^dlet>AUZL;FAYFG4R>xnc2Nl_x{XX z2k&{X^3v1cgHcd@ED~Ej7-X*n#~aa(z(tvBxiGEL7;R#@`9t*xDLFh^@7DmTJyGjW;jm=3iy;I*K&BdGrSFiciicC@?d_Et9R z7YL`Lt&EGNqhT&Tc#cL&BW-0#n?$U-TX&*Qmo89? zZT+h-5k14zXah}MDD3zsr=O1Y>sRy%8sQ+Ms>ij^BT832@pwW3mly>c^w9oci?*KL z>Z09&%ffpGLpnx9ZZ@swV56JjTv(5*P`#KFUvv+c>I!`v*u;{8RNoiemHpl4qU=M! zxT}?Y@3|>iDQTN? ztLGbKS3Crd$}T$e@_FA;IK*w?liNHnkNAK91objN*=&FeChQMjY9KbO(l*s<(*OB71Za2O=$cF7cAAy|Oy^Ck!5y%f3j>|fP zRHM@m&|^~ib0~c*0cFLI6@#5oxgP0aTD;T5Fq})Yjc_iUiQuT?ZY!4%4VRvVele(| z#njI}e=4Z{^;=6xt^rzPlW4RSA8!OZ0!SG~`_r%yiR(f3txzHzqM8uqTVW$iBg9r( z`f3OR(ED%eiu}LAHM_#_AbTZjr8h+T-~H=?-NBVmdLh^h_Clh4jYQvLX?kB{^6>gp zRv*;xC_CS3#98^^VBGgG9vTSBVKIrzQ7NeE0h@efEz*o|BnYxUdh?h6cIl&oC~uJ7 z2=%ag;im=%{5qJNn`&E_#-z8OTA%bM|Kgwgz2Zj)%i1aEWR>)$y!FmgQTEiuD80G1 z*-zuf)>3a)Og}e>Ao@vhZ_;HReZ?lBC83)43=a85R!u*5_ux>ipa;L82Q}Zw2J}ET z-%)SLH(aFNQZ3PNMDCu!iVJrJ!Q9(Fc=}KO>2LpsU;A&tCkHDvEK8XEEzK+YMmDH< zFudQg;c3$uT$2Z)gxSxpa;YW60Gqe*P)su<%ihBNUSFluh?%76T= zw~?$X;u;V6grj_ZpMf`L&#nPPe7(x^k?5TeT?(?dqE_|-$|-=J{|!x7ch62E8$08- zx{w)_FEtlP=`{`2^V35kGDcX72QfNULofWFq@E>vAt_-b4sdkvDVHSsOaW z?2M;c{R-y6KmrDx^c-cenq)#!{5#>k;A)r~W!t{|yR32#k5|B8INgSH^-FzE&aZS; zMT0gBF=86gz89w3^9_KZUuGkju7apB;I$xU0Ir@59KcC|sF~z6clYdjzqxy{&n0uH z2>#yB?qeT_Vb&0FiLwjE*z1R-wcY`Fa$a|@KmKlwAQ*t0dpXrM5X6QQ`iJ0Q`-v)% zlUriX*&DuD^v1xu!XSH|4Myhikiwnu^C4cUcnGf-WG~u;2A=H@4kr2Jw!vIbaW0W@pNRJ{UjfyLthbBSxPLPXFxXmT!fmf0Dy$#|N@ZX7f-x!mVz4??`3W5p? zmH_3|BXi$cXKv2tA`{-UaIzj5DQ&*DAh;+Ce~<+BNR*?U zJ>-g?V-7tGLQ>dX^0_WEcmOKq3`*7PS-%aT6fqyE*`R`SUSp}Q^jRvSNWYPiM0n(W zIgb#!Th$XE6ZBip$f5+a(;HdEho+#21aQ`&DOxZ=*h8(05RyVnIywn9k1$QkKn9)y1xc-HqK9v&+8gMmCyL#kxRs ztGl^3Q7hn5hI?bwv8m;5>W3HSRLw-inYG z2wVRET)d^qb_-_WdL%b$Y!C+txAr2F?6GTf$tdFGwCy6iIqzayH}<1^B^1hHU>9Y{ zS66!anI(Z@xvj3;rGYkv>49Gd6Z5YM_p=@+P-6@88lRX}L#B$kD^dlgiS( zt07c~ol;&mvFxwRAciBxwk>Sm+`Z5xme0w=z-@ zcrW*$@`RcaEFQ#mHy6)DZzCSrt55RS1SQN)5et5wP9T1srs5+_{+{nTKo38s5F7gLpzK379pwF0~8? zzt($1mtvb4a_{y=^C)muq{}@@E|PM2fMG)(7veo-cHZ#q3$E+5x3+v9we_XDDQ*O0 znz^O2c+>KHqZP{-8T*%EF^eo&XC!)!*(1^GVfvw2BR>PwZZBQ59{f;_VldBr;uwGb*?VGCUXCzOIMYjH3IgUwq3wbes8XD#)_G_sI zM$$79CHD)sxRkVZqZG&=$+#F^)=2-0d|tfJY9v{7AEV=!%{}!VCPQ%$g{&K~PZp1e z?5W?R%6O$zTUCn6!utjbsx1vquu36|>xoF8Pbv3JVH9w%Qkqq|56`Swcui&vFbfL! zS$Oj9GE^3(qG1LU>SS+JnOtG+&%#54Nfu|!;%<$f^w2hIC0wbT5i+7puJDqjD}Vw? z*(q8;P`b&&iKiIyjm8S4Mna7sg9^v>k;SLCsj!rtBb4G&I=HP~g3MvuBOX&Bs)*Yt zXInej)-#QPZ1rO-RL*|)=|~SUh+D~`gM$>N^y?~+G^7YBR#Gx_aEU6Ahk^{B&eou9 zp*D~YAg;Tgte2qMcv#7yl(Rp!qC*+AqZ;5UTu&4E-!mB1Fi#bajc}=O^CNq9?_gM~ zAa-sbyRBt?)q|k=9%Ek%{n&i!cfy0018fy^A3q3 zr}W#yn;F_yiO5Cn(fbFj1_EWMEdqp%mrWo%kC9QJ#5vvcw4ZJ!!J?XZMVEMNtOQJL zK!!UZ)u1JLl-gk4_XSMQc$6MTh>&ORJnJ)a9^yQSvbH{#Cq90+pie?h4^REb~*_L3EV)K_W_`%2As*k!&n1)qK))Fp1Lp zs$UMnC^y(p3`(!TFh~uRd{eYG>I_o>U84j_xlH6y(W~6b{^%P~_Q&5)$;WO}N=0lD z13DdTw=O=mi;BMZ%M{gsQae0QtE`ruQvKZnD$#zAFVN6GOlg?z6Ss|Xy40ovEH>Tc z>Z-36>%hj!#S(=YiU2DSZ;9eC7h`3T?aCvSB>Qk4r6hCF3`i!~-}x$IRA+|ylgv2I9!kA%I_YfY0(3)P|;fCR?!GSm!dk#K{ zrIa+K`C%3S(sWxEcJo>Jy4>p_!}vY6=N+tfznkvE+IgBF{S8%JeRgY(9#yk@*_W|61OcYGIAc4#;LDf}xWj*(wRNi+vM~#l4_+HH>A*nU5JK+kvq2 z_nL@_TI#J}WMqwGUB0g)-6Af4(3vcjO?%BdK(>OvRLG}9)_cusq`LY$xpMaohcP~; zc}A#mOUDH4UKdP0MDR?_EfRck{us!HlW31bJ8YOoC%q3GF~9(O__FyjreS=kp1UC(R-mj;7z44Qv{C}=ahaOr2(z}UTb?e z16kz&VEoSV`2!n~?1R5*@CWdOuwN0t8kN=V>{fQW3y!Dz!92>(gM;d`@rD-}|>c5w?$wjzrt9kMp;C zIQL^5!jCPmQHaO;!Seq)+FDs64>1)vOVM1RdQbP2mfY&gwy`%WOVPH_3-wb-2hIvd z2nxOksYD!w)kKJQN-fz?m==R-uDc(reh^g@$I_4aBW!Ki;sqBU+?M|3TR@^(WLmnX zdMg%_!I%&RQ%eIBaulQwF(|AS0#&3g$;?T)HBgQpcnYK9<1SRa0MN=wVuev))=`+n zZ%kDWU{Wi#}O*!Ykpt;ljVk`6<}Jdm*5y^ zD^h#$Qj`HWoyd>Zi`gbTg@Q7&e`1{?uw|s~=SEBhhZ1{}VUy05RLTkS4nURwnUC_1 z6%iJ!e#1KU7L6;JUdgE{Sr9D$nvs>7z!NWw=aYBwCX_Dk4Ate`B(Fh8ma^%dl8PQo>j^4g#L$Bml}F>@u=074pjE z1}sxUFa0Pa&_OA`0|z-HL;~QZgjQt%eUPsbvuq9m^7S&CsYeVz3}JmiLu`WucFWD? zPzQAaP%BE1D)*ZbA-nm4GJt^aL7PEJTv1^G_>Vv>l*V8ZJNQKb$7v!ePWL*xvdnZq z6`Yty+g5!~v}5?sn`>0W`>+>f&>Db9G0&|u1GAB8y5W&ZW%XU~6yP7Yzw&hD%c z4{Db}ByC38Ghz?BaB%AVaLB@BV!K(`I{W<=4F4nyic|qXYNP?!k!TlHG#%XLtn{6R zKE_X|6H$UX*c$4HNWNsEx(^F_ywq(2=;;lJs=xCxxsN=Q*B`@c*QKJ{_Dt>Tk-^1GwXrKt6xm)8udgV$zYJPWNRrk zPyb*|LMzLg-KBDDdtWeQcg3^4jzR0Foy|6#rt->&S{C~fVE?pDHfqaR4p%hfS|A=O zK)TBeW(hz{jq<&5@s%lTI9q1JmWmlmF`w7grI>4r^Z<63yzMjx`nFGm5-3in6!AWX_1!)hr}6i1G#Ul=4C&YWW})%r1S|3QASP zX9~z+`r+!ojbc?a4{=pi-qIrKhG8K`*`}$XOgz8iL{R# zVd|)sfc;``n7v8a+=78nIm^fCu|(p4q)1#1X(+^aNG}%%HpLrZR+$#^G(c=x)`aHvF5c+Kbo7AwrX%glY6zqG2G|nLDE*Y#I_l=n z|My>i>-k^#=AZrgYV}_hh?Y&|V1IbJ!J!m!Z_dhu!wt-+3JY8~+0*GE@gGYV_909O!=Kcgo^e`ct_AItobkxzI`N0y*nh< z=QV3XREHz-_oF_2S>Ldsq@d^;lyo-Mk5buCDoX$%olxRpDB0?Pl$vZ$_)D03SsVXQB}V; zMgcj|4Y9%hve)>HFQc+@Nbk#Q{2T8zE|$WYX(I2ed$9yfNX0Qk9;|isBE;!zL|5+= zx>z};5y3W>pZYsqHPP#!W{xZ$K*&nyFEL@gjQGat9Plf;n1e`)VmfCwNSuLFPhke} zpf3%_y9328bi};H(il+8P|0pPU9W*|MHNTp|2_w(fvdV&R_wIv6$?9fOful14Fb*H z#ROU)XoH3Z(1xmR&{b`k*i<3BQNScnwSG`TT~OE>kJym*5xb!rVud$L0mHm49c1Ea zaJua(ZE%x(kRRxv-q5WxQoCTaqGY-#6Ia4w;e{boj7)MyqYz#q?dKz3MxK%%%d6m` z5gCMw$nBB1QcEYg`wy7s5Q%u=;%%r9WLE?IrDEX4FT9qYXcT4#gmQCR5xZa&hxyuF zev%K@Jo7lfHxuN`6aX7IF2J=$QBkOA+j}peR}Q+%sEK9&F_x0PA6K;mi=*F+wPZz= zviF;;ij`L?GFjNnv(Qwg(~OrD5a61btXP|n5POut`@QU_9wuh8ET)uto8j%6tiYhd z3&w4iSHalihQu$>ReaE|tQ!%TXct%00C-F>vL)%yR{LYQZ9D{8_6uK)GJPk(Dx=;~ zR)=jyKAW_thNY<gLU?&3zj?E#q4QS}B z#0AwZR{sgCbeP?b)t`o;y~pG86tReRpPw`HkgZOu=@~Z?{g>yIT!;ZJ_{gDia+(?d zR3riN(8lwpiCh5e0u)Y*@v3wS{pby+mE(=r7}9KBxq~a9D1X4V^>s4n_BQ9ae5rtZ z?i(RTx)g-gbb2l-!BI4)9wX&Jj9#&?>__Y^CdtCSj<(5ae@}bOD)(-)%m-T3!6-|V zhc#k!i%kn6B+8z&{4VCs&T#n}&DWxgOh8~6k+EX8uFkEoi7yD+nW`e!gq}pi$j`TB zI$q#*74FqX7KaODMO=d9G7_+9o31#-b-zp6p&@5>&9y zO@gTQeiL6PY7;l+yzeq)8#>C^wgHJ-nDS+?7b0IX$41gXb_$$TFjj|}Xp&4UICbmVNFh71H!XyxF%7XrdF=(2T$+*KM8_7#<>+O> z2!U9O@(!Rl(a@^8&rdW$O>-CzL~`Sa2BRT;_e4X+4|9OOv!s<14gZF($H$+pT*(bc z*OqrN!mbU)AsLI6XXKxFktdS{?(+l<$V5P@MOZ>a!+DD{{&h<4*WO{?;QOApzTVTk zh4Q}VNk7bZo1xxial4OmFwdA~h-)16(Oe{#guhZUQJsFT!EC>8JY>dquteXqkD+oI zz@z=PPPCs@-OND38M>i#k?(#TMcz7UVy~Wh4btxFHrzXq}@@7Nc)wQHC#p7J0qb0xY2#KgAXltJ)*IXX)ZKc*v;>5D+4p912+S z*XF`c3WfF6f9Bv|bnWT`THRK&Wk5pwV;Srh4FNB$5Apod>jkUlU39TK>I-vsU4+R( z15o*SNNflM*>_f5+{3}|`!@q^TwCp1+Ach}`h4SjiV^=W<6uAwQuPc)D2 zbL}(yFC!Ud8FbIY3+R-#46G;cOBNJb689BC!3G) zU&K6Y6j?cU^2qXu2M--I(tp}0e`Nl|{L(`6{$pKI+;`?gXL0`2srK^OX1DJis4{=z z#PVYrdS*#HTW)unN8S8_m{Sj4XZ;)c)_;MvcwBob2&gdyTfP(oH*+0`{T>(QPt7kZ zcFs8#X&(bH&z@!MJzN(M62aQUUy}c&Tn!G_d3S8NeR96jSzLO=f#G7uEsE_Yn@gQ} zlNJAey$HP}*KD_!+Xj!RCV#_f@Uy3VW~H;Rr@7EeW9|qlb#!H)>pa?Y{7*n`amBeKJkq@% zNYCi#=-BA^=)~wGoR}V+8J!*7J2pBtHa0#sF*Z3iH8wpqGd4T6cYJhwYysmbZdnaSD7y;Gx8 zV^iZ(6H}8@Q&ZDZGgGrud#6XI$EL@pC#EN-r>3W;XQpST_s)#YjLnSCOw3HqOwCNs z%*@Qr?42E*9h)7WotT}RotmAVotd4T-MbeQ_p*Tcu;&`_FPe!hQEAH>cOg{{nUaO*?%5 zDXHGReP@;)YtNq=*?HJuwCCO7Pb@Dr54*GTC(bnc0W8~a^k;4v1%2$kGo8DosB6$i zKa=1Xaoy*F;6RS=*TAPhUq6_3a|Lq+7@IwRLjUd4IfP6wn@7FPVT$R!=>AF$SF))e z$6uL0%u?@1>*{{=@gVpO#;g4YYrhh_L3=mt0yx&VZsw|I@3z;6M@}@4b=;kIy7uBD zk9Kw*t~eNZth3J@KD?{qJJsIjwgY1l7)P5cm@{v^=9iATmE|*S1i;w3;vStp+jK`4 zkKw4Wak)&abYTj{f@g2--#9o>^1YgblrKg8|J;vyn5gMzkc0$W78WZHqUl~dzTRT#iO6;9Gm^jQuFas z%>~@$-S^*fZyREqIWgb<$UMP~4^ZS;7xuL0AA9(0bAi2fRq9hF+}Enqk~@sB=PIRG NMm*G?{H^Tf{{+?ha~S{t literal 0 HcmV?d00001 diff --git a/test/websocket.test.ts b/test/websocket.test.ts new file mode 100644 index 0000000..49c83b1 --- /dev/null +++ b/test/websocket.test.ts @@ -0,0 +1,283 @@ +import { Account } from '../src/account'; +import { TEST_DNA_URL } from '../src/consts'; +import { Address, PrivateKey } from '../src/crypto'; +import { Identity } from '../src/identity'; +import { WebsocketClient } from '../src/network/websocket/websocketClient'; +import { buildGetDDOTx, buildRegisterDNAidTx } from '../src/smartcontract/nativevm/idContractTxBuilder'; +import { signTransaction } from '../src/transaction/transactionBuilder'; +import { addSign } from './../src/transaction/transactionBuilder'; + +describe('test websocket', () => { + const client = new WebsocketClient(TEST_DNA_URL.SOCKET_URL, true, false); + client.addNotifyListener((result) => { + console.log('listener: ' + result); + }); + + // tslint:disable-next-line:one-variable-per-declaration + const codeHash = '36bb5c053b6b839c8f6b923fe852f91239b9fccc'; + + let txHash: string; + let blockHash: string; + let height: number = 10000; + + const privateKey = PrivateKey.random(); + const publicKey = privateKey.getPublicKey(); + const account = Account.create(privateKey, '123456', ''); + const identity = Identity.create(privateKey, '123456', ''); + const dnaid = identity.dnaid; + const address = account.address; + + const adminPrivateKey = new PrivateKey('7c47df9664e7db85c1308c080f398400cb24283f5d922e76b478b5429e821b97'); + const adminAddress = new Address('AdLUBSSHUuFaak9j169hiamXUmPuCTnaRz'); + + /** + * Registers new DNA ID to create transaction with Events and new block + */ + beforeAll(async () => { + const tx = buildRegisterDNAidTx(dnaid, publicKey, '500', '30000'); + tx.payer = adminAddress; + signTransaction(tx, privateKey); + addSign(tx, adminPrivateKey); + + const result = await client.sendRawTransaction(tx.serialize(), false, true); + txHash = result.Result.TxHash; + }, 5000); + + afterAll(async () => { + client.close(); + }); + + /** + * Gets current block height to be used by following tests. + */ + test('test getBlockHeight', async () => { + const result = await client.getBlockHeight(); + + expect(result.Action).toBe('getblockheight'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('number'); + height = result.Result; + }); + + test.skip('test getBestBlockHash', async () => { + const result = await client.getBlockHash(20); + + expect(result.Action).toBe('getblockhash'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('string'); + }); + + test.skip('test getBlockTxsByHeight', async () => { + const result = await client.getBlockTxsByHeight(20); + + expect(result.Action).toBe('getblocktxsbyheight'); + expect(result.Desc).toBe('SUCCESS'); + }); + + test.skip('test getGasPrice', async () => { + const result = await client.getGasPrice(); + + expect(result.Action).toBe('getgasprice'); + expect(result.Desc).toBe('SUCCESS'); + }); + + test.skip('test getMempoolTxCount', async () => { + const result = await client.getMempoolTxCount(); + + expect(result.Action).toBe('getmempooltxcount'); + expect(result.Desc).toBe('SUCCESS'); + }); + + test.skip('test_getMempoolTxState', async () => { + // tslint:disable-next-line:max-line-length + const result = await client.getMempoolTxState('6f3c0da62e83c126c7e3b2381d5fd6d2513026afcabea295f0a8dd8bcca2a7ad'); + + expect(result.Action).toBe('getmempooltxstate'); + expect(result.Desc).toBe('SUCCESS'); + }); + + test('test getVerson', async () => { + const result = await client.getVersion(); + + expect(result.Action).toBe('getversion'); + expect(result.Desc).toBe('SUCCESS'); + }); + + test('test getNetworkId', async () => { + const result = await client.getNetworkId(); + + expect(result.Action).toBe('getnetworkid'); + expect(result.Desc).toBe('SUCCESS'); + }); + + test('test getBlock by height', async () => { + const result = await client.getBlock(height); + + expect(result.Action).toBe('getblockbyheight'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('string'); + }); + + /** + * Gets block hash to be used by following tests. + */ + test('test getBlockJson by height', async () => { + const result = await client.getBlockJson(height); + + expect(result.Action).toBe('getblockbyheight'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('object'); + expect(result.Result.Hash).toBeDefined(); + blockHash = result.Result.Hash; + }); + + test('send heartbeat', async () => { + const result = await client.sendHeartBeat(); + + expect(result.Action).toBe('heartbeat'); + expect(result.Desc).toBe('SUCCESS'); + expect(result.Result.ConstractsFilter).toBeNull(); + expect(result.Result.SubscribeEvent).toBeFalsy(); + expect(result.Result.SubscribeJsonBlock).toBeFalsy(); + expect(result.Result.SubscribeRawBlock).toBeFalsy(); + expect(result.Result.SubscribeBlockTxHashs).toBeFalsy(); + }); + + test('send subscribe', async () => { + const result = await client.sendSubscribe(); + + expect(result.Action).toBe('subscribe'); + expect(result.Desc).toBe('SUCCESS'); + expect(result.Result.ConstractsFilter).toBeNull(); + expect(result.Result.SubscribeEvent).toBeFalsy(); + expect(result.Result.SubscribeJsonBlock).toBeFalsy(); + expect(result.Result.SubscribeRawBlock).toBeFalsy(); + expect(result.Result.SubscribeBlockTxHashs).toBeFalsy(); + }); + + test('send sendRawTransaction', async () => { + const tx = buildGetDDOTx(dnaid); + const result = await client.sendRawTransaction(tx.serialize(), true); + + expect(result.Action).toBe('sendrawtransaction'); + expect(result.Desc).toBe('SUCCESS'); + expect(result.Result).toBeDefined(); + }); + + test('test getRawTransaction', async () => { + const result = await client.getRawTransaction(txHash); + + expect(result.Action).toBe('gettransaction'); + expect(result.Desc).toBe('SUCCESS'); + expect(result.Result).toBeDefined(); + }); + + test('test getRawTransactionJson', async () => { + const result = await client.getRawTransactionJson(txHash); + + expect(result.Action).toBe('gettransaction'); + expect(result.Desc).toBe('SUCCESS'); + expect(result.Result).toBeDefined(); + expect(result.Result.Payload).toBeDefined(); + }); + + // test('test getGenerateBlockTime', async () => { + // const result = await client.getGenerateBlockTime(); + + // expect(result.Action).toBe('getgenerateblocktime'); + // expect(result.Desc).toBe('SUCCESS'); + // }); + + test('test getNodeCount', async () => { + const result = await client.getNodeCount(); + + expect(result.Action).toBe('getconnectioncount'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('number'); + }); + + test('test getBlock by hash', async () => { + const result = await client.getBlock(blockHash); + + expect(result.Action).toBe('getblockbyhash'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('string'); + }); + + test('test getBlockJson by hash', async () => { + const result = await client.getBlockJson(blockHash); + + expect(result.Action).toBe('getblockbyhash'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('object'); + expect(result.Result.Hash).toBeDefined(); + }); + + test('test getBalance', async () => { + const result = await client.getBalance(address); + + expect(result.Action).toBe('getbalance'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('object'); + expect(result.Result.gas).toBeDefined(); + }); + + test('test getContract', async () => { + const result = await client.getContract(codeHash); + + expect(result.Action).toBe('getcontract'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('string'); + }, 10000); + + test('test getContractJson', async () => { + const result = await client.getContractJson(codeHash); + + expect(result.Action).toBe('getcontract'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('object'); + expect(result.Result.Code).toBeDefined(); + }); + + test('test getSmartCodeEvent by height', async () => { + const result = await client.getSmartCodeEvent(height); + + expect(result.Action).toBe('getsmartcodeeventbyheight'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('string'); + }); + + test.skip('test getSmartCodeEvent by txHash', async () => { + const result = await client.getSmartCodeEvent(txHash); + + expect(result.Action).toBe('getsmartcodeeventbyhash'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('string'); + }); + + test('test getBlockHeightByTxHash', async () => { + const result = await client.getBlockHeightByTxHash(txHash); + + expect(result.Action).toBe('getblockheightbytxhash'); + expect(result.Desc).toBe('SUCCESS'); + expect(typeof result.Result).toBe('number'); + }); + + test.skip('test getStorage', async () => { + const key = '2a6469643a6f6e743a5443375a6b556a62694e36794b61415433687735567a714c713138587538635a4a5702'; + const result = await client.getStorage(codeHash, key); + + expect(result.Action).toBe('getstorage'); + expect(result.Desc).toBe('SUCCESS'); + expect(result.Result).toBeDefined(); + }); + + test('test getMerkleProof', async () => { + const result = await client.getMerkleProof(txHash); + + expect(result.Action).toBe('getmerkleproof'); + expect(result.Desc).toBe('SUCCESS'); + expect(result.Result).toBeDefined(); + expect(result.Result.Type).toBe('MerkleProof'); + }); +}); diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..9130ffc --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,63 @@ +{ + "compilerOptions": { + /* Basic Options */ + "target": "esnext", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', or 'ESNEXT'. */ + "module": "es6", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */ + // "lib": [], /* Specify library files to be included in the compilation: */ + // "allowJs": true, /* Allow javascript files to be compiled. */ + // "checkJs": true, /* Report errors in .js files. */ + // "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */ + "declaration": true, /* Generates corresponding '.d.ts' file. */ + "declarationDir": "./types", /* Output directory for generated declaration files. */ + "sourceMap": true, /* Generates corresponding '.map' file. */ + // "outFile": "./", /* Concatenate and emit output to single file. */ + "outDir": "./dist", /* Redirect output structure to the directory. */ + "rootDirs": ["./src", "./test"], /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */ + // "removeComments": true, /* Do not emit comments to output. */ + // "noEmit": true, /* Do not emit outputs. */ + // "importHelpers": true, /* Import emit helpers from 'tslib'. */ + // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ + + /* Strict Type-Checking Options */ + "strict": true, /* Enable all strict type-checking options. */ + // "noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */ + // "strictNullChecks": true, /* Enable strict null checks. */ + // "strictFunctionTypes": true, /* Enable strict checking of function types. */ + // "noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */ + // "alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */ + "strictPropertyInitialization": false, + /* Additional Checks */ + "noUnusedLocals": true, /* Report errors on unused locals. */ + // "noUnusedParameters": true, /* Report errors on unused parameters. */ + // "noImplicitReturns": true, /* Report error when not all code paths in function return a value. */ + // "noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */ + + /* Module Resolution Options */ + "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */ + // "baseUrl": "./", /* Base directory to resolve non-absolute module names. */ + // "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */ + // "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */ + // "typeRoots": [], /* List of folders to include type definitions from. */ + // "types": [], /* Type declaration files to be included in compilation. */ + // "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */ + // "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */ + + /* Source Map Options */ + // "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */ + // "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */ + // "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */ + // "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */ + + /* Experimental Options */ + // "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */ + // "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */ + }, + "include":[ + "./src/**/*", + "./src/global.d.ts", + "node_modules/@types" + ], + "exclude":[ + ] +} \ No newline at end of file diff --git a/tslint.json b/tslint.json new file mode 100644 index 0000000..34c4a88 --- /dev/null +++ b/tslint.json @@ -0,0 +1,31 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:recommended", "tslint-eslint-rules", "tslint-no-circular-imports" + ], + "jsRules": {}, + "rules": { + "quotemark": [true, "single"], + "ter-indent": [true, 4], + "trailing-comma": [true, {"multiline": "never", "singleline": "never"}], + "interface-name" : [true, "never-prefix"], + "member-access": false, + "max-classes-per-file": false, + "object-literal-sort-keys": false, + "whitespace": [ + true, + "check-branch", + "check-decl", + "check-operator", + "check-module", + "check-separator", + "check-rest-spread", + "check-type", + "check-typecast", + "check-type-operator", + "check-preblock" + ], + "no-bitwise": false + }, + "rulesDirectory": [] +} diff --git a/typedoc.js b/typedoc.js new file mode 100644 index 0000000..608a226 --- /dev/null +++ b/typedoc.js @@ -0,0 +1,20 @@ +module.exports = { + module:'commonjs', + target: 'es5', + out: './apidoc', + readme: './README.md', + includes: './src', + // exclude: [ + // '*/node_modules/**/*.*', + // '*/src/sdk/*.ts', + // '*/src/transaction/txSender.ts', + // '*/src/transaction/vmcode.ts', + // '*/src/common/uint256.ts', + // '*/src/common/uint160.ts', + // '*/src/transaction/program.ts', + // '*/src/transaction/txAttribute.ts' + // ], + exclude: '**/*+(txSender|vmcode|program|uint256|uint160|txAttribute|websocketBuilder|governanceContractTxBuilder|token|nep5TxBuilder).ts', + // mode: 'file', + ignoreCompilerErrors: true +} \ No newline at end of file diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..f105af1 --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,53 @@ +var path = require('path'); +const CleanWebpackPlugin = require('clean-webpack-plugin'); +var nodeExternals = require('webpack-node-externals'); +var TypedocWebpackPlugin = require('typedoc-webpack-plugin'); + +let common = { + entry: './src/index.ts', + devtool: 'source-map', + module: { + rules: [ + { + test: /\.tsx?$/, + use: ['babel-loader', 'ts-loader'], + exclude: /node_modules/ + }, + ] + }, + plugins: [ + new CleanWebpackPlugin(['lib'], { + exclude: ['test.html'] + }), + ], + resolve: { + extensions: ['.tsx', '.ts', '.js'] + }, +}; + +module.exports = [ + Object.assign({}, common, { + target: 'web', + entry: ['babel-polyfill', './src/index.ts'], + output: { + path: path.resolve(__dirname, 'lib'), + filename: 'browser.js', + libraryTarget: 'var', + library: 'DNA' // This is the var name in browser + }, + node: { + fs: 'empty', + child_process: 'empty' + } + }), + Object.assign({}, common, { + target: 'node', + output: { + path: path.resolve(__dirname, 'lib'), + filename: 'index.js', + libraryTarget: 'commonjs2', + }, + externals: [nodeExternals()] + }) +] + diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..5f43285 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,6762 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@babel/code-frame@^7.0.0-beta.35": + version "7.0.0-beta.54" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0-beta.54.tgz#0024f96fdf7028a21d68e273afd4e953214a1ead" + dependencies: + "@babel/highlight" "7.0.0-beta.54" + +"@babel/highlight@7.0.0-beta.54": + version "7.0.0-beta.54" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0-beta.54.tgz#155d507358329b8e7068970017c3fd74a9b08584" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +"@babel/runtime@^7.4.5": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f" + integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA== + dependencies: + regenerator-runtime "^0.13.2" + +"@mrmlnc/readdir-enhanced@^2.2.1": + version "2.2.1" + resolved "https://registry.yarnpkg.com/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz#524af240d1a360527b730475ecfa1344aa540dde" + dependencies: + call-me-maybe "^1.0.1" + glob-to-regexp "^0.3.0" + +"@nodelib/fs.stat@^1.0.1": + version "1.1.0" + resolved "https://registry.yarnpkg.com/@nodelib/fs.stat/-/fs.stat-1.1.0.tgz#50c1e2260ac0ed9439a181de3725a0168d59c48a" + +"@ont-community/hdkey-secp256r1@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@ont-community/hdkey-secp256r1/-/hdkey-secp256r1-1.0.1.tgz#81840bd0ae3442baed490eac204646bb845e9f89" + dependencies: + coinstring "^2.0.0" + elliptic "^6.4.0" + safe-buffer "^5.1.1" + +"@ont-community/html5-websocket@^2.0.2": + version "2.0.3" + resolved "https://registry.yarnpkg.com/@ont-community/html5-websocket/-/html5-websocket-2.0.3.tgz#702419116217ec749c6eea18b234bd3d600b0c5c" + dependencies: + ws "^3.1.0" + +"@samverschueren/stream-to-observable@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz#ecdf48d532c58ea477acfcab80348424f8d0662f" + dependencies: + any-observable "^0.3.0" + +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + +"@types/base-x@*": + version "1.0.29" + resolved "https://registry.yarnpkg.com/@types/base-x/-/base-x-1.0.29.tgz#8a2d73e4a5c3121757a5f8870cfa4509655186b6" + +"@types/base64-url@^2.2.0": + version "2.2.0" + resolved "https://registry.yarnpkg.com/@types/base64-url/-/base64-url-2.2.0.tgz#ff17c19bf357821bd637af2f54f7922443377950" + +"@types/bigi@*": + version "1.4.2" + resolved "https://registry.yarnpkg.com/@types/bigi/-/bigi-1.4.2.tgz#8dda60612e689e5769047568d0ce8b8fa83db953" + +"@types/bs58@^3.0.30": + version "3.0.30" + resolved "https://registry.yarnpkg.com/@types/bs58/-/bs58-3.0.30.tgz#916ba10992465e56f81afc735e7935fd749893e1" + dependencies: + "@types/base-x" "*" + +"@types/crypto-js@^3.1.38": + version "3.1.42" + resolved "https://registry.yarnpkg.com/@types/crypto-js/-/crypto-js-3.1.42.tgz#00f6b6a037693c2dc5e8dcf303e7e682751bb282" + +"@types/ecurve@^1.0.0": + version "1.0.0" + resolved "https://registry.yarnpkg.com/@types/ecurve/-/ecurve-1.0.0.tgz#0d1fce022d8bab2bc4bab28c5d781b64210018c4" + dependencies: + "@types/bigi" "*" + "@types/node" "*" + +"@types/events@*": + version "1.2.0" + resolved "https://registry.yarnpkg.com/@types/events/-/events-1.2.0.tgz#81a6731ce4df43619e5c8c945383b3e62a89ea86" + +"@types/fs-extra@5.0.1": + version "5.0.1" + resolved "https://registry.yarnpkg.com/@types/fs-extra/-/fs-extra-5.0.1.tgz#cd856fbbdd6af2c11f26f8928fd8644c9e9616c9" + dependencies: + "@types/node" "*" + +"@types/glob@*": + version "5.0.35" + resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" + dependencies: + "@types/events" "*" + "@types/minimatch" "*" + "@types/node" "*" + +"@types/handlebars@4.0.36": + version "4.0.36" + resolved "https://registry.yarnpkg.com/@types/handlebars/-/handlebars-4.0.36.tgz#ff57c77fa1ab6713bb446534ddc4d979707a3a79" + +"@types/highlight.js@9.12.2": + version "9.12.2" + resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.12.2.tgz#6ee7cd395effe5ec80b515d3ff1699068cd0cd1d" + +"@types/jest@^22.1.2": + version "22.2.3" + resolved "https://registry.yarnpkg.com/@types/jest/-/jest-22.2.3.tgz#0157c0316dc3722c43a7b71de3fdf3acbccef10d" + +"@types/lodash@4.14.104": + version "4.14.104" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.104.tgz#53ee2357fa2e6e68379341d92eb2ecea4b11bb80" + +"@types/long@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/long/-/long-4.0.0.tgz#719551d2352d301ac8b81db732acb6bdc28dbdef" + +"@types/marked@0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/marked/-/marked-0.3.0.tgz#583c223dd33385a1dda01aaf77b0cd0411c4b524" + +"@types/minimatch@*", "@types/minimatch@3.0.3": + version "3.0.3" + resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d" + +"@types/node@*": + version "10.5.2" + resolved "https://registry.yarnpkg.com/@types/node/-/node-10.5.2.tgz#f19f05314d5421fe37e74153254201a7bf00a707" + +"@types/node@^8.5.2": + version "8.10.21" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.10.21.tgz#12b3f2359b27aa05a45d886c8ba1eb8d1a77e285" + +"@types/promise-timeout@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@types/promise-timeout/-/promise-timeout-1.3.0.tgz#90649ff6f48c1ead9de142e6dd9f62f8c5a54022" + +"@types/scrypt-async@^1.3.0": + version "1.3.0" + resolved "https://registry.yarnpkg.com/@types/scrypt-async/-/scrypt-async-1.3.0.tgz#bdc7bd89fde46de3eb1684afee0dbbb94f058b9b" + +"@types/shelljs@0.7.8": + version "0.7.8" + resolved "https://registry.yarnpkg.com/@types/shelljs/-/shelljs-0.7.8.tgz#4b4d6ee7926e58d7bca448a50ba442fd9f6715bd" + dependencies: + "@types/glob" "*" + "@types/node" "*" + +"@types/uuid@^3.4.3": + version "3.4.3" + resolved "https://registry.yarnpkg.com/@types/uuid/-/uuid-3.4.3.tgz#121ace265f5569ce40f4f6d0ff78a338c732a754" + dependencies: + "@types/node" "*" + +"@webassemblyjs/ast@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.5.13.tgz#81155a570bd5803a30ec31436bc2c9c0ede38f25" + dependencies: + "@webassemblyjs/helper-module-context" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/wast-parser" "1.5.13" + debug "^3.1.0" + mamacro "^0.0.3" + +"@webassemblyjs/floating-point-hex-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.5.13.tgz#29ce0baa97411f70e8cce68ce9c0f9d819a4e298" + +"@webassemblyjs/helper-api-error@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-api-error/-/helper-api-error-1.5.13.tgz#e49b051d67ee19a56e29b9aa8bd949b5b4442a59" + +"@webassemblyjs/helper-buffer@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-buffer/-/helper-buffer-1.5.13.tgz#873bb0a1b46449231137c1262ddfd05695195a1e" + dependencies: + debug "^3.1.0" + +"@webassemblyjs/helper-code-frame@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.5.13.tgz#1bd2181b6a0be14e004f0fe9f5a660d265362b58" + dependencies: + "@webassemblyjs/wast-printer" "1.5.13" + +"@webassemblyjs/helper-fsm@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-fsm/-/helper-fsm-1.5.13.tgz#cdf3d9d33005d543a5c5e5adaabf679ffa8db924" + +"@webassemblyjs/helper-module-context@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-module-context/-/helper-module-context-1.5.13.tgz#dc29ddfb51ed657655286f94a5d72d8a489147c5" + dependencies: + debug "^3.1.0" + mamacro "^0.0.3" + +"@webassemblyjs/helper-wasm-bytecode@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.5.13.tgz#03245817f0a762382e61733146f5773def15a747" + +"@webassemblyjs/helper-wasm-section@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.5.13.tgz#efc76f44a10d3073b584b43c38a179df173d5c7d" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/ieee754@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/ieee754/-/ieee754-1.5.13.tgz#573e97c8c12e4eebb316ca5fde0203ddd90b0364" + dependencies: + ieee754 "^1.1.11" + +"@webassemblyjs/leb128@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/leb128/-/leb128-1.5.13.tgz#ab52ebab9cec283c1c1897ac1da833a04a3f4cee" + dependencies: + long "4.0.0" + +"@webassemblyjs/utf8@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/utf8/-/utf8-1.5.13.tgz#6b53d2cd861cf94fa99c1f12779dde692fbc2469" + +"@webassemblyjs/wasm-edit@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-edit/-/wasm-edit-1.5.13.tgz#c9cef5664c245cf11b3b3a73110c9155831724a8" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/helper-wasm-section" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + "@webassemblyjs/wasm-opt" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + "@webassemblyjs/wast-printer" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/wasm-gen@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-gen/-/wasm-gen-1.5.13.tgz#8e6ea113c4b432fa66540189e79b16d7a140700e" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/ieee754" "1.5.13" + "@webassemblyjs/leb128" "1.5.13" + "@webassemblyjs/utf8" "1.5.13" + +"@webassemblyjs/wasm-opt@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-opt/-/wasm-opt-1.5.13.tgz#147aad7717a7ee4211c36b21a5f4c30dddf33138" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-buffer" "1.5.13" + "@webassemblyjs/wasm-gen" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + debug "^3.1.0" + +"@webassemblyjs/wasm-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wasm-parser/-/wasm-parser-1.5.13.tgz#6f46516c5bb23904fbdf58009233c2dd8a54c72f" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-api-error" "1.5.13" + "@webassemblyjs/helper-wasm-bytecode" "1.5.13" + "@webassemblyjs/ieee754" "1.5.13" + "@webassemblyjs/leb128" "1.5.13" + "@webassemblyjs/utf8" "1.5.13" + +"@webassemblyjs/wast-parser@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-parser/-/wast-parser-1.5.13.tgz#5727a705d397ae6a3ae99d7f5460acf2ec646eea" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/floating-point-hex-parser" "1.5.13" + "@webassemblyjs/helper-api-error" "1.5.13" + "@webassemblyjs/helper-code-frame" "1.5.13" + "@webassemblyjs/helper-fsm" "1.5.13" + long "^3.2.0" + mamacro "^0.0.3" + +"@webassemblyjs/wast-printer@1.5.13": + version "1.5.13" + resolved "https://registry.yarnpkg.com/@webassemblyjs/wast-printer/-/wast-printer-1.5.13.tgz#bb34d528c14b4f579e7ec11e793ec50ad7cd7c95" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/wast-parser" "1.5.13" + long "^3.2.0" + +abab@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/abab/-/abab-1.0.4.tgz#5faad9c2c07f60dd76770f71cf025b62a63cfd4e" + +abbrev@1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" + +acorn-dynamic-import@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-3.0.0.tgz#901ceee4c7faaef7e07ad2a47e890675da50a278" + dependencies: + acorn "^5.0.0" + +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + +acorn@^5.0.0, acorn@^5.3.0, acorn@^5.6.2: + version "5.7.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.1.tgz#f095829297706a7c9776958c0afc8930a9b9d9d8" + +ajv-keywords@^3.1.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.2.0.tgz#e86b819c602cf8821ad637413698f1dec021847a" + +ajv@^5.1.0: + version "5.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" + dependencies: + co "^4.6.0" + fast-deep-equal "^1.0.0" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.3.0" + +ajv@^6.1.0: + version "6.5.2" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-6.5.2.tgz#678495f9b82f7cca6be248dd92f59bff5e1f4360" + dependencies: + fast-deep-equal "^2.0.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.1" + +ansi-escapes@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" + +ansi-escapes@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-3.1.0.tgz#f73207bb81207d75fd6c83f125af26eea378ca30" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@^3.2.0, ansi-styles@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" + dependencies: + color-convert "^1.9.0" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +any-observable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/any-observable/-/any-observable-0.3.0.tgz#af933475e5806a67d0d7df090dd5e8bef65d119b" + +anymatch@^1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.2.tgz#553dcb8f91e3c889845dfdba34c77721b90b9d7a" + dependencies: + micromatch "^2.1.5" + normalize-path "^2.0.0" + +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-transform@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-1.0.0.tgz#046a52ae582a228bd72f58acfbe2967c678759ab" + dependencies: + default-require-extensions "^2.0.0" + +aproba@^1.0.3, aproba@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" + +are-we-there-yet@~1.1.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz#4b35c2944f062a8bfcda66410760350fe9ddfc21" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.6" + +argparse@^1.0.7: + version "1.0.10" + resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" + integrity sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg== + dependencies: + sprintf-js "~1.0.2" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-diff@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" + +arr-flatten@^1.0.1, arr-flatten@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.1.0.tgz#36048bbff4e7b47e136644316c99669ea5ae91f1" + +arr-union@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/arr-union/-/arr-union-3.1.0.tgz#e39b09aea9def866a8f206e288af63919bae39c4" + +array-differ@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-differ/-/array-differ-1.0.0.tgz#eff52e3758249d33be402b8bb8e564bb2b5d4031" + +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + +array-filter@~0.0.0: + version "0.0.1" + resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" + +array-map@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-map/-/array-map-0.0.0.tgz#88a2bab73d1cf7bcd5c1b118a003f66f665fa662" + +array-reduce@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/array-reduce/-/array-reduce-0.0.0.tgz#173899d3ffd1c7d9383e4479525dbe278cab5f2b" + +array-union@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/array-union/-/array-union-1.0.2.tgz#9a34410e4f4e3da23dea375be5be70f24778ec39" + dependencies: + array-uniq "^1.0.1" + +array-uniq@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/array-uniq/-/array-uniq-1.0.3.tgz#af6ac877a25cc7f74e058894753858dfdb24fdb6" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +array-unique@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.3.2.tgz#a894b75d4bc4f6cd679ef3244a9fd8f46ae2d428" + +arrify@^1.0.0, arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asn1.js@^4.0.0: + version "4.10.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.10.1.tgz#b9c2bf5805f1e64aadeed6df3a2bfafb5a73f5a0" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@1.0.0, assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +assign-symbols@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" + +ast-metadata-inferer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ast-metadata-inferer/-/ast-metadata-inferer-0.1.1.tgz#66e24fae9d30ca961fac4880b7fc466f09b25165" + integrity sha512-hc9w8Qrgg9Lf9iFcZVhNjUnhrd2BBpTlyCnegPVvCe6O0yMrF57a6Cmh7k+xUsfUOMh9wajOL5AsGOBNEyTCcw== + +ast-types@0.10.1: + version "0.10.1" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.10.1.tgz#f52fca9715579a14f841d67d7f8d25432ab6a3dd" + +ast-types@0.11.5: + version "0.11.5" + resolved "https://registry.yarnpkg.com/ast-types/-/ast-types-0.11.5.tgz#9890825d660c03c28339f315e9fa0a360e31ec28" + +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async-limiter@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/async-limiter/-/async-limiter-1.0.0.tgz#78faed8c3d074ab81f22b4e985d79e8738f720f8" + +async@^1.5.0: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.1.4, async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + dependencies: + lodash "^4.17.10" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +atob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/atob/-/atob-2.1.1.tgz#ae2d5a729477f289d60dd7f96a6314a22dd6c22a" + +aws-sign2@~0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8" + +aws4@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" + +axios@^0.19.0: + version "0.19.0" + resolved "https://registry.yarnpkg.com/axios/-/axios-0.19.0.tgz#8e09bff3d9122e133f7b8101c8fbdd00ed3d2ab8" + integrity sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ== + dependencies: + follow-redirects "1.5.10" + is-buffer "^2.0.2" + +babel-code-frame@^6.22.0, babel-code-frame@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.26.0.tgz#63fd43f7dc1e3bb7ce35947db8fe369a3f58c74b" + dependencies: + chalk "^1.1.3" + esutils "^2.0.2" + js-tokens "^3.0.2" + +babel-core@^6.0.0, babel-core@^6.26.0, babel-core@^6.26.3: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + 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.4" + 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@^6.18.0, babel-generator@^6.26.0: + version "6.26.1" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" + dependencies: + 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.4" + source-map "^0.5.7" + trim-right "^1.0.1" + +babel-helper-bindify-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.24.1.tgz#14c19e5f142d7b47f19a52431e52b1ccbc40a330" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-builder-binary-assignment-operator-visitor@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz#cce4517ada356f4220bcae8a02c2b346f9a56664" + dependencies: + babel-helper-explode-assignable-expression "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-call-delegate@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz#ece6aacddc76e41c3461f88bfc575bd0daa2df8d" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-define-map@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz#a5f56dab41a25f97ecb498c7ebaca9819f95be5f" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-explode-assignable-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz#f25b82cf7dc10433c55f70592d5746400ac22caa" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-explode-class@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.24.1.tgz#7dc2a3910dee007056e1e31d640ced3d54eaa9eb" + dependencies: + babel-helper-bindify-decorators "^6.24.1" + babel-runtime "^6.22.0" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz#d3475b8c03ed98242a25b48351ab18399d3580a9" + dependencies: + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-get-function-arity@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz#8f7782aa93407c41d3aa50908f89b031b1b6853d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-hoist-variables@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz#1ecb27689c9d25513eadbc9914a73f5408be7a76" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-optimise-call-expression@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz#f7a13427ba9f73f8f4fa993c54a97882d1244257" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-helper-regex@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz#325c59f902f82f24b74faceed0363954f6495e72" + dependencies: + babel-runtime "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-helper-remap-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz#5ec581827ad723fecdd381f1c928390676e4551b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helper-replace-supers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz#bf6dbfe43938d17369a213ca8a8bf74b6a90ab1a" + dependencies: + babel-helper-optimise-call-expression "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-helpers@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.24.1.tgz#3471de9caec388e5c850e597e58a26ddf37602b2" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-jest@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.4.0.tgz#22c34c392e2176f6a4c367992a7fcff69d2e8557" + dependencies: + babel-plugin-istanbul "^4.1.6" + babel-preset-jest "^23.2.0" + +babel-loader@^7.1.4: + version "7.1.5" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.5.tgz#e3ee0cd7394aa557e013b02d3e492bfd07aa6d68" + dependencies: + find-cache-dir "^1.0.0" + loader-utils "^1.0.2" + mkdirp "^0.5.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-22.4.4.tgz#b9851906eab34c7bf6f8c895a2b08bea1a844c0b" + +babel-plugin-jest-hoist@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-constructor-call@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz#9cb9d39fe43c8600bec8146456ddcbd4e1a76416" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-export-extensions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz#70a1484f0f9089a4e84ad44bac353c95b9b12721" + +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-generator-functions@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.24.1.tgz#f058900145fd3e9907a6ddf28da59f215258a5db" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@^6.22.0, babel-plugin-transform-async-to-generator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz#6536e378aff6cb1d5517ac0e40eb3e9fc8d08761" + dependencies: + babel-helper-remap-async-to-generator "^6.24.1" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-constructor-call@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-constructor-call/-/babel-plugin-transform-class-constructor-call-6.24.1.tgz#80dc285505ac067dcb8d6c65e2f6f11ab7765ef9" + dependencies: + babel-plugin-syntax-class-constructor-call "^6.18.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-class-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.24.1.tgz#6a79763ea61d33d36f37b611aa9def81a81b46ac" + dependencies: + babel-helper-function-name "^6.24.1" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-decorators@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.24.1.tgz#788013d8f8c6b5222bdf7b344390dfd77569e24d" + dependencies: + babel-helper-explode-class "^6.24.1" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.23.0, babel-plugin-transform-es2015-block-scoping@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz#d70f5299c1308d05c12f463813b0a09e73b1895f" + dependencies: + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + lodash "^4.17.4" + +babel-plugin-transform-es2015-classes@^6.23.0, babel-plugin-transform-es2015-classes@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz#5a4c58a50c9c9461e564b4b2a3bfabc97a2584db" + dependencies: + babel-helper-define-map "^6.24.1" + babel-helper-function-name "^6.24.1" + babel-helper-optimise-call-expression "^6.24.1" + babel-helper-replace-supers "^6.24.1" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-computed-properties@^6.22.0, babel-plugin-transform-es2015-computed-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz#6fe2a8d16895d5634f4cd999b6d3480a308159b3" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-destructuring@^6.22.0, babel-plugin-transform-es2015-destructuring@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0, babel-plugin-transform-es2015-duplicate-keys@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz#73eb3d310ca969e3ef9ec91c53741a6f1576423e" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-for-of@^6.22.0, babel-plugin-transform-es2015-for-of@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0, babel-plugin-transform-es2015-function-name@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz#834c89853bc36b1af0f3a4c5dbaa94fd8eacaa8b" + dependencies: + babel-helper-function-name "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0, babel-plugin-transform-es2015-modules-amd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz#3b3e54017239842d6d19c3011c4bd2f00a00d154" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-commonjs@^6.23.0, babel-plugin-transform-es2015-modules-commonjs@^6.24.1, babel-plugin-transform-es2015-modules-commonjs@^6.26.2: + version "6.26.2" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz#58a793863a9e7ca870bdc5a881117ffac27db6f3" + dependencies: + 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@^6.23.0, babel-plugin-transform-es2015-modules-systemjs@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz#ff89a142b9119a906195f5f106ecf305d9407d23" + dependencies: + babel-helper-hoist-variables "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-modules-umd@^6.23.0, babel-plugin-transform-es2015-modules-umd@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz#ac997e6285cd18ed6176adb607d602344ad38468" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + +babel-plugin-transform-es2015-object-super@^6.22.0, babel-plugin-transform-es2015-object-super@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz#24cef69ae21cb83a7f8603dad021f572eb278f8d" + dependencies: + babel-helper-replace-supers "^6.24.1" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.23.0, babel-plugin-transform-es2015-parameters@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz#57ac351ab49caf14a97cd13b09f66fdf0a625f2b" + dependencies: + babel-helper-call-delegate "^6.24.1" + babel-helper-get-function-arity "^6.24.1" + babel-runtime "^6.22.0" + babel-template "^6.24.1" + babel-traverse "^6.24.1" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0, babel-plugin-transform-es2015-shorthand-properties@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz#24f875d6721c87661bbd99a4622e51f14de38aa0" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0, babel-plugin-transform-es2015-sticky-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz#00c1cdb1aca71112cdf0cf6126c2ed6b457ccdbc" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0, babel-plugin-transform-es2015-typeof-symbol@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0, babel-plugin-transform-es2015-unicode-regex@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz#d38b12f42ea7323f729387f18a7c5ae1faeb35e9" + dependencies: + babel-helper-regex "^6.24.1" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0, babel-plugin-transform-exponentiation-operator@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz#2ab0c9c7f3098fa48907772bb813fe41e8de3a0e" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.24.1" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-export-extensions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-export-extensions/-/babel-plugin-transform-export-extensions-6.22.0.tgz#53738b47e75e8218589eea946cbbd39109bbe653" + dependencies: + babel-plugin-syntax-export-extensions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^6.8.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.22.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.26.0.tgz#0f36692d50fef6b7e2d4b3ac1478137a963b7b06" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.26.0" + +babel-plugin-transform-regenerator@^6.22.0, babel-plugin-transform-regenerator@^6.24.1: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz#e0703696fbde27f0a3efcacf8b4dca2f7b3a8f2f" + dependencies: + regenerator-transform "^0.10.0" + +babel-plugin-transform-runtime@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-runtime/-/babel-plugin-transform-runtime-6.23.0.tgz#88490d446502ea9b8e7efb0fe09ec4d99479b1ee" + integrity sha1-iEkNRGUC6puOfvsP4J7E2ZR5se4= + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-strict-mode@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz#d5faf7aa578a65bbe591cf5edae04a0c67020758" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.24.1" + +babel-polyfill@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" + dependencies: + babel-runtime "^6.26.0" + core-js "^2.5.0" + regenerator-runtime "^0.10.5" + +babel-preset-env@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/babel-preset-env/-/babel-preset-env-1.7.0.tgz#dea79fa4ebeb883cd35dab07e260c1c9c04df77a" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-to-generator "^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.23.0" + babel-plugin-transform-es2015-classes "^6.23.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.23.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.23.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.23.0" + babel-plugin-transform-es2015-modules-systemjs "^6.23.0" + babel-plugin-transform-es2015-modules-umd "^6.23.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.23.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + 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.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + browserslist "^3.2.6" + invariant "^2.2.2" + semver "^5.3.0" + +babel-preset-es2015@^6.9.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.24.1.tgz#d44050d6bc2c9feea702aaf38d727a0210538939" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.24.1" + babel-plugin-transform-es2015-classes "^6.24.1" + babel-plugin-transform-es2015-computed-properties "^6.24.1" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.24.1" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.24.1" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.24.1" + babel-plugin-transform-es2015-modules-commonjs "^6.24.1" + babel-plugin-transform-es2015-modules-systemjs "^6.24.1" + babel-plugin-transform-es2015-modules-umd "^6.24.1" + babel-plugin-transform-es2015-object-super "^6.24.1" + babel-plugin-transform-es2015-parameters "^6.24.1" + babel-plugin-transform-es2015-shorthand-properties "^6.24.1" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.24.1" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.24.1" + babel-plugin-transform-regenerator "^6.24.1" + +babel-preset-jest@^22.4.3: + version "22.4.4" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-22.4.4.tgz#ec9fbd8bcd7dfd24b8b5320e0e688013235b7c39" + dependencies: + babel-plugin-jest-hoist "^22.4.4" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-preset-jest@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" + dependencies: + babel-plugin-jest-hoist "^23.2.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + +babel-preset-stage-1@^6.5.0: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-1/-/babel-preset-stage-1-6.24.1.tgz#7692cd7dcd6849907e6ae4a0a85589cfb9e2bfb0" + dependencies: + 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@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.24.1.tgz#d9e2960fb3d71187f0e64eec62bc07767219bdc1" + dependencies: + 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@^6.24.1: + version "6.24.1" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.24.1.tgz#836ada0a9e7a7fa37cb138fb9326f87934a48395" + dependencies: + 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.22.0" + +babel-register@^6.26.0, babel-register@^6.9.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.26.0.tgz#6ed021173e2fcb486d7acb45c6009a856f647071" + dependencies: + babel-core "^6.26.0" + babel-runtime "^6.26.0" + core-js "^2.5.0" + home-or-tmp "^2.0.0" + lodash "^4.17.4" + mkdirp "^0.5.1" + source-map-support "^0.4.15" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.26.0, babel-runtime@^6.9.2: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.11.0" + +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" + dependencies: + babel-runtime "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + lodash "^4.17.4" + +babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" + dependencies: + 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.8" + globals "^9.18.0" + invariant "^2.2.2" + lodash "^4.17.4" + +babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: + version "6.26.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" + dependencies: + babel-runtime "^6.26.0" + esutils "^2.0.2" + lodash "^4.17.4" + to-fast-properties "^1.0.3" + +babylon@^6.17.3, babylon@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.18.0.tgz#af2f3b88fa6f5c1e4c634d1a0f8eac4f55b395e3" + +babylon@^7.0.0-beta.47: + version "7.0.0-beta.47" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-7.0.0-beta.47.tgz#6d1fa44f0abec41ab7c780481e62fd9aafbdea80" + +balanced-match@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767" + +base-58@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/base-58/-/base-58-0.0.1.tgz#85d3e70251075661933388f831d1eb8b8f6314e3" + +base-x@^3.0.2: + version "3.0.4" + resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.4.tgz#94c1788736da065edb1d68808869e357c977fa77" + dependencies: + safe-buffer "^5.0.1" + +base64-js@^1.0.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.0.tgz#cab1e6118f051095e58b5281aea8c1cd22bfc0e3" + +base64-url@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/base64-url/-/base64-url-2.2.0.tgz#4bbd6a825df1be522d39e566a721ede51144041a" + +base@^0.11.1: + version "0.11.2" + resolved "https://registry.yarnpkg.com/base/-/base-0.11.2.tgz#7bde5ced145b6d551a90db87f83c558b4eb48a8f" + dependencies: + cache-base "^1.0.1" + class-utils "^0.3.5" + component-emitter "^1.2.1" + define-property "^1.0.0" + isobject "^3.0.1" + mixin-deep "^1.2.0" + pascalcase "^0.1.1" + +bcrypt-pbkdf@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz#a4301d389b6a43f9b67ff3ca11a3f6637e360e9e" + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.2.0" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.2.0.tgz#a5fc298b81b9e0dca2e458824784b65c52ba588e" + +bigi@^1.1.0, bigi@^1.2.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/bigi/-/bigi-1.4.2.tgz#9c665a95f88b8b08fc05cfd731f561859d725825" + +bignumber.js@^7.2.1: + version "7.2.1" + resolved "https://registry.yarnpkg.com/bignumber.js/-/bignumber.js-7.2.1.tgz#80c048759d826800807c4bfd521e50edbba57a5f" + +binary-extensions@^1.0.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.11.0.tgz#46aa1751fb6a2f93ee5e689bb1087d4b14c6c205" + +binaryextensions@2: + version "2.1.1" + resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-2.1.1.tgz#3209a51ca4a4ad541a3b8d3d6a6d5b83a2485935" + +bip39@^2.5.0: + version "2.5.0" + resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235" + dependencies: + create-hash "^1.1.0" + pbkdf2 "^3.0.9" + randombytes "^2.0.1" + safe-buffer "^5.0.1" + unorm "^1.3.3" + +bip66@^1.1.0: + version "1.1.5" + resolved "https://registry.yarnpkg.com/bip66/-/bip66-1.1.5.tgz#01fa8748785ca70955d5011217d1b3139969ca22" + dependencies: + safe-buffer "^5.0.1" + +bluebird@^3.5.1: + version "3.5.1" + resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.5.1.tgz#d9551f9de98f1fcda1e683d17ee91a0602ee2eb9" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.11.6, bn.js@^4.4.0: + version "4.11.8" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.8.tgz#2cde09eb5ee341f484746bb0309b3253b1b1442f" + +brace-expansion@^1.1.7: + version "1.1.11" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.11.tgz#3c7fcbf529d87226f3d2f52b966ff5271eb441dd" + dependencies: + balanced-match "^1.0.0" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +braces@^2.3.0, braces@^2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/braces/-/braces-2.3.2.tgz#5979fd3f14cd531565e5fa2df1abfff1dfaee729" + dependencies: + arr-flatten "^1.1.0" + array-unique "^0.3.2" + extend-shallow "^2.0.1" + fill-range "^4.0.0" + isobject "^3.0.1" + repeat-element "^1.1.2" + snapdragon "^0.8.1" + snapdragon-node "^2.0.1" + split-string "^3.0.2" + to-regex "^3.0.1" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + +browser-process-hrtime@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + +browser-resolve@^1.11.2, browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + dependencies: + resolve "1.1.7" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.2.0" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.2.0.tgz#326734642f403dabc3003209853bb70ad428ef48" + dependencies: + buffer-xor "^1.0.3" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.3" + inherits "^2.0.1" + safe-buffer "^5.0.1" + +browserify-cipher@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.1.tgz#8d6474c1b870bfdabcd3bcfcc1934a10e94f15f0" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.2.tgz#3af4f1f59839403572f1c66204375f7a7f703e9c" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + safe-buffer "^5.1.2" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.4" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.4.tgz#aa4eb68e5d7b658baa6bf6a57e630cbd7a93d298" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.2.0.tgz#2869459d9aa3be245fe8fe2ca1f46e2e7f54d73f" + dependencies: + pako "~1.0.5" + +browserslist@^3.2.6: + version "3.2.8" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-3.2.8.tgz#b0005361d6471f0f5952797a76fc985f1f978fc6" + dependencies: + caniuse-lite "^1.0.30000844" + electron-to-chromium "^1.3.47" + +browserslist@^4.6.3: + version "4.7.2" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.7.2.tgz#1bb984531a476b5d389cedecb195b2cd69fb1348" + integrity sha512-uZavT/gZXJd2UTi9Ov7/Z340WOSQ3+m1iBVRUknf+okKxonL9P83S3ctiBDtuRmRu8PiCHjqyueqQ9HYlJhxiw== + dependencies: + caniuse-lite "^1.0.30001004" + electron-to-chromium "^1.3.295" + node-releases "^1.1.38" + +bs58@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-2.0.1.tgz#55908d58f1982aba2008fa1bed8f91998a29bf8d" + +bs58@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/bs58/-/bs58-4.0.1.tgz#be161e76c354f6f788ae4071f63f34e8c4f0a42a" + dependencies: + base-x "^3.0.2" + +bs58check@<3.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/bs58check/-/bs58check-2.1.1.tgz#8a5d0e587af97b784bf9cbf1b29f454d82bc0222" + dependencies: + bs58 "^4.0.0" + create-hash "^1.1.0" + +bser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/bser/-/bser-2.0.0.tgz#9ac78d3ed5d915804fd87acb158bc797147a1719" + dependencies: + node-int64 "^0.4.0" + +buffer-from@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.0.tgz#87fcaa3a298358e0ade6e442cfce840740d1ad04" + +buffer-xor@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.0.0, builtin-modules@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + +cacache@^10.0.4: + version "10.0.4" + resolved "https://registry.yarnpkg.com/cacache/-/cacache-10.0.4.tgz#6452367999eff9d4188aefd9a14e9d7c6a263460" + dependencies: + bluebird "^3.5.1" + chownr "^1.0.1" + glob "^7.1.2" + graceful-fs "^4.1.11" + lru-cache "^4.1.1" + mississippi "^2.0.0" + mkdirp "^0.5.1" + move-concurrently "^1.0.1" + promise-inflight "^1.0.1" + rimraf "^2.6.2" + ssri "^5.2.4" + unique-filename "^1.1.0" + y18n "^4.0.0" + +cache-base@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/cache-base/-/cache-base-1.0.1.tgz#0a7f46416831c8b662ee36fe4e7c59d76f666ab2" + dependencies: + 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@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + dependencies: + 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" + +call-me-maybe@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-me-maybe/-/call-me-maybe-1.0.1.tgz#26d208ea89e37b5cbde60250a15f031c16a4d66b" + +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + +camelcase@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-4.1.0.tgz#d545635be1e33c542649c69173e5de6acfae34dd" + +caniuse-db@^1.0.30000977: + version "1.0.30001005" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30001005.tgz#a61131ed16f519fbef25612e36dced8e69635455" + integrity sha512-MSRfm2N6FRDSpAJ00ipCuFe0CNink5JJOFzl4S7fLSBJdowhGq3uMxzkWGTjvvReo1PuWfK5YYJydJJ+9mJebw== + +caniuse-lite@^1.0.30000844: + version "1.0.30000865" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000865.tgz#70026616e8afe6e1442f8bb4e1092987d81a2f25" + +caniuse-lite@^1.0.30001004: + version "1.0.30001005" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001005.tgz#823054210be638c725521edcb869435dae46728d" + integrity sha512-g78miZm1Z5njjYR216a5812oPiLgV1ssndgGxITHWUopmjUrCswMisA0a2kSB7a0vZRox6JOKhM51+efmYN8Mg== + +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + dependencies: + rsvp "^3.3.3" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +chalk@^1.0.0, chalk@^1.1.1, chalk@^1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@^2.0.0, chalk@^2.0.1, chalk@^2.1.0, chalk@^2.3.0, chalk@^2.4.1: + version "2.4.1" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.1.tgz#18c49ab16a037b6eb0152cc83e3471338215b66e" + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chardet@^0.4.0: + version "0.4.2" + resolved "https://registry.yarnpkg.com/chardet/-/chardet-0.4.2.tgz#b5473b33dc97c424e5d98dc87d55d4d8a29c8bf2" + +chnl@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chnl/-/chnl-0.4.0.tgz#6c44ea5e8da72b8b7b34903dce0b3af640553e8c" + +chokidar@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +chokidar@^2.0.2: + version "2.0.4" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-2.0.4.tgz#356ff4e2b0e8e43e322d18a372460bbcf3accd26" + dependencies: + anymatch "^2.0.0" + async-each "^1.0.0" + braces "^2.3.0" + glob-parent "^3.1.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^4.0.0" + lodash.debounce "^4.0.8" + normalize-path "^2.1.1" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + upath "^1.0.5" + optionalDependencies: + fsevents "^1.2.2" + +chownr@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.0.1.tgz#e2a75042a9551908bebd25b8523d5f9769d79181" + +chrome-trace-event@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.0.tgz#45a91bd2c20c9411f0963b5aaeb9a1b95e09cc48" + dependencies: + tslib "^1.9.0" + +ci-info@^1.0.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-1.1.3.tgz#710193264bb05c77b8c90d02f5aaf22216a667b2" + +cipher-base@^1.0.0, cipher-base@^1.0.1, cipher-base@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.4.tgz#8760e4ecc272f4c363532f926d874aae2c1397de" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +class-utils@^0.3.5: + version "0.3.6" + resolved "https://registry.yarnpkg.com/class-utils/-/class-utils-0.3.6.tgz#f93369ae8b9a7ce02fd41faad0ca83033190c463" + dependencies: + arr-union "^3.1.0" + define-property "^0.2.5" + isobject "^3.0.0" + static-extend "^0.1.1" + +clean-webpack-plugin@^0.1.19: + version "0.1.19" + resolved "https://registry.yarnpkg.com/clean-webpack-plugin/-/clean-webpack-plugin-0.1.19.tgz#ceda8bb96b00fe168e9b080272960d20fdcadd6d" + dependencies: + rimraf "^2.6.1" + +cli-cursor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-1.0.2.tgz#64da3f7d56a54412e59794bd62dc35295e8f2987" + dependencies: + restore-cursor "^1.0.1" + +cli-cursor@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cli-cursor/-/cli-cursor-2.1.0.tgz#b35dac376479facc3e94747d41d0d0f5238ffcb5" + dependencies: + restore-cursor "^2.0.0" + +cli-spinners@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-0.1.2.tgz#bb764d88e185fb9e1e6a2a1f19772318f605e31c" + +cli-table@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cli-table/-/cli-table-0.3.1.tgz#f53b05266a8b1a0b934b3d0821e6e2dc5914ae23" + dependencies: + colors "1.0.3" + +cli-truncate@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/cli-truncate/-/cli-truncate-0.2.1.tgz#9f15cfbb0705005369216c626ac7d05ab90dd574" + dependencies: + slice-ansi "0.0.4" + string-width "^1.0.1" + +cli-width@^2.0.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/cli-width/-/cli-width-2.2.0.tgz#ff19ede8a9a5e579324147b0c11f0fbcbabed639" + +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + +clone-buffer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" + +clone-response@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" + dependencies: + mimic-response "^1.0.0" + +clone-stats@^0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-0.0.1.tgz#b88f94a82cf38b8791d58046ea4029ad88ca99d1" + +clone-stats@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/clone-stats/-/clone-stats-1.0.0.tgz#b3782dff8bb5474e18b9b6bf0fdfe782f8777680" + +clone@^1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/clone/-/clone-1.0.4.tgz#da309cc263df15994c688ca902179ca3c7cd7c7e" + +clone@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" + +cloneable-readable@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/cloneable-readable/-/cloneable-readable-1.1.2.tgz#d591dee4a8f8bc15da43ce97dceeba13d43e2a65" + dependencies: + inherits "^2.0.1" + process-nextick-args "^2.0.0" + readable-stream "^2.3.5" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +coinstring@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/coinstring/-/coinstring-2.3.0.tgz#cdb63363a961502404a25afb82c2e26d5ff627a4" + dependencies: + bs58 "^2.0.1" + create-hash "^1.1.1" + +collection-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/collection-visit/-/collection-visit-1.0.0.tgz#4bc0373c164bc3291b4d368c829cf1a80a59dca0" + dependencies: + map-visit "^1.0.0" + object-visit "^1.0.0" + +color-convert@^1.9.0: + version "1.9.2" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.2.tgz#49881b8fba67df12a96bdf3f56c0aab9e7913147" + dependencies: + color-name "1.1.1" + +color-name@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.1.tgz#4b1415304cf50028ea81643643bd82ea05803689" + +colors@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" + +colors@^1.1.2: + version "1.3.0" + resolved "https://registry.yarnpkg.com/colors/-/colors-1.3.0.tgz#5f20c9fef6945cb1134260aab33bfbdc8295e04e" + +combined-stream@1.0.6, combined-stream@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" + dependencies: + delayed-stream "~1.0.0" + +commander@^2.12.1: + version "2.16.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.16.0.tgz#f16390593996ceb4f3eeb020b31d78528f7f8a50" + +commander@~2.13.0: + version "2.13.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c" + +commander@~2.20.3: + version "2.20.3" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" + integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +compare-versions@^3.1.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/compare-versions/-/compare-versions-3.3.0.tgz#af93ea705a96943f622ab309578b9b90586f39c3" + +component-emitter@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/component-emitter/-/component-emitter-1.2.1.tgz#137918d6d78283f7df7a6b7c5a63e140e69425e6" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@^1.5.0: + version "1.6.2" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.6.2.tgz#904bdf194cd3122fc675c77fc4ac3d4ff0fd1a34" + dependencies: + buffer-from "^1.0.0" + inherits "^2.0.3" + readable-stream "^2.2.2" + typedarray "^0.0.6" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + +convert-source-map@^1.4.0, convert-source-map@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" + +copy-concurrently@^1.0.0: + version "1.0.5" + resolved "https://registry.yarnpkg.com/copy-concurrently/-/copy-concurrently-1.0.5.tgz#92297398cae34937fcafd6ec8139c18051f0b5e0" + dependencies: + aproba "^1.1.1" + fs-write-stream-atomic "^1.0.8" + iferr "^0.1.5" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.0" + +copy-descriptor@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d" + +core-js@^2.4.0, core-js@^2.4.1, core-js@^2.5.0: + version "2.5.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.5.7.tgz#f972608ff0cead68b841a16a932d0b183791814e" + +core-util-is@1.0.2, core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +cpx@^1.5.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/cpx/-/cpx-1.5.0.tgz#185be018511d87270dedccc293171e37655ab88f" + dependencies: + babel-runtime "^6.9.2" + chokidar "^1.6.0" + duplexer "^0.1.1" + glob "^7.0.5" + glob2base "^0.0.12" + minimatch "^3.0.2" + mkdirp "^0.5.1" + resolve "^1.1.7" + safe-buffer "^5.0.1" + shell-quote "^1.6.1" + subarg "^1.0.0" + +create-ecdh@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.1, create-hash@^1.1.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.2.0.tgz#889078af11a63756bcfb59bd221996be3a9ef196" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + md5.js "^1.3.4" + ripemd160 "^2.0.1" + sha.js "^2.4.0" + +create-hmac@^1.1.0, create-hmac@^1.1.2, create-hmac@^1.1.4: + version "1.1.7" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.7.tgz#69170c78b3ab957147b2b8b04572e47ead2243ff" + dependencies: + cipher-base "^1.0.3" + create-hash "^1.1.0" + inherits "^2.0.1" + ripemd160 "^2.0.0" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +cross-env@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/cross-env/-/cross-env-5.2.0.tgz#6ecd4c015d5773e614039ee529076669b9d126f2" + dependencies: + cross-spawn "^6.0.5" + is-windows "^1.0.0" + +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + +cross-spawn@^6.0.5: + version "6.0.5" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" + dependencies: + nice-try "^1.0.4" + path-key "^2.0.1" + semver "^5.5.0" + shebang-command "^1.2.0" + which "^1.2.9" + +crypto-browserify@^3.11.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.12.0.tgz#396cf9f3137f03e4b8e532c58f698254e00f80ec" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + randomfill "^1.0.3" + +crypto-js@^3.1.9-1: + version "3.1.9-1" + resolved "https://registry.yarnpkg.com/crypto-js/-/crypto-js-3.1.9-1.tgz#fda19e761fc077e01ffbfdc6e9fdfc59e8806cd8" + +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + +"cssstyle@>= 0.3.1 < 0.4.0": + version "0.3.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-0.3.1.tgz#6da9b4cff1bc5d716e6e5fe8e04fcb1b50a49adf" + dependencies: + cssom "0.3.x" + +cyclist@~0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-0.2.2.tgz#1b33792e11e914a2fd6d6ed6447464444e5fa640" + +dargs@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/dargs/-/dargs-5.1.0.tgz#ec7ea50c78564cd36c9d5ec18f66329fade27829" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +data-urls@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.0.tgz#24802de4e81c298ea8a9388bb0d8e461c774684f" + dependencies: + abab "^1.0.4" + whatwg-mimetype "^2.0.0" + whatwg-url "^6.4.0" + +date-fns@^1.27.2: + version "1.29.0" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.29.0.tgz#12e609cdcb935127311d04d33334e2960a2a54e6" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +dateformat@^3.0.3: + version "3.0.3" + resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" + +debug@=3.1.0, debug@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261" + integrity sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g== + dependencies: + ms "2.0.0" + +debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.8, debug@^2.6.9: + version "2.6.9" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" + dependencies: + ms "2.0.0" + +decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +decode-uri-component@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" + +decompress-response@^3.2.0, decompress-response@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" + dependencies: + mimic-response "^1.0.0" + +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-2.0.0.tgz#f5f8fbb18a7d6d50b21f641f649ebb522cfe24f7" + dependencies: + strip-bom "^3.0.0" + +define-properties@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" + dependencies: + foreach "^2.0.5" + object-keys "^1.0.8" + +define-property@^0.2.5: + version "0.2.5" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" + dependencies: + is-descriptor "^0.1.0" + +define-property@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-1.0.0.tgz#769ebaaf3f4a63aad3af9e8d304c9bbe79bfb0e6" + dependencies: + is-descriptor "^1.0.0" + +define-property@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/define-property/-/define-property-2.0.2.tgz#d459689e8d654ba77e02a817f8710d702cb16e9d" + dependencies: + is-descriptor "^1.0.2" + isobject "^3.0.1" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +detect-conflict@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/detect-conflict/-/detect-conflict-1.0.1.tgz#088657a66a961c05019db7c4230883b1c6b4176e" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +detect-libc@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" + +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + +diff@^3.2.0, diff@^3.3.1, diff@^3.5.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + +diffie-hellman@^5.0.0: + version "5.0.3" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dir-glob@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/dir-glob/-/dir-glob-2.0.0.tgz#0b205d2b6aef98238ca286598a8204d29d0a0034" + dependencies: + arrify "^1.0.1" + path-type "^3.0.0" + +doctrine@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/doctrine/-/doctrine-0.7.2.tgz#7cb860359ba3be90e040b26b729ce4bfa654c523" + dependencies: + esutils "^1.1.6" + isarray "0.0.1" + +domain-browser@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.2.0.tgz#3d31f50191a6749dd1375a7f522e823d42e54eda" + +domexception@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + +duplexer3@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2" + +duplexer@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/duplexer/-/duplexer-0.1.1.tgz#ace6ff808c1ce66b57d1ebf97977acb02334cfc1" + +duplexify@^3.4.2, duplexify@^3.6.0: + version "3.6.0" + resolved "https://registry.yarnpkg.com/duplexify/-/duplexify-3.6.0.tgz#592903f5d80b38d037220541264d69a198fb3410" + dependencies: + end-of-stream "^1.0.0" + inherits "^2.0.1" + readable-stream "^2.0.0" + stream-shift "^1.0.0" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ecdsa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/ecdsa/-/ecdsa-0.7.0.tgz#f65ce2300227b1628102902b2b93607c806de1d9" + dependencies: + bigi "^1.2.1" + bip66 "^1.1.0" + create-hmac "^1.1.4" + ecurve "^1.0.0" + typeforce "^1.6.1" + +ecurve@^1.0.0, ecurve@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/ecurve/-/ecurve-1.0.6.tgz#dfdabbb7149f8d8b78816be5a7d5b83fcf6de797" + dependencies: + bigi "^1.1.0" + safe-buffer "^5.0.1" + +editions@^1.3.3: + version "1.3.4" + resolved "https://registry.yarnpkg.com/editions/-/editions-1.3.4.tgz#3662cb592347c3168eb8e498a0ff73271d67f50b" + +ejs@^2.5.9: + version "2.6.1" + resolved "https://registry.yarnpkg.com/ejs/-/ejs-2.6.1.tgz#498ec0d495655abc6f23cd61868d926464071aa0" + +electron-to-chromium@^1.3.295: + version "1.3.296" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.296.tgz#a1d4322d742317945285d3ba88966561b67f3ac8" + integrity sha512-s5hv+TSJSVRsxH190De66YHb50pBGTweT9XGWYu/LMR20KX6TsjFzObo36CjVAzM+PUeeKSBRtm/mISlCzeojQ== + +electron-to-chromium@^1.3.47: + version "1.3.52" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.52.tgz#d2d9f1270ba4a3b967b831c40ef71fb4d9ab5ce0" + +elegant-spinner@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" + +elliptic@^6.0.0, elliptic@^6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +end-of-stream@^1.0.0, end-of-stream@^1.1.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.1.tgz#ed29634d19baba463b6ce6b80a37213eab71ec43" + dependencies: + once "^1.4.0" + +enhanced-resolve@^4.0.0, enhanced-resolve@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + tapable "^1.0.0" + +envinfo@^5.7.0: + version "5.10.0" + resolved "https://registry.yarnpkg.com/envinfo/-/envinfo-5.10.0.tgz#503a9774ae15b93ea68bdfae2ccd6306624ea6df" + +errno@^0.1.3, errno@~0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.7.tgz#4684d71779ad39af177e3f007996f7c67c852618" + dependencies: + prr "~1.0.1" + +error-ex@^1.2.0, error-ex@^1.3.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf" + dependencies: + is-arrayish "^0.2.1" + +error@^7.0.2: + version "7.0.2" + resolved "https://registry.yarnpkg.com/error/-/error-7.0.2.tgz#a5f75fff4d9926126ddac0ea5dc38e689153cb02" + dependencies: + string-template "~0.2.1" + xtend "~4.0.0" + +es-abstract@^1.5.1, es-abstract@^1.9.0: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + +escape-string-regexp@^1.0.2, escape-string-regexp@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escodegen@^1.9.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + +eslint-plugin-compat@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-compat/-/eslint-plugin-compat-3.3.0.tgz#ece063f53793e6859243ce6cb9634865f745b72e" + integrity sha512-QCgYy3pZ+zH10dkBJus1xER0359h1UhJjufhQRqp9Owm6BEoLZeSqxf2zINwL1OGao9Yc96xPYIW3nQj5HUryg== + dependencies: + "@babel/runtime" "^7.4.5" + ast-metadata-inferer "^0.1.1" + browserslist "^4.6.3" + caniuse-db "^1.0.30000977" + lodash.memoize "4.1.2" + mdn-browser-compat-data "^0.0.84" + semver "^6.1.2" + +eslint-scope@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.0.tgz#50bf3071e9338bcdc43331794a0cb533f0136172" + dependencies: + esrecurse "^4.1.0" + estraverse "^4.1.1" + +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + +esprima@^4.0.0, esprima@~4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.1.tgz#13b04cdb3e6c5d19df91ab6987a8695619b0aa71" + integrity sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A== + +esrecurse@^4.1.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/esrecurse/-/esrecurse-4.2.1.tgz#007a3b9fdbc2b3bb87e4879ea19c92fdbd3942cf" + dependencies: + estraverse "^4.1.0" + +estraverse@^4.1.0, estraverse@^4.1.1, estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +esutils@^1.1.6: + version "1.1.6" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.1.6.tgz#c01ccaa9ae4b897c6d0c3e210ae52f3c7a844375" + +esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +events@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz#7fcbdb198dc71959432efe13842684e0525acb02" + dependencies: + md5.js "^1.3.4" + safe-buffer "^5.1.1" + +exec-sh@^0.2.0: + version "0.2.2" + resolved "https://registry.yarnpkg.com/exec-sh/-/exec-sh-0.2.2.tgz#2a5e7ffcbd7d0ba2755bdecb16e5a427dfbdec36" + dependencies: + merge "^1.2.0" + +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + +exit-hook@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/exit-hook/-/exit-hook-1.1.1.tgz#f05ca233b48c05d54fff07765df8507e95c02ff8" + +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-brackets@^2.1.4: + version "2.1.4" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-2.1.4.tgz#b77735e315ce30f6b6eff0f83b04151a22449622" + dependencies: + debug "^2.3.3" + define-property "^0.2.5" + extend-shallow "^2.0.1" + posix-character-classes "^0.1.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +expand-tilde@^2.0.0, expand-tilde@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/expand-tilde/-/expand-tilde-2.0.2.tgz#97e801aa052df02454de46b02bf621642cdc8502" + dependencies: + homedir-polyfill "^1.0.1" + +expect@^22.4.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/expect/-/expect-22.4.3.tgz#d5a29d0a0e1fb2153557caef2674d4547e914674" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^22.4.3" + jest-get-type "^22.4.3" + jest-matcher-utils "^22.4.3" + jest-message-util "^22.4.3" + jest-regex-util "^22.4.3" + +expect@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-23.4.0.tgz#6da4ecc99c1471253e7288338983ad1ebadb60c3" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^23.2.0" + jest-get-type "^22.1.0" + jest-matcher-utils "^23.2.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + +extend-shallow@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" + dependencies: + is-extendable "^0.1.0" + +extend-shallow@^3.0.0, extend-shallow@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-3.0.2.tgz#26a71aaf073b39fb2127172746131c2704028db8" + dependencies: + assign-symbols "^1.0.0" + is-extendable "^1.0.1" + +extend@3.0.2, extend@~3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + integrity sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g== + +external-editor@^2.1.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" + dependencies: + chardet "^0.4.0" + iconv-lite "^0.4.17" + tmp "^0.0.33" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extglob@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-2.0.4.tgz#ad00fe4dc612a9232e8718711dc5cb5ab0285543" + dependencies: + array-unique "^0.3.2" + define-property "^1.0.0" + expand-brackets "^2.1.4" + extend-shallow "^2.0.1" + fragment-cache "^0.2.1" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +extsprintf@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05" + +extsprintf@^1.2.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f" + +fast-deep-equal@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz#c053477817c86b51daa853c81e059b733d023614" + +fast-deep-equal@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz#7b05218ddf9667bf7f370bf7fdb2cb15fdd0aa49" + +fast-glob@^2.0.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-2.2.2.tgz#71723338ac9b4e0e2fff1d6748a2a13d5ed352bf" + dependencies: + "@mrmlnc/readdir-enhanced" "^2.2.1" + "@nodelib/fs.stat" "^1.0.1" + glob-parent "^3.1.0" + is-glob "^4.0.0" + merge2 "^1.2.1" + micromatch "^3.1.10" + +fast-json-stable-stringify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +fb-watchman@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/fb-watchman/-/fb-watchman-2.0.0.tgz#54e9abf7dfa2f26cd9b1636c588c1afc05de5d58" + dependencies: + bser "^2.0.0" + +figures@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-1.7.0.tgz#cbe1e3affcf1cd44b80cadfed28dc793a9701d2e" + dependencies: + escape-string-regexp "^1.0.5" + object-assign "^4.1.0" + +figures@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/figures/-/figures-2.0.0.tgz#3ab1a2d2a62c8bfb431a0c94cb797a2fce27c962" + dependencies: + escape-string-regexp "^1.0.5" + +filename-regex@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" + +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + +fill-range@^2.1.0: + version "2.2.4" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.4.tgz#eb1e773abb056dcd8df2bfdf6af59b8b3a936565" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^3.0.0" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +fill-range@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-4.0.0.tgz#d544811d428f98eb06a63dc402d2403c328c38f7" + dependencies: + extend-shallow "^2.0.1" + is-number "^3.0.0" + repeat-string "^1.6.1" + to-regex-range "^2.1.0" + +find-cache-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-1.0.0.tgz#9288e3e9e3cc3748717d39eade17cf71fc30ee6f" + dependencies: + commondir "^1.0.1" + make-dir "^1.0.0" + pkg-dir "^2.0.0" + +find-index@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-index/-/find-index-0.1.1.tgz#675d358b2ca3892d795a1ab47232f8b6e2e0dde4" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +find-up@^2.0.0, find-up@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" + dependencies: + locate-path "^2.0.0" + +first-chunk-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/first-chunk-stream/-/first-chunk-stream-2.0.0.tgz#1bdecdb8e083c0664b91945581577a43a9f31d70" + dependencies: + readable-stream "^2.0.2" + +flat-options@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/flat-options/-/flat-options-0.1.3.tgz#56f644aaa095e5f984ecdd329f119e8a196c8aa3" + +flow-parser@^0.*: + version "0.76.0" + resolved "https://registry.yarnpkg.com/flow-parser/-/flow-parser-0.76.0.tgz#f7d4c4d26df74805c3a0babd5d8ea4c2cd57190b" + +flush-write-stream@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/flush-write-stream/-/flush-write-stream-1.0.3.tgz#c5d586ef38af6097650b49bc41b55fabb19f35bd" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.4" + +follow-redirects@1.5.10: + version "1.5.10" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.5.10.tgz#7b7a9f9aea2fdff36786a94ff643ed07f4ff5e2a" + integrity sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ== + dependencies: + debug "=3.1.0" + +for-in@^1.0.1, for-in@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.3.1: + version "2.3.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" + dependencies: + asynckit "^0.4.0" + combined-stream "1.0.6" + mime-types "^2.1.12" + +fragment-cache@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/fragment-cache/-/fragment-cache-0.2.1.tgz#4290fad27f13e89be7f33799c6bc5a0abfff0d19" + dependencies: + map-cache "^0.2.2" + +from2@^2.1.0, from2@^2.1.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" + dependencies: + inherits "^2.0.1" + readable-stream "^2.0.0" + +fs-extra@6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-6.0.0.tgz#0f0afb290bb3deb87978da816fcd3c7797f3a817" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-extra@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/fs-extra/-/fs-extra-5.0.0.tgz#414d0110cdd06705734d055652c5411260c31abd" + dependencies: + graceful-fs "^4.1.2" + jsonfile "^4.0.0" + universalify "^0.1.0" + +fs-minipass@^1.2.5: + version "1.2.5" + resolved "https://registry.yarnpkg.com/fs-minipass/-/fs-minipass-1.2.5.tgz#06c277218454ec288df77ada54a03b8702aacb9d" + dependencies: + minipass "^2.2.1" + +fs-write-stream-atomic@^1.0.8: + version "1.0.10" + resolved "https://registry.yarnpkg.com/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz#b47df53493ef911df75731e70a9ded0189db40c9" + dependencies: + graceful-fs "^4.1.2" + iferr "^0.1.5" + imurmurhash "^0.1.4" + readable-stream "1 || 2" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0, fsevents@^1.2.2, fsevents@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +function-bind@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" + +gauge@~2.7.3: + version "2.7.4" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.4.tgz#2c03405c7538c39d7eb37b317022e325fb018bf7" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +get-caller-file@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.3.tgz#f978fa4c90d1dfe7ff2d6beda2a515e713bdcf4a" + +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + +get-value@^2.0.3, get-value@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" + +getpass@^0.1.1: + version "0.1.7" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa" + dependencies: + assert-plus "^1.0.0" + +gh-got@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/gh-got/-/gh-got-6.0.0.tgz#d74353004c6ec466647520a10bd46f7299d268d0" + dependencies: + got "^7.0.0" + is-plain-obj "^1.1.0" + +github-username@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/github-username/-/github-username-4.1.0.tgz#cbe280041883206da4212ae9e4b5f169c30bf417" + dependencies: + gh-got "^6.0.0" + +glob-all@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-all/-/glob-all-3.1.0.tgz#8913ddfb5ee1ac7812656241b03d5217c64b02ab" + dependencies: + glob "^7.0.5" + yargs "~1.2.6" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob-parent@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" + dependencies: + is-glob "^3.1.0" + path-dirname "^1.0.0" + +glob-to-regexp@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" + +glob2base@^0.0.12: + version "0.0.12" + resolved "https://registry.yarnpkg.com/glob2base/-/glob2base-0.0.12.tgz#9d419b3e28f12e83a362164a277055922c9c0d56" + dependencies: + find-index "^0.1.1" + +glob@^7.0.0, glob@^7.0.3, glob@^7.0.5, glob@^7.1.1, glob@^7.1.2: + version "7.1.2" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.2.tgz#c19c9df9a028702d678612384a6552404c636d15" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.4" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global-modules@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" + dependencies: + global-prefix "^1.0.1" + is-windows "^1.0.1" + resolve-dir "^1.0.0" + +global-prefix@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" + dependencies: + expand-tilde "^2.0.2" + homedir-polyfill "^1.0.1" + ini "^1.3.4" + is-windows "^1.0.1" + which "^1.2.14" + +globals@^9.18.0: + version "9.18.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.18.0.tgz#aa3896b3e69b487f17e31ed2143d69a8e30c2d8a" + +globby@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-7.1.1.tgz#fb2ccff9401f8600945dfada97440cca972b8680" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +globby@^8.0.1: + version "8.0.1" + resolved "https://registry.yarnpkg.com/globby/-/globby-8.0.1.tgz#b5ad48b8aa80b35b814fc1281ecc851f1d2b5b50" + dependencies: + array-union "^1.0.1" + dir-glob "^2.0.0" + fast-glob "^2.0.2" + glob "^7.1.2" + ignore "^3.3.5" + pify "^3.0.0" + slash "^1.0.0" + +got@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + 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-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + +graceful-fs@^4.1.11, graceful-fs@^4.1.2, graceful-fs@^4.1.6: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +grouped-queue@^0.3.3: + version "0.3.3" + resolved "https://registry.yarnpkg.com/grouped-queue/-/grouped-queue-0.3.3.tgz#c167d2a5319c5a0e0964ef6a25b7c2df8996c85c" + dependencies: + lodash "^4.17.2" + +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + +handlebars@^4.0.3, handlebars@^4.0.6: + version "4.5.0" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.5.0.tgz#d5d902dfe0f266ef79f3921b89233a5f611cdea7" + integrity sha512-yss1ZbupTpRfe86dpM1abxnnSfxa6eIRn3laqBPIgRYy87qgYtX6xinSOeybjYo/4AVzdTTWK5Kr06A6AllxJg== + dependencies: + eslint-plugin-compat "^3.3.0" + neo-async "^2.6.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" + +har-validator@~5.0.3: + version "5.0.3" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd" + dependencies: + ajv "^5.1.0" + har-schema "^2.0.0" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-flag@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd" + +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + dependencies: + has-symbol-support-x "^1.4.1" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has-value@^0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-0.3.1.tgz#7b1f58bada62ca827ec0a2078025654845995e1f" + dependencies: + get-value "^2.0.3" + has-values "^0.1.4" + isobject "^2.0.0" + +has-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-value/-/has-value-1.0.0.tgz#18b281da585b1c5c51def24c930ed29a0be6b177" + dependencies: + get-value "^2.0.6" + has-values "^1.0.0" + isobject "^3.0.0" + +has-values@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-0.1.4.tgz#6d61de95d91dfca9b9a02089ad384bff8f62b771" + +has-values@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-values/-/has-values-1.0.0.tgz#95b0b63fec2146619a6fe57fe75628d5a39efe4f" + dependencies: + is-number "^3.0.0" + kind-of "^4.0.0" + +has@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796" + dependencies: + function-bind "^1.1.1" + +hash-base@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/hash-base/-/hash-base-3.0.4.tgz#5fc8686847ecd73499403319a6b0a3f3f6ae4918" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.1.5" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.5.tgz#e38ab4b85dfb1e0c40fe9265c0e9b54854c23812" + dependencies: + inherits "^2.0.3" + minimalistic-assert "^1.0.1" + +highlight.js@^9.0.0: + version "9.12.0" + resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.12.0.tgz#e6d9dbe57cbefe60751f02af336195870c90c01e" + +hmac-drbg@^1.0.0, hmac-drbg@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.1.tgz#d2745701025a6c775a6c545793ed502fc0c649a1" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +homedir-polyfill@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc" + dependencies: + parse-passwd "^1.0.0" + +hosted-git-info@^2.1.4: + version "2.7.1" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.7.1.tgz#97f236977bd6e125408930ff6de3eec6281ec047" + +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" + +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1" + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73" + +iconv-lite@0.4.19: + version "0.4.19" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" + +iconv-lite@^0.4.17, iconv-lite@^0.4.4: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + +ieee754@^1.1.11, ieee754@^1.1.4: + version "1.1.12" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.12.tgz#50bf24e5b9c8bb98af4964c941cdb0918da7b60b" + +iferr@^0.1.5: + version "0.1.5" + resolved "https://registry.yarnpkg.com/iferr/-/iferr-0.1.5.tgz#c60eed69e6d8fdb6b3104a1fcbca1c192dc5b501" + +ignore-walk@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/ignore-walk/-/ignore-walk-3.0.1.tgz#a83e62e7d272ac0e3b551aaa82831a19b69f82f8" + dependencies: + minimatch "^3.0.4" + +ignore@^3.3.5: + version "3.3.10" + resolved "https://registry.yarnpkg.com/ignore/-/ignore-3.3.10.tgz#0a97fb876986e8081c631160f8f9f389157f0043" + +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + +imurmurhash@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" + +indent-string@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-2.1.0.tgz#8e2d48348742121b4a8218b7a137e9a52049dc80" + dependencies: + repeating "^2.0.0" + +indent-string@^3.0.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/indent-string/-/indent-string-3.2.0.tgz#4a5fd6d27cc332f37e5419a504dbb837105c9289" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@^2.0.3, inherits@~2.0.1, inherits@~2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@^1.3.4, ini@~1.3.0: + version "1.3.5" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" + +inquirer@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-5.2.0.tgz#db350c2b73daca77ff1243962e9f22f099685726" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.1.0" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rxjs "^5.5.2" + string-width "^2.1.0" + strip-ansi "^4.0.0" + through "^2.3.6" + +interpret@^1.0.0, interpret@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" + +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + +invariant@^2.2.2: + version "2.2.4" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +is-accessor-descriptor@^0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz#a9e12cb3ae8d876727eeef3843f8a0897b5c98d6" + dependencies: + kind-of "^3.0.2" + +is-accessor-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz#169c2f6d3df1f992618072365c9b0ea1f6878656" + dependencies: + kind-of "^6.0.0" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be" + +is-buffer@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.3.tgz#4ecf3fcf749cbd1e472689e109ac66261a25e725" + integrity sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw== + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + +is-ci@^1.0.10: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" + dependencies: + ci-info "^1.0.0" + +is-data-descriptor@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz#0b5ee648388e2c860282e793f1856fec3f301b56" + dependencies: + kind-of "^3.0.2" + +is-data-descriptor@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz#d84876321d0e7add03990406abbbbd36ba9268c7" + dependencies: + kind-of "^6.0.0" + +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + +is-descriptor@^0.1.0: + version "0.1.6" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-0.1.6.tgz#366d8240dde487ca51823b1ab9f07a10a78251ca" + dependencies: + is-accessor-descriptor "^0.1.6" + is-data-descriptor "^0.1.4" + kind-of "^5.0.0" + +is-descriptor@^1.0.0, is-descriptor@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-descriptor/-/is-descriptor-1.0.2.tgz#3b159746a66604b04f8c81524ba365c5f14d86ec" + dependencies: + is-accessor-descriptor "^1.0.0" + is-data-descriptor "^1.0.0" + kind-of "^6.0.2" + +is-dotfile@^1.0.0: + version "1.0.3" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.3.tgz#a6a2f32ffd2dfb04f5ca25ecd0f6b83cf798a1e1" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.0, is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extendable@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-1.0.1.tgz#a7470f9e426733d81bd81e1155264e3a3507cab4" + dependencies: + is-plain-object "^2.0.4" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.0, is-extglob@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" + +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-glob@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.0.tgz#9521c76845cc2610a85203ddf080a958c2ffabc0" + dependencies: + is-extglob "^2.1.1" + +is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-number@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-3.0.0.tgz#24fd6201a4782cf50561c810276afc7d12d71195" + dependencies: + kind-of "^3.0.2" + +is-number@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-4.0.0.tgz#0026e37f5454d73e356dfe6564699867c6a7f0ff" + +is-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-object/-/is-object-1.0.1.tgz#8952688c5ec2ffd6b03ecc85e769e02903083470" + +is-observable@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-observable/-/is-observable-1.1.0.tgz#b3e986c8f44de950867cab5403f5a3465005975e" + dependencies: + symbol-observable "^1.1.0" + +is-plain-obj@^1.0.0, is-plain-obj@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-plain-obj/-/is-plain-obj-1.1.0.tgz#71a50c8429dfca773c92a390a4a03b39fcd51d3e" + +is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: + version "2.0.4" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" + dependencies: + isobject "^3.0.1" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-promise@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-promise/-/is-promise-2.1.0.tgz#79a2a9ece7f096e80f36d2b2f3bc16c1ff4bf3fa" + +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.1.0.tgz#11a060568b67339444033d0125a61a20d564fb34" + +is-scoped@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-scoped/-/is-scoped-1.0.0.tgz#449ca98299e713038256289ecb2b540dc437cb30" + dependencies: + scoped-regex "^1.0.0" + +is-stream@^1.0.0, is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +is-windows@^1.0.0, is-windows@^1.0.1, is-windows@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-windows/-/is-windows-1.0.2.tgz#d1850eb9791ecd18e6182ce12a30f396634bb19d" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isbinaryfile@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/isbinaryfile/-/isbinaryfile-3.0.2.tgz#4a3e974ec0cba9004d3fc6cde7209ea69368a621" + +isexe@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isobject@^3.0.0, isobject@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-3.0.1.tgz#4e431e92b11a9731636aa1f9c8d1ccbcfdab78df" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +istanbul-api@^1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.1.tgz#4c3b05d18c0016d1022e079b98dc82c40f488954" + dependencies: + async "^2.1.4" + compare-versions "^3.1.0" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-hook "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-report "^1.1.4" + istanbul-lib-source-maps "^1.2.4" + istanbul-reports "^1.3.0" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz#f7d8f2e42b97e37fe796114cb0f9d68b5e3a4341" + +istanbul-lib-hook@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.1.tgz#f614ec45287b2a8fc4f07f5660af787575601805" + dependencies: + append-transform "^1.0.0" + +istanbul-lib-instrument@^1.10.1: + version "1.10.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz#724b4b6caceba8692d3f1f9d0727e279c401af7b" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.0" + semver "^5.3.0" + +istanbul-lib-report@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz#e886cdf505c4ebbd8e099e4396a90d0a28e2acb5" + dependencies: + istanbul-lib-coverage "^1.2.0" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.4: + version "1.2.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.5.tgz#ffe6be4e7ab86d3603e4290d54990b14506fc9b1" + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.0" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.3.0.tgz#2f322e81e1d9520767597dca3c20a0cce89a3554" + dependencies: + handlebars "^4.0.3" + +istextorbinary@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-2.2.1.tgz#a5231a08ef6dd22b268d0895084cf8d58b5bec53" + dependencies: + binaryextensions "2" + editions "^1.3.3" + textextensions "2" + +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + +jest-changed-files@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.0.tgz#f1b304f98c235af5d9a31ec524262c5e4de3c6ff" + dependencies: + throat "^4.0.0" + +jest-cli@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.4.1.tgz#c1ffd33254caee376990aa2abe2963e0de4ca76b" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.3.1" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-source-maps "^1.2.4" + jest-changed-files "^23.4.0" + jest-config "^23.4.1" + jest-environment-jsdom "^23.4.0" + jest-get-type "^22.1.0" + jest-haste-map "^23.4.1" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve-dependencies "^23.4.1" + jest-runner "^23.4.1" + jest-runtime "^23.4.1" + jest-snapshot "^23.4.1" + jest-util "^23.4.0" + jest-validate "^23.4.0" + jest-watcher "^23.4.0" + jest-worker "^23.2.0" + micromatch "^2.3.11" + node-notifier "^5.2.1" + prompts "^0.1.9" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^11.0.0" + +jest-config@^22.4.3, jest-config@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-22.4.4.tgz#72a521188720597169cd8b4ff86934ef5752d86a" + dependencies: + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^22.4.1" + jest-environment-node "^22.4.1" + jest-get-type "^22.1.0" + jest-jasmine2 "^22.4.4" + jest-regex-util "^22.1.0" + jest-resolve "^22.4.2" + jest-util "^22.4.1" + jest-validate "^22.4.4" + pretty-format "^22.4.0" + +jest-config@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.4.1.tgz#3172fa21f0507d7f8a088ed1dbe4157057f201e9" + dependencies: + babel-core "^6.0.0" + babel-jest "^23.4.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^23.4.0" + jest-environment-node "^23.4.0" + jest-get-type "^22.1.0" + jest-jasmine2 "^23.4.1" + jest-regex-util "^23.3.0" + jest-resolve "^23.4.1" + jest-util "^23.4.0" + jest-validate "^23.4.0" + pretty-format "^23.2.0" + +jest-diff@^22.4.0, jest-diff@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-22.4.3.tgz#e18cc3feff0aeef159d02310f2686d4065378030" + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + +jest-diff@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.2.0.tgz#9f2cf4b51e12c791550200abc16b47130af1062a" + dependencies: + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.1.0" + pretty-format "^23.2.0" + +jest-docblock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" + dependencies: + detect-newline "^2.1.0" + +jest-each@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.4.0.tgz#2fa9edd89daa1a4edc9ff9bf6062a36b71345143" + dependencies: + chalk "^2.0.1" + pretty-format "^23.2.0" + +jest-environment-jsdom@^22.4.1: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-22.4.3.tgz#d67daa4155e33516aecdd35afd82d4abf0fa8a1e" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + jsdom "^11.5.1" + +jest-environment-jsdom@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + jsdom "^11.5.1" + +jest-environment-node@^22.4.1: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-22.4.3.tgz#54c4eaa374c83dd52a9da8759be14ebe1d0b9129" + dependencies: + jest-mock "^22.4.3" + jest-util "^22.4.3" + +jest-environment-node@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + +jest-get-type@^22.1.0, jest-get-type@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + +jest-haste-map@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.4.1.tgz#43a174ba7ac079ae1dd74eaf5a5fe78989474dd2" + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + jest-docblock "^23.2.0" + jest-serializer "^23.0.1" + jest-worker "^23.2.0" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-22.4.4.tgz#c55f92c961a141f693f869f5f081a79a10d24e23" + dependencies: + chalk "^2.0.1" + co "^4.6.0" + expect "^22.4.0" + graceful-fs "^4.1.11" + is-generator-fn "^1.0.0" + jest-diff "^22.4.0" + jest-matcher-utils "^22.4.0" + jest-message-util "^22.4.0" + jest-snapshot "^22.4.0" + jest-util "^22.4.1" + source-map-support "^0.5.0" + +jest-jasmine2@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.4.1.tgz#fa192262430d418e827636e4a98423e5e7ff0fce" + dependencies: + chalk "^2.0.1" + co "^4.6.0" + expect "^23.4.0" + is-generator-fn "^1.0.0" + jest-diff "^23.2.0" + jest-each "^23.4.0" + jest-matcher-utils "^23.2.0" + jest-message-util "^23.4.0" + jest-snapshot "^23.4.1" + jest-util "^23.4.0" + pretty-format "^23.2.0" + +jest-leak-detector@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.2.0.tgz#c289d961dc638f14357d4ef96e0431ecc1aa377d" + dependencies: + pretty-format "^23.2.0" + +jest-matcher-utils@^22.4.0, jest-matcher-utils@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-22.4.3.tgz#4632fe428ebc73ebc194d3c7b65d37b161f710ff" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.4.3" + pretty-format "^22.4.3" + +jest-matcher-utils@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.2.0.tgz#4d4981f23213e939e3cedf23dc34c747b5ae1913" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + pretty-format "^23.2.0" + +jest-message-util@^22.4.0, jest-message-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-22.4.3.tgz#cf3d38aafe4befddbfc455e57d65d5239e399eb7" + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-message-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-22.4.3.tgz#f63ba2f07a1511772cdc7979733397df770aabc7" + +jest-mock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" + +jest-regex-util@^22.1.0, jest-regex-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-22.4.3.tgz#a826eb191cdf22502198c5401a1fc04de9cef5af" + +jest-regex-util@^23.3.0: + version "23.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" + +jest-resolve-dependencies@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.4.1.tgz#a1d85247e2963f8b3859f6b0ec61b741b359378e" + dependencies: + jest-regex-util "^23.3.0" + jest-snapshot "^23.4.1" + +jest-resolve@^22.4.2: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-22.4.3.tgz#0ce9d438c8438229aa9b916968ec6b05c1abb4ea" + dependencies: + browser-resolve "^1.11.2" + chalk "^2.0.1" + +jest-resolve@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.4.1.tgz#7f3c17104732a2c0c940a01256025ed745814982" + dependencies: + browser-resolve "^1.11.3" + chalk "^2.0.1" + realpath-native "^1.0.0" + +jest-runner@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.4.1.tgz#d41fd1459b95d35d6df685f1468c09e617c8c260" + dependencies: + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^23.4.1" + jest-docblock "^23.2.0" + jest-haste-map "^23.4.1" + jest-jasmine2 "^23.4.1" + jest-leak-detector "^23.2.0" + jest-message-util "^23.4.0" + jest-runtime "^23.4.1" + jest-util "^23.4.0" + jest-worker "^23.2.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.4.1.tgz#c1822eba5eb19294debe6b25b2760d0a8c532fd1" + dependencies: + babel-core "^6.0.0" + babel-plugin-istanbul "^4.1.6" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.11" + jest-config "^23.4.1" + jest-haste-map "^23.4.1" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.4.1" + jest-snapshot "^23.4.1" + jest-util "^23.4.0" + jest-validate "^23.4.0" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^11.0.0" + +jest-serializer@^23.0.1: + version "23.0.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" + +jest-snapshot@^22.4.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-22.4.3.tgz#b5c9b42846ffb9faccb76b841315ba67887362d2" + dependencies: + chalk "^2.0.1" + jest-diff "^22.4.3" + jest-matcher-utils "^22.4.3" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^22.4.3" + +jest-snapshot@^23.4.1: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.4.1.tgz#090de9acae927f6a3af3005bda40d912b83e9c96" + dependencies: + babel-traverse "^6.0.0" + babel-types "^6.0.0" + chalk "^2.0.1" + jest-diff "^23.2.0" + jest-matcher-utils "^23.2.0" + jest-message-util "^23.4.0" + jest-resolve "^23.4.1" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^23.2.0" + semver "^5.5.0" + +jest-util@^22.4.1, jest-util@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-22.4.3.tgz#c70fec8eec487c37b10b0809dc064a7ecf6aafac" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^22.4.3" + mkdirp "^0.5.1" + source-map "^0.6.0" + +jest-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^23.4.0" + mkdirp "^0.5.1" + slash "^1.0.0" + source-map "^0.6.0" + +jest-validate@^22.4.4: + version "22.4.4" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-22.4.4.tgz#1dd0b616ef46c995de61810d85f57119dbbcec4d" + dependencies: + chalk "^2.0.1" + jest-config "^22.4.4" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^22.4.0" + +jest-validate@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.4.0.tgz#d96eede01ef03ac909c009e9c8e455197d48c201" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.2.0" + +jest-watcher@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + string-length "^2.0.0" + +jest-worker@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" + dependencies: + merge-stream "^1.0.1" + +jest@^23.0.0: + version "23.4.1" + resolved "https://registry.yarnpkg.com/jest/-/jest-23.4.1.tgz#39550c72f3237f63ae1b434d8d122cdf6fa007b6" + dependencies: + import-local "^1.0.0" + jest-cli "^23.4.1" + +js-sha3@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/js-sha3/-/js-sha3-0.7.0.tgz#0a5c57b36f79882573b2d84051f8bb85dd1bd63a" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +"js-tokens@^3.0.0 || ^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + +js-yaml@^3.7.0: + version "3.13.1" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.13.1.tgz#aff151b30bfdfa8e49e05da22e7415e9dfa37847" + integrity sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw== + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jscodeshift@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.4.1.tgz#da91a1c2eccfa03a3387a21d39948e251ced444a" + dependencies: + async "^1.5.0" + babel-plugin-transform-flow-strip-types "^6.8.0" + babel-preset-es2015 "^6.9.0" + babel-preset-stage-1 "^6.5.0" + babel-register "^6.9.0" + babylon "^6.17.3" + colors "^1.1.2" + flow-parser "^0.*" + lodash "^4.13.1" + micromatch "^2.3.7" + node-dir "0.1.8" + nomnom "^1.8.1" + recast "^0.12.5" + temp "^0.8.1" + write-file-atomic "^1.2.0" + +jscodeshift@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/jscodeshift/-/jscodeshift-0.5.1.tgz#4af6a721648be8638ae1464a190342da52960c33" + dependencies: + babel-plugin-transform-flow-strip-types "^6.8.0" + babel-preset-es2015 "^6.9.0" + babel-preset-stage-1 "^6.5.0" + babel-register "^6.9.0" + babylon "^7.0.0-beta.47" + colors "^1.1.2" + flow-parser "^0.*" + lodash "^4.13.1" + micromatch "^2.3.7" + neo-async "^2.5.0" + node-dir "0.1.8" + nomnom "^1.8.1" + recast "^0.15.0" + temp "^0.8.1" + write-file-atomic "^1.2.0" + +jsdom@^11.5.1: + version "11.11.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.11.0.tgz#df486efad41aee96c59ad7a190e2449c7eb1110e" + dependencies: + abab "^1.0.4" + acorn "^5.3.0" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle ">= 0.3.1 < 0.4.0" + data-urls "^1.0.0" + domexception "^1.0.0" + escodegen "^1.9.0" + html-encoding-sniffer "^1.0.2" + left-pad "^1.2.0" + nwsapi "^2.0.0" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.83.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.3" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^4.0.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-buffer@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.0.tgz#5b1f397afc75d677bde8bcfc0e47e1f9a3d9a898" + +json-parse-better-errors@^1.0.1, json-parse-better-errors@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz#bb867cfb3450e69107c131d1c514bab3dc8bcaa9" + +json-schema-traverse@^0.3.0: + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" + +json-schema-traverse@^0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz#69f6a87d9513ab8bb8fe63bdb0979c448e684660" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json5@^0.5.0, json5@^0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonfile@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/jsonfile/-/jsonfile-4.0.0.tgz#8771aae0799b64076b76640fca058f9c10e33ecb" + optionalDependencies: + graceful-fs "^4.1.6" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsprim@^1.2.2: + version "1.4.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2" + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.2.3" + verror "1.10.0" + +keyv@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" + dependencies: + json-buffer "3.0.0" + +kind-of@^3.0.2, kind-of@^3.0.3, kind-of@^3.2.0: + version "3.2.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.2.2.tgz#31ea21a734bab9bbb0f32466d893aea51e4a3c64" + dependencies: + is-buffer "^1.1.5" + +kind-of@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-4.0.0.tgz#20813df3d712928b207378691a45066fae72dd57" + dependencies: + is-buffer "^1.1.5" + +kind-of@^5.0.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-5.1.0.tgz#729c91e2d857b7a419a1f9aa65685c4c33f5845d" + +kind-of@^6.0.0, kind-of@^6.0.2: + version "6.0.2" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" + +kleur@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-1.0.2.tgz#637f126d3cda40a423b1297da88cf753bd04ebdd" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +left-pad@^1.2.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + +leven@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +listr-silent-renderer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/listr-silent-renderer/-/listr-silent-renderer-1.1.1.tgz#924b5a3757153770bf1a8e3fbf74b8bbf3f9242e" + +listr-update-renderer@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/listr-update-renderer/-/listr-update-renderer-0.4.0.tgz#344d980da2ca2e8b145ba305908f32ae3f4cc8a7" + dependencies: + chalk "^1.1.3" + cli-truncate "^0.2.1" + elegant-spinner "^1.0.1" + figures "^1.7.0" + indent-string "^3.0.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + strip-ansi "^3.0.1" + +listr-verbose-renderer@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz#8206f4cf6d52ddc5827e5fd14989e0e965933a35" + dependencies: + chalk "^1.1.3" + cli-cursor "^1.0.2" + date-fns "^1.27.2" + figures "^1.7.0" + +listr@^0.14.1: + version "0.14.1" + resolved "https://registry.yarnpkg.com/listr/-/listr-0.14.1.tgz#8a7afa4a7135cee4c921d128e0b7dfc6e522d43d" + dependencies: + "@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.0" + log-symbols "^1.0.2" + log-update "^1.0.2" + ora "^0.2.3" + p-map "^1.1.1" + rxjs "^6.1.0" + strip-ansi "^3.0.1" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +load-json-file@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-4.0.0.tgz#2f5f45ab91e33216234fd53adab668eb4ec0993b" + dependencies: + graceful-fs "^4.1.2" + parse-json "^4.0.0" + pify "^3.0.0" + strip-bom "^3.0.0" + +loader-runner@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + +loader-utils@^1.0.2, loader-utils@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.1.0.tgz#c98aef488bcceda2ffb5e2de646d6a754429f5cd" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +locate-path@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/locate-path/-/locate-path-2.0.0.tgz#2b568b265eec944c6d9c0de9c3dbbbca0354cd8e" + dependencies: + p-locate "^2.0.0" + path-exists "^3.0.0" + +lodash.clone@^4.5.0: + version "4.5.0" + resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" + +lodash.debounce@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" + +lodash.memoize@4.1.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" + integrity sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4= + +lodash.merge@^4.6.0: + version "4.6.2" + resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a" + integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ== + +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + +lodash@^4.13.1, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.3.0: + version "4.17.15" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548" + integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A== + +log-symbols@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-1.0.2.tgz#376ff7b58ea3086a0f09facc74617eca501e1a18" + dependencies: + chalk "^1.0.0" + +log-symbols@^2.1.0, log-symbols@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/log-symbols/-/log-symbols-2.2.0.tgz#5740e1c5d6f0dfda4ad9323b5332107ef6b4c40a" + dependencies: + chalk "^2.0.1" + +log-update@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/log-update/-/log-update-1.0.2.tgz#19929f64c4093d2d2e7075a1dad8af59c296b8d1" + dependencies: + ansi-escapes "^1.0.0" + cli-cursor "^1.0.2" + +long@4.0.0, long@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" + +long@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/long/-/long-3.2.0.tgz#d821b7138ca1cb581c172990ef14db200b5c474b" + +loose-envify@^1.0.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf" + dependencies: + js-tokens "^3.0.0 || ^4.0.0" + +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + +lowercase-keys@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" + +lru-cache@^4.0.1, lru-cache@^4.1.1: + version "4.1.3" + resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.3.tgz#a1175cf3496dfc8436c156c334b4955992bce69c" + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + +make-dir@^1.0.0, make-dir@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + dependencies: + pify "^3.0.0" + +makeerror@1.0.x: + version "1.0.11" + resolved "https://registry.yarnpkg.com/makeerror/-/makeerror-1.0.11.tgz#e01a5c9109f2af79660e4e8b9587790184f5a96c" + dependencies: + tmpl "1.0.x" + +mamacro@^0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/mamacro/-/mamacro-0.0.3.tgz#ad2c9576197c9f1abf308d0787865bd975a3f3e4" + +map-cache@^0.2.2: + version "0.2.2" + resolved "https://registry.yarnpkg.com/map-cache/-/map-cache-0.2.2.tgz#c32abd0bd6525d9b051645bb4f26ac5dc98a0dbf" + +map-visit@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/map-visit/-/map-visit-1.0.0.tgz#ecdca8f13144e660f1b5bd41f12f3479d98dfb8f" + dependencies: + object-visit "^1.0.0" + +marked@^0.3.17: + version "0.3.19" + resolved "https://registry.yarnpkg.com/marked/-/marked-0.3.19.tgz#5d47f709c4c9fc3c216b6d46127280f40b39d790" + +math-random@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/math-random/-/math-random-1.0.1.tgz#8b3aac588b8a66e4975e3cdea67f7bb329601fac" + +md5.js@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/md5.js/-/md5.js-1.3.4.tgz#e9bdbde94a20a5ac18b04340fc5764d5b09d901d" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +mdn-browser-compat-data@^0.0.84: + version "0.0.84" + resolved "https://registry.yarnpkg.com/mdn-browser-compat-data/-/mdn-browser-compat-data-0.0.84.tgz#791d0e238cff5779fae589f99f5b2c7b84ea44b5" + integrity sha512-fAznuGNaQMQiWLVf+gyp33FaABTglYWqMT7JqvH+4RZn2UQPD12gbMqxwP9m0lj8AAbNpu5/kD6n4Ox1SOffpw== + dependencies: + extend "3.0.2" + +mem-fs-editor@^4.0.0: + version "4.0.3" + resolved "https://registry.yarnpkg.com/mem-fs-editor/-/mem-fs-editor-4.0.3.tgz#d282a0c4e0d796e9eff9d75661f25f68f389af53" + dependencies: + commondir "^1.0.1" + deep-extend "^0.6.0" + ejs "^2.5.9" + glob "^7.0.3" + globby "^7.1.1" + isbinaryfile "^3.0.2" + mkdirp "^0.5.0" + multimatch "^2.0.0" + rimraf "^2.2.8" + through2 "^2.0.0" + vinyl "^2.0.1" + +mem-fs@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/mem-fs/-/mem-fs-1.1.3.tgz#b8ae8d2e3fcb6f5d3f9165c12d4551a065d989cc" + dependencies: + through2 "^2.0.0" + vinyl "^1.1.0" + vinyl-file "^2.0.0" + +mem@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/mem/-/mem-1.1.0.tgz#5edd52b485ca1d900fe64895505399a0dfa45f76" + dependencies: + mimic-fn "^1.0.0" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + +merge2@^1.2.1: + version "1.2.2" + resolved "https://registry.yarnpkg.com/merge2/-/merge2-1.2.2.tgz#03212e3da8d86c4d8523cebd6318193414f94e34" + +merge@^1.2.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.1.tgz#38bebf80c3220a8a487b6fcfb3941bb11720c145" + integrity sha512-VjFo4P5Whtj4vsLzsYBu5ayHhoHJ0UqNm7ibvShmbmoz7tGi0vXaoJbGdB+GmDMLUdg8DpQXEIeVDAe8MaABvQ== + +micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +micromatch@^3.1.10, micromatch@^3.1.4, micromatch@^3.1.8: + version "3.1.10" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + braces "^2.3.1" + define-property "^2.0.2" + extend-shallow "^3.0.2" + extglob "^2.0.4" + fragment-cache "^0.2.1" + kind-of "^6.0.2" + nanomatch "^1.2.9" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.2" + +milagro-crypto-js@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/milagro-crypto-js/-/milagro-crypto-js-3.3.0.tgz#4135222d5e6a23bc98ea8d4e093017707df0990f" + +miller-rabin@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.1.tgz#f080351c865b0dc562a8462966daa53543c78a4d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +mime-db@~1.35.0: + version "1.35.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.35.0.tgz#0569d657466491283709663ad379a99b90d9ab47" + +mime-types@^2.1.12, mime-types@~2.1.17: + version "2.1.19" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.19.tgz#71e464537a7ef81c15f2db9d97e913fc0ff606f0" + dependencies: + mime-db "~1.35.0" + +mimic-fn@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-1.2.0.tgz#820c86a39334640e99516928bd03fca88057d022" + +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b" + +minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + +minimatch@^3.0.0, minimatch@^3.0.2, minimatch@^3.0.3, minimatch@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083" + dependencies: + brace-expansion "^1.1.7" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.1.0.tgz#99df657a52574c21c9057497df742790b2b4c0de" + +minimist@^1.1.0, minimist@^1.1.1, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +minimist@~0.0.1: + version "0.0.10" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf" + integrity sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8= + +minipass@^2.2.1, minipass@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/minipass/-/minipass-2.3.3.tgz#a7dcc8b7b833f5d368759cce544dccb55f50f233" + dependencies: + safe-buffer "^5.1.2" + yallist "^3.0.0" + +minizlib@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/minizlib/-/minizlib-1.1.0.tgz#11e13658ce46bc3a70a267aac58359d1e0c29ceb" + dependencies: + minipass "^2.2.1" + +mississippi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/mississippi/-/mississippi-2.0.0.tgz#3442a508fafc28500486feea99409676e4ee5a6f" + dependencies: + concat-stream "^1.5.0" + duplexify "^3.4.2" + end-of-stream "^1.1.0" + flush-write-stream "^1.0.0" + from2 "^2.1.0" + parallel-transform "^1.1.0" + pump "^2.0.1" + pumpify "^1.3.3" + stream-each "^1.1.0" + through2 "^2.0.0" + +mixin-deep@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/mixin-deep/-/mixin-deep-1.3.1.tgz#a49e7268dce1a0d9698e45326c5626df3543d0fe" + dependencies: + for-in "^1.0.2" + is-extendable "^1.0.1" + +mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +move-concurrently@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" + dependencies: + aproba "^1.1.1" + copy-concurrently "^1.0.0" + fs-write-stream-atomic "^1.0.8" + mkdirp "^0.5.1" + rimraf "^2.5.4" + run-queue "^1.0.3" + +ms@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8" + +multimatch@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/multimatch/-/multimatch-2.1.0.tgz#9c7906a22fb4c02919e2f5f75161b4cdbd4b2a2b" + dependencies: + array-differ "^1.0.0" + array-union "^1.0.1" + arrify "^1.0.0" + minimatch "^3.0.0" + +mute-stream@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/mute-stream/-/mute-stream-0.0.7.tgz#3075ce93bc21b8fab43e1bc4da7e8115ed1e7bab" + +nan@^2.9.2: + version "2.10.0" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.10.0.tgz#96d0cd610ebd58d4b4de9cc0c6828cda99c7548f" + +nanomatch@^1.2.9: + version "1.2.13" + resolved "https://registry.yarnpkg.com/nanomatch/-/nanomatch-1.2.13.tgz#b87a8aa4fc0de8fe6be88895b38983ff265bd119" + dependencies: + arr-diff "^4.0.0" + array-unique "^0.3.2" + define-property "^2.0.2" + extend-shallow "^3.0.2" + fragment-cache "^0.2.1" + is-windows "^1.0.2" + kind-of "^6.0.2" + object.pick "^1.3.0" + regex-not "^1.0.0" + snapdragon "^0.8.1" + to-regex "^3.0.1" + +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + +needle@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.1.tgz#b5e325bd3aae8c2678902fa296f729455d1d3a7d" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + +neo-async@^2.5.0, neo-async@^2.6.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/neo-async/-/neo-async-2.6.1.tgz#ac27ada66167fa8849a6addd837f6b189ad2081c" + integrity sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw== + +nice-try@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.4.tgz#d93962f6c52f2c1558c0fbda6d512819f1efe1c4" + +node-dir@0.1.8: + version "0.1.8" + resolved "https://registry.yarnpkg.com/node-dir/-/node-dir-0.1.8.tgz#55fb8deb699070707fb67f91a460f0448294c77d" + +node-int64@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/node-int64/-/node-int64-0.4.0.tgz#87a9065cdb355d3182d8f94ce11188b825c68a3b" + +node-libs-browser@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.1.0.tgz#5f94263d404f6e44767d726901fff05478d600df" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.2.0" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "^1.0.0" + os-browserify "^0.3.0" + path-browserify "0.0.0" + process "^0.11.10" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.3.3" + stream-browserify "^2.0.1" + stream-http "^2.7.2" + string_decoder "^1.0.0" + timers-browserify "^2.0.4" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-notifier@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" + dependencies: + growly "^1.3.0" + semver "^5.4.1" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + +node-releases@^1.1.38: + version "1.1.39" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.39.tgz#c1011f30343aff5b633153b10ff691d278d08e8d" + integrity sha512-8MRC/ErwNCHOlAFycy9OPca46fQYUjbJRDcZTHVWIGXIjYLM73k70vv3WkYutVnM4cCo4hE0MqBVVZjP6vjISA== + dependencies: + semver "^6.3.0" + +nomnom@^1.8.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + +nopt@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d" + dependencies: + abbrev "1" + osenv "^0.1.4" + +normalize-package-data@^2.3.2: + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.1.1.tgz#1ab28b556e198363a8c1a6f7e6fa20137fe6aed9" + dependencies: + remove-trailing-separator "^1.0.1" + +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + +npm-bundled@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/npm-bundled/-/npm-bundled-1.0.3.tgz#7e71703d973af3370a9591bafe3a63aca0be2308" + +npm-packlist@^1.1.6: + version "1.1.10" + resolved "https://registry.yarnpkg.com/npm-packlist/-/npm-packlist-1.1.10.tgz#1039db9e985727e464df066f4cf0ab6ef85c398a" + dependencies: + ignore-walk "^3.0.1" + npm-bundled "^1.0.1" + +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/npm-run-path/-/npm-run-path-2.0.2.tgz#35a9232dfa35d7067b4cb2ddf2357b1871536c5f" + dependencies: + path-key "^2.0.0" + +npmlog@^4.0.2: + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.3" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +nwsapi@^2.0.0: + version "2.0.5" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.5.tgz#3998cfe7a014600e5e30dedb1fef2a4404b2871f" + +oauth-sign@~0.8.2: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-copy@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c" + dependencies: + copy-descriptor "^0.1.0" + define-property "^0.2.5" + kind-of "^3.0.3" + +object-keys@^1.0.8: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + +object-visit@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/object-visit/-/object-visit-1.0.1.tgz#f79c4493af0c5377b59fe39d395e41042dd045bb" + dependencies: + isobject "^3.0.0" + +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +object.pick@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/object.pick/-/object.pick-1.3.0.tgz#87a10ac4c1694bd2e1cbf53591a66141fb5dd747" + dependencies: + isobject "^3.0.1" + +once@^1.3.0, once@^1.3.1, once@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" + dependencies: + wrappy "1" + +onetime@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz#a1f7838f8314c516f05ecefcbc4ccfe04b4ed789" + +onetime@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/onetime/-/onetime-2.0.1.tgz#067428230fd67443b2794b22bba528b6867962d4" + dependencies: + mimic-fn "^1.0.0" + +optimist@^0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/optimist/-/optimist-0.6.1.tgz#da3ea74686fa21a19a111c326e90eb15a0196686" + integrity sha1-2j6nRob6IaGaERwybpDrFaAZZoY= + dependencies: + minimist "~0.0.1" + wordwrap "~0.0.2" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +ora@^0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/ora/-/ora-0.2.3.tgz#37527d220adcd53c39b73571d754156d5db657a4" + dependencies: + chalk "^1.1.1" + cli-cursor "^1.0.2" + cli-spinners "^0.1.2" + object-assign "^4.0.1" + +os-browserify@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-2.1.0.tgz#42bc2900a6b5b8bd17376c8e882b65afccf24bf2" + dependencies: + execa "^0.7.0" + lcid "^1.0.0" + mem "^1.1.0" + +os-tmpdir@^1.0.0, os-tmpdir@^1.0.1, os-tmpdir@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +osenv@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/osenv/-/osenv-0.1.5.tgz#85cdfafaeb28e8677f416e287592b5f3f49ea410" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.0" + +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + +p-each-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-1.0.0.tgz#930f3d12dd1f50e7434457a22cd6f04ac6ad7f71" + dependencies: + p-reduce "^1.0.0" + +p-finally@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" + +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + +p-lazy@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-lazy/-/p-lazy-1.0.0.tgz#ec53c802f2ee3ac28f166cc82d0b2b02de27a835" + +p-limit@^1.1.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" + dependencies: + p-try "^1.0.0" + +p-locate@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/p-locate/-/p-locate-2.0.0.tgz#20a0103b222a70c8fd39cc2e580680f3dde5ec43" + dependencies: + p-limit "^1.1.0" + +p-map@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/p-map/-/p-map-1.2.0.tgz#e4e94f311eabbc8633a1e79908165fca26241b6b" + +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + dependencies: + p-finally "^1.0.0" + +p-timeout@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" + dependencies: + p-finally "^1.0.0" + +p-try@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-try/-/p-try-1.0.0.tgz#cbc79cdbaf8fd4228e13f621f2b1a237c1b207b3" + +pako@~1.0.5: + version "1.0.6" + resolved "https://registry.yarnpkg.com/pako/-/pako-1.0.6.tgz#0101211baa70c4bca4a0f63f2206e97b7dfaf258" + +parallel-transform@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/parallel-transform/-/parallel-transform-1.1.0.tgz#d410f065b05da23081fcd10f28854c29bda33b06" + dependencies: + cyclist "~0.2.2" + inherits "^2.0.3" + readable-stream "^2.1.5" + +parse-asn1@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.1.1.tgz#f6bf293818332bd0dab54efb16087724745e6ca8" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parse-json@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-4.0.0.tgz#be35f5425be1f7f6c747184f98a788cb99477ee0" + dependencies: + error-ex "^1.3.1" + json-parse-better-errors "^1.0.1" + +parse-passwd@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" + +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + +pascalcase@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/pascalcase/-/pascalcase-0.1.1.tgz#b363e55e8006ca6fe21784d2db22bd15d7917f14" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + +path-dirname@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/path-dirname/-/path-dirname-1.0.2.tgz#cc33d24d525e099a5388c0336c6e32b9160609e0" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-exists@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-3.0.0.tgz#ce0ebeaa5f78cb18925ea7d810d7b59b010fd515" + +path-is-absolute@^1.0.0, path-is-absolute@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-key@^2.0.0, path-key@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +path-type@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-3.0.0.tgz#cef31dc8e0a1a3bb0d105c0cd97cf3bf47f4e36f" + dependencies: + pify "^3.0.0" + +pbkdf2@^3.0.3, pbkdf2@^3.0.9: + version "3.0.16" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.16.tgz#7404208ec6b01b62d85bf83853a8064f8d9c2a5c" + dependencies: + create-hash "^1.1.2" + create-hmac "^1.1.4" + ripemd160 "^2.0.1" + safe-buffer "^5.0.1" + sha.js "^2.4.8" + +performance-now@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" + +pify@^2.0.0, pify@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkcs7@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pkcs7/-/pkcs7-1.0.2.tgz#b6dba527528c2942bfc122ce2dafcdb5e59074e7" + +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" + +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + +posix-character-classes@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +prepend-http@^1.0.1: + version "1.0.4" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" + +prepend-http@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-2.0.0.tgz#e92434bfa5ea8c19f41cdfd401d741a3c819d897" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +prettier@^1.12.1: + version "1.13.7" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.13.7.tgz#850f3b8af784a49a6ea2d2eaa7ed1428a34b7281" + +pretty-bytes@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/pretty-bytes/-/pretty-bytes-4.0.2.tgz#b2bf82e7350d65c6c33aa95aaa5a4f6327f61cd9" + +pretty-format@^22.4.0, pretty-format@^22.4.3: + version "22.4.3" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-22.4.3.tgz#f873d780839a9c02e9664c8a082e9ee79eaac16f" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +pretty-format@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.2.0.tgz#3b0aaa63c018a53583373c1cb3a5d96cc5e83017" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +private@^0.1.6, private@^0.1.8, private@~0.1.5: + version "0.1.8" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" + +process-nextick-args@^2.0.0, process-nextick-args@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-2.0.0.tgz#a37d732f4271b4ab1ad070d35508e8290788ffaa" + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + +progress@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/progress/-/progress-2.0.0.tgz#8a1be366bf8fc23db2bd23f10c6fe920b4389d1f" + +promise-controller@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/promise-controller/-/promise-controller-0.2.0.tgz#dd4789327aec81dfd6ce9531b4d3839998684753" + +promise-inflight@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/promise-inflight/-/promise-inflight-1.0.1.tgz#98472870bf228132fcbdd868129bad12c3c029e3" + +promise-timeout@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/promise-timeout/-/promise-timeout-1.3.0.tgz#d1c78dd50a607d5f0a5207410252a3a0914e1014" + +promise.prototype.finally@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/promise.prototype.finally/-/promise.prototype.finally-3.1.0.tgz#66f161b1643636e50e7cf201dc1b84a857f3864e" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.9.0" + function-bind "^1.1.1" + +prompts@^0.1.9: + version "0.1.12" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.12.tgz#39dc42de7d2f0ec3e2af76bf40713fcb8726090d" + dependencies: + kleur "^1.0.0" + sisteransi "^0.1.1" + +prr@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/prr/-/prr-1.0.1.tgz#d3fc114ba06995a45ec6893f484ceb1d78f5f476" + +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" + +psl@^1.1.24: + version "1.1.28" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.28.tgz#4fb6ceb08a1e2214d4fd4de0ca22dae13740bc7b" + +public-encrypt@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + +pump@^2.0.0, pump@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pump/-/pump-2.0.1.tgz#12399add6e4cf7526d973cbc8b5ce2e2908b3909" + dependencies: + end-of-stream "^1.1.0" + once "^1.3.1" + +pumpify@^1.3.3: + version "1.5.1" + resolved "https://registry.yarnpkg.com/pumpify/-/pumpify-1.5.1.tgz#36513be246ab27570b1a374a5ce278bfd74370ce" + dependencies: + duplexify "^3.6.0" + inherits "^2.0.3" + pump "^2.0.0" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + +qs@~6.5.1: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +randomatic@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-3.0.0.tgz#d35490030eb4f7578de292ce6dfb04a91a128923" + dependencies: + is-number "^4.0.0" + kind-of "^6.0.0" + math-random "^1.0.1" + +randombytes@^2.0.0, randombytes@^2.0.1, randombytes@^2.0.5: + version "2.0.6" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.6.tgz#d302c522948588848a8d300c932b44c24231da80" + dependencies: + safe-buffer "^5.1.0" + +randomfill@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/randomfill/-/randomfill-1.0.4.tgz#c92196fc86ab42be983f1bf31778224931d61458" + dependencies: + randombytes "^2.0.5" + safe-buffer "^5.1.0" + +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +read-chunk@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/read-chunk/-/read-chunk-2.1.0.tgz#6a04c0928005ed9d42e1a6ac5600e19cbc7ff655" + dependencies: + pify "^3.0.0" + safe-buffer "^5.1.1" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg-up@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-3.0.0.tgz#3ed496685dba0f8fe118d0691dc51f4a1ff96f07" + dependencies: + find-up "^2.0.0" + read-pkg "^3.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +read-pkg@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-3.0.0.tgz#9cbc686978fee65d16c00e2b19c237fcf6e38389" + dependencies: + load-json-file "^4.0.0" + normalize-package-data "^2.3.2" + path-type "^3.0.0" + +"readable-stream@1 || 2", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6: + version "2.3.6" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.6.tgz#b11c27d88b8ff1fbe070643cf94b0c79ae1b0aaf" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.3" + isarray "~1.0.0" + process-nextick-args "~2.0.0" + safe-buffer "~5.1.1" + string_decoder "~1.1.1" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +realpath-native@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.1.tgz#07f40a0cce8f8261e2e8b7ebebf5c95965d7b633" + dependencies: + util.promisify "^1.0.0" + +recast@^0.12.5: + version "0.12.9" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.12.9.tgz#e8e52bdb9691af462ccbd7c15d5a5113647a15f1" + dependencies: + ast-types "0.10.1" + core-js "^2.4.1" + esprima "~4.0.0" + private "~0.1.5" + source-map "~0.6.1" + +recast@^0.15.0: + version "0.15.2" + resolved "https://registry.yarnpkg.com/recast/-/recast-0.15.2.tgz#bcaebf7cdb0728e38ec6d1438e7fb3594505cee3" + dependencies: + ast-types "0.11.5" + esprima "~4.0.0" + private "~0.1.5" + source-map "~0.6.1" + +rechoir@^0.6.2: + version "0.6.2" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" + dependencies: + resolve "^1.1.6" + +regenerate@^1.2.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.4.0.tgz#4a856ec4b56e4077c557589cae85e7a4c8869a11" + +regenerator-runtime@^0.10.5: + version "0.10.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz#336c3efc1220adcedda2c9fab67b5a7955a33658" + +regenerator-runtime@^0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" + +regenerator-runtime@^0.13.2: + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" + integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== + +regenerator-transform@^0.10.0: + version "0.10.1" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.10.1.tgz#1e4996837231da8b7f3cf4114d71b5691a0680dd" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.4" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.4.tgz#75bdc58a2a1496cec48a12835bc54c8d562336dd" + dependencies: + is-equal-shallow "^0.1.3" + +regex-not@^1.0.0, regex-not@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" + dependencies: + extend-shallow "^3.0.2" + safe-regex "^1.1.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +remove-trailing-separator@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz#c24bce2a283adad5bc3f58e0d48249b92379d8ef" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2, repeat-string@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +replace-ext@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-0.0.1.tgz#29bbd92078a739f0bcce2b4ee41e837953522924" + +replace-ext@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" + +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + +request@^2.83.0: + version "2.87.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.87.0.tgz#32f00235cd08d482b4d0d68db93a829c0ed5756e" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.6.0" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.1" + forever-agent "~0.6.1" + form-data "~2.3.1" + 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.17" + oauth-sign "~0.8.2" + performance-now "^2.1.0" + qs "~6.5.1" + safe-buffer "^5.1.1" + tough-cookie "~2.3.3" + tunnel-agent "^0.6.0" + uuid "^3.1.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +resolve-cwd@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" + dependencies: + resolve-from "^3.0.0" + +resolve-dir@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/resolve-dir/-/resolve-dir-1.0.1.tgz#79a40644c362be82f26effe739c9bb5382046f43" + dependencies: + expand-tilde "^2.0.0" + global-modules "^1.0.0" + +resolve-from@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-3.0.0.tgz#b22c7af7d9d6881bc8b6e653335eebcb0a188748" + +resolve-url@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" + +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + +resolve@^1.1.6, resolve@^1.1.7, resolve@^1.3.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.8.1.tgz#82f1ec19a423ac1fbd080b0bab06ba36e84a7a26" + dependencies: + path-parse "^1.0.5" + +responselike@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" + dependencies: + lowercase-keys "^1.0.0" + +restore-cursor@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-1.0.1.tgz#34661f46886327fed2991479152252df92daa541" + dependencies: + exit-hook "^1.0.0" + onetime "^1.0.0" + +restore-cursor@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf" + dependencies: + onetime "^2.0.0" + signal-exit "^3.0.2" + +ret@~0.1.10: + version "0.1.15" + resolved "https://registry.yarnpkg.com/ret/-/ret-0.1.15.tgz#b8a4825d5bdb1fc3f6f53c2bc33f81388681c7bc" + +rimraf@^2.2.8, rimraf@^2.5.4, rimraf@^2.6.1, rimraf@^2.6.2: + version "2.6.2" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.2.tgz#2ed8150d24a16ea8651e6d6ef0f47c4158ce7a36" + dependencies: + glob "^7.0.5" + +rimraf@~2.2.6: + version "2.2.8" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.2.8.tgz#e439be2aaee327321952730f99a8929e4fc50582" + +ripemd160@^2.0.0, ripemd160@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-2.0.2.tgz#a1c1a6f624751577ba5d07914cbc92850585890c" + dependencies: + hash-base "^3.0.0" + inherits "^2.0.1" + +rsvp@^3.3.3: + version "3.6.2" + resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" + +run-async@^2.0.0, run-async@^2.2.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.3.0.tgz#0371ab4ae0bdd720d4166d7dfda64ff7a445a6c0" + dependencies: + is-promise "^2.1.0" + +run-queue@^1.0.0, run-queue@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/run-queue/-/run-queue-1.0.3.tgz#e848396f057d223f24386924618e25694161ec47" + dependencies: + aproba "^1.1.1" + +rxjs@^5.5.2: + version "5.5.11" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-5.5.11.tgz#f733027ca43e3bec6b994473be4ab98ad43ced87" + dependencies: + symbol-observable "1.0.1" + +rxjs@^6.1.0: + version "6.2.2" + resolved "https://registry.yarnpkg.com/rxjs/-/rxjs-6.2.2.tgz#eb75fa3c186ff5289907d06483a77884586e1cf9" + dependencies: + tslib "^1.9.0" + +safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + +safe-regex@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/safe-regex/-/safe-regex-1.1.0.tgz#40a3669f3b077d1e943d44629e157dd48023bf2e" + dependencies: + ret "~0.1.10" + +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" + +sane@^2.0.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + +sax@^1.2.4: + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" + +schema-utils@^0.4.4, schema-utils@^0.4.5: + version "0.4.5" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.5.tgz#21836f0608aac17b78f9e3e24daff14a5ca13a3e" + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + +scoped-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/scoped-regex/-/scoped-regex-1.0.0.tgz#a346bb1acd4207ae70bd7c0c7ca9e566b6baddb8" + +scrypt-async@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/scrypt-async/-/scrypt-async-2.0.0.tgz#419e8e9b40cef9173b44b4602acf50a3d27cf8ad" + +secure-random@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/secure-random/-/secure-random-1.1.1.tgz#0880f2d8c5185f4bcb4684058c836b4ddb07145a" + +"semver@2 || 3 || 4 || 5", semver@^5.0.1, semver@^5.3.0, semver@^5.4.1, semver@^5.5.0: + version "5.5.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" + +semver@^6.1.2, semver@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" + integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== + +serialize-javascript@^1.4.0: + version "1.5.0" + resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-1.5.0.tgz#1aa336162c88a890ddad5384baebc93a655161fe" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +set-value@^0.4.3: + version "0.4.3" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-0.4.3.tgz#7db08f9d3d22dc7f78e53af3c3bf4666ecdfccf1" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.1" + to-object-path "^0.3.0" + +set-value@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.0.tgz#71ae4a88f0feefbbf52d1ea604f3fb315ebb6274" + dependencies: + extend-shallow "^2.0.1" + is-extendable "^0.1.1" + is-plain-object "^2.0.3" + split-string "^3.0.1" + +setimmediate@^1.0.4: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +sha.js@^2.4.0, sha.js@^2.4.8: + version "2.4.11" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.11.tgz#37a5cf0b81ecbc6943de109ba2960d1b26584ae7" + dependencies: + inherits "^2.0.1" + safe-buffer "^5.0.1" + +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" + dependencies: + shebang-regex "^1.0.0" + +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" + +shell-quote@^1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/shell-quote/-/shell-quote-1.6.1.tgz#f4781949cce402697127430ea3b3c5476f481767" + dependencies: + array-filter "~0.0.0" + array-map "~0.0.0" + array-reduce "~0.0.0" + jsonify "~0.0.0" + +shelljs@^0.8.0, shelljs@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/shelljs/-/shelljs-0.8.2.tgz#345b7df7763f4c2340d584abb532c5f752ca9e35" + dependencies: + glob "^7.0.0" + interpret "^1.0.0" + rechoir "^0.6.2" + +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + +signal-exit@^3.0.0, signal-exit@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +sisteransi@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +slice-ansi@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/slice-ansi/-/slice-ansi-0.0.4.tgz#edbf8903f66f7ce2f8eafd6ceed65e264c831b35" + +slide@^1.1.5: + version "1.1.6" + resolved "https://registry.yarnpkg.com/slide/-/slide-1.1.6.tgz#56eb027d65b4d2dce6cb2e2d32c4d4afc9e1d707" + +sm.js@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/sm.js/-/sm.js-0.1.7.tgz#e2ac81ab2819306c0971675705c5043336ba5548" + dependencies: + bn.js "^4.11.6" + elliptic "^6.4.0" + hash.js "^1.0.3" + hmac-drbg "^1.0.1" + inherits "^2.0.3" + +snapdragon-node@^2.0.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/snapdragon-node/-/snapdragon-node-2.1.1.tgz#6c175f86ff14bdb0724563e8f3c1b021a286853b" + dependencies: + define-property "^1.0.0" + isobject "^3.0.0" + snapdragon-util "^3.0.1" + +snapdragon-util@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/snapdragon-util/-/snapdragon-util-3.0.1.tgz#f956479486f2acd79700693f6f7b805e45ab56e2" + dependencies: + kind-of "^3.2.0" + +snapdragon@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/snapdragon/-/snapdragon-0.8.2.tgz#64922e7c565b0e14204ba1aa7d6964278d25182d" + dependencies: + base "^0.11.1" + debug "^2.2.0" + define-property "^0.2.5" + extend-shallow "^2.0.1" + map-cache "^0.2.2" + source-map "^0.5.6" + source-map-resolve "^0.5.0" + use "^3.1.0" + +sort-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" + dependencies: + is-plain-obj "^1.0.0" + +source-list-map@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.0.tgz#aaa47403f7b245a92fbc97ea08f250d6087ed085" + +source-map-resolve@^0.5.0: + version "0.5.2" + resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" + dependencies: + 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@^0.4.15: + version "0.4.18" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.18.tgz#0286a6de8be42641338594e97ccea75f0a2c585f" + dependencies: + source-map "^0.5.6" + +source-map-support@^0.5.0, source-map-support@^0.5.5, source-map-support@^0.5.6: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.6.tgz#4435cee46b1aab62b8e8610ce60f788091c51c13" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + +source-map-url@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3" + +source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7: + version "0.5.7" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" + +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" + +spdx-correct@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.0.0.tgz#05a5b4d7153a195bc92c3c425b69f3b2a9524c82" + dependencies: + spdx-expression-parse "^3.0.0" + spdx-license-ids "^3.0.0" + +spdx-exceptions@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz#2c7ae61056c714a5b9b9b2b2af7d311ef5c78fe9" + +spdx-expression-parse@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0" + dependencies: + spdx-exceptions "^2.1.0" + spdx-license-ids "^3.0.0" + +spdx-license-ids@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz#7a7cd28470cc6d3a1cfe6d66886f6bc430d3ac87" + +split-string@^3.0.1, split-string@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/split-string/-/split-string-3.1.0.tgz#7cb09dda3a86585705c64b39a6466038682e8fe2" + dependencies: + extend-shallow "^3.0.0" + +sprintf-js@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c" + integrity sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw= + +sshpk@^1.7.0: + version "1.14.2" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.14.2.tgz#c6fc61648a3d9c4e764fd3fcdf4ea105e492ba98" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + safer-buffer "^2.0.2" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +ssri@^5.2.4: + version "5.3.0" + resolved "https://registry.yarnpkg.com/ssri/-/ssri-5.3.0.tgz#ba3872c9c6d33a0704a7d71ff045e5ec48999d06" + dependencies: + safe-buffer "^5.1.1" + +stack-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + +static-extend@^0.1.1: + version "0.1.2" + resolved "https://registry.yarnpkg.com/static-extend/-/static-extend-0.1.2.tgz#60809c39cbff55337226fd5e0b520f341f1fb5c6" + dependencies: + define-property "^0.2.5" + object-copy "^0.1.0" + +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-each@^1.1.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/stream-each/-/stream-each-1.2.2.tgz#8e8c463f91da8991778765873fe4d960d8f616bd" + dependencies: + end-of-stream "^1.1.0" + stream-shift "^1.0.0" + +stream-http@^2.7.2: + version "2.8.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.8.3.tgz#b2d242469288a5a27ec4fe8933acf623de6514fc" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.3.6" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +stream-shift@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/stream-shift/-/stream-shift-1.0.0.tgz#d5c752825e5367e786f78e18e445ea223a155952" + +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + +string-template@~0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/string-template/-/string-template-0.2.1.tgz#42932e598a352d01fc22ec3367d9d84eec6c9add" + +string-width@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + +string_decoder@^1.0.0, string_decoder@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.1.1.tgz#9cf1611ba62685d7030ae9e4ba34149c3af03fc8" + dependencies: + safe-buffer "~5.1.0" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom-stream@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom-stream/-/strip-bom-stream-2.0.0.tgz#f87db5ef2613f6968aa545abfe1ec728b6a829ca" + dependencies: + first-chunk-stream "^2.0.0" + strip-bom "^2.0.0" + +strip-bom@3.0.0, strip-bom@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +subarg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/subarg/-/subarg-1.0.0.tgz#f62cf17581e996b48fc965699f54c06ae268b8d2" + dependencies: + minimist "^1.1.0" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.2: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +supports-color@^5.3.0, supports-color@^5.4.0: + version "5.4.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.4.0.tgz#1c6b337402c2137605efe19f10fec390f6faab54" + dependencies: + has-flag "^3.0.0" + +symbol-observable@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.0.1.tgz#8340fc4702c3122df5d22288f88283f513d3fdd4" + +symbol-observable@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" + +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + +tapable@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-1.0.0.tgz#cbb639d9002eed9c6b5975eb20598d7936f1f9f2" + +tar@^4: + version "4.4.4" + resolved "https://registry.yarnpkg.com/tar/-/tar-4.4.4.tgz#ec8409fae9f665a4355cc3b4087d0820232bb8cd" + dependencies: + chownr "^1.0.1" + fs-minipass "^1.2.5" + minipass "^2.3.3" + minizlib "^1.1.0" + mkdirp "^0.5.0" + safe-buffer "^5.1.2" + yallist "^3.0.2" + +temp@^0.8.1: + version "0.8.3" + resolved "https://registry.yarnpkg.com/temp/-/temp-0.8.3.tgz#e0c6bc4d26b903124410e4fed81103014dfc1f59" + dependencies: + os-tmpdir "^1.0.0" + rimraf "~2.2.6" + +test-exclude@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.1.tgz#dfa222f03480bca69207ca728b37d74b45f724fa" + dependencies: + arrify "^1.0.1" + micromatch "^3.1.8" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + +text-table@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" + +textextensions@2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-2.2.0.tgz#38ac676151285b658654581987a0ce1a4490d286" + +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + +through2@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through@^2.3.6: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + +timers-browserify@^2.0.4: + version "2.0.10" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.10.tgz#1d28e3d2aadf1d5a5996c4e9f95601cd053480ae" + dependencies: + setimmediate "^1.0.4" + +tmp@^0.0.33: + version "0.0.33" + resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.33.tgz#6d34335889768d21b2bcda0aa277ced3b1bfadf9" + dependencies: + os-tmpdir "~1.0.2" + +tmpl@1.0.x: + version "1.0.4" + resolved "https://registry.yarnpkg.com/tmpl/-/tmpl-1.0.4.tgz#23640dd7b42d00433911140820e5cf440e521dd1" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + +to-fast-properties@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.3.tgz#b83571fa4d8c25b82e231b06e3a3055de4ca1a47" + +to-object-path@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/to-object-path/-/to-object-path-0.3.0.tgz#297588b7b0e7e0ac08e04e672f85c1f4999e17af" + dependencies: + kind-of "^3.0.2" + +to-regex-range@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/to-regex-range/-/to-regex-range-2.1.1.tgz#7c80c17b9dfebe599e27367e0d4dd5590141db38" + dependencies: + is-number "^3.0.0" + repeat-string "^1.6.1" + +to-regex@^3.0.1, to-regex@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/to-regex/-/to-regex-3.0.2.tgz#13cfdd9b336552f30b51f33a8ae1b42a7a7599ce" + dependencies: + define-property "^2.0.2" + extend-shallow "^3.0.2" + regex-not "^1.0.2" + safe-regex "^1.1.0" + +tough-cookie@>=2.3.3, tough-cookie@^2.3.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + +tough-cookie@~2.3.3: + version "2.3.4" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" + dependencies: + punycode "^1.4.1" + +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +ts-jest@^22.4.6: + version "22.4.6" + resolved "https://registry.yarnpkg.com/ts-jest/-/ts-jest-22.4.6.tgz#a5d7f5e8b809626d1f4143209d301287472ec344" + dependencies: + babel-core "^6.26.3" + babel-plugin-istanbul "^4.1.6" + babel-plugin-transform-es2015-modules-commonjs "^6.26.2" + babel-preset-jest "^22.4.3" + cpx "^1.5.0" + fs-extra "6.0.0" + jest-config "^22.4.3" + lodash "^4.17.10" + pkg-dir "^2.0.0" + source-map-support "^0.5.5" + yargs "^11.0.0" + +ts-loader@^4.3.0: + version "4.4.2" + resolved "https://registry.yarnpkg.com/ts-loader/-/ts-loader-4.4.2.tgz#778d4464b24436873c78f7f9e914d88194c2a248" + dependencies: + chalk "^2.3.0" + enhanced-resolve "^4.0.0" + loader-utils "^1.0.2" + micromatch "^3.1.4" + semver "^5.0.1" + +tslib@1.9.0: + version "1.9.0" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.0.tgz#e37a86fda8cbbaf23a057f473c9f4dc64e5fc2e8" + +tslib@^1.7.1, tslib@^1.8.0, tslib@^1.8.1, tslib@^1.9.0: + version "1.9.3" + resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.9.3.tgz#d7e4dd79245d85428c4d7e4822a79917954ca286" + +tslint-eslint-rules@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/tslint-eslint-rules/-/tslint-eslint-rules-5.3.1.tgz#10dec4361df0b3e4385d91ff8e0226bda4ec2ad4" + dependencies: + doctrine "0.7.2" + tslib "1.9.0" + tsutils "2.8.0" + +tslint-no-circular-imports@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/tslint-no-circular-imports/-/tslint-no-circular-imports-0.4.0.tgz#da22d442376f0eb5b03738b0b91a3d8949f6b8f3" + +tslint@^5.10.0: + version "5.11.0" + resolved "https://registry.yarnpkg.com/tslint/-/tslint-5.11.0.tgz#98f30c02eae3cde7006201e4c33cb08b48581eed" + dependencies: + babel-code-frame "^6.22.0" + builtin-modules "^1.1.1" + chalk "^2.3.0" + commander "^2.12.1" + diff "^3.2.0" + glob "^7.1.1" + js-yaml "^3.7.0" + minimatch "^3.0.4" + resolve "^1.3.2" + semver "^5.3.0" + tslib "^1.8.0" + tsutils "^2.27.2" + +tsutils@2.8.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.8.0.tgz#0160173729b3bf138628dd14a1537e00851d814a" + dependencies: + tslib "^1.7.1" + +tsutils@^2.27.2: + version "2.28.0" + resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-2.28.0.tgz#6bd71e160828f9d019b6f4e844742228f85169a1" + dependencies: + tslib "^1.8.1" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +typedarray@^0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +typedoc-default-themes@^0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz#6dc2433e78ed8bea8e887a3acde2f31785bd6227" + +typedoc-webpack-plugin@^1.1.4: + version "1.1.4" + resolved "https://registry.yarnpkg.com/typedoc-webpack-plugin/-/typedoc-webpack-plugin-1.1.4.tgz#5d3bfc6d824a52f40109ee89d2bfbca5f1ac30a1" + dependencies: + lodash.clone "^4.5.0" + lodash.merge "^4.6.0" + +typedoc@^0.11.1: + version "0.11.1" + resolved "https://registry.yarnpkg.com/typedoc/-/typedoc-0.11.1.tgz#9f033887fd2218c769e1045feb88a1efed9f12c9" + dependencies: + "@types/fs-extra" "5.0.1" + "@types/handlebars" "4.0.36" + "@types/highlight.js" "9.12.2" + "@types/lodash" "4.14.104" + "@types/marked" "0.3.0" + "@types/minimatch" "3.0.3" + "@types/shelljs" "0.7.8" + fs-extra "^5.0.0" + handlebars "^4.0.6" + highlight.js "^9.0.0" + lodash "^4.17.5" + marked "^0.3.17" + minimatch "^3.0.0" + progress "^2.0.0" + shelljs "^0.8.1" + typedoc-default-themes "^0.5.0" + typescript "2.7.2" + +typeforce@^1.6.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/typeforce/-/typeforce-1.12.0.tgz#ca40899919f1466d7819e37be039406beb912a2e" + +typescript@2.7.2: + version "2.7.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.7.2.tgz#2d615a1ef4aee4f574425cdff7026edf81919836" + +typescript@^2.8.3: + version "2.9.2" + resolved "https://registry.yarnpkg.com/typescript/-/typescript-2.9.2.tgz#1cbf61d05d6b96269244eb6a3bce4bd914e0f00c" + +uglify-es@^3.3.4: + version "3.3.9" + resolved "https://registry.yarnpkg.com/uglify-es/-/uglify-es-3.3.9.tgz#0c1c4f0700bed8dbc124cdb304d2592ca203e677" + dependencies: + commander "~2.13.0" + source-map "~0.6.1" + +uglify-js@^3.1.4: + version "3.6.4" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.6.4.tgz#88cc880c6ed5cf9868fdfa0760654e7bed463f1d" + integrity sha512-9Yc2i881pF4BPGhjteCXQNaXx1DCwm3dtOyBaG2hitHjLWOczw/ki8vD1bqyT3u6K0Ms/FpCShkmfg+FtlOfYA== + dependencies: + commander "~2.20.3" + source-map "~0.6.1" + +uglifyjs-webpack-plugin@^1.2.4: + version "1.2.7" + resolved "https://registry.yarnpkg.com/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.7.tgz#57638dd99c853a1ebfe9d97b42160a8a507f9d00" + dependencies: + cacache "^10.0.4" + find-cache-dir "^1.0.0" + schema-utils "^0.4.5" + serialize-javascript "^1.4.0" + source-map "^0.6.1" + uglify-es "^3.3.4" + webpack-sources "^1.1.0" + worker-farm "^1.5.2" + +ultron@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ultron/-/ultron-1.1.1.tgz#9fe1536a10a664a65266a1e3ccf85fd36302bc9c" + +underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + +union-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/union-value/-/union-value-1.0.0.tgz#5c71c34cb5bad5dcebe3ea0cd08207ba5aa1aea4" + dependencies: + arr-union "^3.1.0" + get-value "^2.0.6" + is-extendable "^0.1.1" + set-value "^0.4.3" + +unique-filename@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/unique-filename/-/unique-filename-1.1.0.tgz#d05f2fe4032560871f30e93cbe735eea201514f3" + dependencies: + unique-slug "^2.0.0" + +unique-slug@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/unique-slug/-/unique-slug-2.0.0.tgz#db6676e7c7cc0629878ff196097c78855ae9f4ab" + dependencies: + imurmurhash "^0.1.4" + +universalify@^0.1.0: + version "0.1.2" + resolved "https://registry.yarnpkg.com/universalify/-/universalify-0.1.2.tgz#b646f69be3942dabcecc9d6639c80dc105efaa66" + +unorm@^1.3.3: + version "1.4.1" + resolved "https://registry.yarnpkg.com/unorm/-/unorm-1.4.1.tgz#364200d5f13646ca8bcd44490271335614792300" + +unset-value@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unset-value/-/unset-value-1.0.0.tgz#8376873f7d2335179ffb1e6fc3a8ed0dfc8ab559" + dependencies: + has-value "^0.3.1" + isobject "^3.0.0" + +untildify@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/untildify/-/untildify-3.0.3.tgz#1e7b42b140bcfd922b22e70ca1265bfe3634c7c9" + +upath@^1.0.5: + version "1.1.0" + resolved "https://registry.yarnpkg.com/upath/-/upath-1.1.0.tgz#35256597e46a581db4793d0ce47fa9aebfc9fabd" + +uri-js@^4.2.1: + version "4.2.2" + resolved "https://registry.yarnpkg.com/uri-js/-/uri-js-4.2.2.tgz#94c540e1ff772956e2299507c010aea6c8838eb0" + dependencies: + punycode "^2.1.0" + +urix@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/urix/-/urix-0.1.0.tgz#da937f7a62e21fec1fd18d49b35c2935067a6c72" + +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + dependencies: + prepend-http "^1.0.1" + +url-parse-lax@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" + dependencies: + prepend-http "^2.0.0" + +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +use@^3.1.0: + version "3.1.1" + resolved "https://registry.yarnpkg.com/use/-/use-3.1.1.tgz#d50c8cac79a19fbc20f2911f56eb973f4e10070f" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + +util@0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +util@^0.10.3: + version "0.10.4" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.4.tgz#3aa0125bfe668a4672de58857d3ace27ecb76901" + dependencies: + inherits "2.0.3" + +uuid@^3.1.0, uuid@^3.2.1: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + +v8-compile-cache@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.0.tgz#526492e35fc616864284700b7043e01baee09f0a" + +validate-npm-package-license@^3.0.1: + version "3.0.3" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz#81643bcbef1bdfecd4623793dc4648948ba98338" + dependencies: + spdx-correct "^3.0.0" + spdx-expression-parse "^3.0.0" + +verror@1.10.0: + version "1.10.0" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400" + dependencies: + assert-plus "^1.0.0" + core-util-is "1.0.2" + extsprintf "^1.2.0" + +vinyl-file@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/vinyl-file/-/vinyl-file-2.0.0.tgz#a7ebf5ffbefda1b7d18d140fcb07b223efb6751a" + dependencies: + graceful-fs "^4.1.2" + pify "^2.3.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + strip-bom-stream "^2.0.0" + vinyl "^1.1.0" + +vinyl@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-1.2.0.tgz#5c88036cf565e5df05558bfc911f8656df218884" + dependencies: + clone "^1.0.0" + clone-stats "^0.0.1" + replace-ext "0.0.1" + +vinyl@^2.0.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/vinyl/-/vinyl-2.2.0.tgz#d85b07da96e458d25b2ffe19fece9f2caa13ed86" + dependencies: + clone "^2.1.1" + clone-buffer "^1.0.0" + clone-stats "^1.0.0" + cloneable-readable "^1.0.0" + remove-trailing-separator "^1.0.1" + replace-ext "^1.0.0" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + +walker@~1.0.5: + version "1.0.7" + resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" + dependencies: + makeerror "1.0.x" + +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + +watchpack@^1.5.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.6.0.tgz#4bc12c2ebe8aa277a71f1d3f14d685c7b446cd00" + dependencies: + chokidar "^2.0.2" + graceful-fs "^4.1.2" + neo-async "^2.5.0" + +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + +webpack-addons@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/webpack-addons/-/webpack-addons-1.1.5.tgz#2b178dfe873fb6e75e40a819fa5c26e4a9bc837a" + dependencies: + jscodeshift "^0.4.0" + +webpack-cli@^2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-2.1.5.tgz#3081fdeb2f205f0a54aa397986880b0c20a71f7a" + dependencies: + chalk "^2.4.1" + cross-spawn "^6.0.5" + diff "^3.5.0" + enhanced-resolve "^4.0.0" + envinfo "^5.7.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.0" + 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.12.1" + supports-color "^5.4.0" + v8-compile-cache "^2.0.0" + webpack-addons "^1.1.5" + yargs "^11.1.0" + yeoman-environment "^2.1.1" + yeoman-generator "^2.0.5" + +webpack-node-externals@^1.7.2: + version "1.7.2" + resolved "https://registry.yarnpkg.com/webpack-node-externals/-/webpack-node-externals-1.7.2.tgz#6e1ee79ac67c070402ba700ef033a9b8d52ac4e3" + +webpack-sources@^1.0.1, webpack-sources@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-1.1.0.tgz#a101ebae59d6507354d71d8013950a3a8b7a5a54" + dependencies: + source-list-map "^2.0.0" + source-map "~0.6.1" + +webpack@^4.8.3: + version "4.16.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.16.1.tgz#2c4b89ea648125c3e67bcca6adf49ce2c14b2d31" + dependencies: + "@webassemblyjs/ast" "1.5.13" + "@webassemblyjs/helper-module-context" "1.5.13" + "@webassemblyjs/wasm-edit" "1.5.13" + "@webassemblyjs/wasm-opt" "1.5.13" + "@webassemblyjs/wasm-parser" "1.5.13" + acorn "^5.6.2" + acorn-dynamic-import "^3.0.0" + ajv "^6.1.0" + ajv-keywords "^3.1.0" + chrome-trace-event "^1.0.0" + enhanced-resolve "^4.1.0" + eslint-scope "^4.0.0" + json-parse-better-errors "^1.0.2" + loader-runner "^2.3.0" + loader-utils "^1.1.0" + memory-fs "~0.4.1" + micromatch "^3.1.8" + mkdirp "~0.5.0" + neo-async "^2.5.0" + node-libs-browser "^2.0.0" + schema-utils "^0.4.4" + tapable "^1.0.0" + uglifyjs-webpack-plugin "^1.2.4" + watchpack "^1.5.0" + webpack-sources "^1.0.1" + +websocket-as-promised@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/websocket-as-promised/-/websocket-as-promised-0.8.0.tgz#4f7020963f2167cdfcc079d5a2ba90c2b2f7a62e" + dependencies: + chnl "^0.4.0" + flat-options "^0.1.3" + promise-controller "^0.2.0" + promise.prototype.finally "^3.1.0" + +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz#57c235bc8657e914d24e1a397d3c82daee0a6ba3" + dependencies: + iconv-lite "0.4.19" + +whatwg-mimetype@^2.0.0, whatwg-mimetype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" + +whatwg-url@^6.4.0, whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +which-module@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-2.0.0.tgz#d9ef07dce77b9902b8a3a8fa4b31c3e3f7e6e87a" + +which@^1.2.12, which@^1.2.14, which@^1.2.9, which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + +wide-align@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" + dependencies: + string-width "^1.0.2 || 2" + +wif@^2.0.6: + version "2.0.6" + resolved "https://registry.yarnpkg.com/wif/-/wif-2.0.6.tgz#08d3f52056c66679299726fade0d432ae74b4704" + dependencies: + bs58check "<3.0.0" + +wordwrap@~0.0.2: + version "0.0.3" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" + integrity sha1-o9XabNXAvAAI03I0u68b7WMFkQc= + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +worker-farm@^1.5.2: + version "1.6.0" + resolved "https://registry.yarnpkg.com/worker-farm/-/worker-farm-1.6.0.tgz#aecc405976fab5a95526180846f0dba288f3a4a0" + dependencies: + errno "~0.1.7" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +write-file-atomic@^1.2.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-1.3.4.tgz#f807a4f0b1d9e913ae7a48112e6cc3af1991b45f" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + slide "^1.1.5" + +write-file-atomic@^2.1.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" + dependencies: + graceful-fs "^4.1.11" + imurmurhash "^0.1.4" + signal-exit "^3.0.2" + +ws@^3.1.0: + version "3.3.3" + resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + ultron "~1.1.0" + +ws@^4.0.0, ws@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/ws/-/ws-4.1.0.tgz#a979b5d7d4da68bf54efe0408967c324869a7289" + dependencies: + async-limiter "~1.0.0" + safe-buffer "~5.1.0" + +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + +xtend@^4.0.0, xtend@~4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +y18n@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-4.0.0.tgz#95ef94f85ecc81d007c264e190a120f0a3c8566b" + +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" + +yallist@^3.0.0, yallist@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.0.2.tgz#8452b4bb7e83c7c188d8041c1a837c773d6d8bb9" + +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + dependencies: + camelcase "^4.1.0" + +yargs@^11.0.0, yargs@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + +yargs@~1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-1.2.6.tgz#9c7b4a82fd5d595b2bf17ab6dcc43135432fe34b" + dependencies: + minimist "^0.1.0" + +yeoman-environment@^2.0.5, yeoman-environment@^2.1.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/yeoman-environment/-/yeoman-environment-2.3.1.tgz#1aa00cc474a8e48518ab2b0f64b43034215e9997" + dependencies: + chalk "^2.1.0" + cross-spawn "^6.0.5" + debug "^3.1.0" + diff "^3.3.1" + escape-string-regexp "^1.0.2" + 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.1.0" + mem-fs "^1.1.0" + strip-ansi "^4.0.0" + text-table "^0.2.0" + untildify "^3.0.2" + +yeoman-generator@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/yeoman-generator/-/yeoman-generator-2.0.5.tgz#57b0b3474701293cc9ec965288f3400b00887c81" + dependencies: + async "^2.6.0" + chalk "^2.3.0" + 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.0" + error "^7.0.2" + find-up "^2.1.0" + github-username "^4.0.0" + istextorbinary "^2.2.1" + lodash "^4.17.10" + make-dir "^1.1.0" + mem-fs-editor "^4.0.0" + 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.0.0" + shelljs "^0.8.0" + text-table "^0.2.0" + through2 "^2.0.0" + yeoman-environment "^2.0.5"