diff --git a/.gitignore b/.gitignore index 81718389521..4f32cb30339 100644 --- a/.gitignore +++ b/.gitignore @@ -13,12 +13,28 @@ pids *.pid *.seed +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + # Coverage directory used by tools like istanbul coverage +test/.coverage-unit # nyc test coverage .nyc_output +# cypress media +templates/cypress.tmpl/screenshots/ +templates/cypress.tmpl/videos/ +templates/cypress.tmpl/plugins/ +templates/cypress.tmpl/support/ +cypress/screenshots +cypress/videos +cypress/plugins + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + # node-waf configuration .lock-wscript @@ -40,4 +56,16 @@ jspm_packages tmp # Distribution directory -dist +.vscode +dist/ +dist-node/ +dist-browser/ +browsertest.build/ +browsertest/package.json +browsertest/browsertest.js +browsertest/browsertest.min.js +browsertest/src +browsertest/test + +# Unsupported lock files +yarn.lock diff --git a/.lintstagedrc.json b/.lintstagedrc.json new file mode 100644 index 00000000000..b7c6f9a778b --- /dev/null +++ b/.lintstagedrc.json @@ -0,0 +1,3 @@ +{ + "*.{ts,js}": ["prettier --write", "git add"] +} diff --git a/.npmrc b/.npmrc new file mode 120000 index 00000000000..e48092b8968 --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +templates/.npmrc.tmpl \ No newline at end of file diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 00000000000..2a5dd0d6389 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +8.14.0 diff --git a/.nycrc b/.nycrc new file mode 120000 index 00000000000..ca9add23011 --- /dev/null +++ b/.nycrc @@ -0,0 +1 @@ +templates/.nycrc.tmpl \ No newline at end of file diff --git a/.prettierignore b/.prettierignore new file mode 120000 index 00000000000..ff34f2eca16 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +./templates/.prettierignore.tmpl \ No newline at end of file diff --git a/.prettierrc.json b/.prettierrc.json new file mode 120000 index 00000000000..2710f71b380 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1 @@ +templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/Jenkinsfile.elements b/Jenkinsfile.elements new file mode 100644 index 00000000000..01ada8ee205 --- /dev/null +++ b/Jenkinsfile.elements @@ -0,0 +1,113 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +@Library('lisk-jenkins') _ +pipeline { + agent { node { label 'lisk-elements' } } + stages { + stage('Cancel previous running PR') { + steps { + script{ + if (env.CHANGE_ID) { + // This is a Pull Request + cancelPreviousBuild() + } + } + } + } + stage('Install dependencies') { + steps { + nvm(getNodejsVersion()) { + sh ''' + mkdir -p "/home/lisk/.cache/Cypress/$( jq -r .devDependencies.cypress ./packages/lisk-constants/package.json )/Cypress" + npm ci + ''' + } + } + } + stage('Build') { + steps { + nvm(getNodejsVersion()) { + sh 'npm run build' + } + } + } + stage('Run lint') { + steps { + ansiColor('xterm') { + nvm(getNodejsVersion()) { + sh 'npm run lint' + } + } + } + } + stage('Run tests') { + steps { + timeout(10) { + ansiColor('xterm') { + nvm(getNodejsVersion()) { + sh 'npm run test' + } + } + } + } + } + stage('Run node tests') { + steps { + timeout(10) { + ansiColor('xterm') { + nvm(getNodejsVersion()) { + sh 'npm run test:node' + } + } + } + } + } + stage('Run browser tests') { + steps { + timeout(10) { + ansiColor('xterm') { + nvm(getNodejsVersion()) { + sh ''' + npm run build:browsertest + npm run test:browser + ''' + } + } + } + } + } + } + post { + success { + script { + build_info = getBuildInfo() + liskSlackSend('good', "Recovery: build ${build_info} was successful.") + } + deleteDir() + githubNotify context: 'continuous-integration/jenkins/lisk-elements', description: 'The build passed.', status: 'SUCCESS' + } + failure { + script { + build_info = getBuildInfo() + liskSlackSend('danger', "Build ${build_info} failed (<${env.BUILD_URL}/console|console>, <${env.BUILD_URL}/changes|changes>)\n") + } + archiveArtifacts allowEmptyArchive: true, artifacts: 'cypress/screenshots/' + githubNotify context: 'continuous-integration/jenkins/lisk-elements', description: 'The build failed.', status: 'FAILURE' + } + aborted { + githubNotify context: 'continuous-integration/jenkins/lisk-elements', description: 'The build was aborted.', status: 'ERROR' + } + } +} diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index fe623959cfc..e7a1b254041 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -1,14 +1,14 @@ -# Contributing to Lisk Commander +# Contributing to Lisk Elements First off, thanks for taking the time to contribute! :raised_hands: -The following is a set of guidelines for contributing to Lisk Commander, which are hosted in the [LiskHQ Organization](https://github.com/LiskHQ) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. +The following is a set of guidelines for contributing to Lisk Elements, which are hosted in the [LiskHQ Organization](https://github.com/LiskHQ) on GitHub. These are mostly guidelines, not rules. Use your best judgment, and feel free to propose changes to this document in a pull request. #### Table Of Contents 1. [Code of Conduct](#code-of-conduct) -1. [Help! I don't want to read this whole thing, I just have one question. :mag_right:](#help-i-dont-want-to-read-this-whole-thing-i-just-have-a-question-mag_right) +1. [Help! I don't want to read this whole thing, I just have one question. :mag_right:](#help!-i-dont-want-to-read-this-whole-thing-i-just-have-a-question) 1. [How Can I Contribute?](#how-can-i-contribute) 1. [Reporting Bugs](#reporting-bugs) @@ -21,7 +21,7 @@ The following is a set of guidelines for contributing to Lisk Commander, which a ## Code of Conduct -This project and everyone participating in it is governed by the [Lisk Commander Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [info@lisk.io](mailto:info@lisk.io). +This project and everyone participating in it is governed by the [Lisk Elements Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior to [info@lisk.io](mailto:info@lisk.io). ## Project License @@ -57,16 +57,15 @@ In case you've never submitted a pull request (PR) via GitHub before, please rea *Before* submitting a pull request, please make sure the following is done: 1. Fork the repo. -1. If you are creating a pull request that addresses a specific issue, take a look at the projects that issue is a part of (in the right-hand sidebar). Most issues will be a part of a project for a specific version, such as "Version 0.3.0". If this is the case, create your branch from the relevant version branch, e.g. `0.3.0`, and submit your pull request against that branch as a base. Otherwise, create your branch from `master`. -1. Add tests to the code you have contributed! All new code must come with complete test coverage. See [here](test/README.md) for a guide to the testing approach we’re using. -1. End all files with a newline. In general, your code should conform to the rules listed in the `.editorconfig` file. There are plugins for most editors/IDEs to do this for you automatically. Update the README for the changes that adhere to your new code. -1. Ensure the test and linting suite passes (`npm run prepush` runs both). Follow the [JavaScript](https://github.com/airbnb/javascript) styleguide from Airbnb with the [lisk extension](https://github.com/LiskHQ/eslint-config-lisk-base). -1. Submit a pull request via GitHub. Include issue numbers in the PR title, at the end with: `Description - Closes #IssueNumber`. +1. If you are creating a pull request that addresses a specific issue, take a look at the projects that issue is a part of (in the right-hand sidebar). Most issues will be a part of a project for a specific version, such as "Version 1.0.0". If this is the case, create your branch from the relevant version branch, e.g. `1.0.0`, and submit your pull request against that branch as a base. Otherwise, create your branch from master. +1. Add tests to the code you have contributed! All new code must come with complete test coverage. End all files with a newline. In general, your code should conform to the rules listed in the .editorconfig file. There are plugins for most editors/IDEs to do this for you automatically. Update the README for the changes that adhere to your new code. +1. Ensure the test and linting suite passes (`npm run prepush` runs both). Follow the JavaScript styleguide from Airbnb with the lisk extension. +1. Submit a pull request via GitHub. Include issue numbers in the PR title, at the end with: Description - Closes #IssueNumber. Also mention the #IssueNumber in the Comment, to easier browse to the issue. 1. Check that Jenkins CI tests pass (pull request turns green). First time contributors will need to wait for a trusted team member to start Jenkins CI on a Pull Request. ### Reporting Bugs -This section guides you through submitting a bug report for Lisk Commander. Following these guidelines helps maintainers and the community understand your report :pencil:, reproduce the behavior :computer: :computer:, and find related reports :mag_right:. +This section guides you through submitting a bug report for Lisk Elements. Following these guidelines helps maintainers and the community understand your report :pencil:, reproduce the behavior :computer: :computer:, and find related reports :mag_right:. Before creating bug reports, please check [this list](#before-submitting-a-bug-report) as you might find out that you don't need to create one. When you are creating a bug report, please [include as many details as possible](#how-do-i-submit-a-good-bug-report). Fill out [the required template](ISSUE_TEMPLATE.md), the information it asks for helps us resolve issues faster. @@ -85,7 +84,7 @@ Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Explain the problem and include additional details to help maintainers reproduce the problem: * **Use a clear and descriptive title** for the issue to identify the problem. -* **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how you started Lisk Commander, e.g. in interactive or non-interactive mode, and with which commands. When listing steps, **don't just say what you did, but explain how you did it**. For example, if you have passed a sensitive input via a file provide the permissions for that file. **Make sure to erase sensitive information from the configuration or details you are passing - NEVER SHARE YOUR SECRET PASSPHRASES OR PRIVATE KEYS**. +* **Describe the exact steps which reproduce the problem** in as many details as possible. For example, start by explaining how you started Lisk Elements, e.g. with Node.js or in the Browser (which one? which version?), or how you started Lisk Elements otherwise. When listing steps, **don't just say what you did, but explain how you did it**. For example, if you have used an API model provide the configuration you have chosen and the functions you have executed. **Make sure to erase sensitive information from the configuration or details you are passing - NEVER SHARE YOUR SECRET PASSPHRASES OR PRIVATE KEYS**. * **Provide specific examples to demonstrate the steps**. Include links to files or GitHub projects, or copy/pasteable snippets, which you use in those examples. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). * **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior. * **Explain which behavior you expected to see instead and why.** @@ -94,15 +93,15 @@ Explain the problem and include additional details to help maintainers reproduce Provide more context by answering these questions: -* **Did the problem start happening recently** (e.g. after updating to a new version of Lisk Commander, Lisk or any other repository) or was this always a problem? -* If the problem started happening recently, **can you reproduce the problem in an older version of Lisk Commander?** What's the most recent version in which the problem doesn't happen? You can download older versions of Lisk Commander from [the releases page](https://github.com/LiskHQ/lisk-commander/releases). +* **Did the problem start happening recently** (e.g. after updating to a new version of Lisk Elements, Lisk or any other repository) or was this always a problem? +* If the problem started happening recently, **can you reproduce the problem in an older version of Lisk Elements?** What's the most recent version in which the problem doesn't happen? You can download older versions of Lisk Elements from [the releases page](https://github.com/LiskHQ/lisk-elements/releases). * **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens. ### Suggesting Enhancements -This section guides you through submitting an enhancement suggestion for Lisk Commander, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion :pencil: and find related suggestions :mag_right:. +This section guides you through submitting an enhancement suggestion for Lisk Elements, including completely new features and minor improvements to existing functionality. Following these guidelines helps maintainers and the community understand your suggestion :pencil: and find related suggestions :mag_right:. -When you are creating an enhancement suggestion, please include as many details as possible. Fill in [the template](ISSUE_TEMPLATE.md), including the steps that you imagine you would take if the feature you're requesting existed. + When you are creating an enhancement suggestion, please include as many details as possible. Fill in [the template](ISSUE_TEMPLATE.md), including the steps that you imagine you would take if the feature you're requesting existed. #### How Do I Submit A (Good) Enhancement Suggestion? @@ -112,9 +111,9 @@ Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com * **Provide a step-by-step description of the suggested enhancement** in as many details as possible. * **Provide specific examples to demonstrate the steps**. Include copy/pasteable snippets which you use in those examples, as [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). * **Describe the current behavior** and **explain which behavior you expected to see instead** and why. -* **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part of Lisk Commander which the suggestion is related to. You can use [this tool](http://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. -* **Explain why this enhancement would be useful** to most Lisk and Lisk Commander users. -* **Specify which version of Lisk and Lisk Commander you're using.** +* **Include screenshots and animated GIFs** which help you demonstrate the steps or point out the part of Lisk Elements which the suggestion is related to. You can use [this tool](http://www.cockos.com/licecap/) to record GIFs on macOS and Windows, and [this tool](https://github.com/colinkeenan/silentcast) or [this tool](https://github.com/GNOME/byzanz) on Linux. +* **Explain why this enhancement would be useful** to most Lisk and Lisk Elements users. +* **Specify which version of Lisk and Lisk Elements you're using.** * **Specify the name and version of the OS you're using.** ## Styleguides @@ -126,25 +125,25 @@ Enhancement suggestions are tracked as [GitHub issues](https://guides.github.com * Limit the first line to 72 characters or less * Reference issues and pull requests liberally after the first line * Consider starting the commit message with an applicable emoji: - * :seedling: `:seedling:` when adding a new feature - * :bug: `:bug:` when fixing a bug - * :books: `:books:` when adding or updating documentation - * :nail_care: `:nail_care:` when making changes to code style (e.g. lint settings) - * :recycle: `:recycle:` when refactoring code - * :fire: `:fire:` when removing code or files (including dependencies) - * :racehorse: `:racehorse:` when improving performance - * :white_check_mark: `:white_check_mark:` when adding or updating tests - * :construction_worker: `:construction_worker:` when updating the build process - * :bowtie: `:bowtie:` when updating CI - * :house: `:house:` when performing chores - * :new: `:new:` when adding a new dependency - * :arrow_up: `:arrow_up:` when upgrading a dependency - * :arrow_down: `:arrow_down:` when downgrading a dependency - * :back: `:back:` when reverting changes + * :seedling: `:seedling:` when adding a new feature + * :bug: `:bug:` when fixing a bug + * :books: `:books:` when adding or updating documentation + * :nail_care: `:nail_care:` when making changes to code style (e.g. lint settings) + * :recycle: `:recycle:` when refactoring code + * :fire: `:fire:` when removing code or files (including dependencies) + * :racehorse: `:racehorse:` when improving performance + * :white_check_mark: `:white_check_mark:` when adding or updating tests + * :construction_worker: `:construction_worker:` when updating the build process + * :bowtie: `:bowtie:` when updating CI + * :house: `:house:` when performing chores + * :new: `:new:` when adding a new dependency + * :arrow_up: `:arrow_up:` when upgrading a dependency + * :arrow_down: `:arrow_down:` when downgrading a dependency + * :back: `:back:` when reverting changes ### JavaScript Styleguide -On Lisk Commander we are using [ESLint](https://eslint.org/). +On Lisk Elements we are using [ESLint](https://eslint.org/). Our JavaScript style expands [Airbnb's](https://github.com/airbnb/javascript) style. You can get more details here: https://github.com/LiskHQ/eslint-config-lisk-base These contribution guidelines were inspired by and are based on Atom's contribution guidelines. They were modified for the purposes of this repository. https://github.com/atom/atom/blob/master/CONTRIBUTING.md - Copyright (c) 2011-2017 GitHub Inc. (MIT) diff --git a/docs/ISSUE_TEMPLATE.md b/docs/ISSUE_TEMPLATE.md index 846a8ace854..cb64c746fce 100644 --- a/docs/ISSUE_TEMPLATE.md +++ b/docs/ISSUE_TEMPLATE.md @@ -1,25 +1,7 @@ -Have you read Lisk Commander's Code of Conduct? By filing an Issue, you are expected to comply with it, including treating everyone with respect: https://github.com/LiskHQ/lisk-commander/blob/master/CODE_OF_CONDUCT.md +### Expected behavior -### Description +### Actual behavior -[Description of the issue] +### Steps to reproduce -### Steps to Reproduce - -1. [First Step] -1. [Second Step] -1. [and so on...] - -**Expected behavior:** [What you expect to happen] - -**Actual behavior:** [What actually happens] - -**Reproduces how often:** [What percentage of the time does it reproduce?] - -### Versions - -Please provide the version you are working with. Please include the OS and what version of the OS you're running. - -### Additional Information - -Any additional information, configuration or data that might be necessary to reproduce the issue. +### Which version(s) does this affect? (Environment, OS, etc...) diff --git a/elements/README.md b/elements/README.md new file mode 100644 index 00000000000..b8176dc16a9 --- /dev/null +++ b/elements/README.md @@ -0,0 +1,114 @@ +# Lisk Elements + +[![Build Status](https://jenkins.lisk.io/buildStatus/icon?job=lisk-elements/development)](https://jenkins.lisk.io/job/lisk-elements/job/development/) +Dependency Status +devDependency Status +[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0) + +## What is Lisk Elements + +Lisk Elements is collection of JavaScript libraries for [Lisk SDK](https://github.com/LiskHQ/lisk-sdk), the blockchain application development kit. Each library is developed with the proven and tested knowledge over time from Lisk Protocol implementation which was formally called [Lisk Core](https://github.com/LiskHQ/lisk). + +## Packages + +| Package | Version | Description | +| ---------------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------ | +| [lisk-elements](/packages/lisk-elements) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/lisk-elements) | Package contains everything | +| [@liskhq/lisk-client](/packages/lisk-client) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-client) | A default set of Elements for use by clients of the Lisk network | +| [@liskhq/lisk-api-client](/packages/lisk-api-client) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-api-client) | An API client for the Lisk network | +| [@liskhq/lisk-constants](/packages/lisk-constants) | [![](https://img.shields.io/badge/npm-v1.2.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-constants) | General constants for use with Lisk-related software | +| [@liskhq/lisk-cryptography](/packages/lisk-cryptography) | [![](https://img.shields.io/badge/npm-v2.1.0_alpha.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-cryptography) | General cryptographic functions for use with Lisk-related software | +| [@liskhq/lisk-passphrase](/packages/lisk-passphrase) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-passphrase) | Mnemonic passphrase helpers for use with Lisk-related software | +| [@liskhq/lisk-transactions](/packages/lisk-transactions) | [![](https://img.shields.io/badge/npm-v2.1.0_alpha.4-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-transactions) | Everything related to transactions according to the Lisk protocol | +| [@liskhq/lisk-transaction-pool](/packages/lisk-transaction-pool) | [![](https://img.shields.io/badge/npm-v0.1.0_alpha.1-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-transaction-pool) | Transaction pool implementation for the Lisk network | +| [@liskhq/lisk-p2p](/packages/lisk-p2p) | [![](https://img.shields.io/badge/npm-v0.1.0_alpha.4-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-p2p) | _unstructured_ P2P library for the Lisk protocol | + +## Installation + +If you want to install all elements as dependency of your project you can install it via. + +```sh +$ npm install --save lisk-elements +``` + +Or you can install individual packages what you need e.g. + +```sh +$ npm install --save @liskhq/lisk-transactions +$ npm install --save @liskhq/lisk-cryptography +``` + +## Usage + +Access functionality via the relevant namespace. For example, the following will create and (locally) sign a transfer (type 0) transaction, and then broadcast it to the Lisk Testnet. + +```js +const { APIClient, transaction } = require('lisk-elements'); + +const transferTransaction = lisk.transaction.transfer({ + amount: '123000000', + recipientId: '12668885769632475474L', + passphrase: + 'robust swift grocery peasant forget share enable convince deputy road keep cheap', +}); + +const client = APIClient.createTestnetAPIClient(); + +client.transactions + .broadcast(transferTransaction) + .then(console.info) + .catch(console.error); +``` + +Full documentation can be found on the [Lisk documentation site][]. + +## Tests + +To run tests for all packages in lisk-elements, run the following command in the root folder: + +``` +npm test +``` + +To run tests for a specific package, run the same command in the relevant package directory. + +Example: + +``` +cd packages/lisk-cryptography +npm test +``` + +## Get Involved + +| | | +| ------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | +| Found a bug | [Create new issue](https://github.com/LiskHQ/lisk-sdk/issues/new) | +| Want to develop with us | [Create a fork](https://github.com/LiskHQ/lisk-sdk/fork) | +| Have ideas to share | [Come to Lisk.chat](http://lisk.chat) | +| Want to involve community | [Join community gitter](https://gitter.im/LiskHQ/lisk-sdk?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) | +| Found a security issue | [See our bounty program](https://blog.lisk.io/announcing-lisk-bug-bounty-program-5895bdd46ed4) | + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +--- + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/elements/lisk-api-client/.npmignore b/elements/lisk-api-client/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-api-client/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/.npmrc b/elements/lisk-api-client/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-api-client/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/.nycrc b/elements/lisk-api-client/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-api-client/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/.prettierignore b/elements/lisk-api-client/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-api-client/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/.prettierrc.json b/elements/lisk-api-client/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-api-client/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/LICENSE b/elements/lisk-api-client/LICENSE new file mode 100644 index 00000000000..9cecc1d4669 --- /dev/null +++ b/elements/lisk-api-client/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/elements/lisk-api-client/README.md b/elements/lisk-api-client/README.md new file mode 100644 index 00000000000..3c8b711ecec --- /dev/null +++ b/elements/lisk-api-client/README.md @@ -0,0 +1,36 @@ +# @liskhq/lisk-api-client +@liskhq/lisk-api-client is containing an API client for the Lisk network + +## Installation + +```sh +$ npm install --save @liskhq/lisk-api-client +``` + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-api-client/browsertest b/elements/lisk-api-client/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-api-client/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/cypress b/elements/lisk-api-client/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-api-client/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/cypress.json b/elements/lisk-api-client/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-api-client/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/package-lock.json b/elements/lisk-api-client/package-lock.json new file mode 100644 index 00000000000..129a5bb22d8 --- /dev/null +++ b/elements/lisk-api-client/package-lock.json @@ -0,0 +1,4899 @@ +{ + "name": "@liskhq/lisk-api-client", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "@sinonjs/commons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", + "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", + "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "dev": true, + "requires": { + "@sinonjs/samsam": "^2 || ^3" + } + }, + "@sinonjs/samsam": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.1.0.tgz", + "integrity": "sha512-IXio+GWY+Q8XUjHUOgK7wx8fpvr7IFffgyXb1bnJFfX3001KmHt35Zq4tp7MXZyjJPCLPuadesDYNk41LYtVjw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash.get": "^4.4.2" + } + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-as-promised": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz", + "integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/sinon": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.5.tgz", + "integrity": "sha512-4DShbH857bZVOY4tPi1RQJNrLcf89hEtU0klZ9aYTMbtt95Ok4XdPqqcbtGOHIbAHMLSzQP8Uw/6qtBBqyloww==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "@types/verror": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.3.tgz", + "integrity": "sha512-7Jz0MPsW2pWg5dJfEp9nJYI0RDCYfgjg2wIo5HfQ8vOJvUq0/BxT7Mv2wNQvkKBmV9uT++6KF3reMnLmh/0HrA==" + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "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" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "axios": { + "version": "0.18.0", + "resolved": "http://registry.npmjs.org/axios/-/axios-0.18.0.tgz", + "integrity": "sha1-MtU+SFHv3AoRmTts0AB4nXDAUQI=", + "requires": { + "follow-redirects": "^1.3.0", + "is-buffer": "^1.1.5" + } + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "http://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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "http://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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha1-CGRdgl3rhpbuYXJdv1kMAS6wDKA=", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, + "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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.3.tgz", + "integrity": "sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "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": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "http://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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.0.tgz", + "integrity": "sha1-kc1BfRUqv4Wzexqz6/O9Jc3GToA=", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "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" + } + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "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-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 + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", + "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==", + "requires": { + "debug": "=3.1.0" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", + "dev": true + }, + "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.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", + "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=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha1-IwKlam/+9/mr6gFH2Dil6ba2p5s=", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=" + }, + "is-ci": { + "version": "1.0.10", + "resolved": "http://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "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 + } + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "lolex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.0.0.tgz", + "integrity": "sha512-hcnW80h3j2lbUfFdMArd5UPA/vxZJ+G8vobd+wg3nVEQA0EigStbYcrG030FJxL6xiDDPEkoMatV9xIh5OecQQ==", + "dev": true + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha1-bYrlCPWRZ/lA8rWzxKYSrlDJCuY=", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nise": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.1.0", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + } + } + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + } + } + }, + "ora": { + "version": "0.2.3", + "resolved": "http://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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "portfinder": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", + "integrity": "sha512-syFcRIRzVI1BoEFOCaAiizwDolh1S1YXSodsVhncbhjzjZQulhczNRbqnUl9N31Q4dKGOXsNDqxC2BWBgSMqeQ==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "sinon": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", + "integrity": "sha512-i6j7sqcLEqTYqUcMV327waI745VASvYuSuQMCjbAwlpAeuCgKZ3LtrjDxAbu+GjNQR0FEDpywtwGCIh8GicNyg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/samsam": "^3.0.2", + "diff": "^3.5.0", + "lolex": "^3.0.0", + "nise": "^1.4.8", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "sinon-chai": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.3.0.tgz", + "integrity": "sha512-r2JhDY7gbbmh5z3Q62pNbrjxZdOAjpsqW/8yxAZRSqLZqowmfGZPGUZPFf3UX36NLis0cv8VEM5IJh9HgkSOAA==", + "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 + }, + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "http://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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "supports-color": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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" + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha1-DBxPBwC+2NvBJM2zBNJZLKID5nc=", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha1-aWS8pnaF33wfFDDFhPB9dZeIW5w=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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 + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-api-client/package.json b/elements/lisk-api-client/package.json new file mode 100644 index 00000000000..7e1a73bed60 --- /dev/null +++ b/elements/lisk-api-client/package.json @@ -0,0 +1,93 @@ +{ + "name": "@liskhq/lisk-api-client", + "version": "2.0.0", + "description": "An API client for the Lisk network", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-api-client#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s liskAPIClient", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js ./browsertest.build/test/**/*.js -o ./browsertest.build/browsertest.js -s liskAPIClient", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/}/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11541 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11541) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11541 && cypress run --config baseUrl=http://localhost:11541 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@types/node": "10.12.21", + "@types/verror": "1.10.3", + "axios": "0.18.0", + "verror": "1.10.0" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/chai-as-promised": "7.1.0", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "@types/sinon": "7.0.5", + "@types/sinon-chai": "3.2.2", + "browserify": "16.2.3", + "chai": "4.2.0", + "chai-as-promised": "7.1.1", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "sinon": "7.2.3", + "sinon-chai": "3.3.0", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-api-client/scripts b/elements/lisk-api-client/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-api-client/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/src/api_client.ts b/elements/lisk-api-client/src/api_client.ts new file mode 100644 index 00000000000..f5075a21d66 --- /dev/null +++ b/elements/lisk-api-client/src/api_client.ts @@ -0,0 +1,188 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as os from 'os'; +import { HashMap, InitOptions } from './api_types'; +import * as constants from './constants'; +import { AccountsResource } from './resources/accounts'; +import { BlocksResource } from './resources/blocks'; +import { DappsResource } from './resources/dapps'; +import { DelegatesResource } from './resources/delegates'; +import { NodeResource } from './resources/node'; +import { PeersResource } from './resources/peers'; +import { SignaturesResource } from './resources/signatures'; +import { TransactionsResource } from './resources/transactions'; +import { VotersResource } from './resources/voters'; +import { VotesResource } from './resources/votes'; + +const defaultOptions = { + bannedNodes: [], + randomizeNodes: true, +}; + +const commonHeaders: HashMap = { + Accept: 'application/json', + 'Content-Type': 'application/json', +}; + +const getClientHeaders = (clientOptions: ClientOptions): HashMap => { + const { name = '????', version = '????', engine = '????' } = clientOptions; + + const liskElementsInformation = + 'LiskElements/1.0 (+https://github.com/LiskHQ/lisk-elements)'; + const locale: string | undefined = + process.env.LC_ALL || + process.env.LC_MESSAGES || + process.env.LANG || + process.env.LANGUAGE; + const systemInformation = `${os.platform()} ${os.release()}; ${os.arch()}${ + locale ? `; ${locale}` : '' + }`; + + return { + 'User-Agent': `${name}/${version} (${engine}) ${liskElementsInformation} ${systemInformation}`, + }; +}; + +export interface ClientOptions { + readonly engine?: string; + readonly name?: string; + readonly version?: string; +} + +export class APIClient { + public static get constants(): typeof constants { + return constants; + } + + public static createMainnetAPIClient(options?: InitOptions): APIClient { + return new APIClient(constants.MAINNET_NODES, { + nethash: constants.MAINNET_NETHASH, + ...options, + }); + } + + public static createTestnetAPIClient(options?: InitOptions): APIClient { + return new APIClient(constants.TESTNET_NODES, { + nethash: constants.TESTNET_NETHASH, + ...options, + }); + } + + public accounts: AccountsResource; + public bannedNodes!: ReadonlyArray; + public blocks: BlocksResource; + public currentNode!: string; + public dapps: DappsResource; + public delegates: DelegatesResource; + public headers!: HashMap; + public node: NodeResource; + public nodes!: ReadonlyArray; + public peers: PeersResource; + public randomizeNodes!: boolean; + public signatures: SignaturesResource; + public transactions: TransactionsResource; + public voters: VotersResource; + public votes: VotesResource; + + public constructor( + nodes: ReadonlyArray, + providedOptions: InitOptions = {}, + ) { + this.initialize(nodes, providedOptions); + this.accounts = new AccountsResource(this); + this.blocks = new BlocksResource(this); + this.dapps = new DappsResource(this); + this.delegates = new DelegatesResource(this); + this.node = new NodeResource(this); + this.peers = new PeersResource(this); + this.signatures = new SignaturesResource(this); + this.transactions = new TransactionsResource(this); + this.voters = new VotersResource(this); + this.votes = new VotesResource(this); + } + + public banActiveNode(): boolean { + return this.banNode(this.currentNode); + } + + public banActiveNodeAndSelect(): boolean { + const banned = this.banActiveNode(); + if (banned) { + this.currentNode = this.getNewNode(); + } + + return banned; + } + + public banNode(node: string): boolean { + if (!this.isBanned(node)) { + this.bannedNodes = [...this.bannedNodes, node]; + + return true; + } + + return false; + } + + public getNewNode(): string { + const nodes = this.nodes.filter( + (node: string): boolean => !this.isBanned(node), + ); + + if (nodes.length === 0) { + throw new Error('Cannot get new node: all nodes have been banned.'); + } + + const randomIndex = Math.floor(Math.random() * nodes.length); + + return nodes[randomIndex]; + } + + public hasAvailableNodes(): boolean { + return this.nodes.some((node: string): boolean => !this.isBanned(node)); + } + + public initialize( + nodes: ReadonlyArray, + providedOptions: InitOptions = {}, + ): void { + if (!Array.isArray(nodes) || nodes.length <= 0) { + throw new Error('APIClient requires nodes for initialization.'); + } + + if (typeof providedOptions !== 'object' || Array.isArray(providedOptions)) { + throw new Error( + 'APIClient takes an optional object as the second parameter.', + ); + } + + const options: InitOptions = { ...defaultOptions, ...providedOptions }; + + this.headers = { + ...commonHeaders, + ...(options.nethash ? { nethash: options.nethash } : {}), + ...(options.client ? getClientHeaders(options.client) : {}), + }; + + this.nodes = nodes; + this.bannedNodes = [...(options.bannedNodes || [])]; + this.currentNode = options.node || this.getNewNode(); + this.randomizeNodes = options.randomizeNodes !== false; + } + + public isBanned(node: string): boolean { + return this.bannedNodes.includes(node); + } +} diff --git a/elements/lisk-api-client/src/api_method.ts b/elements/lisk-api-client/src/api_method.ts new file mode 100644 index 00000000000..44bd4369208 --- /dev/null +++ b/elements/lisk-api-client/src/api_method.ts @@ -0,0 +1,97 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { AxiosRequestConfig } from 'axios'; +import { + APIHandler, + APIResponse, + HashMap, + RequestConfig, + Resource, +} from './api_types'; +import { GET } from './constants'; +import { solveURLParams, toQueryString } from './utils'; + +// Bind to resource class +export const apiMethod = (options: RequestConfig = {}): APIHandler => + async function apiHandler( + this: Resource, + // tslint:disable-next-line readonly-array + ...args: Array + ): Promise { + const { + method = GET, + path = '', + urlParams = [], + validator, + defaultData = {}, + retry = false, + } = options; + + if (urlParams.length > 0 && args.length < urlParams.length) { + return Promise.reject( + new Error( + `This endpoint must be supplied with the following parameters: ${urlParams.toString()}`, + ), + ); + } + + const data = { + ...defaultData, + ...(args.length > urlParams.length && + typeof args[urlParams.length] === 'object' + ? (args[urlParams.length] as object) + : {}), + }; + + if (validator) { + try { + validator(data); + } catch (err) { + return Promise.reject(err); + } + } + + const resolvedURLObject = urlParams.reduce( + // tslint:disable-next-line no-inferred-empty-object-type + (accumulator: HashMap, param: string, i: number): HashMap => { + const value = args[i]; + if (typeof value !== 'string' && typeof value !== 'number') { + throw new Error('Parameter must be a string or a number'); + } + + return { + ...accumulator, + [param]: typeof value === 'number' ? value.toString() : value, + }; + }, + {}, + ); + + const requestData: AxiosRequestConfig = { + headers: this.headers, + method, + url: solveURLParams(`${this.resourcePath}${path}`, resolvedURLObject), + }; + + if (Object.keys(data).length > 0) { + if (method === GET) { + requestData.url += `?${toQueryString(data)}`; + } else { + requestData.data = data; + } + } + + return this.request(requestData, retry); + }; diff --git a/elements/lisk-api-client/src/api_resource.ts b/elements/lisk-api-client/src/api_resource.ts new file mode 100644 index 00000000000..1e3200c4dc8 --- /dev/null +++ b/elements/lisk-api-client/src/api_resource.ts @@ -0,0 +1,103 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import Axios, { AxiosError, AxiosRequestConfig, AxiosResponse } from 'axios'; +import { APIClient } from './api_client'; +import { APIErrorResponse, APIResponse, HashMap } from './api_types'; +import { APIError } from './errors'; + +const API_RECONNECT_MAX_RETRY_COUNT = 3; + +const REQUEST_RETRY_TIMEOUT = 1000; + +export class APIResource { + public apiClient: APIClient; + public path: string; + + public constructor(apiClient: APIClient) { + this.apiClient = apiClient; + this.path = ''; + } + + public get headers(): HashMap { + return this.apiClient.headers; + } + + public get resourcePath(): string { + return `${this.apiClient.currentNode}/api${this.path}`; + } + + public async handleRetry( + error: Error, + req: AxiosRequestConfig, + retryCount: number, + ): Promise { + if (this.apiClient.hasAvailableNodes()) { + return new Promise(resolve => + setTimeout(resolve, REQUEST_RETRY_TIMEOUT), + ).then( + async (): Promise => { + if (retryCount > API_RECONNECT_MAX_RETRY_COUNT) { + throw error; + } + if (this.apiClient.randomizeNodes) { + this.apiClient.banActiveNodeAndSelect(); + } + + return this.request(req, true, retryCount + 1); + }, + ); + } + + return Promise.reject(error); + } + + public async request( + req: AxiosRequestConfig, + retry: boolean, + retryCount: number = 1, + ): Promise { + const request = Axios.request(req) + .then((res: AxiosResponse) => res.data) + .catch( + (error: AxiosError): void => { + if (error.response) { + const { status } = error.response; + if (error.response.data) { + const { + error: errorString, + errors, + message, + }: APIErrorResponse = error.response.data; + throw new APIError( + message || errorString || 'An unknown error has occurred.', + status, + errors, + ); + } + throw new APIError('An unknown error has occurred.', status); + } + throw error; + }, + ); + + if (retry) { + return request.catch(async (err: Error) => + this.handleRetry(err, req, retryCount), + ); + } + + return request; + } +} diff --git a/elements/lisk-api-client/src/api_types.ts b/elements/lisk-api-client/src/api_types.ts new file mode 100644 index 00000000000..694f3f070e1 --- /dev/null +++ b/elements/lisk-api-client/src/api_types.ts @@ -0,0 +1,64 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +/* tslint:disable no-mixed-interface */ +export type APIHandler = ( + // tslint:disable-next-line readonly-array + ...args: Array +) => Promise; + +export interface APIResponse { + readonly data: unknown; + readonly links: object; + readonly meta: object; +} + +export interface APIErrorResponse { + readonly error?: string; + readonly errors?: ReadonlyArray; + readonly message?: string; +} + +export interface APIErrorContents { + readonly code?: string; + readonly message?: string; +} + +export interface HashMap { + readonly [key: string]: string; +} + +export interface InitOptions { + readonly bannedNodes?: ReadonlyArray; + readonly client?: object; + readonly nethash?: string; + readonly node?: string; + readonly randomizeNodes?: boolean; +} + +export interface RequestConfig { + readonly defaultData?: object; + readonly method?: string; + readonly path?: string; + readonly retry?: boolean; + readonly urlParams?: ReadonlyArray; + readonly validator?: (data: { readonly needed?: string }) => void; +} + +export interface Resource { + readonly headers: HashMap; + readonly path: string; + readonly request: (data: object, retry: boolean) => Promise; + readonly resourcePath: string; +} diff --git a/elements/lisk-api-client/src/constants.ts b/elements/lisk-api-client/src/constants.ts new file mode 100644 index 00000000000..08d1c9970be --- /dev/null +++ b/elements/lisk-api-client/src/constants.ts @@ -0,0 +1,36 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export const GET = 'GET'; +export const POST = 'POST'; +export const PUT = 'PUT'; + +export const TESTNET_NETHASH = + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba'; +export const MAINNET_NETHASH = + 'ed14889723f24ecc54871d058d98ce91ff2f973192075c0155ba2b7b70ad2511'; + +export const TESTNET_NODES: ReadonlyArray = [ + 'https://testnet.lisk.io:443', +]; +export const MAINNET_NODES: ReadonlyArray = [ + 'https://node01.lisk.io:443', + 'https://node02.lisk.io:443', + 'https://node03.lisk.io:443', + 'https://node04.lisk.io:443', + 'https://node05.lisk.io:443', + 'https://node06.lisk.io:443', + 'https://node07.lisk.io:443', + 'https://node08.lisk.io:443', +]; diff --git a/elements/lisk-api-client/src/errors.ts b/elements/lisk-api-client/src/errors.ts new file mode 100644 index 00000000000..032871787ca --- /dev/null +++ b/elements/lisk-api-client/src/errors.ts @@ -0,0 +1,24 @@ +import { VError } from 'verror'; + +const defaultErrorNo = 500; + +export interface APIErrorData { + readonly code?: string; + readonly message?: string; +} + +export class APIError extends VError { + public errno: number; + public errors?: ReadonlyArray; + + public constructor( + message: string = '', + errno: number = defaultErrorNo, + errors?: ReadonlyArray, + ) { + super(message); + this.name = 'APIError'; + this.errno = errno; + this.errors = errors; + } +} diff --git a/elements/lisk-api-client/src/index.ts b/elements/lisk-api-client/src/index.ts new file mode 100644 index 00000000000..d962093e3ad --- /dev/null +++ b/elements/lisk-api-client/src/index.ts @@ -0,0 +1,15 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export * from './api_client'; diff --git a/elements/lisk-api-client/src/resources/accounts.ts b/elements/lisk-api-client/src/resources/accounts.ts new file mode 100644 index 00000000000..60c84dacf47 --- /dev/null +++ b/elements/lisk-api-client/src/resources/accounts.ts @@ -0,0 +1,47 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET } from '../constants'; + +export class AccountsResource extends APIResource { + public get: APIHandler; + public getMultisignatureGroups: APIHandler; + public getMultisignatureMemberships: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/accounts'; + + this.get = apiMethod({ + method: GET, + }).bind(this); + + this.getMultisignatureGroups = apiMethod({ + method: GET, + path: '/{address}/multisignature_groups', + urlParams: ['address'], + }).bind(this); + + this.getMultisignatureMemberships = apiMethod({ + method: GET, + path: '/{address}/multisignature_memberships', + urlParams: ['address'], + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/blocks.ts b/elements/lisk-api-client/src/resources/blocks.ts new file mode 100644 index 00000000000..8fa2c88cd97 --- /dev/null +++ b/elements/lisk-api-client/src/resources/blocks.ts @@ -0,0 +1,33 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET } from '../constants'; + +export class BlocksResource extends APIResource { + public get: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/blocks'; + + this.get = apiMethod({ + method: GET, + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/dapps.ts b/elements/lisk-api-client/src/resources/dapps.ts new file mode 100644 index 00000000000..378ac32a31d --- /dev/null +++ b/elements/lisk-api-client/src/resources/dapps.ts @@ -0,0 +1,33 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET } from '../constants'; + +export class DappsResource extends APIResource { + public get: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/dapps'; + + this.get = apiMethod({ + method: GET, + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/delegates.ts b/elements/lisk-api-client/src/resources/delegates.ts new file mode 100644 index 00000000000..53a2710bf3d --- /dev/null +++ b/elements/lisk-api-client/src/resources/delegates.ts @@ -0,0 +1,58 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET } from '../constants'; + +export class DelegatesResource extends APIResource { + public get: APIHandler; + public getForgers: APIHandler; + public getForgingStatistics: APIHandler; + public getStandby: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/delegates'; + + this.get = apiMethod({ + defaultData: { + sort: 'rank:asc', + }, + method: GET, + }).bind(this); + + this.getStandby = apiMethod({ + defaultData: { + offset: 101, + sort: 'rank:asc', + }, + method: GET, + }).bind(this); + + this.getForgers = apiMethod({ + method: GET, + path: '/forgers', + }).bind(this); + + this.getForgingStatistics = apiMethod({ + method: GET, + path: '/{address}/forging_statistics', + urlParams: ['address'], + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/index.ts b/elements/lisk-api-client/src/resources/index.ts new file mode 100644 index 00000000000..565a7cd2992 --- /dev/null +++ b/elements/lisk-api-client/src/resources/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export { AccountsResource } from './accounts'; +export { BlocksResource } from './blocks'; +export { DappsResource } from './dapps'; +export { DelegatesResource } from './delegates'; +export { NodeResource } from './node'; +export { PeersResource } from './peers'; +export { SignaturesResource } from './signatures'; +export { TransactionsResource } from './transactions'; +export { VotersResource } from './voters'; +export { VotesResource } from './votes'; diff --git a/elements/lisk-api-client/src/resources/node.ts b/elements/lisk-api-client/src/resources/node.ts new file mode 100644 index 00000000000..63ae70dbc9c --- /dev/null +++ b/elements/lisk-api-client/src/resources/node.ts @@ -0,0 +1,59 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET, PUT } from '../constants'; + +export class NodeResource extends APIResource { + public getConstants: APIHandler; + public getForgingStatus: APIHandler; + public getStatus: APIHandler; + public getTransactions: APIHandler; + public path: string; + public updateForgingStatus: APIHandler; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/node'; + + this.getConstants = apiMethod({ + method: GET, + path: '/constants', + }).bind(this); + + this.getStatus = apiMethod({ + method: GET, + path: '/status', + }).bind(this); + + this.getForgingStatus = apiMethod({ + method: GET, + path: '/status/forging', + }).bind(this); + + this.updateForgingStatus = apiMethod({ + method: PUT, + path: '/status/forging', + }).bind(this); + + this.getTransactions = apiMethod({ + method: GET, + path: '/transactions/{state}', + urlParams: ['state'], + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/peers.ts b/elements/lisk-api-client/src/resources/peers.ts new file mode 100644 index 00000000000..1c66084b451 --- /dev/null +++ b/elements/lisk-api-client/src/resources/peers.ts @@ -0,0 +1,33 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET } from '../constants'; + +export class PeersResource extends APIResource { + public get: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/peers'; + + this.get = apiMethod({ + method: GET, + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/signatures.ts b/elements/lisk-api-client/src/resources/signatures.ts new file mode 100644 index 00000000000..5493f2962f3 --- /dev/null +++ b/elements/lisk-api-client/src/resources/signatures.ts @@ -0,0 +1,33 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { POST } from '../constants'; + +export class SignaturesResource extends APIResource { + public broadcast: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/signatures'; + + this.broadcast = apiMethod({ + method: POST, + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/transactions.ts b/elements/lisk-api-client/src/resources/transactions.ts new file mode 100644 index 00000000000..96cce6f84c8 --- /dev/null +++ b/elements/lisk-api-client/src/resources/transactions.ts @@ -0,0 +1,37 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET, POST } from '../constants'; + +export class TransactionsResource extends APIResource { + public broadcast: APIHandler; + public get: APIHandler; + public path: string; + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/transactions'; + + this.get = apiMethod({ + method: GET, + }).bind(this); + + this.broadcast = apiMethod({ + method: POST, + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/voters.ts b/elements/lisk-api-client/src/resources/voters.ts new file mode 100644 index 00000000000..6f355cd5e8b --- /dev/null +++ b/elements/lisk-api-client/src/resources/voters.ts @@ -0,0 +1,33 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET } from '../constants'; + +export class VotersResource extends APIResource { + public get: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/voters'; + + this.get = apiMethod({ + method: GET, + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/resources/votes.ts b/elements/lisk-api-client/src/resources/votes.ts new file mode 100644 index 00000000000..bc102fb9d9e --- /dev/null +++ b/elements/lisk-api-client/src/resources/votes.ts @@ -0,0 +1,32 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../api_client'; +import { apiMethod } from '../api_method'; +import { APIResource } from '../api_resource'; +import { APIHandler } from '../api_types'; +import { GET } from '../constants'; + +export class VotesResource extends APIResource { + public get: APIHandler; + public path: string; + + public constructor(apiClient: APIClient) { + super(apiClient); + this.path = '/votes'; + this.get = apiMethod({ + method: GET, + }).bind(this); + } +} diff --git a/elements/lisk-api-client/src/utils.ts b/elements/lisk-api-client/src/utils.ts new file mode 100644 index 00000000000..6fccaf220c3 --- /dev/null +++ b/elements/lisk-api-client/src/utils.ts @@ -0,0 +1,52 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { HashMap } from './api_types'; + +export const toQueryString = (obj: HashMap): string => { + const parts = Object.keys(obj).reduce( + ( + accumulator: ReadonlyArray, + key: string, + ): ReadonlyArray => [ + ...accumulator, + `${encodeURIComponent(key)}=${encodeURIComponent(obj[key])}`, + ], + [], + ); + + return parts.join('&'); +}; + +const urlParamRegex = /{[^}]+}/; +export const solveURLParams = (url: string, params: HashMap = {}): string => { + if (Object.keys(params).length === 0) { + if (url.match(urlParamRegex) !== null) { + throw new Error('URL is not completely solved'); + } + + return url; + } + const solvedURL = Object.keys(params).reduce( + (accumulator: string, key: string): string => + accumulator.replace(`{${key}}`, params[key]), + url, + ); + + if (solvedURL.match(urlParamRegex) !== null) { + throw new Error('URL is not completely solved'); + } + + return encodeURI(solvedURL); +}; diff --git a/elements/lisk-api-client/test/_global_hooks.ts b/elements/lisk-api-client/test/_global_hooks.ts new file mode 100644 index 00000000000..230fac15eac --- /dev/null +++ b/elements/lisk-api-client/test/_global_hooks.ts @@ -0,0 +1,17 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +afterEach(() => { + return sandbox.restore(); +}); diff --git a/elements/lisk-api-client/test/_setup.ts b/elements/lisk-api-client/test/_setup.ts new file mode 100644 index 00000000000..cf1ed383615 --- /dev/null +++ b/elements/lisk-api-client/test/_setup.ts @@ -0,0 +1,27 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as chai from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import 'chai/register-expect'; +import * as sinonChai from 'sinon-chai'; +import * as sinon from 'sinon'; + +process.env.NODE_ENV = 'test'; + +[sinonChai, chaiAsPromised].forEach(plugin => chai.use(plugin)); + +global.sandbox = sinon.createSandbox({ + useFakeTimers: true, +}); diff --git a/elements/lisk-api-client/test/api_client.ts b/elements/lisk-api-client/test/api_client.ts new file mode 100644 index 00000000000..91008bcc2be --- /dev/null +++ b/elements/lisk-api-client/test/api_client.ts @@ -0,0 +1,407 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as os from 'os'; +import { APIClient } from '../src/api_client'; + +describe('APIClient module', () => { + const mainnetHash = + 'ed14889723f24ecc54871d058d98ce91ff2f973192075c0155ba2b7b70ad2511'; + const mainnetNodes: ReadonlyArray = [ + 'https://node01.lisk.io:443', + 'https://node02.lisk.io:443', + 'https://node03.lisk.io:443', + 'https://node04.lisk.io:443', + 'https://node05.lisk.io:443', + 'https://node06.lisk.io:443', + 'https://node07.lisk.io:443', + 'https://node08.lisk.io:443', + ]; + const testnetHash = + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba'; + const testnetNodes: ReadonlyArray = ['https://testnet.lisk.io:443']; + const locale = + process.env.LC_ALL || + process.env.LC_MESSAGES || + process.env.LANG || + process.env.LANGUAGE; + const platformInfo = `${os.platform()} ${os.release()}; ${os.arch()}${ + locale ? `; ${locale}` : '' + }`; + const baseUserAgent = `LiskElements/1.0 (+https://github.com/LiskHQ/lisk-elements) ${platformInfo}`; + const customUserAgent = `LiskHub/5.0 (+https://github.com/LiskHQ/lisk-hub) ${baseUserAgent}`; + const defaultHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json', + }; + + const customHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json', + 'User-Agent': customUserAgent, + nethash: testnetHash, + }; + + const localNode = 'http://localhost:7000'; + const externalNode = 'https://googIe.com:8080'; + const sslNode = 'https://external.lisk.io:443'; + const externalTestnetNode = 'http://testnet.lisk.io'; + const defaultNodes: ReadonlyArray = [ + localNode, + externalNode, + sslNode, + ]; + const defaultSelectedNode = 'selected_node'; + + let apiClient: APIClient; + + beforeEach(() => { + apiClient = new APIClient(defaultNodes); + return Promise.resolve(); + }); + + describe('#constructor', () => { + let initializeStub: () => void; + + beforeEach(() => { + initializeStub = sandbox.stub(APIClient.prototype, 'initialize'); + return Promise.resolve(); + }); + + it('should create a new instance of APIClient', () => { + return expect(apiClient) + .to.be.an('object') + .and.be.instanceof(APIClient); + }); + + it('should call initialize with the nodes and default options', () => { + apiClient = new APIClient(defaultNodes); + return expect(initializeStub).to.be.calledWithExactly(defaultNodes, {}); + }); + + it('should call initialize with the nodes and provided options', () => { + const providedOptions = { + nethash: + '0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef', + }; + apiClient = new APIClient(defaultNodes, providedOptions); + return expect(initializeStub).to.be.calledWithExactly( + defaultNodes, + providedOptions, + ); + }); + }); + + describe('#createMainnetAPIClient', () => { + let client: APIClient; + beforeEach(() => { + client = APIClient.createMainnetAPIClient(); + return Promise.resolve(); + }); + + it('should return APIClient instance', () => { + return expect(client).to.be.instanceof(APIClient); + }); + + it('should contain mainnet nodes', () => { + return expect(client.nodes).to.eql(mainnetNodes); + }); + + it('should be set to mainnet hash', () => { + return expect(client.headers.nethash).to.equal(mainnetHash); + }); + }); + + describe('#createTestnetAPIClient', () => { + let client: APIClient; + beforeEach(() => { + client = APIClient.createTestnetAPIClient(); + return Promise.resolve(); + }); + + it('should return APIClient instance', () => { + return expect(client).to.be.instanceof(APIClient); + }); + + it('should contain testnet nodes', () => { + return expect(client.nodes).to.eql(testnetNodes); + }); + + it('should be set to testnet hash', () => { + return expect(client.headers.nethash).to.equal(testnetHash); + }); + }); + + describe('#constants', () => { + it('should expose API constants', () => { + return expect(APIClient.constants).to.be.an('object'); + }); + }); + + describe('#initialize', () => { + it('should throw an error if no arguments are passed to constructor', () => { + return expect(apiClient.initialize.bind(apiClient)).to.throw( + Error, + 'APIClient requires nodes for initialization.', + ); + }); + + it('should throw an error if first argument passed to constructor is not array', () => { + return expect( + apiClient.initialize.bind(apiClient, 'non-array' as any), + ).to.throw(Error, 'APIClient requires nodes for initialization.'); + }); + + it('should throw an error if first argument passed to constructor is empty array', () => { + return expect(apiClient.initialize.bind(apiClient, [])).to.throw( + Error, + 'APIClient requires nodes for initialization.', + ); + }); + + it('should throw an error if second argument passed to constructor is a string', () => { + return expect( + apiClient.initialize.bind( + apiClient, + defaultNodes, + 'option string' as any, + ), + ).to.throw( + Error, + 'APIClient takes an optional object as the second parameter.', + ); + }); + + it('should throw an error if second argument passed to constructor is an array', () => { + return expect( + apiClient.initialize.bind(apiClient, defaultNodes, [] as any), + ).to.throw( + Error, + 'APIClient takes an optional object as the second parameter.', + ); + }); + + describe('headers', () => { + it('should set with passed nethash, with default options', () => { + return expect(apiClient) + .to.have.property('headers') + .and.eql(defaultHeaders); + }); + + it('should set custom headers with supplied options', () => { + apiClient = new APIClient(defaultNodes, { + nethash: testnetHash, + client: { + name: 'LiskHub', + version: '5.0', + engine: '+https://github.com/LiskHQ/lisk-hub', + }, + }); + return expect(apiClient) + .to.have.property('headers') + .and.eql(customHeaders); + }); + + it('should not set User-Agent header when client options were not given', () => { + apiClient = new APIClient(defaultNodes, { + nethash: testnetHash, + }); + return expect(apiClient.headers).to.not.have.property('User-Agent'); + }); + }); + + describe('nodes', () => { + it('should have nodes supplied to constructor', () => { + return expect(apiClient) + .to.have.property('nodes') + .and.equal(defaultNodes); + }); + }); + + describe('bannedNodes', () => { + it('should set empty array if no option is passed', () => { + return expect(apiClient) + .to.have.property('bannedNodes') + .be.eql([]); + }); + + it('should set bannedNodes when passed as an option', () => { + const bannedNodes = ['a', 'b']; + apiClient = new APIClient(defaultNodes, { bannedNodes }); + return expect(apiClient) + .to.have.property('bannedNodes') + .be.eql(bannedNodes); + }); + }); + + describe('currentNode', () => { + it('should set with random node with initialized setup if no node is specified by options', () => { + return expect(apiClient).to.have.property('currentNode').and.not.be + .empty; + }); + + it('should set with supplied node if node is specified by options', () => { + apiClient = new APIClient(defaultNodes, { + node: externalTestnetNode, + }); + return expect(apiClient) + .to.have.property('currentNode') + .and.equal(externalTestnetNode); + }); + }); + + describe('randomizeNodes', () => { + it('should set randomizeNodes to true when randomizeNodes not explicitly set', () => { + apiClient = new APIClient(defaultNodes, { + randomizeNodes: undefined, + }); + return expect(apiClient).to.have.property('randomizeNodes').be.true; + }); + + it('should set randomizeNodes to true on initialization when passed as an option', () => { + apiClient = new APIClient(defaultNodes, { + randomizeNodes: true, + }); + return expect(apiClient).to.have.property('randomizeNodes').be.true; + }); + + it('should set randomizeNodes to false on initialization when passed as an option', () => { + apiClient = new APIClient(defaultNodes, { + randomizeNodes: false, + }); + return expect(apiClient).to.have.property('randomizeNodes').be.false; + }); + }); + }); + + describe('#getNewNode', () => { + it('should throw an error if all relevant nodes are banned', () => { + apiClient.bannedNodes = [...defaultNodes]; + return expect(apiClient.getNewNode.bind(apiClient)).to.throw( + 'Cannot get new node: all nodes have been banned.', + ); + }); + + it('should return a node', () => { + const result = apiClient.getNewNode(); + return expect(defaultNodes).to.contain(result); + }); + + it('should randomly select the node', () => { + const firstResult = apiClient.getNewNode(); + let nextResult = apiClient.getNewNode(); + // Test will almost certainly time out if not random + while (nextResult === firstResult) { + nextResult = apiClient.getNewNode(); + } + return Promise.resolve(); + }); + }); + + describe('#banNode', () => { + it('should add node to banned nodes', () => { + const banned = apiClient.banNode(localNode); + expect(banned).to.be.true; + return expect(apiClient.isBanned(localNode)).to.be.true; + }); + + it('should not duplicate a banned node', () => { + const bannedNodes = [localNode]; + apiClient.bannedNodes = bannedNodes; + const banned = apiClient.banNode(localNode); + + expect(banned).to.be.false; + return expect(apiClient.bannedNodes).to.be.eql(bannedNodes); + }); + }); + + describe('#banActiveNode', () => { + let currentNode: string; + + beforeEach(() => { + ({ currentNode } = apiClient); + return Promise.resolve(); + }); + + it('should add current node to banned nodes', () => { + const banned = apiClient.banActiveNode(); + expect(banned).to.be.true; + return expect(apiClient.isBanned(currentNode)).to.be.true; + }); + + it('should not duplicate a banned node', () => { + const bannedNodes = [currentNode]; + apiClient.bannedNodes = bannedNodes; + const banned = apiClient.banActiveNode(); + + expect(banned).to.be.false; + return expect(apiClient.bannedNodes).to.be.eql(bannedNodes); + }); + }); + + describe('#banActiveNodeAndSelect', () => { + let currentNode: string; + let getNewNodeStub: () => string; + + beforeEach(() => { + ({ currentNode } = apiClient); + getNewNodeStub = sandbox + .stub(apiClient, 'getNewNode') + .returns(defaultSelectedNode); + return Promise.resolve(); + }); + + it('should call ban current node', () => { + apiClient.banActiveNodeAndSelect(); + return expect(apiClient.isBanned(currentNode)).to.be.true; + }); + + it('should call selectNewNode when the node is banned', () => { + apiClient.banActiveNodeAndSelect(); + return expect(getNewNodeStub).to.be.calledOnce; + }); + + it('should not call selectNewNode when the node is not banned', () => { + const bannedNodes = [currentNode]; + apiClient.bannedNodes = bannedNodes; + apiClient.banActiveNodeAndSelect(); + return expect(getNewNodeStub).not.to.be.called; + }); + }); + + describe('#isBanned', () => { + it('should return true when provided node is banned', () => { + apiClient.bannedNodes = [...apiClient.bannedNodes, localNode]; + return expect(apiClient.isBanned(localNode)).to.be.true; + }); + + it('should return false when provided node is not banned', () => { + return expect(apiClient.isBanned(localNode)).to.be.false; + }); + }); + + describe('#hasAvailableNodes', () => { + it('should return false without nodes left', () => { + apiClient.bannedNodes = [...defaultNodes]; + const result = apiClient.hasAvailableNodes(); + return expect(result).to.be.false; + }); + + it('should return true if nodes are available', () => { + const result = apiClient.hasAvailableNodes(); + return expect(result).to.be.true; + }); + }); +}); diff --git a/elements/lisk-api-client/test/api_method.ts b/elements/lisk-api-client/test/api_method.ts new file mode 100644 index 00000000000..3d901b4af27 --- /dev/null +++ b/elements/lisk-api-client/test/api_method.ts @@ -0,0 +1,206 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { apiMethod } from '../src/api_method'; +import { Resource, APIHandler } from '../src/api_types'; + +describe('API method module', () => { + const GET = 'GET'; + const POST = 'POST'; + const defaultBasePath = 'http://localhost:1234/api'; + const defaultResourcePath = '/resources'; + const defaultFullPath = `${defaultBasePath}${defaultResourcePath}`; + const defaultHeaders = { + 'Content-Type': 'application/json', + nethash: 'mainnetHash', + os: 'lisk-elements-api', + version: '1.0.0', + minVersion: '>=0.5.0', + port: '443', + }; + const errorArgumentNumber = + 'This endpoint must be supplied with the following parameters: related,id'; + const firstURLParam = 'r-123'; + const secondURLParam = 123; + let resource: Resource; + let requestResult: object; + let handler: APIHandler; + let validationError: Error; + + beforeEach(() => { + requestResult = { success: true, sendRequest: true }; + resource = { + path: defaultResourcePath, + resourcePath: defaultFullPath, + headers: defaultHeaders, + request: sandbox.stub().resolves(requestResult), + }; + validationError = new Error('No data'); + return Promise.resolve(); + }); + + describe('#apiMethod', () => { + describe('when no parameters are passed', () => { + beforeEach(() => { + handler = apiMethod().bind(resource); + + return Promise.resolve(); + }); + + it('should return function', () => { + return expect(handler).to.be.a('function'); + }); + + it('should request GET with default URL', () => { + return handler().then(() => { + expect(resource.request).to.be.calledOnce; + return expect(resource.request).to.be.calledWithExactly( + { + method: GET, + url: defaultFullPath, + headers: defaultHeaders, + }, + false, + ); + }); + }); + }); + + describe('when initialized with POST / parameters', () => { + const parameterStringError = 'Parameter must be a string or a number'; + + beforeEach(() => { + handler = apiMethod({ + method: POST, + path: '/{related}/ids/{id}', + urlParams: ['related', 'id'], + validator: data => { + if (!data.needed) { + throw validationError; + } + }, + defaultData: { + sort: 'id', + }, + retry: true, + }).bind(resource); + return Promise.resolve(); + }); + + it('should return function', () => { + return expect(handler).to.be.a('function'); + }); + + it('should be rejected with error without param', () => { + return expect(handler()).to.be.rejectedWith(Error, errorArgumentNumber); + }); + + it('should be rejected with error without enough param', () => { + return expect(handler(firstURLParam)).to.be.rejectedWith( + Error, + errorArgumentNumber, + ); + }); + + it('should throw an error if input is not a string or a number', () => { + return expect( + handler({ num: 3 }, secondURLParam, { needed: true }), + ).to.be.rejectedWith(Error, parameterStringError); + }); + + it('should be rejected with no data', () => { + return expect( + handler(firstURLParam, secondURLParam), + ).to.be.rejectedWith(validationError); + }); + + it('should call request with the given data', () => { + return handler(firstURLParam, secondURLParam, { needed: true }).then( + () => { + expect(resource.request).to.be.calledOnce; + return expect(resource.request).to.be.calledWithExactly( + { + method: POST, + url: `${defaultFullPath}/${firstURLParam}/ids/${secondURLParam}`, + headers: defaultHeaders, + data: { + needed: true, + sort: 'id', + }, + }, + true, + ); + }, + ); + }); + }); + + describe('when initialized with GET / parameters', () => { + beforeEach(() => { + handler = apiMethod({ + method: GET, + path: '/{related}/ids/{id}', + urlParams: ['related', 'id'], + validator: data => { + if (!data.needed) { + throw validationError; + } + }, + defaultData: { + sort: 'id', + }, + }).bind(resource); + return Promise.resolve(); + }); + + it('should return a function', () => { + return expect(handler).to.be.a('function'); + }); + + it('should be rejected with error without parameters', () => { + return expect(handler()).to.be.rejectedWith(Error, errorArgumentNumber); + }); + + it('should be rejected with error without enough parameters', () => { + return expect(handler(firstURLParam)).to.be.rejectedWith( + Error, + errorArgumentNumber, + ); + }); + + it('should be rejected with no data', () => { + return expect( + handler(firstURLParam, secondURLParam), + ).to.be.rejectedWith(validationError); + }); + + it('should be request with the given data', () => { + return handler(firstURLParam, secondURLParam, { needed: true }).then( + () => { + expect(resource.request).to.be.calledOnce; + return expect(resource.request).to.be.calledWithExactly( + { + method: GET, + url: `${defaultFullPath}/${firstURLParam}/ids/${secondURLParam}?sort=id&needed=true`, + headers: defaultHeaders, + }, + false, + ); + }, + ); + }); + }); + }); +}); diff --git a/elements/lisk-api-client/test/api_resource.ts b/elements/lisk-api-client/test/api_resource.ts new file mode 100644 index 00000000000..040da939f18 --- /dev/null +++ b/elements/lisk-api-client/test/api_resource.ts @@ -0,0 +1,315 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../src/api_client'; +import { APIResource } from '../src/api_resource'; +import * as sinon from 'sinon'; +// Required for stub +const axios = require('axios'); + +describe('API resource module', () => { + const GET = 'GET'; + const defaultBasePath = 'http://localhost:1234'; + const defaultResourcePath = '/resources'; + const defaultFullPath = `${defaultBasePath}/api${defaultResourcePath}`; + const defaultHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json', + nethash: 'mainnetHash', + os: 'lisk-elements-api', + version: '1.0.0', + minVersion: '>=0.5.0', + port: '443', + }; + const defaultRequest = { + method: GET, + url: defaultFullPath, + headers: defaultHeaders, + }; + + const sendRequestResult = { + data: [], + body: {}, + limit: 0, + }; + + interface FakeAPIClient { + headers: object; + currentNode: string; + hasAvailableNodes: () => boolean | void; + randomizeNodes: boolean; + banActiveNodeAndSelect: () => void; + } + + let resource: APIResource; + let apiClient: FakeAPIClient; + + beforeEach(() => { + apiClient = { + headers: { ...defaultHeaders }, + currentNode: defaultBasePath, + hasAvailableNodes: () => true, + randomizeNodes: false, + banActiveNodeAndSelect: sandbox.stub(), + }; + resource = new APIResource(apiClient as APIClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should create an API resource instance', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + }); + + describe('get headers', () => { + it('should return header set to apiClient', () => { + return expect(resource.headers).to.eql(defaultHeaders); + }); + }); + + describe('get resourcePath', () => { + it('should return the resource’s full path', () => { + return expect(resource.resourcePath).to.equal(`${defaultBasePath}/api`); + }); + + it('should return the resource’s full path with set path', () => { + resource.path = defaultResourcePath; + return expect(resource.resourcePath).to.equal( + `${defaultBasePath}/api${defaultResourcePath}`, + ); + }); + }); + + describe('#request', () => { + let requestStub: sinon.SinonStub; + let handleRetryStub: () => Promise; + + beforeEach(() => { + requestStub = sandbox.stub(axios, 'request').resolves({ + status: 200, + data: sendRequestResult, + } as any); + handleRetryStub = sandbox.stub(resource, 'handleRetry'); + return Promise.resolve(); + }); + + it('should make a request to API without calling retry', () => { + return resource.request(defaultRequest, false).then(res => { + expect(requestStub).to.be.calledOnce; + expect(requestStub).to.be.calledWithExactly(defaultRequest); + expect(handleRetryStub).not.to.be.called; + return expect(res).to.eql(sendRequestResult); + }); + }); + + it('should make a request to API without calling retry when it succeeds', () => { + return resource.request(defaultRequest, true).then(res => { + expect(requestStub).to.be.calledOnce; + expect(requestStub).to.be.calledWithExactly(defaultRequest); + expect(handleRetryStub).not.to.be.called; + return expect(res).to.eql(sendRequestResult); + }); + }); + + describe('when response status is greater than 300', () => { + it('should reject with errno if status code is supplied', () => { + const statusCode = 300; + requestStub.rejects({ + response: { + status: statusCode, + data: undefined, + }, + }); + + return resource.request(defaultRequest, false).catch(err => { + return expect(err.errno).to.equal(statusCode); + }); + }); + + it('should reject with "An unknown error has occured." message if there is no data is supplied', () => { + const statusCode = 300; + requestStub.rejects({ + response: { + status: statusCode, + data: undefined, + }, + }); + + return resource.request(defaultRequest, false).catch(err => { + return expect(err.message).to.equal('An unknown error has occurred.'); + }); + }); + + it('should reject with "An unknown error has occured." message if there is no message is supplied', () => { + const statusCode = 300; + requestStub.rejects({ + response: { + status: statusCode, + data: sendRequestResult, + }, + }); + + return resource.request(defaultRequest, false).catch(err => { + return expect(err.message).to.equal('An unknown error has occurred.'); + }); + }); + + it('should reject with error message from server if message is supplied', () => { + const serverErrorMessage = 'validation error'; + const statusCode = 300; + requestStub.rejects({ + response: { + status: statusCode, + data: { message: serverErrorMessage }, + }, + }); + + return resource.request(defaultRequest, false).catch(err => { + return expect(err.message).to.eql(serverErrorMessage); + }); + }); + + it('should reject with error message from server if message is undefined and error is supplied', () => { + const serverErrorMessage = 'error from server'; + const statusCode = 300; + requestStub.rejects({ + response: { + status: statusCode, + data: { message: undefined, error: serverErrorMessage }, + }, + }); + + return resource.request(defaultRequest, false).catch(err => { + return expect(err.message).to.eql(serverErrorMessage); + }); + }); + + it('should reject with errors from server if errors are supplied', () => { + const serverErrorMessage = 'validation error'; + const statusCode = 300; + const errors = [ + { + code: 'error_code_1', + message: 'message1', + }, + { + code: 'error_code_2', + message: 'message2', + }, + ]; + requestStub.rejects({ + response: { + status: statusCode, + data: { message: serverErrorMessage, errors }, + }, + }); + + return resource.request(defaultRequest, false).catch(err => { + return expect(err.errors).to.eql(errors); + }); + }); + + it('should reject with error if client rejects with plain error', () => { + const clientError = new Error('client error'); + requestStub.rejects(clientError); + return resource.request(defaultRequest, false).catch(err => { + return expect(err).to.eql(clientError); + }); + }); + + it('should make a request to API with calling retry', () => { + const statusCode = 300; + requestStub.rejects({ + response: { + status: statusCode, + data: sendRequestResult, + }, + }); + return resource.request(defaultRequest, true).catch(() => { + expect(requestStub).to.be.calledOnce; + return expect(handleRetryStub).to.be.calledOnce; + }); + }); + }); + }); + + describe('#handleRetry', () => { + let requestStub: sinon.SinonStub; + let defaultError: Error; + beforeEach(() => { + defaultError = new Error('could not connect to a node'); + requestStub = sandbox + .stub(resource, 'request') + .returns(Promise.resolve(sendRequestResult.body) as any); + return Promise.resolve(); + }); + + describe('when there is available node', () => { + let clock: sinon.SinonFakeTimers; + + beforeEach(() => { + clock = sinon.useFakeTimers(); + apiClient.hasAvailableNodes = () => true; + return Promise.resolve(); + }); + + afterEach(() => { + return clock.restore(); + }); + + it('should call banActiveNode when randomizeNodes is true', () => { + apiClient.randomizeNodes = true; + const req = resource.handleRetry(defaultError, defaultRequest, 1); + clock.tick(1000); + return req.then(res => { + expect(apiClient.banActiveNodeAndSelect).to.be.calledOnce; + expect(requestStub).to.be.calledWith(defaultRequest, true); + return expect(res).to.be.eql(sendRequestResult.body); + }); + }); + + it('should not call ban active node when randomizeNodes is false', () => { + apiClient.randomizeNodes = false; + const req = resource.handleRetry(defaultError, defaultRequest, 1); + clock.tick(1000); + return req.then(res => { + expect(apiClient.banActiveNodeAndSelect).not.to.be.called; + expect(requestStub).to.be.calledWith(defaultRequest, true); + return expect(res).to.be.eql(sendRequestResult.body); + }); + }); + + it('should throw an error when randomizeNodes is false and the maximum retry count has been reached', () => { + apiClient.randomizeNodes = false; + const req = resource.handleRetry(defaultError, defaultRequest, 4); + clock.tick(1000); + return expect(req).to.be.rejectedWith(defaultError); + }); + }); + + describe('when there is no available node', () => { + beforeEach(() => { + apiClient.hasAvailableNodes = () => false; + return Promise.resolve(); + }); + + it('should throw an error that is the same as input error', () => { + const res = resource.handleRetry(defaultError, defaultRequest, 1); + return expect(res).to.be.rejectedWith(defaultError); + }); + }); + }); +}); diff --git a/elements/lisk-api-client/test/constants.ts b/elements/lisk-api-client/test/constants.ts new file mode 100644 index 00000000000..75ef380a99b --- /dev/null +++ b/elements/lisk-api-client/test/constants.ts @@ -0,0 +1,40 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { GET, POST, PUT, TESTNET_NODES, MAINNET_NODES } from '../src/constants'; + +describe('api constants module', () => { + it('GET should be a string', () => { + return expect(GET).to.be.a('string'); + }); + + it('POST should be a string', () => { + return expect(POST).to.be.a('string'); + }); + + it('PUT should be a string', () => { + return expect(PUT).to.be.a('string'); + }); + + it('TESTNET_NODES should be an array of strings', () => { + expect(TESTNET_NODES).to.be.an('array'); + return TESTNET_NODES.forEach(node => expect(node).to.be.a('string')); + }); + + it('MAINNET_NODES should be an array of strings', () => { + expect(MAINNET_NODES).to.be.an('array'); + return MAINNET_NODES.forEach(node => expect(node).to.be.a('string')); + }); +}); diff --git a/elements/lisk-api-client/test/errors.ts b/elements/lisk-api-client/test/errors.ts new file mode 100644 index 00000000000..51382672e13 --- /dev/null +++ b/elements/lisk-api-client/test/errors.ts @@ -0,0 +1,95 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIError, APIErrorData } from '../src/errors'; + +describe('api errors module', () => { + let apiError: APIError; + const defaultMessage = 'this is an error'; + const defaultErrno = 401; + + beforeEach(() => { + apiError = new APIError(); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should create a new instance of APIError', () => { + return expect(apiError) + .to.be.an('object') + .and.be.instanceof(APIError); + }); + + it('should set error name to `APIError`', () => { + return expect(apiError.name).to.eql('APIError'); + }); + + it('should set error message to empty string by default', () => { + return expect(apiError.message).to.eql(''); + }); + + it('should set errno to 500 by default', () => { + return expect(apiError.errno).to.eql(500); + }); + + describe('when passed errno', () => { + beforeEach(() => { + apiError = new APIError(defaultMessage, defaultErrno); + return Promise.resolve(); + }); + + it('should set error message when passed through first argument', () => { + return expect(apiError.message).to.eql(defaultMessage); + }); + + it('should set errno when passed through second argument', () => { + return expect(apiError.errno).to.eql(defaultErrno); + }); + }); + + describe('when passed errno and errors', () => { + const errors = [ + { + code: 'error_code_1', + message: 'message1', + }, + { + code: 'error_code_2', + message: 'message2', + }, + ]; + + beforeEach(() => { + apiError = new APIError(defaultMessage, defaultErrno, errors); + return Promise.resolve(); + }); + + it('should set error message when passed through first argument', () => { + return expect(apiError.message).to.eql(defaultMessage); + }); + + it('should set errno when passed through second argument', () => { + return expect(apiError.errno).to.eql(defaultErrno); + }); + + it('should set errors when passed through third argument', () => { + expect(apiError.errors).to.have.lengthOf(2); + const errorData = apiError.errors as ReadonlyArray; + expect(errorData[0].code).to.equal(errors[0].code); + return expect(errorData[0].message).to.equal(errors[0].message); + }); + }); + }); +}); diff --git a/elements/lisk-api-client/test/index.ts b/elements/lisk-api-client/test/index.ts new file mode 100644 index 00000000000..bab72e34567 --- /dev/null +++ b/elements/lisk-api-client/test/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '../src'; +import { expect } from 'chai'; + +describe('api client', () => { + describe('exports', () => { + it('should have APIClient as a function', () => { + return expect(APIClient).to.be.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/mocha.opts b/elements/lisk-api-client/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-api-client/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/test/resources/accounts.ts b/elements/lisk-api-client/test/resources/accounts.ts new file mode 100644 index 00000000000..7083c7486b1 --- /dev/null +++ b/elements/lisk-api-client/test/resources/accounts.ts @@ -0,0 +1,66 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { AccountsResource } from '../../src/resources/accounts'; + +describe('AccountsResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/accounts'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new AccountsResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + + it('should have a "getMultisignatureGroups" function', () => { + return expect(resource) + .to.have.property('getMultisignatureGroups') + .which.is.a('function'); + }); + + it('should have a "getMultisignatureMemberships" function', () => { + return expect(resource) + .to.have.property('getMultisignatureMemberships') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/blocks.ts b/elements/lisk-api-client/test/resources/blocks.ts new file mode 100644 index 00000000000..4459108049b --- /dev/null +++ b/elements/lisk-api-client/test/resources/blocks.ts @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { BlocksResource } from '../../src/resources/blocks'; + +describe('BlocksResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/blocks'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new BlocksResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/dapps.ts b/elements/lisk-api-client/test/resources/dapps.ts new file mode 100644 index 00000000000..8d042bab702 --- /dev/null +++ b/elements/lisk-api-client/test/resources/dapps.ts @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { DappsResource } from '../../src/resources/dapps'; + +describe('DappsResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/dapps'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new DappsResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/delegates.ts b/elements/lisk-api-client/test/resources/delegates.ts new file mode 100644 index 00000000000..6a8c38cf772 --- /dev/null +++ b/elements/lisk-api-client/test/resources/delegates.ts @@ -0,0 +1,72 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { DelegatesResource } from '../../src/resources/delegates'; + +describe('DelegatesResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/delegates'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new DelegatesResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + + it('should have a "getStandby" function', () => { + return expect(resource) + .to.have.property('getStandby') + .which.is.a('function'); + }); + + it('should have a "getForgers" function', () => { + return expect(resource) + .to.have.property('getForgers') + .which.is.a('function'); + }); + + it('should have a "getForgingStatistics" function', () => { + return expect(resource) + .to.have.property('getForgingStatistics') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/node.ts b/elements/lisk-api-client/test/resources/node.ts new file mode 100644 index 00000000000..da8ebd1a8d2 --- /dev/null +++ b/elements/lisk-api-client/test/resources/node.ts @@ -0,0 +1,78 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { NodeResource } from '../../src/resources/node'; + +describe('NodeResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/node'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new NodeResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "getConstants" function', () => { + return expect(resource) + .to.have.property('getConstants') + .which.is.a('function'); + }); + + it('should have a "getStatus" function', () => { + return expect(resource) + .to.have.property('getStatus') + .which.is.a('function'); + }); + + it('should have a "getForgingStatus" function', () => { + return expect(resource) + .to.have.property('getForgingStatus') + .which.is.a('function'); + }); + + it('should have a "updateForgingStatus" function', () => { + return expect(resource) + .to.have.property('updateForgingStatus') + .which.is.a('function'); + }); + + it('should have a "getTransactions" function', () => { + return expect(resource) + .to.have.property('getTransactions') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/peers.ts b/elements/lisk-api-client/test/resources/peers.ts new file mode 100644 index 00000000000..fb863ebc79f --- /dev/null +++ b/elements/lisk-api-client/test/resources/peers.ts @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { PeersResource } from '../../src/resources/peers'; + +describe('PeersResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/peers'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new PeersResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/signatures.ts b/elements/lisk-api-client/test/resources/signatures.ts new file mode 100644 index 00000000000..243371c4ef8 --- /dev/null +++ b/elements/lisk-api-client/test/resources/signatures.ts @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { SignaturesResource } from '../../src/resources/signatures'; + +describe('SignaturesResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/signatures'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new SignaturesResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "broadcast" function', () => { + return expect(resource) + .to.have.property('broadcast') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/transactions.ts b/elements/lisk-api-client/test/resources/transactions.ts new file mode 100644 index 00000000000..567ab5dd217 --- /dev/null +++ b/elements/lisk-api-client/test/resources/transactions.ts @@ -0,0 +1,60 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { TransactionsResource } from '../../src/resources/transactions'; + +describe('TransactionsResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/transactions'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new TransactionsResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + + it('should have a "broadcast" function', () => { + return expect(resource) + .to.have.property('broadcast') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/voters.ts b/elements/lisk-api-client/test/resources/voters.ts new file mode 100644 index 00000000000..2b323fa50c7 --- /dev/null +++ b/elements/lisk-api-client/test/resources/voters.ts @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { VotersResource } from '../../src/resources/voters'; + +describe('VotersResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/voters'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new VotersResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/resources/votes.ts b/elements/lisk-api-client/test/resources/votes.ts new file mode 100644 index 00000000000..7e065065da5 --- /dev/null +++ b/elements/lisk-api-client/test/resources/votes.ts @@ -0,0 +1,54 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { APIClient } from '../../src/api_client'; +import { APIResource } from '../../src/api_resource'; +import { VotesResource } from '../../src/resources/votes'; + +describe('VotesResource', () => { + const defaultBasePath = 'http://localhost:1234'; + const path = '/votes'; + + let apiClient: APIClient; + let resource: APIResource; + + beforeEach(() => { + apiClient = new APIClient([defaultBasePath]); + resource = new VotesResource(apiClient); + return Promise.resolve(); + }); + + describe('#constructor', () => { + it('should be instance of APIResource', () => { + return expect(resource).to.be.instanceOf(APIResource); + }); + + it('should have correct full path', () => { + return expect(resource.resourcePath).to.eql( + `${defaultBasePath}/api${path}`, + ); + }); + + it('should set resource path', () => { + return expect(resource.path).to.equal(path); + }); + + it('should have a "get" function', () => { + return expect(resource) + .to.have.property('get') + .which.is.a('function'); + }); + }); +}); diff --git a/elements/lisk-api-client/test/tsconfig.json b/elements/lisk-api-client/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-api-client/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/test/tslint.json b/elements/lisk-api-client/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-api-client/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/test/utils.ts b/elements/lisk-api-client/test/utils.ts new file mode 100644 index 00000000000..198d34866e8 --- /dev/null +++ b/elements/lisk-api-client/test/utils.ts @@ -0,0 +1,86 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { toQueryString, solveURLParams } from '../src/utils'; + +describe('api utils module', () => { + const defaultURL = 'http://localhost:8080/api/resources'; + + describe('#toQueryString', () => { + it('should create a query string from an object', () => { + const queryString = toQueryString({ + key1: 'value1', + key2: 'value2', + key3: 'value3', + }); + return expect(queryString).to.be.equal( + 'key1=value1&key2=value2&key3=value3', + ); + }); + + it('should escape invalid special characters', () => { + const queryString = toQueryString({ + 'key:/;?': 'value:/;?', + }); + return expect(queryString).to.be.equal( + 'key%3A%2F%3B%3F=value%3A%2F%3B%3F', + ); + }); + }); + + describe('#solveURLParams', () => { + it('should return original URL with no param', () => { + const solvedURL = solveURLParams(defaultURL); + return expect(solvedURL).to.be.equal(defaultURL); + }); + + it('should throw error if url has variable but no param', () => { + return expect(solveURLParams.bind(null, `${defaultURL}/{id}`)).to.throw( + Error, + 'URL is not completely solved', + ); + }); + + it('should throw error if url has variable but not matching params', () => { + return expect( + solveURLParams.bind(null, `${defaultURL}/{id}`, { accountId: '123' }), + ).to.throw(Error, 'URL is not completely solved'); + }); + + it('should replace variable with correct id', () => { + const solvedURL = solveURLParams(`${defaultURL}/{id}`, { + id: '456', + accountId: '123', + }); + return expect(solvedURL).to.be.equal(`${defaultURL}/456`); + }); + + it('should replace multiple variables with correct id and accountId', () => { + const solvedURL = solveURLParams(`${defaultURL}/{accountId}/{id}`, { + id: '456', + accountId: '123', + }); + return expect(solvedURL).to.be.equal(`${defaultURL}/123/456`); + }); + + it('should replace variable with correct id and encode special characters', () => { + const solvedURL = solveURLParams(`${defaultURL}/{id}`, { + id: '456ß1234sd', + accountId: '123', + }); + return expect(solvedURL).to.be.equal(`${defaultURL}/456%C3%9F1234sd`); + }); + }); +}); diff --git a/elements/lisk-api-client/tsconfig.browsertest.json b/elements/lisk-api-client/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-api-client/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/tsconfig.json b/elements/lisk-api-client/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-api-client/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-api-client/tslint.json b/elements/lisk-api-client/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-api-client/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-client/.npmignore b/elements/lisk-client/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-client/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-client/.npmrc b/elements/lisk-client/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-client/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-client/.nycrc b/elements/lisk-client/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-client/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-client/.prettierignore b/elements/lisk-client/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-client/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-client/.prettierrc.json b/elements/lisk-client/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-client/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-client/README.md b/elements/lisk-client/README.md new file mode 100644 index 00000000000..990320cbd97 --- /dev/null +++ b/elements/lisk-client/README.md @@ -0,0 +1,85 @@ +# @liskhq/lisk-client + +A default set of Elements for use by clients of the Lisk network + +## Installation + +### Installation via npm + +Add Lisk Client as a dependency of your project: + +```sh +$ npm install --save @liskhq/lisk-client +``` + +Import using ES6 modules syntax: + +```js +import lisk from '@liskhq/lisk-client'; +``` + +Or using Node.js modules: + +```js +const lisk = require('@liskhq/lisk-client'); +``` + +Or import specific namespaced functionality: + +```js +import { APIClient, transactions } from '@liskhq/lisk-client'; +// or +const { APIClient, transactions } = require('@liskhq/lisk-client'); +``` + +### Installation via CDN + +Include the following script using the following HTML. The `lisk` variable will be exposed. + +```html + +``` + +Or minified: + +```html + +``` + +## Packages + +| Package | Version | Description | +| ------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------ | +| [@liskhq/lisk-api-client](../lisk-api-client) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-api-client) | An API client for the Lisk network | +| [@liskhq/lisk-constants](../lisk-constants) | [![](https://img.shields.io/badge/npm-v1.2.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-constants) | General constants for use with Lisk-related software | +| [@liskhq/lisk-cryptography](../lisk-cryptography) | [![](https://img.shields.io/badge/npm-v2.1.0_alpha.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-cryptography) | General cryptographic functions for use with Lisk-related software | +| [@liskhq/lisk-passphrase](../lisk-passphrase) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-passphrase) | Mnemonic passphrase helpers for use with Lisk-related software | +| [@liskhq/lisk-transactions](/packages/lisk-transactions) | [![](https://img.shields.io/badge/npm-v2.1.0_alpha.4-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-transactions) | Everything related to transactions according to the Lisk protocol | + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-client/browsertest b/elements/lisk-client/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-client/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-client/cypress b/elements/lisk-client/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-client/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-client/cypress.json b/elements/lisk-client/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-client/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-client/index.html b/elements/lisk-client/index.html new file mode 100644 index 00000000000..12191c63250 --- /dev/null +++ b/elements/lisk-client/index.html @@ -0,0 +1,14 @@ + + + + + Title + + +Open the console to get started with Lisk Client. +
+ + + + + diff --git a/elements/lisk-client/package-lock.json b/elements/lisk-client/package-lock.json new file mode 100644 index 00000000000..a20a59de87b --- /dev/null +++ b/elements/lisk-client/package-lock.json @@ -0,0 +1,4768 @@ +{ + "name": "@liskhq/lisk-client", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "http://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "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" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.3.tgz", + "integrity": "sha512-l00tmFFZOBHtYhN4Cz7k32VM7vTn3rE2ANjQDxdEN6zmXZ/xq1jQuutnmHvMG1ZJ7xd72+TA5YpUK8wz3rWsfQ==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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": "http://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "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": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "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" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.0.tgz", + "integrity": "sha1-kc1BfRUqv4Wzexqz6/O9Jc3GToA=", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "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-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 + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", + "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==", + "dev": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", + "dev": true + }, + "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.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", + "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=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha1-IwKlam/+9/mr6gFH2Dil6ba2p5s=", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha1-7uJfVtscnsYIXgwid4CD9Zar+Sc=", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha1-76ouqdqg16suoTqXsritUf776L4=", + "dev": true + }, + "is-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "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 + } + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8=", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha1-bYrlCPWRZ/lA8rWzxKYSrlDJCuY=", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha1-l2wgZTBhexTrsyEUI597CTNuk6Y=", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "portfinder": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", + "integrity": "sha512-syFcRIRzVI1BoEFOCaAiizwDolh1S1YXSodsVhncbhjzjZQulhczNRbqnUl9N31Q4dKGOXsNDqxC2BWBgSMqeQ==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha1-0wLFIpSFiISKjTAMkytEwkIx2oA=", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw=", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "http://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "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 + }, + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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" + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha1-DBxPBwC+2NvBJM2zBNJZLKID5nc=", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha1-aWS8pnaF33wfFDDFhPB9dZeIW5w=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "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" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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 + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-client/package.json b/elements/lisk-client/package.json new file mode 100644 index 00000000000..ade5816467e --- /dev/null +++ b/elements/lisk-client/package.json @@ -0,0 +1,91 @@ +{ + "name": "@liskhq/lisk-client", + "version": "2.0.0", + "description": "A default set of Elements for use by clients of the Lisk network", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-client#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "prestart": "./scripts/prestart.sh", + "start": "./scripts/start.sh", + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s lisk", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s lisk", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{js,json}\" \"{src,test}/**/*.{js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/**/*.ts test/**/**/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11546 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11546) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11546 && cypress run --config baseUrl=http://localhost:11546 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "NODE_ENV=test nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@liskhq/lisk-api-client": "2.0.0", + "@liskhq/lisk-constants": "1.2.0", + "@liskhq/lisk-cryptography": "2.1.0-alpha.0", + "@liskhq/lisk-passphrase": "2.0.0", + "@liskhq/lisk-transactions": "2.1.0-alpha.4", + "@types/node": "10.12.21" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-client/scripts b/elements/lisk-client/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-client/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-client/src/index.ts b/elements/lisk-client/src/index.ts new file mode 100644 index 00000000000..444dd6ac06b --- /dev/null +++ b/elements/lisk-client/src/index.ts @@ -0,0 +1,35 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient as APIClientModule } from '@liskhq/lisk-api-client'; +import * as constantsModule from '@liskhq/lisk-constants'; +import * as cryptographyModule from '@liskhq/lisk-cryptography'; +import * as passphraseModule from '@liskhq/lisk-passphrase'; +import * as transactionModule from '@liskhq/lisk-transactions'; + +// tslint:disable-next-line variable-name +export const APIClient = APIClientModule; +export const constants = constantsModule; +export const cryptography = cryptographyModule; +export const passphrase = passphraseModule; +export const transaction = transactionModule; + +// tslint:disable-next-line no-default-export +export default { + APIClient, + constants, + cryptography, + passphrase, + transaction, +}; diff --git a/elements/lisk-client/test/_setup.ts b/elements/lisk-client/test/_setup.ts new file mode 100644 index 00000000000..000104e6fba --- /dev/null +++ b/elements/lisk-client/test/_setup.ts @@ -0,0 +1,17 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import 'chai/register-expect'; + +process.env.NODE_ENV = 'test'; diff --git a/elements/lisk-client/test/index.ts b/elements/lisk-client/test/index.ts new file mode 100644 index 00000000000..9c0e948c613 --- /dev/null +++ b/elements/lisk-client/test/index.ts @@ -0,0 +1,44 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + APIClient, + constants, + cryptography, + passphrase, + transaction, +} from '../src'; + +describe('lisk-client', () => { + it('APIClient should be a function', () => { + return expect(APIClient).to.be.a('function'); + }); + + it('constants should be an object', () => { + return expect(constants).to.be.an('object'); + }); + + it('cryptography should be an object', () => { + return expect(cryptography).to.be.an('object'); + }); + + it('passphrase should be an object', () => { + return expect(passphrase).to.be.an('object'); + }); + + it('transaction should be an object', () => { + return expect(transaction).to.be.an('object'); + }); +}); diff --git a/elements/lisk-client/test/mocha.opts b/elements/lisk-client/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-client/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-client/test/tsconfig.json b/elements/lisk-client/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-client/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-client/test/tslint.json b/elements/lisk-client/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-client/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-client/tsconfig.browsertest.json b/elements/lisk-client/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-client/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-client/tsconfig.json b/elements/lisk-client/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-client/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-client/tslint.json b/elements/lisk-client/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-client/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/.gitignore b/elements/lisk-constants/.gitignore new file mode 100644 index 00000000000..ed87397f43c --- /dev/null +++ b/elements/lisk-constants/.gitignore @@ -0,0 +1,3 @@ +# Compiled files +src/**/*.js +test/**/*.js diff --git a/elements/lisk-constants/.npmignore b/elements/lisk-constants/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-constants/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/.npmrc b/elements/lisk-constants/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-constants/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/.nycrc b/elements/lisk-constants/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-constants/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/.prettierignore b/elements/lisk-constants/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-constants/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/.prettierrc.json b/elements/lisk-constants/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-constants/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/LICENSE b/elements/lisk-constants/LICENSE new file mode 100644 index 00000000000..9cecc1d4669 --- /dev/null +++ b/elements/lisk-constants/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/elements/lisk-constants/README.md b/elements/lisk-constants/README.md new file mode 100644 index 00000000000..e23e97727c2 --- /dev/null +++ b/elements/lisk-constants/README.md @@ -0,0 +1,37 @@ +# lisk-constants + +@liskhq/lisk-constants is containing general constants for use with Lisk-related software + +## Installation + +```sh +$ npm install --save @liskhq/lisk-constants +``` + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-constants/browsertest b/elements/lisk-constants/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-constants/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/cypress b/elements/lisk-constants/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-constants/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/cypress.json b/elements/lisk-constants/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-constants/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/package-lock.json b/elements/lisk-constants/package-lock.json new file mode 100644 index 00000000000..0b55c70a639 --- /dev/null +++ b/elements/lisk-constants/package-lock.json @@ -0,0 +1,4714 @@ +{ + "name": "@liskhq/lisk-constants", + "version": "1.2.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "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" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha1-vNZ5HqWuCXJeF+WtmIE0zUCz2RE=", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha1-u3GFBpDh8TZWfeYp0tVHHe2kweg=", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.4.tgz", + "integrity": "sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha1-Sl7Hxk364iw6FBJNus3uhG2Ay8Q=", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.0.tgz", + "integrity": "sha1-kc1BfRUqv4Wzexqz6/O9Jc3GToA=", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha1-E7BM2z5sXRnfkatph6hpVhmwqnE=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "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" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "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-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 + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", + "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==", + "dev": true, + "requires": { + "debug": "=3.1.0" + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha1-pWiZ0+o8m6uHS7l3O3xe3pL0iV0=", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha1-OWCDLT8VdBCDQtr9OmezMsCWnfE=", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.8.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.8.0.tgz", + "integrity": "sha512-io6LkyPVuzCHBSQV9fmOwxZkUk6nIaGmxheLDgmuFv89j0fm2aqDbIXKAGfzCMHqz3HLF2Zf8WSG6VqMh2qFmA==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", + "dev": true + }, + "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.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha1-ci18v8H2qoJB8W3YFOAR4fQeh5Y=", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", + "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=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha1-IwKlam/+9/mr6gFH2Dil6ba2p5s=", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.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-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.0.tgz", + "integrity": "sha1-6u1lbsg0TxD1J8a/obbiJE3hZ9E=", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.10", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", + "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha1-bYrlCPWRZ/lA8rWzxKYSrlDJCuY=", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha1-ozeKdpbOfSI+iPybdkvX7xCJ42Y=", + "dev": true + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha1-1i27VnlAXXLEc37FhgDp3c8G0kw=", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "portfinder": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", + "integrity": "sha512-syFcRIRzVI1BoEFOCaAiizwDolh1S1YXSodsVhncbhjzjZQulhczNRbqnUl9N31Q4dKGOXsNDqxC2BWBgSMqeQ==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.8.1.tgz", + "integrity": "sha1-gvHsGaQjrB+9CAsLqwa6NuhKeiY=", + "dev": true, + "requires": { + "path-parse": "^1.0.5" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha1-RPoWGwGHuVSd2Eu5GAL5vYOFzWo=", + "dev": true + }, + "semver": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.1.tgz", + "integrity": "sha512-PqpAxfrEhlSUWge8dwIp4tZnQ25DIOthpiaHNIthsjEFQD6EvqUKUDM7L8O2rShkFccYo1VjJR0coWfNkCubRw==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "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 + }, + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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" + } + }, + "supports-color": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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" + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha1-1+TdeSRdhUKMTX5IIqeZF5VMooY=", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha1-DBxPBwC+2NvBJM2zBNJZLKID5nc=", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha1-aWS8pnaF33wfFDDFhPB9dZeIW5w=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha1-lMVA4f93KVbiKZUHwBCupsiDjrA=", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha1-tYsBCsQMIsVldhbI0sLALHv0eew=", + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "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" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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 + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha1-pFBD1U9YBTFtqNYvn1CRjT2nCwo=", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-constants/package.json b/elements/lisk-constants/package.json new file mode 100644 index 00000000000..569ae78272a --- /dev/null +++ b/elements/lisk-constants/package.json @@ -0,0 +1,84 @@ +{ + "name": "@liskhq/lisk-constants", + "version": "1.2.0", + "description": "General constants for use with Lisk-related software", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-constants#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s liskConstants", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s liskConstants", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/**/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11542 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11542) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11542 && cypress run --config baseUrl=http://localhost:11542 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@types/node": "10.12.21" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-constants/scripts b/elements/lisk-constants/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-constants/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/src/index.ts b/elements/lisk-constants/src/index.ts new file mode 100644 index 00000000000..cc611f04cde --- /dev/null +++ b/elements/lisk-constants/src/index.ts @@ -0,0 +1,35 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +// tslint:disable-next-line:no-magic-numbers +export const EPOCH_TIME = new Date(Date.UTC(2016, 4, 24, 17, 0, 0, 0)); +export const EPOCH_TIME_MILLISECONDS = EPOCH_TIME.getTime(); +const MS_FACTOR = 1000; +export const EPOCH_TIME_SECONDS = Math.floor(EPOCH_TIME.getTime() / MS_FACTOR); + +// Largest possible number which can be stored in eight bytes. +// Derived from bignum.fromBuffer(Buffer.from(new Array(8).fill(255))). +const MAX_EIGHT_BYTE_NUMBER = '18446744073709551615'; + +export const MAX_ADDRESS_NUMBER = MAX_EIGHT_BYTE_NUMBER; +export const MAX_TRANSACTION_ID = MAX_EIGHT_BYTE_NUMBER; +// Largest possible amount. Maximum value for PostgreSQL bigint. +export const MAX_TRANSACTION_AMOUNT = '9223372036854775807'; + +export const SIGNED_MESSAGE_PREFIX = 'Lisk Signed Message:\n'; + +export const TESTNET_NETHASH = + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba'; +export const MAINNET_NETHASH = + 'ed14889723f24ecc54871d058d98ce91ff2f973192075c0155ba2b7b70ad2511'; diff --git a/elements/lisk-constants/test/_setup.ts b/elements/lisk-constants/test/_setup.ts new file mode 100644 index 00000000000..5932774a733 --- /dev/null +++ b/elements/lisk-constants/test/_setup.ts @@ -0,0 +1,45 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { Assertion } from 'chai'; + +process.env.NODE_ENV = 'test'; + +Assertion.addProperty('hexString', function handleAssert( + this: Chai.ChaiStatic, +) { + const actual = this._obj; + + new Assertion(actual).to.be.a('string'); + + const expected = Buffer.from(actual, 'hex').toString('hex'); + this.assert( + expected === actual, + 'expected #{this} to be a hexString', + 'expected #{this} not to be a hexString', + ); +}); + +Assertion.addProperty('integer', function handleAssert(this: Chai.ChaiStatic) { + const actual = this._obj; + + new Assertion(actual).to.be.a('number'); + + const expected = parseInt(actual, 10); + this.assert( + actual === expected, + 'expected #{this} to be an integer', + 'expected #{this} not to be an integer', + ); +}); diff --git a/elements/lisk-constants/test/index.ts b/elements/lisk-constants/test/index.ts new file mode 100644 index 00000000000..6e42fcc9da5 --- /dev/null +++ b/elements/lisk-constants/test/index.ts @@ -0,0 +1,64 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + EPOCH_TIME, + EPOCH_TIME_SECONDS, + EPOCH_TIME_MILLISECONDS, + MAX_ADDRESS_NUMBER, + MAX_TRANSACTION_ID, + MAX_TRANSACTION_AMOUNT, + TESTNET_NETHASH, + MAINNET_NETHASH, + SIGNED_MESSAGE_PREFIX, +} from '../src'; + +describe('lisk-constants', () => { + it('EPOCH_TIME should be a Date instance', () => { + return expect(EPOCH_TIME).to.be.instanceOf(Date); + }); + + it('EPOCH_TIME_SECONDS should be an integer', () => { + return expect(EPOCH_TIME_SECONDS).to.be.an.integer; + }); + + it('EPOCH_TIME_MILLISECONDS should be an integer', () => { + return expect(EPOCH_TIME_MILLISECONDS).to.be.an.integer; + }); + + it('MAX_ADDRESS_NUMBER should be a string', () => { + return expect(MAX_ADDRESS_NUMBER).to.be.a('string'); + }); + + it('MAX_TRANSACTION_ID should be a string', () => { + return expect(MAX_TRANSACTION_ID).to.be.a('string'); + }); + + it('MAX_TRANSACTION_AMOUNT should be a string', () => { + return expect(MAX_TRANSACTION_AMOUNT).to.be.a('string'); + }); + + it('TESTNET_NETHASH should be a string', () => { + return expect(TESTNET_NETHASH).to.be.a.hexString; + }); + + it('MAINNET_NETHASH should be a string', () => { + return expect(MAINNET_NETHASH).to.be.a.hexString; + }); + + it('SIGNED_MESSAGE_PREFIX should be a string', () => { + return expect(SIGNED_MESSAGE_PREFIX).to.be.a('string'); + }); +}); diff --git a/elements/lisk-constants/test/mocha.opts b/elements/lisk-constants/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-constants/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/test/tsconfig.json b/elements/lisk-constants/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-constants/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/test/tslint.json b/elements/lisk-constants/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-constants/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/tsconfig.browsertest.json b/elements/lisk-constants/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-constants/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/tsconfig.json b/elements/lisk-constants/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-constants/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-constants/tslint.json b/elements/lisk-constants/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-constants/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/.npmignore b/elements/lisk-cryptography/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-cryptography/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/.npmrc b/elements/lisk-cryptography/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-cryptography/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/.nycrc b/elements/lisk-cryptography/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-cryptography/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/.prettierignore b/elements/lisk-cryptography/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-cryptography/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/.prettierrc.json b/elements/lisk-cryptography/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-cryptography/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/LICENSE b/elements/lisk-cryptography/LICENSE new file mode 100644 index 00000000000..9cecc1d4669 --- /dev/null +++ b/elements/lisk-cryptography/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/elements/lisk-cryptography/README.md b/elements/lisk-cryptography/README.md new file mode 100644 index 00000000000..5a74effc062 --- /dev/null +++ b/elements/lisk-cryptography/README.md @@ -0,0 +1,63 @@ +# @liskhq/lisk-cryptography + +@liskhq/lisk-cryptography is containing general cryptographic functions for use with Lisk-related software + + +## Installation + +```sh +$ npm install --save @liskhq/lisk-cryptography +``` + +## Benchmarking + +Install optional dependencies: + +```sh +$ npm i -D benchmark sodium-native +``` + +Benchmark nacl functions: + +```sh +$ npx babel-node ./benchmark/nacl +``` + +Benchmark results for nacl functions: + +| Function | Fast | Slow | Winner | +| :-----------------: | :-----------------------:|:-----------------------: | :----: | +| box | x 23,982 ops/sec ±0.59% | x 771 ops/sec ±0.44% | Fast | +| openBox | x 24,247 ops/sec ±0.42% | x 770 ops/sec ±0.69% | Fast | +| signDetached | x 46,402 ops/sec ±0.32% | x 236 ops/sec ±1.63% | Fast | +| verifyDetached | x 17,153 ops/sec ±0.19% | x 122 ops/sec ±0.61% | Fast | +| getRandomBytes | x 207,866 ops/sec ±0.23% | x 299,959 ops/sec ±0.39% | Slow | +| getKeyPair | x 38,815 ops/sec ±0.16% | x 242 ops/sec ±0.62% | Fast | + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-cryptography/benchmark/nacl.js b/elements/lisk-cryptography/benchmark/nacl.js new file mode 100644 index 00000000000..4361e9ff1aa --- /dev/null +++ b/elements/lisk-cryptography/benchmark/nacl.js @@ -0,0 +1,141 @@ +/* +* Copyright © 2018 Lisk Foundation +* +* See the LICENSE file at the top-level directory of this distribution +* for licensing information. +* +* Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, +* no part of this software, including this file, may be copied, modified, +* propagated, or distributed except according to the terms contained in the +* LICENSE file. +* +* Removal or modification of this copyright notice is prohibited. +* +*/ +import Benchmark from 'benchmark'; +import * as fast from '../src/nacl/fast'; +import * as slow from '../src/nacl/slow'; + +Benchmark.options.minSamples = 100; + +const defaultPublicKey = + '7ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; +const defaultPrivateKey = + '314852d7afb0d4c283692fef8a2cb40e30c7a5df2ed79994178c10ac168d6d977ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; +const defaultMessage = 'Some default text.'; +const defaultSignature = + '68937004b6720d7e1902ef05a577e6d9f9ab2756286b1f2ae918f8a0e5153c15e4f410916076f750b708f8979be2430e4cfc7ebb523ae1905d2ea1f5d24ce700'; +const defaultEncryptedMessage = + 'a232e5ea10e18249efc5a0aa8ed68271fc494d02245c52277ee2e14cddd960144a65'; +const defaultNonce = 'df4c8b09e270d2cb3f7b3d53dfa8a6f3441ad3b14a13fb66'; +const defaultHash = + '314852d7afb0d4c283692fef8a2cb40e30c7a5df2ed79994178c10ac168d6d97'; +const defaultDigest = + 'aba8462bb7a1460f1e36c36a71f0b7f67d1606562001907c1b2dad08a8ce74ae'; +const defaultConvertedPublicKeyEd2Curve = + 'b8c0eecfd16c1cc4f057a6fc6d8dd3d46e4aa9625408d4bd0ba00e991326fe00'; +const defaultConvertedPrivateKeyEd2Curve = + 'b0e3276b64b086b381e11928e56f966d062dc677b7801cc594aeb2d4193e8d57'; + +const boxBenchmark = new Benchmark.Suite('box') + .add('fast.box', () => { + fast.box( + Buffer.from(defaultMessage, 'utf8'), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + }) + .add('slow.box', () => { + slow.box( + Buffer.from(defaultMessage, 'utf8'), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + }); + +const openBoxBenchmark = new Benchmark.Suite('openBox') + .add('fast.openBox', () => { + fast.openBox( + Buffer.from(defaultEncryptedMessage, 'hex'), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + }) + .add('slow.openBox', () => { + slow.openBox( + Buffer.from(defaultEncryptedMessage, 'hex'), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + }); + +const signDetachedBenchmark = new Benchmark.Suite('signDetached') + .add('fast.signDetached', () => { + fast.signDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(defaultPrivateKey, 'hex'), + ); + }) + .add('slow.signDetached', () => { + slow.signDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(defaultPrivateKey, 'hex'), + ); + }); + +const verifyDetachedBenchmark = new Benchmark.Suite('verifyDetached') + .add('fast.verifyDetached', () => { + fast.verifyDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(defaultSignature, 'hex'), + Buffer.from(defaultPublicKey, 'hex'), + ); + }) + .add('slow.verifyDetached', () => { + slow.verifyDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(defaultSignature, 'hex'), + Buffer.from(defaultPublicKey, 'hex'), + ); + }); + +const getRandomBytesBenchmark = new Benchmark.Suite('getRandomBytes') + .add('fast.getRandomBytes', () => { + fast.getRandomBytes(24); + }) + .add('slow.getRandomBytes', () => { + slow.getRandomBytes(24); + }); + +const getKeyPairBenchmark = new Benchmark.Suite('getKeyPair') + .add('fast.getKeyPair', () => { + fast.getKeyPair(Buffer.from(defaultHash, 'hex')); + }) + .add('slow.getKeyPair', () => { + slow.getKeyPair(Buffer.from(defaultHash, 'hex')); + }); + +[ + boxBenchmark, + openBoxBenchmark, + signDetachedBenchmark, + verifyDetachedBenchmark, + getRandomBytesBenchmark, + getKeyPairBenchmark, +].forEach(benchmark => { + benchmark + .on('start', () => { + console.info(`Evaluating ${benchmark.name}..`); + }) + .on('cycle', event => { + console.info(String(event.target)); + }) + .on('complete', function callback() { + console.info(`Winner is ${this.filter('fastest').map('name')}!`); + }) + .run(); +}); diff --git a/elements/lisk-cryptography/browsertest b/elements/lisk-cryptography/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-cryptography/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/cypress b/elements/lisk-cryptography/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-cryptography/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/cypress.json b/elements/lisk-cryptography/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-cryptography/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/package-lock.json b/elements/lisk-cryptography/package-lock.json new file mode 100644 index 00000000000..56acbe61a38 --- /dev/null +++ b/elements/lisk-cryptography/package-lock.json @@ -0,0 +1,4977 @@ +{ + "name": "@liskhq/lisk-cryptography", + "version": "2.1.0-alpha.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@liskhq/bignum": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@liskhq/bignum/-/bignum-1.3.1.tgz", + "integrity": "sha512-q9+NvqbpmXOqpPmV8Y+XSEIUJFMZDGyfW6rkN9Ej3nzPb/qurY/Ic2UPTeTTaj8+q/bcw5JUwTb86hi7PIziDg==", + "requires": { + "@types/node": "11.11.2" + }, + "dependencies": { + "@types/node": { + "version": "11.11.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.2.tgz", + "integrity": "sha512-iEaHiDNkHv4Jrm9O5T37OYEUwjJesiyt6ZlhLFK0sbo4CLD0jyCOB4Pc2F9iD3MbW2397SLNxZKdDGntGaBjQQ==" + } + } + }, + "@sinonjs/commons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", + "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", + "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "dev": true, + "requires": { + "@sinonjs/samsam": "^2 || ^3" + } + }, + "@sinonjs/samsam": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.1.0.tgz", + "integrity": "sha512-IXio+GWY+Q8XUjHUOgK7wx8fpvr7IFffgyXb1bnJFfX3001KmHt35Zq4tp7MXZyjJPCLPuadesDYNk41LYtVjw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash.get": "^4.4.2" + } + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/ed2curve": { + "version": "0.2.2", + "resolved": "http://registry.npmjs.org/@types/ed2curve/-/ed2curve-0.2.2.tgz", + "integrity": "sha512-G1sTX5xo91ydevQPINbL2nfgVAj/s1ZiqZxC8OCWduwu+edoNGUm5JXtTkg9F3LsBZbRI46/0HES4CPUE2wc9g==", + "requires": { + "tweetnacl": "^1.0.0" + } + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "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" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + } + } + }, + "benchmark": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/benchmark/-/benchmark-2.1.4.tgz", + "integrity": "sha1-CfPeMckWQl1JjMLuVloOvzwqVik=", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "platform": "^1.3.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "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" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-reverse": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-reverse/-/buffer-reverse-1.0.1.tgz", + "integrity": "sha1-SSg8jvpvkBvAH6MwTQYCeXGuL2A=" + }, + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.4.tgz", + "integrity": "sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "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" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "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" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.0.tgz", + "integrity": "sha512-EblWYTd+wPIAMQ0U4oYJZ7QBypT9ZUIwpqli0bKDjeIIQnXDBK2dXtZ9yzRCOlkW1HkO8gn7/FxLK1yPIW17pw==", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "ed2curve": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/ed2curve/-/ed2curve-0.2.1.tgz", + "integrity": "sha1-Iuaqo1aePE2/Tu+ilhLsMp5YGQw=", + "requires": { + "tweetnacl": "0.x.x" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=" + } + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "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-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 + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.9", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.9.tgz", + "integrity": "sha512-Bh65EZI/RU8nx0wbYF9shkFZlqLP+6WT/5FnA3cE/djNSuKNHJEinGGZgu/cQEkeeb2GdFOgenAmn8qaqYke2w==", + "dev": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "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.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha512-6JeGDGoujJLmhjiRGlt8yK8Z9Kl0vnl/dQoQZlc4oeqaUoAKQg94NILLfrY3oWzSyFaQCVNTcKE5PZ3cH8VP9w==", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.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-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "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 + } + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "lolex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.0.0.tgz", + "integrity": "sha512-hcnW80h3j2lbUfFdMArd5UPA/vxZJ+G8vobd+wg3nVEQA0EigStbYcrG030FJxL6xiDDPEkoMatV9xIh5OecQQ==", + "dev": true + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "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": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "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" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nan": { + "version": "2.11.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.11.1.tgz", + "integrity": "sha512-iji6k87OSXa0CcrLl9z+ZiYSuR2o+c0bGuNmXdrhTQTakxytAFsC56SArGYoiHlJlFoHSnvmhpceZJaXkVuOtA==", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nise": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.1.0", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + } + } + }, + "node-gyp-build": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-3.5.0.tgz", + "integrity": "sha512-qjEE8eIWVyqZhkAFUzytGpOGvLHeX5kXBB6MYyTOCPZBrBlsLyXAAzTsp/hWMbVlg8kVpzDJCZZowIrnKpwmqQ==", + "dev": true + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "platform": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz", + "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", + "dev": true + }, + "portfinder": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.19.tgz", + "integrity": "sha512-23aeQKW9KgHe6citUrG3r9HjeX6vls0h713TAa+CwTKZwNIr/pD2ApaxYF4Um3ZZyq4ar+Siv3+fhoHaIwSOSw==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "sinon": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", + "integrity": "sha512-i6j7sqcLEqTYqUcMV327waI745VASvYuSuQMCjbAwlpAeuCgKZ3LtrjDxAbu+GjNQR0FEDpywtwGCIh8GicNyg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/samsam": "^3.0.2", + "diff": "^3.5.0", + "lolex": "^3.0.0", + "nise": "^1.4.8", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "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 + }, + "sodium-native": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/sodium-native/-/sodium-native-2.2.1.tgz", + "integrity": "sha512-3CfftYV2ATXQFMIkLOvcNUk/Ma+lran0855j5Z/HEjUkSTzjLZi16CK362udOoNVrwn/TwGV8bKEt5OylsFrQA==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "nan": "^2.4.0", + "node-gyp-build": "^3.0.0" + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + } + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "dev": true + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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" + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-1.0.1.tgz", + "integrity": "sha512-kcoMoKTPYnoeS50tzoqjPY3Uv9axeuuFAZY9M/9zFnhoVvRfxz9K29IMPD7jGmt2c8SW7i3gT9WqDl2+nV7p4A==" + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "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" + }, + "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 + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "varuint-bitcoin": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.1.0.tgz", + "integrity": "sha512-jCEPG+COU/1Rp84neKTyDJQr478/hAfVp5xxYn09QEH0yBjbmPeMfuuQIrp+BUD83hybtYZKhr5elV3bvdV1bA==", + "requires": { + "safe-buffer": "^5.1.1" + } + }, + "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" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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 + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-cryptography/package.json b/elements/lisk-cryptography/package.json new file mode 100644 index 00000000000..1eb058e95d2 --- /dev/null +++ b/elements/lisk-cryptography/package.json @@ -0,0 +1,93 @@ +{ + "name": "@liskhq/lisk-cryptography", + "version": "2.1.0-alpha.0", + "description": "General cryptographic functions for use with Lisk-related software", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-cryptography#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s liskCryptography", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s liskCryptography", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,json}\" \"{src,test}/**/*.{ts,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/}/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11543 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11543) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11543 && cypress run --config baseUrl=http://localhost:11543 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "NODE_ENV=test nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@liskhq/bignum": "1.3.1", + "@types/ed2curve": "0.2.2", + "@types/node": "10.12.21", + "buffer-reverse": "1.0.1", + "ed2curve": "0.2.1", + "tweetnacl": "1.0.1", + "varuint-bitcoin": "1.1.0" + }, + "optionalDependencies": { + "sodium-native": "2.2.1" + }, + "devDependencies": { + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "benchmark": "2.1.4", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "sinon": "7.2.3", + "sodium-native": "2.2.1", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-cryptography/scripts b/elements/lisk-cryptography/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-cryptography/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/src/buffer.ts b/elements/lisk-cryptography/src/buffer.ts new file mode 100644 index 00000000000..f2964730836 --- /dev/null +++ b/elements/lisk-cryptography/src/buffer.ts @@ -0,0 +1,43 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; + +export const bigNumberToBuffer = (bignumber: string, size: number) => + new BigNum(bignumber).toBuffer({ size, endian: 'big' }); + +export const bufferToBigNumberString = (bigNumberBuffer: Buffer): string => + BigNum.fromBuffer(bigNumberBuffer).toString(); + +export const bufferToHex = (buffer: Buffer): string => + Buffer.from(buffer).toString('hex'); + +const hexRegex = /^[0-9a-f]+/i; +export const hexToBuffer = (hex: string, argumentName = 'Argument'): Buffer => { + if (typeof hex !== 'string') { + throw new TypeError(`${argumentName} must be a string.`); + } + const matchedHex = (hex.match(hexRegex) || [])[0]; + if (!matchedHex || matchedHex.length !== hex.length) { + throw new TypeError(`${argumentName} must be a valid hex string.`); + } + // tslint:disable-next-line no-magic-numbers + if (matchedHex.length % 2 !== 0) { + throw new TypeError( + `${argumentName} must have a valid length of hex string.`, + ); + } + + return Buffer.from(matchedHex, 'hex'); +}; diff --git a/elements/lisk-cryptography/src/constants.ts b/elements/lisk-cryptography/src/constants.ts new file mode 100644 index 00000000000..5f9d3109d8e --- /dev/null +++ b/elements/lisk-cryptography/src/constants.ts @@ -0,0 +1,15 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export const SIGNED_MESSAGE_PREFIX = 'Lisk Signed Message:\n'; diff --git a/elements/lisk-cryptography/src/convert.ts b/elements/lisk-cryptography/src/convert.ts new file mode 100644 index 00000000000..031d84da902 --- /dev/null +++ b/elements/lisk-cryptography/src/convert.ts @@ -0,0 +1,125 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +// Required because first level function export +// tslint:disable-next-line no-require-imports +import reverse = require('buffer-reverse'); +import * as ed2curve from 'ed2curve'; +import * as querystring from 'querystring'; +import { bufferToBigNumberString } from './buffer'; +import { EncryptedPassphraseObject } from './encrypt'; +import { hash } from './hash'; + +export const getFirstEightBytesReversed = (input: string | Buffer): Buffer => { + const BUFFER_SIZE = 8; + // Union type arguments on overloaded functions do not work in typescript. + // Relevant discussion: https://github.com/Microsoft/TypeScript/issues/23155 + if (typeof input === 'string') { + return reverse(Buffer.from(input).slice(0, BUFFER_SIZE)); + } + + return reverse(Buffer.from(input).slice(0, BUFFER_SIZE)); +}; + +export const toAddress = (buffer: Buffer): string => { + const BUFFER_SIZE = 8; + if ( + !Buffer.from(buffer) + .slice(0, BUFFER_SIZE) + .equals(buffer) + ) { + throw new Error( + 'The buffer for Lisk addresses must not have more than 8 bytes', + ); + } + + return `${bufferToBigNumberString(buffer)}L`; +}; + +export const getAddressFromPublicKey = (publicKey: string): string => { + const publicKeyHash = hash(publicKey, 'hex'); + + const publicKeyTransform = getFirstEightBytesReversed(publicKeyHash); + const address = toAddress(publicKeyTransform); + + return address; +}; + +export const convertPublicKeyEd2Curve = ed2curve.convertPublicKey; + +export const convertPrivateKeyEd2Curve = ed2curve.convertSecretKey; + +export const stringifyEncryptedPassphrase = ( + encryptedPassphrase: EncryptedPassphraseObject, +): string => { + if (typeof encryptedPassphrase !== 'object' || encryptedPassphrase === null) { + throw new Error('Encrypted passphrase to stringify must be an object.'); + } + const objectToStringify = encryptedPassphrase.iterations + ? encryptedPassphrase + : { + salt: encryptedPassphrase.salt, + cipherText: encryptedPassphrase.cipherText, + iv: encryptedPassphrase.iv, + tag: encryptedPassphrase.tag, + version: encryptedPassphrase.version, + }; + + return querystring.stringify(objectToStringify); +}; + +const parseIterations = (iterationsString?: string): number | undefined => { + const iterations = + iterationsString === undefined ? undefined : parseInt(iterationsString, 10); + + if (typeof iterations !== 'undefined' && Number.isNaN(iterations)) { + throw new Error('Could not parse iterations.'); + } + + return iterations; +}; + +export const parseEncryptedPassphrase = ( + encryptedPassphrase: string, +): EncryptedPassphraseObject => { + if (typeof encryptedPassphrase !== 'string') { + throw new Error('Encrypted passphrase to parse must be a string.'); + } + const keyValuePairs = querystring.parse(encryptedPassphrase); + + const { iterations, salt, cipherText, iv, tag, version } = keyValuePairs; + + // Review, and find a better solution + if ( + (typeof iterations !== 'string' && typeof iterations !== 'undefined') || + typeof salt !== 'string' || + typeof cipherText !== 'string' || + typeof iv !== 'string' || + typeof tag !== 'string' || + typeof version !== 'string' + ) { + throw new Error( + 'Encrypted passphrase to parse must have only one value per key.', + ); + } + + return { + iterations: parseIterations(iterations), + salt, + cipherText, + iv, + tag, + version, + }; +}; diff --git a/elements/lisk-cryptography/src/encrypt.ts b/elements/lisk-cryptography/src/encrypt.ts new file mode 100644 index 00000000000..122b8638ecc --- /dev/null +++ b/elements/lisk-cryptography/src/encrypt.ts @@ -0,0 +1,210 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as crypto from 'crypto'; +import { bufferToHex, hexToBuffer } from './buffer'; +import { convertPrivateKeyEd2Curve, convertPublicKeyEd2Curve } from './convert'; +import { getPrivateAndPublicKeyBytesFromPassphrase } from './keys'; +import { box, getRandomBytes, openBox } from './nacl'; + +const PBKDF2_ITERATIONS = 1e6; +const PBKDF2_KEYLEN = 32; +const PBKDF2_HASH_FUNCTION = 'sha256'; +const ENCRYPTION_VERSION = '1'; + +export interface EncryptedMessageWithNonce { + readonly encryptedMessage: string; + readonly nonce: string; +} + +export const encryptMessageWithPassphrase = ( + message: string, + passphrase: string, + recipientPublicKey: string, +): EncryptedMessageWithNonce => { + const { + privateKeyBytes: senderPrivateKeyBytes, + } = getPrivateAndPublicKeyBytesFromPassphrase(passphrase); + const convertedPrivateKey = Buffer.from( + convertPrivateKeyEd2Curve(senderPrivateKeyBytes), + ); + const recipientPublicKeyBytes = hexToBuffer(recipientPublicKey); + const messageInBytes = Buffer.from(message, 'utf8'); + const nonceSize = 24; + const nonce = getRandomBytes(nonceSize); + const publicKeyUint8Array = convertPublicKeyEd2Curve(recipientPublicKeyBytes); + + // This cannot be reproduced, but external library have type union with null + if (publicKeyUint8Array === null) { + throw new Error('given public key is not a valid Ed25519 public key'); + } + + const convertedPublicKey = Buffer.from(publicKeyUint8Array); + + const cipherBytes = box( + messageInBytes, + nonce, + convertedPublicKey, + convertedPrivateKey, + ); + + const nonceHex = bufferToHex(nonce); + const encryptedMessage = bufferToHex(cipherBytes); + + return { + nonce: nonceHex, + encryptedMessage, + }; +}; + +export const decryptMessageWithPassphrase = ( + cipherHex: string, + nonce: string, + passphrase: string, + senderPublicKey: string, +): string => { + const { + privateKeyBytes: recipientPrivateKeyBytes, + } = getPrivateAndPublicKeyBytesFromPassphrase(passphrase); + const convertedPrivateKey = Buffer.from( + convertPrivateKeyEd2Curve(recipientPrivateKeyBytes), + ); + const senderPublicKeyBytes = hexToBuffer(senderPublicKey); + const cipherBytes = hexToBuffer(cipherHex); + const nonceBytes = hexToBuffer(nonce); + + const publicKeyUint8Array = convertPublicKeyEd2Curve(senderPublicKeyBytes); + + // This cannot be reproduced, but external library have type union with null + if (publicKeyUint8Array === null) { + throw new Error('given public key is not a valid Ed25519 public key'); + } + + const convertedPublicKey = Buffer.from(publicKeyUint8Array); + + try { + const decoded = openBox( + cipherBytes, + nonceBytes, + convertedPublicKey, + convertedPrivateKey, + ); + + return Buffer.from(decoded).toString(); + } catch (error) { + if ( + error.message.match( + /bad nonce size|nonce must be a buffer of size crypto_box_NONCEBYTES/, + ) + ) { + throw new Error('Expected nonce to be 24 bytes.'); + } + throw new Error( + 'Something went wrong during decryption. Is this the full encrypted message?', + ); + } +}; + +const getKeyFromPassword = ( + password: string, + salt: Buffer, + iterations: number, +): Buffer => + crypto.pbkdf2Sync( + password, + salt, + iterations, + PBKDF2_KEYLEN, + PBKDF2_HASH_FUNCTION, + ); + +export interface EncryptedPassphraseObject { + readonly cipherText: string; + readonly iterations?: number; + readonly iv: string; + readonly salt: string; + readonly tag: string; + readonly version: string; +} + +const encryptAES256GCMWithPassword = ( + plainText: string, + password: string, + iterations: number = PBKDF2_ITERATIONS, +): EncryptedPassphraseObject => { + const IV_BUFFER_SIZE = 12; + const SALT_BUFFER_SIZE = 16; + const iv = crypto.randomBytes(IV_BUFFER_SIZE); + const salt = crypto.randomBytes(SALT_BUFFER_SIZE); + const key = getKeyFromPassword(password, salt, iterations); + + const cipher = crypto.createCipheriv('aes-256-gcm', key, iv); + const firstBlock = cipher.update(plainText, 'utf8'); + const encrypted = Buffer.concat([firstBlock, cipher.final()]); + const tag = cipher.getAuthTag(); + + return { + iterations, + cipherText: encrypted.toString('hex'), + iv: iv.toString('hex'), + salt: salt.toString('hex'), + tag: tag.toString('hex'), + version: ENCRYPTION_VERSION, + }; +}; + +const getTagBuffer = (tag: string): Buffer => { + const TAG_BUFFER_SIZE = 16; + const tagBuffer = hexToBuffer(tag, 'Tag'); + if (tagBuffer.length !== TAG_BUFFER_SIZE) { + throw new Error('Tag must be 16 bytes.'); + } + + return tagBuffer; +}; + +const decryptAES256GCMWithPassword = ( + encryptedPassphrase: EncryptedPassphraseObject, + password: string, +): string => { + const { + iterations = PBKDF2_ITERATIONS, + cipherText, + iv, + salt, + tag, + } = encryptedPassphrase; + + const tagBuffer = getTagBuffer(tag); + const key = getKeyFromPassword( + password, + hexToBuffer(salt, 'Salt'), + iterations, + ); + + const decipher = crypto.createDecipheriv( + 'aes-256-gcm', + key, + hexToBuffer(iv, 'IV'), + ); + decipher.setAuthTag(tagBuffer); + const firstBlock = decipher.update(hexToBuffer(cipherText, 'Cipher text')); + const decrypted = Buffer.concat([firstBlock, decipher.final()]); + + return decrypted.toString(); +}; + +export const encryptPassphraseWithPassword = encryptAES256GCMWithPassword; + +export const decryptPassphraseWithPassword = decryptAES256GCMWithPassword; diff --git a/elements/lisk-cryptography/src/hash.ts b/elements/lisk-cryptography/src/hash.ts new file mode 100644 index 00000000000..a25e84044de --- /dev/null +++ b/elements/lisk-cryptography/src/hash.ts @@ -0,0 +1,45 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as crypto from 'crypto'; +import { hexToBuffer } from './buffer'; + +const cryptoHashSha256 = (data: Buffer): Buffer => { + const dataHash = crypto.createHash('sha256'); + dataHash.update(data); + + return dataHash.digest(); +}; + +export const hash = (data: Buffer | string, format?: string): Buffer => { + if (Buffer.isBuffer(data)) { + return cryptoHashSha256(data); + } + + if (typeof data === 'string' && typeof format === 'string') { + if (!['utf8', 'hex'].includes(format)) { + throw new Error( + 'Unsupported string format. Currently only `hex` and `utf8` are supported.', + ); + } + const encoded = + format === 'utf8' ? Buffer.from(data, 'utf8') : hexToBuffer(data); + + return cryptoHashSha256(encoded); + } + + throw new Error( + 'Unsupported data format. Currently only Buffers or `hex` and `utf8` strings are supported.', + ); +}; diff --git a/elements/lisk-cryptography/src/index.ts b/elements/lisk-cryptography/src/index.ts new file mode 100644 index 00000000000..51902b5b7e3 --- /dev/null +++ b/elements/lisk-cryptography/src/index.ts @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as constants from './constants'; + +export * from './buffer'; +export * from './convert'; +export * from './encrypt'; +export * from './hash'; +export * from './keys'; +export * from './sign'; + +export { constants }; diff --git a/elements/lisk-cryptography/src/keys.ts b/elements/lisk-cryptography/src/keys.ts new file mode 100644 index 00000000000..1dd2c2f9ad9 --- /dev/null +++ b/elements/lisk-cryptography/src/keys.ts @@ -0,0 +1,81 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { bufferToHex, hexToBuffer } from './buffer'; +import { getAddressFromPublicKey } from './convert'; +import { hash } from './hash'; +import { getKeyPair, getPublicKey } from './nacl'; + +export interface KeypairBytes { + readonly privateKeyBytes: Buffer; + readonly publicKeyBytes: Buffer; +} + +export interface Keypair { + readonly privateKey: string; + readonly publicKey: string; +} + +export const getPrivateAndPublicKeyBytesFromPassphrase = ( + passphrase: string, +): KeypairBytes => { + const hashed = hash(passphrase, 'utf8'); + const { publicKeyBytes, privateKeyBytes } = getKeyPair(hashed); + + return { + privateKeyBytes, + publicKeyBytes, + }; +}; + +export const getPrivateAndPublicKeyFromPassphrase = ( + passphrase: string, +): Keypair => { + const { + privateKeyBytes, + publicKeyBytes, + } = getPrivateAndPublicKeyBytesFromPassphrase(passphrase); + + return { + privateKey: bufferToHex(privateKeyBytes), + publicKey: bufferToHex(publicKeyBytes), + }; +}; + +export const getKeys = getPrivateAndPublicKeyFromPassphrase; + +export const getAddressAndPublicKeyFromPassphrase = ( + passphrase: string, +): { readonly address: string; readonly publicKey: string } => { + const { publicKey } = getKeys(passphrase); + const address = getAddressFromPublicKey(publicKey); + + return { + address, + publicKey, + }; +}; + +export const getAddressFromPassphrase = (passphrase: string): string => { + const { publicKey } = getKeys(passphrase); + + return getAddressFromPublicKey(publicKey); +}; + +export const getAddressFromPrivateKey = (privateKey: string): string => { + const publicKeyBytes = getPublicKey(hexToBuffer(privateKey)); + const publicKey = bufferToHex(publicKeyBytes); + + return getAddressFromPublicKey(publicKey); +}; diff --git a/elements/lisk-cryptography/src/nacl/fast.ts b/elements/lisk-cryptography/src/nacl/fast.ts new file mode 100644 index 00000000000..35cadd04a42 --- /dev/null +++ b/elements/lisk-cryptography/src/nacl/fast.ts @@ -0,0 +1,111 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +// tslint:disable-next-line no-implicit-dependencies +import * as sodium from 'sodium-native'; +import { NaclInterface } from './nacl_types'; + +export const box: NaclInterface['box'] = ( + messageInBytes, + nonceInBytes, + convertedPublicKey, + convertedPrivateKey, +) => { + const cipherBytes = Buffer.alloc( + messageInBytes.length + sodium.crypto_box_MACBYTES, + ); + sodium.crypto_box_easy( + cipherBytes, + messageInBytes, + nonceInBytes, + convertedPublicKey, + convertedPrivateKey, + ); + + return cipherBytes; +}; + +export const openBox: NaclInterface['openBox'] = ( + cipherBytes, + nonceBytes, + convertedPublicKey, + convertedPrivateKey, +) => { + const plainText = Buffer.alloc( + cipherBytes.length - sodium.crypto_box_MACBYTES, + ); + // Returns false if decryption fails + if ( + !sodium.crypto_box_open_easy( + plainText, + cipherBytes, + nonceBytes, + convertedPublicKey, + convertedPrivateKey, + ) + ) { + throw new Error('Failed to decrypt message'); + } + + return plainText; +}; + +export const signDetached: NaclInterface['signDetached'] = ( + messageBytes, + privateKeyBytes, +) => { + const signatureBytes = Buffer.alloc(sodium.crypto_sign_BYTES); + sodium.crypto_sign_detached(signatureBytes, messageBytes, privateKeyBytes); + + return signatureBytes; +}; + +export const verifyDetached: NaclInterface['verifyDetached'] = ( + messageBytes, + signatureBytes, + publicKeyBytes, +) => + sodium.crypto_sign_verify_detached( + signatureBytes, + messageBytes, + publicKeyBytes, + ); + +export const getRandomBytes: NaclInterface['getRandomBytes'] = length => { + const nonce = Buffer.alloc(length); + sodium.randombytes_buf(nonce); + + return nonce; +}; + +export const getKeyPair: NaclInterface['getKeyPair'] = hashedSeed => { + const publicKeyBytes = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES); + const privateKeyBytes = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES); + + sodium.crypto_sign_seed_keypair(publicKeyBytes, privateKeyBytes, hashedSeed); + + return { + publicKeyBytes, + privateKeyBytes, + }; +}; + +export const getPublicKey: NaclInterface['getPublicKey'] = privateKey => { + const publicKeyBytes = Buffer.alloc(sodium.crypto_sign_PUBLICKEYBYTES); + const privateKeyBytes = Buffer.alloc(sodium.crypto_sign_SECRETKEYBYTES); + + sodium.crypto_sign_seed_keypair(publicKeyBytes, privateKeyBytes, privateKey); + + return publicKeyBytes; +}; diff --git a/elements/lisk-cryptography/src/nacl/index.ts b/elements/lisk-cryptography/src/nacl/index.ts new file mode 100644 index 00000000000..5198f546dd1 --- /dev/null +++ b/elements/lisk-cryptography/src/nacl/index.ts @@ -0,0 +1,45 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { NaclInterface } from './nacl_types'; + +// tslint:disable-next-line no-let +let lib: NaclInterface; + +try { + if (process.env.NACL_FAST === 'disable') { + throw new Error('Use tweetnacl'); + } + // Require used for conditional importing + // tslint:disable-next-line no-var-requires no-require-imports + lib = require('./fast'); +} catch (err) { + process.env.NACL_FAST = 'disable'; + // tslint:disable-next-line no-var-requires no-require-imports + lib = require('./slow'); +} + +export const NACL_SIGN_PUBLICKEY_LENGTH = 32; + +export const NACL_SIGN_SIGNATURE_LENGTH = 64; + +export const { + box, + openBox, + signDetached, + verifyDetached, + getRandomBytes, + getKeyPair, + getPublicKey, +} = lib; diff --git a/elements/lisk-cryptography/src/nacl/nacl_types.ts b/elements/lisk-cryptography/src/nacl/nacl_types.ts new file mode 100644 index 00000000000..8930ae72617 --- /dev/null +++ b/elements/lisk-cryptography/src/nacl/nacl_types.ts @@ -0,0 +1,25 @@ +import { KeypairBytes } from '../keys'; + +export interface NaclInterface { + box( + messageInBytes: Buffer, + nonceInBytes: Buffer, + convertedPublicKey: Buffer, + convertedPrivateKey: Buffer, + ): Buffer; + getKeyPair(hashedSeed: Buffer): KeypairBytes; + getPublicKey(privateKey: Buffer): Buffer; + getRandomBytes(length: number): Buffer; + openBox( + cipherBytes: Buffer, + nonceBytes: Buffer, + convertedPublicKey: Buffer, + convertedPrivateKey: Buffer, + ): Buffer; + signDetached(messageBytes: Buffer, privateKeyBytes: Buffer): Buffer; + verifyDetached( + messageBytes: Buffer, + signatureBytes: Buffer, + publicKeyBytes: Buffer, + ): boolean; +} diff --git a/elements/lisk-cryptography/src/nacl/slow.ts b/elements/lisk-cryptography/src/nacl/slow.ts new file mode 100644 index 00000000000..e75383a2f33 --- /dev/null +++ b/elements/lisk-cryptography/src/nacl/slow.ts @@ -0,0 +1,82 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as tweetnacl from 'tweetnacl'; +import { NaclInterface } from './nacl_types'; + +export const box: NaclInterface['box'] = ( + messageInBytes, + nonceInBytes, + convertedPublicKey, + convertedPrivateKey, +) => + Buffer.from( + tweetnacl.box( + messageInBytes, + nonceInBytes, + convertedPublicKey, + convertedPrivateKey, + ), + ); + +export const openBox: NaclInterface['openBox'] = ( + cipherBytes, + nonceBytes, + convertedPublicKey, + convertedPrivateKey, +) => { + const originalMessage = tweetnacl.box.open( + cipherBytes, + nonceBytes, + convertedPublicKey, + convertedPrivateKey, + ); + // Returns null if decryption fails + if (originalMessage === null) { + throw new Error('Failed to decrypt message'); + } + + return Buffer.from(originalMessage); +}; + +export const signDetached: NaclInterface['signDetached'] = ( + messageBytes, + privateKeyBytes, +) => Buffer.from(tweetnacl.sign.detached(messageBytes, privateKeyBytes)); + +export const verifyDetached: NaclInterface['verifyDetached'] = + // tslint:disable-next-line no-unbound-method + tweetnacl.sign.detached.verify; + +export const getRandomBytes: NaclInterface['getRandomBytes'] = length => + Buffer.from(tweetnacl.randomBytes(length)); + +export const getKeyPair: NaclInterface['getKeyPair'] = hashedSeed => { + const { publicKey, secretKey } = tweetnacl.sign.keyPair.fromSeed(hashedSeed); + + return { + privateKeyBytes: Buffer.from(secretKey), + publicKeyBytes: Buffer.from(publicKey), + }; +}; + +const PRIVATE_KEY_LENGTH = 32; + +export const getPublicKey: NaclInterface['getPublicKey'] = privateKey => { + const { publicKey } = tweetnacl.sign.keyPair.fromSeed( + privateKey.slice(0, PRIVATE_KEY_LENGTH), + ); + + return Buffer.from(publicKey); +}; diff --git a/elements/lisk-cryptography/src/sign.ts b/elements/lisk-cryptography/src/sign.ts new file mode 100644 index 00000000000..adb55861587 --- /dev/null +++ b/elements/lisk-cryptography/src/sign.ts @@ -0,0 +1,251 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { encode as encodeVarInt } from 'varuint-bitcoin'; +import { bufferToHex, hexToBuffer } from './buffer'; +import { SIGNED_MESSAGE_PREFIX } from './constants'; +import { hash } from './hash'; +import { getPrivateAndPublicKeyBytesFromPassphrase } from './keys'; +import { + NACL_SIGN_PUBLICKEY_LENGTH, + NACL_SIGN_SIGNATURE_LENGTH, + signDetached, + verifyDetached, +} from './nacl'; + +const createHeader = (text: string): string => `-----${text}-----`; +const signedMessageHeader = createHeader('BEGIN LISK SIGNED MESSAGE'); +const messageHeader = createHeader('MESSAGE'); +const publicKeyHeader = createHeader('PUBLIC KEY'); +const secondPublicKeyHeader = createHeader('SECOND PUBLIC KEY'); +const signatureHeader = createHeader('SIGNATURE'); +const secondSignatureHeader = createHeader('SECOND SIGNATURE'); +const signatureFooter = createHeader('END LISK SIGNED MESSAGE'); + +const SIGNED_MESSAGE_PREFIX_BYTES = Buffer.from(SIGNED_MESSAGE_PREFIX, 'utf8'); +const SIGNED_MESSAGE_PREFIX_LENGTH = encodeVarInt(SIGNED_MESSAGE_PREFIX.length); + +export interface SignedMessageWithOnePassphrase { + readonly message: string; + readonly publicKey: string; + readonly signature: string; +} +export const digestMessage = (message: string): Buffer => { + const msgBytes = Buffer.from(message, 'utf8'); + const msgLenBytes = encodeVarInt(message.length); + const dataBytes = Buffer.concat([ + SIGNED_MESSAGE_PREFIX_LENGTH, + SIGNED_MESSAGE_PREFIX_BYTES, + msgLenBytes, + msgBytes, + ]); + + return hash(hash(dataBytes)); +}; + +export const signMessageWithPassphrase = ( + message: string, + passphrase: string, +): SignedMessageWithOnePassphrase => { + const msgBytes = digestMessage(message); + const { + privateKeyBytes, + publicKeyBytes, + } = getPrivateAndPublicKeyBytesFromPassphrase(passphrase); + const signature = signDetached(msgBytes, privateKeyBytes); + + return { + message, + publicKey: bufferToHex(publicKeyBytes), + signature: bufferToHex(signature), + }; +}; + +export const verifyMessageWithPublicKey = ({ + message, + publicKey, + signature, +}: SignedMessageWithOnePassphrase): boolean => { + const msgBytes = digestMessage(message); + const signatureBytes = hexToBuffer(signature); + const publicKeyBytes = hexToBuffer(publicKey); + + if (publicKeyBytes.length !== NACL_SIGN_PUBLICKEY_LENGTH) { + throw new Error( + `Invalid publicKey, expected ${NACL_SIGN_PUBLICKEY_LENGTH}-byte publicKey`, + ); + } + + if (signatureBytes.length !== NACL_SIGN_SIGNATURE_LENGTH) { + throw new Error( + `Invalid signature length, expected ${NACL_SIGN_SIGNATURE_LENGTH}-byte signature`, + ); + } + + return verifyDetached(msgBytes, signatureBytes, publicKeyBytes); +}; + +export interface SignedMessageWithTwoPassphrases { + readonly message: string; + readonly publicKey: string; + readonly secondPublicKey: string; + readonly secondSignature: string; + readonly signature: string; +} + +export const signMessageWithTwoPassphrases = ( + message: string, + passphrase: string, + secondPassphrase: string, +): SignedMessageWithTwoPassphrases => { + const msgBytes = digestMessage(message); + const keypairBytes = getPrivateAndPublicKeyBytesFromPassphrase(passphrase); + const secondKeypairBytes = getPrivateAndPublicKeyBytesFromPassphrase( + secondPassphrase, + ); + + const signature = signDetached(msgBytes, keypairBytes.privateKeyBytes); + const secondSignature = signDetached( + msgBytes, + secondKeypairBytes.privateKeyBytes, + ); + + return { + message, + publicKey: bufferToHex(keypairBytes.publicKeyBytes), + secondPublicKey: bufferToHex(secondKeypairBytes.publicKeyBytes), + signature: bufferToHex(signature), + secondSignature: bufferToHex(secondSignature), + }; +}; + +export const verifyMessageWithTwoPublicKeys = ({ + message, + signature, + secondSignature, + publicKey, + secondPublicKey, +}: SignedMessageWithTwoPassphrases) => { + const messageBytes = digestMessage(message); + const signatureBytes = hexToBuffer(signature); + const secondSignatureBytes = hexToBuffer(secondSignature); + const publicKeyBytes = hexToBuffer(publicKey); + const secondPublicKeyBytes = hexToBuffer(secondPublicKey); + + if (signatureBytes.length !== NACL_SIGN_SIGNATURE_LENGTH) { + throw new Error( + `Invalid first signature length, expected ${NACL_SIGN_SIGNATURE_LENGTH}-byte signature`, + ); + } + + if (secondSignatureBytes.length !== NACL_SIGN_SIGNATURE_LENGTH) { + throw new Error( + `Invalid second signature length, expected ${NACL_SIGN_SIGNATURE_LENGTH}-byte signature`, + ); + } + + if (publicKeyBytes.length !== NACL_SIGN_PUBLICKEY_LENGTH) { + throw new Error( + `Invalid first publicKey, expected ${NACL_SIGN_PUBLICKEY_LENGTH}-byte publicKey`, + ); + } + + if (secondPublicKeyBytes.length !== NACL_SIGN_PUBLICKEY_LENGTH) { + throw new Error( + `Invalid second publicKey, expected ${NACL_SIGN_PUBLICKEY_LENGTH}-byte publicKey`, + ); + } + + const verifyFirstSignature = () => + verifyDetached(messageBytes, signatureBytes, publicKeyBytes); + const verifySecondSignature = () => + verifyDetached(messageBytes, secondSignatureBytes, secondPublicKeyBytes); + + return verifyFirstSignature() && verifySecondSignature(); +}; + +export interface SingleOrDoubleSignedMessage { + readonly message: string; + readonly publicKey: string; + readonly secondPublicKey?: string; + readonly secondSignature?: string; + readonly signature: string; +} + +export const printSignedMessage = ({ + message, + signature, + publicKey, + secondSignature, + secondPublicKey, +}: SingleOrDoubleSignedMessage): string => + [ + signedMessageHeader, + messageHeader, + message, + publicKeyHeader, + publicKey, + secondPublicKey ? secondPublicKeyHeader : undefined, + secondPublicKey, + signatureHeader, + signature, + secondSignature ? secondSignatureHeader : undefined, + secondSignature, + signatureFooter, + ] + .filter(Boolean) + .join('\n'); + +export const signAndPrintMessage = ( + message: string, + passphrase: string, + secondPassphrase?: string, +): string => { + const signedMessage: + | SignedMessageWithOnePassphrase + | SignedMessageWithTwoPassphrases = secondPassphrase + ? signMessageWithTwoPassphrases(message, passphrase, secondPassphrase) + : signMessageWithPassphrase(message, passphrase); + + return printSignedMessage(signedMessage); +}; + +export const signDataWithPrivateKey = ( + data: Buffer, + privateKey: Buffer, +): string => { + const signature = signDetached(data, privateKey); + + return bufferToHex(signature); +}; + +export const signDataWithPassphrase = ( + data: Buffer, + passphrase: string, +): string => { + const { privateKeyBytes } = getPrivateAndPublicKeyBytesFromPassphrase( + passphrase, + ); + + return signDataWithPrivateKey(data, privateKeyBytes); +}; + +export const signData = signDataWithPassphrase; + +export const verifyData = ( + data: Buffer, + signature: string, + publicKey: string, +): boolean => + verifyDetached(data, hexToBuffer(signature), hexToBuffer(publicKey)); diff --git a/elements/lisk-cryptography/test/_global_hooks.ts b/elements/lisk-cryptography/test/_global_hooks.ts new file mode 100644 index 00000000000..21464e90f21 --- /dev/null +++ b/elements/lisk-cryptography/test/_global_hooks.ts @@ -0,0 +1,3 @@ +afterEach(() => { + return sandbox.restore(); +}); diff --git a/elements/lisk-cryptography/test/_setup.ts b/elements/lisk-cryptography/test/_setup.ts new file mode 100644 index 00000000000..a28020ba1c6 --- /dev/null +++ b/elements/lisk-cryptography/test/_setup.ts @@ -0,0 +1,51 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { Assertion } from 'chai'; +import 'chai/register-expect'; +import * as sinon from 'sinon'; + +process.env.NODE_ENV = 'test'; + +Assertion.addProperty('hexString', function handleAssert( + this: Chai.ChaiStatic, +) { + const actual = this._obj; + + new Assertion(actual).to.be.a('string'); + + const expected = Buffer.from(actual, 'hex').toString('hex'); + this.assert( + expected === actual, + 'expected #{this} to be a hexString', + 'expected #{this} not to be a hexString', + ); +}); + +Assertion.addProperty('integer', function handleAssert(this: Chai.ChaiStatic) { + const actual = this._obj; + + new Assertion(actual).to.be.a('number'); + + const expected = parseInt(actual, 10); + this.assert( + actual === expected, + 'expected #{this} to be an integer', + 'expected #{this} not to be an integer', + ); +}); + +global.sandbox = sinon.createSandbox({ + useFakeTimers: true, +}); diff --git a/elements/lisk-cryptography/test/buffer.ts b/elements/lisk-cryptography/test/buffer.ts new file mode 100644 index 00000000000..e78da8ad1b2 --- /dev/null +++ b/elements/lisk-cryptography/test/buffer.ts @@ -0,0 +1,126 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + bigNumberToBuffer, + bufferToBigNumberString, + bufferToHex, + hexToBuffer, +} from '../src/buffer'; + +describe('buffer', () => { + const defaultBuffer = Buffer.from('\xe5\xe4\xf6'); + const defaultHex = 'c3a5c3a4c3b6'; + + describe('#bufferToHex', () => { + it('should create a hex string from a Buffer', () => { + const hex = bufferToHex(defaultBuffer); + return expect(hex).to.be.equal(defaultHex); + }); + }); + + describe('#hexToBuffer', () => { + it('should create a Buffer from a hex string', () => { + const buffer = hexToBuffer(defaultHex); + return expect(buffer).to.be.eql(defaultBuffer); + }); + + it('should throw TypeError with number', () => { + return expect(hexToBuffer.bind(null, 123 as any)).to.throw( + TypeError, + 'Argument must be a string.', + ); + }); + + it('should throw TypeError with object', () => { + return expect(hexToBuffer.bind(null, {} as any)).to.throw( + TypeError, + 'Argument must be a string.', + ); + }); + + it('should throw an error for a non-string input with custom argument name', () => { + return expect(hexToBuffer.bind(null, {} as any, 'Custom')).to.throw( + 'Custom must be a string.', + ); + }); + + it('should throw TypeError with non hex string', () => { + return expect(hexToBuffer.bind(null, 'yKJj')).to.throw( + TypeError, + 'Argument must be a valid hex string.', + ); + }); + + it('should throw TypeError with partially correct hex string', () => { + return expect(hexToBuffer.bind(null, 'Abxzzzz')).to.throw( + TypeError, + 'Argument must be a valid hex string.', + ); + }); + + it('should throw TypeError with odd number of string with partially correct hex string', () => { + return expect(hexToBuffer.bind(null, 'Abxzzab')).to.throw( + TypeError, + 'Argument must be a valid hex string.', + ); + }); + + it('should throw TypeError with odd number hex string with invalid hex', () => { + return expect(hexToBuffer.bind(null, '123xxxx')).to.throw( + TypeError, + 'Argument must be a valid hex string.', + ); + }); + + it('should throw an error for a non-hex string input with custom argument name', () => { + return expect(hexToBuffer.bind(null, 'yKJj', 'Custom')).to.throw( + 'Custom must be a valid hex string.', + ); + }); + + it('should throw TypeError with odd-length hex string', () => { + return expect(hexToBuffer.bind(null, 'c3a5c3a4c3b6a')).to.throw( + TypeError, + 'Argument must have a valid length of hex string.', + ); + }); + + it('should throw an error for an odd-length hex string input with custom argument name', () => { + return expect(hexToBuffer.bind(null, 'c3a5c3a4c3b6a', 'Custom')).to.throw( + 'Custom must have a valid length of hex string.', + ); + }); + }); + + describe('#bigNumberToBuffer', () => { + it('should convert a big number to a buffer', () => { + const bigNumber = '58191285901858109'; + const addressSize = 8; + const expectedBuffer = Buffer.from('00cebcaa8d34153d', 'hex'); + return expect(bigNumberToBuffer(bigNumber, addressSize)).to.be.eql( + expectedBuffer, + ); + }); + }); + + describe('#bufferToBigNumberString', () => { + it('should convert a buffer to a big number', () => { + const bigNumber = '58191285901858109'; + const buffer = Buffer.from('00cebcaa8d34153d', 'hex'); + return expect(bufferToBigNumberString(buffer)).to.be.equal(bigNumber); + }); + }); +}); diff --git a/elements/lisk-cryptography/test/convert.ts b/elements/lisk-cryptography/test/convert.ts new file mode 100644 index 00000000000..b089fda0786 --- /dev/null +++ b/elements/lisk-cryptography/test/convert.ts @@ -0,0 +1,229 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + getFirstEightBytesReversed, + toAddress, + getAddressFromPublicKey, + convertPublicKeyEd2Curve, + convertPrivateKeyEd2Curve, + stringifyEncryptedPassphrase, + parseEncryptedPassphrase, +} from '../src/convert'; +// Require is used for stubbing +const hashModule = require('../src/hash'); + +describe('convert', () => { + // keys for passphrase 'secret'; + const defaultPrivateKey = + '2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const defaultPublicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const defaultPublicKeyHash = Buffer.from( + '3a971fd02b4a07fc20aad1936d3cb1d263b96e0ffd938625e5c0db1ad8ba2a29', + 'hex', + ); + const defaultPrivateKeyCurve = Buffer.from( + '68b211b2c01cc88690ba76a07895a5b4805e1c11fdd3af4c863e6d4efeb14378', + 'hex', + ); + const defaultPublicKeyCurve = Buffer.from( + '6f9d780305bda43dd47a291d897f2d8845a06160632d82fb1f209fdd46ed3c1e', + 'hex', + ); + const defaultAddress = '18160565574430594874L'; + const defaultStringWithMoreThanEightCharacters = '0123456789'; + const defaultFirstEightCharactersReversed = '76543210'; + const defaultDataForBuffer = 'Hello!'; + const defaultAddressFromBuffer = '79600447942433L'; + + describe('#getFirstEightBytesReversed', () => { + it('should get the first eight bytes reversed from a Buffer', () => { + const bufferEntry = Buffer.from(defaultStringWithMoreThanEightCharacters); + const reversedAndCut = getFirstEightBytesReversed(bufferEntry); + return expect(reversedAndCut).to.be.eql( + Buffer.from(defaultFirstEightCharactersReversed), + ); + }); + + it('should get the first eight bytes reversed from a string', () => { + const reversedAndCut = getFirstEightBytesReversed( + defaultStringWithMoreThanEightCharacters, + ); + return expect(reversedAndCut).to.be.eql( + Buffer.from(defaultFirstEightCharactersReversed), + ); + }); + }); + + describe('#toAddress', () => { + it('should create an address from a buffer', () => { + const bufferInit = Buffer.from(defaultDataForBuffer); + const address = toAddress(bufferInit); + return expect(address).to.be.eql(defaultAddressFromBuffer); + }); + + it('should throw on more than 8 bytes as input', () => { + const bufferExceedError = + 'The buffer for Lisk addresses must not have more than 8 bytes'; + const bufferInit = Buffer.from(defaultStringWithMoreThanEightCharacters); + return expect(toAddress.bind(null, bufferInit)).to.throw( + bufferExceedError, + ); + }); + }); + + describe('#getAddressFromPublicKey', () => { + beforeEach(() => { + return sandbox.stub(hashModule, 'hash').returns(defaultPublicKeyHash); + }); + + it('should generate address from publicKey', () => { + const address = getAddressFromPublicKey(defaultPublicKey); + return expect(address).to.be.equal(defaultAddress); + }); + }); + + describe('#convertPublicKeyEd2Curve', () => { + it('should convert publicKey ED25519 to Curve25519 key', () => { + const result = convertPublicKeyEd2Curve( + Buffer.from(defaultPublicKey, 'hex'), + ); + expect(result).to.not.be.null; + const curveRepresentation = result as Buffer; + return expect( + defaultPublicKeyCurve.equals(Buffer.from(curveRepresentation)), + ).to.be.true; + }); + }); + + describe('#convertPrivateKeyEd2Curve', () => { + it('should convert privateKey ED25519 to Curve25519 key', () => { + const curveRepresentation = convertPrivateKeyEd2Curve( + Buffer.from(defaultPrivateKey, 'hex'), + ); + return expect( + defaultPrivateKeyCurve.equals(Buffer.from(curveRepresentation)), + ).to.be.true; + }); + }); + + describe('#stringifyEncryptedPassphrase', () => { + it('should throw an error if encrypted passphrase is not an object', () => { + const encryptedPassphrase = + 'salt=e8c7dae4c893e458e0ebb8bff9a36d84&cipherText=c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333&iv=1a2206e426c714091b7e48f6&tag=3a9d9f9f9a92c9a58296b8df64820c15&version=1'; + return expect( + stringifyEncryptedPassphrase.bind(null, encryptedPassphrase as any), + ).to.throw('Encrypted passphrase to stringify must be an object.'); + }); + + it('should format an encrypted passphrase as a string', () => { + const encryptedPassphrase = { + salt: 'e8c7dae4c893e458e0ebb8bff9a36d84', + cipherText: + 'c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333', + iv: '1a2206e426c714091b7e48f6', + tag: '3a9d9f9f9a92c9a58296b8df64820c15', + version: '1', + }; + const stringifiedEncryptedPassphrase = + 'salt=e8c7dae4c893e458e0ebb8bff9a36d84&cipherText=c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333&iv=1a2206e426c714091b7e48f6&tag=3a9d9f9f9a92c9a58296b8df64820c15&version=1'; + return expect(stringifyEncryptedPassphrase(encryptedPassphrase)).to.equal( + stringifiedEncryptedPassphrase, + ); + }); + + it('should format an encrypted passphrase with custom iterations as a string', () => { + const encryptedPassphrase = { + iterations: 1, + salt: 'e8c7dae4c893e458e0ebb8bff9a36d84', + cipherText: + 'c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333', + iv: '1a2206e426c714091b7e48f6', + tag: '3a9d9f9f9a92c9a58296b8df64820c15', + version: '1', + }; + const stringifiedEncryptedPassphrase = + 'iterations=1&salt=e8c7dae4c893e458e0ebb8bff9a36d84&cipherText=c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333&iv=1a2206e426c714091b7e48f6&tag=3a9d9f9f9a92c9a58296b8df64820c15&version=1'; + return expect(stringifyEncryptedPassphrase(encryptedPassphrase)).to.equal( + stringifiedEncryptedPassphrase, + ); + }); + }); + + describe('#parseEncryptedPassphrase', () => { + it('should throw an error if encrypted passphrase is not a string', () => { + const stringifiedEncryptedPassphrase = { abc: 'def' }; + return expect( + parseEncryptedPassphrase.bind( + null, + stringifiedEncryptedPassphrase as any, + ), + ).to.throw('Encrypted passphrase to parse must be a string.'); + }); + + it('should throw an error if iterations is present but not a valid number', () => { + const stringifiedEncryptedPassphrase = + 'iterations=null&salt=e8c7dae4c893e458e0ebb8bff9a36d84&cipherText=c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333&iv=1a2206e426c714091b7e48f6&tag=3a9d9f9f9a92c9a58296b8df64820c15&version=1'; + return expect( + parseEncryptedPassphrase.bind(null, stringifiedEncryptedPassphrase), + ).to.throw('Could not parse iterations.'); + }); + + it('should throw an error if multiple values are in a key', () => { + const stringifiedEncryptedPassphrase = + 'salt=xxx&salt=e8c7dae4c893e458e0ebb8bff9a36d84&cipherText=c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333&iv=1a2206e426c714091b7e48f6&tag=3a9d9f9f9a92c9a58296b8df64820c15&version=1'; + return expect( + parseEncryptedPassphrase.bind(null, stringifiedEncryptedPassphrase), + ).to.throw( + 'Encrypted passphrase to parse must have only one value per key.', + ); + }); + + it('should parse an encrypted passphrase string', () => { + const stringifiedEncryptedPassphrase = + 'salt=e8c7dae4c893e458e0ebb8bff9a36d84&cipherText=c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333&iv=1a2206e426c714091b7e48f6&tag=3a9d9f9f9a92c9a58296b8df64820c15&version=1'; + const encryptedPassphrase = { + iterations: undefined, + salt: 'e8c7dae4c893e458e0ebb8bff9a36d84', + cipherText: + 'c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333', + iv: '1a2206e426c714091b7e48f6', + tag: '3a9d9f9f9a92c9a58296b8df64820c15', + version: '1', + }; + return expect( + parseEncryptedPassphrase(stringifiedEncryptedPassphrase), + ).to.eql(encryptedPassphrase); + }); + + it('should parse an encrypted passphrase string with custom iterations', () => { + const stringifiedEncryptedPassphrase = + 'iterations=1&salt=e8c7dae4c893e458e0ebb8bff9a36d84&cipherText=c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333&iv=1a2206e426c714091b7e48f6&tag=3a9d9f9f9a92c9a58296b8df64820c15&version=1'; + const encryptedPassphrase = { + iterations: 1, + salt: 'e8c7dae4c893e458e0ebb8bff9a36d84', + cipherText: + 'c0fab123d83c386ffacef9a171b6e0e0e9d913e58b7972df8e5ef358afbc65f99c9a2b6fe7716f708166ed72f59f007d2f96a91f48f0428dd51d7c9962e0c6a5fc27ca0722038f1f2cf16333', + iv: '1a2206e426c714091b7e48f6', + tag: '3a9d9f9f9a92c9a58296b8df64820c15', + version: '1', + }; + return expect( + parseEncryptedPassphrase(stringifiedEncryptedPassphrase), + ).to.eql(encryptedPassphrase); + }); + }); +}); diff --git a/elements/lisk-cryptography/test/encrypt.ts b/elements/lisk-cryptography/test/encrypt.ts new file mode 100644 index 00000000000..eca8ed5ad0d --- /dev/null +++ b/elements/lisk-cryptography/test/encrypt.ts @@ -0,0 +1,418 @@ +/** Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as sinon from 'sinon'; +import { + EncryptedPassphraseObject, + EncryptedMessageWithNonce, + encryptMessageWithPassphrase, + decryptMessageWithPassphrase, + encryptPassphraseWithPassword, + decryptPassphraseWithPassword, +} from '../src/encrypt'; +// Require is used for stubbing +const convert = require('../src/convert'); +const keys = require('../src/keys'); +const hashModule = require('../src/hash'); + +describe('encrypt', () => { + const PBKDF2_ITERATIONS = 1e6; + const ENCRYPTION_VERSION = '1'; + const defaultPassphrase = + 'minute omit local rare sword knee banner pair rib museum shadow juice'; + const defaultPrivateKey = + '314852d7afb0d4c283692fef8a2cb40e30c7a5df2ed79994178c10ac168d6d977ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; + const defaultPublicKey = + '7ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; + const defaultSecondPassphrase = 'second secret'; + const defaultSecondPrivateKey = + '9ef4146f8166d32dc8051d3d9f3a0c4933e24aa8ccb439b5d9ad00078a89e2fc0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f'; + const defaultSecondPublicKey = + '0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f'; + const defaultMessage = 'Some default text.'; + const defaultPassword = 'myTotal53cr3t%&'; + const customIterations = 12; + + let defaultEncryptedMessageWithNonce: EncryptedMessageWithNonce; + + let getPrivateAndPublicKeyBytesFromPassphraseStub; + let hashStub: sinon.SinonStub; + + beforeEach(() => { + defaultEncryptedMessageWithNonce = { + encryptedMessage: + '299390b9cbb92fe6a43daece2ceaecbacd01c7c03cfdba51d693b5c0e2b65c634115', + nonce: 'df4c8b09e270d2cb3f7b3d53dfa8a6f3441ad3b14a13fb66', + }; + sandbox + .stub(convert, 'convertPrivateKeyEd2Curve') + .returns( + Buffer.from( + 'd8be8cacb03fb02f34e85030f902b635f364d6c23f090c7640e9dc9c568e7d5e', + 'hex', + ), + ); + sandbox + .stub(convert, 'convertPublicKeyEd2Curve') + .returns( + Buffer.from( + 'f245e78c83196d73452e55581ef924a1b792d352c142257aa3af13cded2e7905', + 'hex', + ), + ); + + getPrivateAndPublicKeyBytesFromPassphraseStub = sandbox.stub( + keys, + 'getPrivateAndPublicKeyBytesFromPassphrase', + ); + getPrivateAndPublicKeyBytesFromPassphraseStub + .withArgs(defaultPassphrase) + .returns({ + privateKey: Buffer.from(defaultPrivateKey, 'hex'), + publicKey: Buffer.from(defaultPublicKey, 'hex'), + }); + getPrivateAndPublicKeyBytesFromPassphraseStub + .withArgs(defaultSecondPassphrase) + .returns({ + privateKey: Buffer.from(defaultSecondPrivateKey, 'hex'), + publicKey: Buffer.from(defaultSecondPublicKey, 'hex'), + }); + + hashStub = sandbox + .stub(hashModule, 'hash') + .returns( + Buffer.from( + 'd43eed9049dd8f35106c720669a1148b2c6288d9ea517b936c33a1d84117a760', + 'hex', + ), + ); + return Promise.resolve(); + }); + + describe('#encryptMessageWithPassphrase', () => { + let encryptedMessage: EncryptedMessageWithNonce; + + beforeEach(() => { + encryptedMessage = encryptMessageWithPassphrase( + defaultMessage, + defaultPassphrase, + defaultPublicKey, + ); + return Promise.resolve(); + }); + + it('should encrypt a message', () => { + return expect(encryptedMessage) + .to.have.property('encryptedMessage') + .be.hexString.with.length(68); + }); + + it('should output the nonce', () => { + return expect(encryptedMessage) + .to.have.property('nonce') + .be.hexString.with.length(48); + }); + }); + + describe('#decryptMessageWithPassphrase', () => { + it('should be able to decrypt the message correctly using the receiver’s secret passphrase', () => { + const decryptedMessage = decryptMessageWithPassphrase( + defaultEncryptedMessageWithNonce.encryptedMessage, + defaultEncryptedMessageWithNonce.nonce, + defaultPassphrase, + defaultPublicKey, + ); + + return expect(decryptedMessage).to.be.equal(defaultMessage); + }); + + it('should inform the user if the nonce is the wrong length', () => { + return expect( + decryptMessageWithPassphrase.bind( + null, + defaultEncryptedMessageWithNonce.encryptedMessage, + defaultEncryptedMessageWithNonce.encryptedMessage.slice(0, 2), + defaultPassphrase, + defaultPublicKey, + ), + ).to.throw('Expected nonce to be 24 bytes.'); + }); + + it('should inform the user if something goes wrong during decryption', () => { + return expect( + decryptMessageWithPassphrase.bind( + null, + defaultEncryptedMessageWithNonce.encryptedMessage.slice(0, 2), + defaultEncryptedMessageWithNonce.nonce, + defaultSecondPassphrase, + defaultPublicKey, + ), + ).to.throw( + 'Something went wrong during decryption. Is this the full encrypted message?', + ); + }); + }); + + describe('encrypt and decrypt passphrase with password', () => { + beforeEach(() => { + return hashStub.returns( + Buffer.from( + 'e09dfc943d65d63f4f31e444c81afc6d5cf442c988fb87180165dd7119d3ae61', + 'hex', + ), + ); + }); + + describe('#encryptPassphraseWithPassword', () => { + let startTime: number; + let encryptedPassphrase: EncryptedPassphraseObject; + + beforeEach(() => { + startTime = Date.now(); + encryptedPassphrase = encryptPassphraseWithPassword( + defaultPassphrase, + defaultPassword, + ); + return Promise.resolve(); + }); + + it('should encrypt a passphrase', () => { + return expect(encryptedPassphrase).to.have.property('cipherText').and.be + .hexString; + }); + + it('should output the IV', () => { + return expect(encryptedPassphrase) + .to.have.property('iv') + .and.be.hexString.and.have.length(24); + }); + + it('should output the salt', () => { + return expect(encryptedPassphrase) + .to.have.property('salt') + .and.be.hexString.and.have.length(32); + }); + + it('should output the tag', () => { + return expect(encryptedPassphrase) + .to.have.property('tag') + .and.be.hexString.and.have.length(32); + }); + + it('should output the current version of Lisk Elements', () => { + return expect(encryptedPassphrase) + .to.have.property('version') + .which.is.equal(ENCRYPTION_VERSION); + }); + + it('should output the default number of iterations', () => { + return expect(encryptedPassphrase) + .to.have.property('iterations') + .equal(PBKDF2_ITERATIONS); + }); + + it('should take more than 0.5 seconds @node-only', () => { + const endTime = Date.now(); + return expect(endTime - startTime).to.be.above(500); + }); + + it('should take less than 2 seconds @node-only', () => { + const endTime = Date.now(); + return expect(endTime - startTime).to.be.below(2e3); + }); + + it('should accept and output a custom number of iterations', () => { + const encryptedPassphraseWithIterations = encryptPassphraseWithPassword( + defaultPassphrase, + defaultPassword, + customIterations, + ); + return expect(encryptedPassphraseWithIterations) + .to.have.property('iterations') + .and.equal(customIterations); + }); + }); + + describe('#decryptPassphraseWithPassword', () => { + let encryptedPassphrase = { + iterations: undefined, + cipherText: + '5cfd7bcc13022a482e7c8bd250cd73ef3eb7c49c849d5e761ce717608293f777cca8e0e18587ee307beab65bcc1b273caeb23d4985010b675391b354c38f8e84e342c1e7aa', + iv: '7b820ad6936a63152d13ffa2', + salt: 'b60036ab30da7af68c6ecf370471ce1b', + tag: '336c68fa92d414c229e5638249847774', + version: '1', + }; + + it('should decrypt a passphrase with a password', () => { + const decrypted = decryptPassphraseWithPassword( + encryptedPassphrase, + defaultPassword, + ); + return expect(decrypted).to.be.equal(defaultPassphrase); + }); + + it('should inform the user if cipherText is missing', () => { + const { + cipherText, + ...encryptedPassphraseWithoutCipherText + } = encryptedPassphrase; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithoutCipherText as any, + defaultPassword, + ), + ).to.throw('Cipher text must be a string.'); + }); + + it('should inform the user if iv is missing', () => { + const { iv, ...encryptedPassphraseWithoutIv } = encryptedPassphrase; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithoutIv as any, + defaultPassword, + ), + ).to.throw('IV must be a string.'); + }); + + it('should inform the user if salt is missing', () => { + const { salt, ...encryptedPassphraseWithoutSalt } = encryptedPassphrase; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithoutSalt as any, + defaultPassword, + ), + ).to.throw('Salt must be a string.'); + }); + + it('should inform the user if tag is missing', () => { + const { tag, ...encryptedPassphraseWithoutTag } = encryptedPassphrase; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithoutTag as any, + defaultPassword, + ), + ).to.throw('Tag must be a string.'); + }); + + it('should inform the user if the salt has been altered', () => { + const { salt, ...encryptedPassphraseWithoutSalt } = encryptedPassphrase; + const encryptedPassphraseWithAlteredSalt = { + salt: `00${encryptedPassphrase.salt.slice(2)}`, + ...encryptedPassphraseWithoutSalt, + }; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithAlteredSalt, + defaultPassword, + ), + ).to.throw('Unsupported state or unable to authenticate data'); + }); + + it('should inform the user if the tag has been shortened', () => { + const { tag, ...encryptedPassphraseWithoutTag } = encryptedPassphrase; + const encryptedPassphraseWithAlteredTag = { + tag: encryptedPassphrase.tag.slice(0, 30), + ...encryptedPassphraseWithoutTag, + }; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithAlteredTag, + defaultPassword, + ), + ).to.throw('Tag must be 16 bytes.'); + }); + + it('should inform the user if the tag is not a hex string', () => { + const { tag, ...encryptedPassphraseWithoutTag } = encryptedPassphrase; + const encryptedPassphraseWithAlteredTag = { + tag: `${encryptedPassphrase.tag.slice(0, 30)}gg`, + ...encryptedPassphraseWithoutTag, + }; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithAlteredTag, + defaultPassword, + ), + ).to.throw('Tag must be a valid hex string.'); + }); + + it('should inform the user if the tag has been altered', () => { + const { tag, ...encryptedPassphraseWithoutTag } = encryptedPassphrase; + const encryptedPassphraseWithAlteredTag = { + tag: `00${encryptedPassphrase.tag.slice(2)}`, + ...encryptedPassphraseWithoutTag, + }; + return expect( + decryptPassphraseWithPassword.bind( + null, + encryptedPassphraseWithAlteredTag, + defaultPassword, + ), + ).to.throw('Unsupported state or unable to authenticate data'); + }); + + it('should decrypt a passphrase with a password and a custom number of iterations', () => { + const encryptedPassphraseWithCustomIterations = { + iterations: 12, + cipherText: + '1f06671e13c0329aee057fee995e08a516bdacd287c7ff2714a74be6099713c87bbc3e005c63d4d3d02f8ba89b42810a5854444ad2b76855007a0925fafa7d870875beb010', + iv: '3a583b21bbac609c7df3e7e0', + salt: '245c6859a96339a7735a6cac78ccf625', + tag: '63653f1d4e8d422a42d98b25d3844792', + version: '1', + }; + const decrypted = decryptPassphraseWithPassword( + encryptedPassphraseWithCustomIterations, + defaultPassword, + ); + return expect(decrypted).to.be.equal(defaultPassphrase); + }); + }); + + describe('integration test', () => { + it('should encrypt a given passphrase with a password and decrypt it back to the original passphrase @node-only', () => { + const encryptedPassphrase = encryptPassphraseWithPassword( + defaultPassphrase, + defaultPassword, + ); + const decryptedString = decryptPassphraseWithPassword( + encryptedPassphrase, + defaultPassword, + ); + return expect(decryptedString).to.be.equal(defaultPassphrase); + }).timeout(5000); + + it('should encrypt a given passphrase with a password and custom number of iterations and decrypt it back to the original passphrase @node-only', () => { + const encryptedPassphrase = encryptPassphraseWithPassword( + defaultPassphrase, + defaultPassword, + customIterations, + ); + const decryptedString = decryptPassphraseWithPassword( + encryptedPassphrase, + defaultPassword, + ); + return expect(decryptedString).to.equal(defaultPassphrase); + }); + }); + }); +}); diff --git a/elements/lisk-cryptography/test/hash.ts b/elements/lisk-cryptography/test/hash.ts new file mode 100644 index 00000000000..2e74b779167 --- /dev/null +++ b/elements/lisk-cryptography/test/hash.ts @@ -0,0 +1,60 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { hash as hashFunction } from '../src/hash'; +import { expect } from 'chai'; + +describe('hash', () => { + const defaultText = 'text123*'; + let arrayToHash: ReadonlyArray; + let defaultHash: Buffer; + + beforeEach(() => { + defaultHash = Buffer.from( + '7607d6792843d6003c12495b54e34517a508d2a8622526aff1884422c5478971', + 'hex', + ); + arrayToHash = [1, 2, 3]; + return Promise.resolve(); + }); + + it('should generate a sha256 hash from a Buffer', () => { + const testBuffer = Buffer.from(defaultText); + const hash = hashFunction(testBuffer); + return expect(hash).to.be.eql(defaultHash); + }); + + it('should generate a sha256 hash from a utf8 string', () => { + const hash = hashFunction(defaultText, 'utf8'); + return expect(hash).to.be.eql(defaultHash); + }); + + it('should generate a sha256 hash from a hex string', () => { + const testHex = Buffer.from(defaultText).toString('hex'); + const hash = hashFunction(testHex, 'hex'); + return expect(hash).to.be.eql(defaultHash); + }); + + it('should throw on unknown format when trying a string with format "utf32"', () => { + return expect(hashFunction.bind(null, defaultText, 'utf32')).to.throw( + 'Unsupported string format. Currently only `hex` and `utf8` are supported.', + ); + }); + + it('should throw on unknown format when using an array', () => { + return expect(hashFunction.bind(null, arrayToHash as any)).to.throw( + 'Unsupported data format. Currently only Buffers or `hex` and `utf8` strings are supported.', + ); + }); +}); diff --git a/elements/lisk-cryptography/test/helpers/index.ts b/elements/lisk-cryptography/test/helpers/index.ts new file mode 100644 index 00000000000..9fbe6ab31c0 --- /dev/null +++ b/elements/lisk-cryptography/test/helpers/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export const makeInvalid = (str: string): string => { + const char = str[0] === '0' ? '1' : '0'; + return `${char}${str.slice(1)}`; +}; diff --git a/elements/lisk-cryptography/test/index.ts b/elements/lisk-cryptography/test/index.ts new file mode 100644 index 00000000000..9b7991e749b --- /dev/null +++ b/elements/lisk-cryptography/test/index.ts @@ -0,0 +1,22 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as cryptography from '../src'; +import { expect } from 'chai'; + +describe('cryptography index.js', () => { + it('should export an object', () => { + return expect(cryptography).to.be.an('object'); + }); +}); diff --git a/elements/lisk-cryptography/test/keys.ts b/elements/lisk-cryptography/test/keys.ts new file mode 100644 index 00000000000..f2a1715f920 --- /dev/null +++ b/elements/lisk-cryptography/test/keys.ts @@ -0,0 +1,145 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + Keypair, + KeypairBytes, + getPrivateAndPublicKeyFromPassphrase, + getPrivateAndPublicKeyBytesFromPassphrase, + getKeys, + getAddressAndPublicKeyFromPassphrase, + getAddressFromPassphrase, + getAddressFromPrivateKey, +} from '../src/keys'; +// Require is used for stubbing +const buffer = require('../src/buffer'); +const hashModule = require('../src/hash'); + +describe('keys', () => { + const defaultPassphrase = 'secret'; + const defaultPassphraseHash = + '2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b'; + const defaultPrivateKey = + '2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const defaultPublicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const defaultAddress = '16402986683325069355L'; + const defaultAddressAndPublicKey = { + publicKey: defaultPublicKey, + address: defaultAddress, + }; + + let bufferToHexStub; + + beforeEach(() => { + bufferToHexStub = sandbox.stub(buffer, 'bufferToHex'); + bufferToHexStub + .withArgs(Buffer.from(defaultPrivateKey, 'hex')) + .returns(defaultPrivateKey); + bufferToHexStub + .withArgs(Buffer.from(defaultPublicKey, 'hex')) + .returns(defaultPublicKey); + return sandbox + .stub(hashModule, 'hash') + .returns(Buffer.from(defaultPassphraseHash, 'hex')); + }); + + describe('#getPrivateAndPublicKeyBytesFromPassphrase', () => { + let keyPair: KeypairBytes; + + beforeEach(() => { + keyPair = getPrivateAndPublicKeyBytesFromPassphrase(defaultPassphrase); + return Promise.resolve(); + }); + + it('should create buffer publicKey', () => { + return expect( + Buffer.from(keyPair.publicKeyBytes).toString('hex'), + ).to.be.equal(defaultPublicKey); + }); + + it('should create buffer privateKey', () => { + return expect( + Buffer.from(keyPair.privateKeyBytes).toString('hex'), + ).to.be.equal(defaultPrivateKey); + }); + }); + + describe('#getPrivateAndPublicKeyFromPassphrase', () => { + let keyPair: Keypair; + + beforeEach(() => { + keyPair = getPrivateAndPublicKeyFromPassphrase(defaultPassphrase); + return Promise.resolve(); + }); + + it('should generate the correct publicKey from a passphrase', () => { + return expect(keyPair) + .to.have.property('publicKey') + .and.be.equal(defaultPublicKey); + }); + + it('should generate the correct privateKey from a passphrase', () => { + return expect(keyPair) + .to.have.property('privateKey') + .and.be.equal(defaultPrivateKey); + }); + }); + + describe('#getKeys', () => { + let keyPair: Keypair; + + beforeEach(() => { + keyPair = getKeys(defaultPassphrase); + return Promise.resolve(); + }); + + it('should generate the correct publicKey from a passphrase', () => { + return expect(keyPair) + .to.have.property('publicKey') + .and.be.equal(defaultPublicKey); + }); + + it('should generate the correct privateKey from a passphrase', () => { + return expect(keyPair) + .to.have.property('privateKey') + .and.be.equal(defaultPrivateKey); + }); + }); + + describe('#getAddressAndPublicKeyFromPassphrase', () => { + it('should create correct address and publicKey', () => { + return expect( + getAddressAndPublicKeyFromPassphrase(defaultPassphrase), + ).to.eql(defaultAddressAndPublicKey); + }); + }); + + describe('#getAddressFromPassphrase', () => { + it('should create correct address', () => { + return expect(getAddressFromPassphrase(defaultPassphrase)).to.equal( + defaultAddress, + ); + }); + }); + + describe('#getAddressFromPrivateKey', () => { + it('should create correct address', () => { + return expect( + getAddressFromPrivateKey(defaultPrivateKey.slice(0, 64)), + ).to.equal(defaultAddress); + }); + }); +}); diff --git a/elements/lisk-cryptography/test/mocha.opts b/elements/lisk-cryptography/test/mocha.opts new file mode 100644 index 00000000000..89154765d09 --- /dev/null +++ b/elements/lisk-cryptography/test/mocha.opts @@ -0,0 +1,8 @@ +--recursive +--require ts-node/register +--require tsconfig-paths/register +--require source-map-support/register +--require ./test/_setup.ts +--file ./test/_global_hooks.ts +--watch-extensions ts +--timeout 5000 diff --git a/elements/lisk-cryptography/test/nacl/index.ts b/elements/lisk-cryptography/test/nacl/index.ts new file mode 100644 index 00000000000..a433d0b5d33 --- /dev/null +++ b/elements/lisk-cryptography/test/nacl/index.ts @@ -0,0 +1,133 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { NaclInterface } from '../../src/nacl/nacl_types'; +import * as fast from '../../src/nacl/fast'; +import * as slow from '../../src/nacl/slow'; +// Require is used for stubbing +const moduleLibrary = require('module'); + +const resetTest = () => { + // Reset environment variable + delete process.env.NACL_FAST; + // Delete require cache to force it to re-load module + delete require.cache[require.resolve('../../src/nacl')]; +}; + +interface naclLibrary extends NaclInterface { + NACL_SIGN_PUBLICKEY_LENGTH: number; + NACL_SIGN_SIGNATURE_LENGTH: number; +} + +const stripConstants = (library: naclLibrary) => { + // Constants are added in ../../src/nacl/index.js + const { + NACL_SIGN_PUBLICKEY_LENGTH, + NACL_SIGN_SIGNATURE_LENGTH, + ...strippedLib + } = library; + return strippedLib; +}; + +describe('nacl index.js', () => { + let initialEnvVar: string | undefined; + before(() => { + initialEnvVar = process.env.NACL_FAST; + return Promise.resolve(); + }); + + after(() => { + if (initialEnvVar) { + process.env.NACL_FAST = initialEnvVar; + } else { + delete process.env.NACL_FAST; + } + return Promise.resolve(); + }); + + beforeEach(() => { + resetTest(); + return Promise.resolve(); + }); + + describe('nacl fast installed', () => { + beforeEach(() => { + resetTest(); + return Promise.resolve(); + }); + + it('should load nacl fast if process.env.NACL_FAST is set to enable', () => { + process.env.NACL_FAST = 'enable'; + const loadedLibrary = require('../../src/nacl'); + const strippedLibrary = stripConstants(loadedLibrary); + return expect(strippedLibrary).to.be.eql(fast); + }); + + it('should load nacl slow if process.env.NACL_FAST is set to disable', () => { + process.env.NACL_FAST = 'disable'; + const loadedLibrary = require('../../src/nacl'); + const strippedLibrary = stripConstants(loadedLibrary); + return expect(strippedLibrary).to.be.eql(slow); + }); + + it('should load nacl fast if process.env.NACL_FAST is undefined', () => { + process.env.NACL_FAST = undefined; + const loadedLibrary = require('../../src/nacl'); + const strippedLibrary = stripConstants(loadedLibrary); + return expect(strippedLibrary).to.be.eql(fast); + }); + }); + + describe('nacl fast not installed', () => { + const moduleNotFoundError = new Error('MODULE_NOT_FOUND'); + beforeEach(() => { + resetTest(); + + // "require" is a wrapper around Module._load which handles the actual loading + sandbox + .stub(moduleLibrary, '_load') + .callThrough() + .withArgs('./fast') + .throws(moduleNotFoundError); + return Promise.resolve(); + }); + + it('should set process.env.NACL_FAST to disable', () => { + require('../../src/nacl'); + return expect(process.env.NACL_FAST).to.eql('disable'); + }); + + it('should load nacl slow if process.env.NACL_FAST is set to enable', () => { + process.env.NACL_FAST = 'enable'; + const loadedLibrary = require('../../src/nacl'); + const strippedLibrary = stripConstants(loadedLibrary); + return expect(strippedLibrary).to.eql(slow); + }); + + it('should load nacl slow if process.env.NACL_FAST is set to disable', () => { + process.env.NACL_FAST = 'disable'; + const loadedLibrary = require('../../src/nacl'); + const strippedLibrary = stripConstants(loadedLibrary); + return expect(strippedLibrary).to.eql(slow); + }); + + it('should load nacl slow if process.env.NACL_FAST is undefined', () => { + process.env.NACL_FAST = undefined; + const loadedLibrary = require('../../src/nacl'); + const strippedLibrary = stripConstants(loadedLibrary); + return expect(strippedLibrary).to.eql(slow); + }); + }); +}); diff --git a/elements/lisk-cryptography/test/nacl/nacl.ts b/elements/lisk-cryptography/test/nacl/nacl.ts new file mode 100644 index 00000000000..1578e6a3b05 --- /dev/null +++ b/elements/lisk-cryptography/test/nacl/nacl.ts @@ -0,0 +1,279 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { KeypairBytes } from '../../src/keys'; +import { makeInvalid } from '../helpers'; +import { NaclInterface } from '../../src/nacl/nacl_types'; +import * as fast from '../../src/nacl/fast'; +import * as slow from '../../src/nacl/slow'; + +describe('nacl', () => { + const defaultPublicKey = + '7ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; + const defaultPrivateKey = + '314852d7afb0d4c283692fef8a2cb40e30c7a5df2ed79994178c10ac168d6d977ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; + const defaultMessage = 'Some default text.'; + const defaultSignature = + '68937004b6720d7e1902ef05a577e6d9f9ab2756286b1f2ae918f8a0e5153c15e4f410916076f750b708f8979be2430e4cfc7ebb523ae1905d2ea1f5d24ce700'; + const defaultEncryptedMessage = + 'a232e5ea10e18249efc5a0aa8ed68271fc494d02245c52277ee2e14cddd960144a65'; + const defaultNonce = 'df4c8b09e270d2cb3f7b3d53dfa8a6f3441ad3b14a13fb66'; + const defaultHash = + '314852d7afb0d4c283692fef8a2cb40e30c7a5df2ed79994178c10ac168d6d97'; + const defaultDigest = + 'aba8462bb7a1460f1e36c36a71f0b7f67d1606562001907c1b2dad08a8ce74ae'; + const defaultConvertedPublicKeyEd2Curve = + 'b8c0eecfd16c1cc4f057a6fc6d8dd3d46e4aa9625408d4bd0ba00e991326fe00'; + const defaultConvertedPrivateKeyEd2Curve = + 'b0e3276b64b086b381e11928e56f966d062dc677b7801cc594aeb2d4193e8d57'; + + const libraries = [ + { + name: 'fast', + library: fast, + }, + { + name: 'slow', + library: slow, + }, + ]; + + interface library { + name: string; + library: NaclInterface; + } + + libraries.forEach((nacl: library) => { + describe(`${nacl.name}`, () => { + const { + box, + getRandomBytes, + getKeyPair, + getPublicKey, + openBox, + signDetached, + verifyDetached, + }: NaclInterface = nacl.library; + + describe('#getRandomBytes', () => { + const size = 24; + let randomBuffer: Buffer; + + beforeEach(() => { + randomBuffer = getRandomBytes(size); + return Promise.resolve(); + }); + + it('should return an uint8array', () => { + return expect(randomBuffer).to.be.instanceOf(Uint8Array); + }); + + it('should return an uint8array of size 24', () => { + return expect(randomBuffer.length).to.be.eql(24); + }); + }); + + describe('#getKeyPair', () => { + let signedKeys: KeypairBytes; + + beforeEach(() => { + signedKeys = getKeyPair(Buffer.from(defaultHash, 'hex')); + return Promise.resolve(); + }); + + it('should create a publicKey', () => { + return expect( + Buffer.from(signedKeys.publicKeyBytes).toString('hex'), + ).to.be.eql(defaultPublicKey); + }); + + it('should create a publicKey of type uint8array', () => { + return expect(signedKeys.publicKeyBytes).to.be.instanceOf(Uint8Array); + }); + + it('should create a privateKey', () => { + return expect( + Buffer.from(signedKeys.privateKeyBytes).toString('hex'), + ).to.be.eql(defaultPrivateKey); + }); + + it('should create a privateKey of type uint8array', () => { + return expect(signedKeys.privateKeyBytes).to.be.instanceOf( + Uint8Array, + ); + }); + }); + + describe('#getPublicKey', () => { + let publicKey: Buffer; + + beforeEach(() => { + publicKey = getPublicKey(Buffer.from(defaultPrivateKey, 'hex')); + + return Promise.resolve(); + }); + + it('should create a publicKey', () => { + return expect(Buffer.from(publicKey).toString('hex')).to.be.eql( + defaultPublicKey, + ); + }); + + it('should create a publicKey when private key is 32 bytes', () => { + publicKey = getPublicKey( + Buffer.from(defaultPrivateKey, 'hex').slice(0, 32), + ); + return expect(Buffer.from(publicKey).toString('hex')).to.be.eql( + defaultPublicKey, + ); + }); + + it('should create a publicKey of type uint8array', () => { + return expect(publicKey).to.be.instanceOf(Uint8Array); + }); + }); + + describe('#signDetached', () => { + let signatureBytes: Buffer; + + beforeEach(() => { + signatureBytes = signDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(defaultPrivateKey, 'hex'), + ); + return Promise.resolve(); + }); + + it('should create a signature', () => { + return expect(Buffer.from(signatureBytes).toString('hex')).to.be.eql( + defaultSignature, + ); + }); + + it('should create a signature of type uint8array', () => { + return expect(signatureBytes).to.be.instanceOf(Uint8Array); + }); + }); + + describe('#verifyDetached', () => { + it('should return false if the signature is invalid', () => { + const verification = verifyDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(makeInvalid(defaultSignature), 'hex'), + Buffer.from(defaultPublicKey, 'hex'), + ); + return expect(verification).to.be.false; + }); + + it('should return true if the signature is valid', () => { + const verification = verifyDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(defaultSignature, 'hex'), + Buffer.from(defaultPublicKey, 'hex'), + ); + return expect(verification).to.be.true; + }); + }); + + describe('#box', () => { + let encryptedMessageBytes: Buffer; + + beforeEach(() => { + encryptedMessageBytes = box( + Buffer.from(defaultMessage, 'utf8'), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + return Promise.resolve(); + }); + + it('should encrypt a message', () => { + return expect( + Buffer.from(encryptedMessageBytes).toString('hex'), + ).to.be.eql(defaultEncryptedMessage); + }); + }); + + describe('#openBox', () => { + let decryptedMessageBytes: Buffer; + + beforeEach(() => { + decryptedMessageBytes = openBox( + Buffer.from(defaultEncryptedMessage, 'hex'), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + return Promise.resolve(); + }); + + it('should decrypt a message', () => { + return expect( + Buffer.from(decryptedMessageBytes).toString('utf8'), + ).to.be.eql(defaultMessage); + }); + + it('should throw an error for an invalid message', () => { + return expect( + openBox.bind( + null, + Buffer.from( + 'abcdef1234567890abcdef1234567890abcdef1234567890', + 'hex', + ), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ), + ).to.throw(Error, 'Failed to decrypt message'); + }); + }); + + describe('integration tests', () => { + it('should encrypt a given message with a nonce and converted key pair, and decrypt it back to the original message', () => { + const encryptedMessageBytes = box( + Buffer.from(defaultMessage, 'utf8'), + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + const decryptedMessageBytes = openBox( + encryptedMessageBytes, + Buffer.from(defaultNonce, 'hex'), + Buffer.from(defaultConvertedPublicKeyEd2Curve, 'hex'), + Buffer.from(defaultConvertedPrivateKeyEd2Curve, 'hex'), + ); + return expect( + Buffer.from(decryptedMessageBytes).toString('utf8'), + ).to.equal(defaultMessage); + }); + + it('should sign a given message and verify it using the same signature', () => { + const signatureBytes = signDetached( + Buffer.from(defaultDigest, 'hex'), + Buffer.from(defaultPrivateKey, 'hex'), + ); + const verification = verifyDetached( + Buffer.from(defaultDigest, 'hex'), + signatureBytes, + Buffer.from(defaultPublicKey, 'hex'), + ); + return expect(verification).to.be.true; + }); + }); + }); + }); +}); diff --git a/elements/lisk-cryptography/test/sign.ts b/elements/lisk-cryptography/test/sign.ts new file mode 100644 index 00000000000..6435bd88cad --- /dev/null +++ b/elements/lisk-cryptography/test/sign.ts @@ -0,0 +1,407 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { makeInvalid } from './helpers'; +import { + SignedMessageWithOnePassphrase, + SignedMessageWithTwoPassphrases, + signMessageWithPassphrase, + signMessageWithTwoPassphrases, + verifyMessageWithPublicKey, + verifyMessageWithTwoPublicKeys, + printSignedMessage, + signAndPrintMessage, + signData, + signDataWithPassphrase, + signDataWithPrivateKey, + verifyData, + digestMessage, +} from '../src/sign'; +// Require is used for stubbing +const keys = require('../src/keys'); + +const changeLength = (str: string): string => `00${str}`; + +describe('sign', () => { + const defaultPassphrase = + 'minute omit local rare sword knee banner pair rib museum shadow juice'; + const defaultPrivateKey = + '314852d7afb0d4c283692fef8a2cb40e30c7a5df2ed79994178c10ac168d6d977ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; + const defaultPublicKey = + '7ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; + const defaultSecondPassphrase = 'second secret'; + const defaultSecondPrivateKey = + '9ef4146f8166d32dc8051d3d9f3a0c4933e24aa8ccb439b5d9ad00078a89e2fc0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f'; + const defaultSecondPublicKey = + '0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f'; + const defaultMessage = 'Some default text.'; + const defaultSignature = + '68937004b6720d7e1902ef05a577e6d9f9ab2756286b1f2ae918f8a0e5153c15e4f410916076f750b708f8979be2430e4cfc7ebb523ae1905d2ea1f5d24ce700'; + const defaultSecondSignature = + '58013cd8dbc4c194cedb5bdc27232f9de225d077b4dfe817ba810189486bd43e8600e0e8295623882e9db0ba5685bd30e7b7c81f38bc1b668fd9e2370ab9d905'; + const defaultPrintedMessage = ` +-----BEGIN LISK SIGNED MESSAGE----- +-----MESSAGE----- +${defaultMessage} +-----PUBLIC KEY----- +${defaultPublicKey} +-----SIGNATURE----- +${defaultSignature} +-----END LISK SIGNED MESSAGE----- +`.trim(); + const defaultSecondSignedPrintedMessage = ` +-----BEGIN LISK SIGNED MESSAGE----- +-----MESSAGE----- +${defaultMessage} +-----PUBLIC KEY----- +${defaultPublicKey} +-----SECOND PUBLIC KEY----- +${defaultSecondPublicKey} +-----SIGNATURE----- +${defaultSignature} +-----SECOND SIGNATURE----- +${defaultSecondSignature} +-----END LISK SIGNED MESSAGE----- +`.trim(); + const defaultData = Buffer.from('This is some data'); + const defaultDataSignature = + 'b8704e11c4d9fad9960c7b6a69dcf48c1bede5b74ed8974cd005d9a407deef618dd800fe69ceed1fd52bb1e0881e71aec137c35b90eda9afe93716a5652ee009'; + + let defaultSignedMessage: SignedMessageWithOnePassphrase; + let defaultDoubleSignedMessage: SignedMessageWithTwoPassphrases; + + let getPrivateAndPublicKeyBytesFromPassphraseStub; + + beforeEach(() => { + defaultSignedMessage = { + message: defaultMessage, + publicKey: defaultPublicKey, + signature: defaultSignature, + }; + defaultDoubleSignedMessage = { + message: defaultMessage, + publicKey: defaultPublicKey, + secondPublicKey: defaultSecondPublicKey, + signature: defaultSignature, + secondSignature: defaultSecondSignature, + }; + + getPrivateAndPublicKeyBytesFromPassphraseStub = sandbox.stub( + keys, + 'getPrivateAndPublicKeyBytesFromPassphrase', + ); + getPrivateAndPublicKeyBytesFromPassphraseStub + .withArgs(defaultPassphrase) + .returns({ + privateKeyBytes: Buffer.from(defaultPrivateKey, 'hex'), + publicKeyBytes: Buffer.from(defaultPublicKey, 'hex'), + }); + return getPrivateAndPublicKeyBytesFromPassphraseStub + .withArgs(defaultSecondPassphrase) + .returns({ + privateKeyBytes: Buffer.from(defaultSecondPrivateKey, 'hex'), + publicKeyBytes: Buffer.from(defaultSecondPublicKey, 'hex'), + }); + }); + + describe('#digestMessage', () => { + const strGenerator = (len: number, chr: string): string => chr.repeat(len); + + it('should create message digest for message with length = 0', () => { + const msgBytes = digestMessage(''); + const expectedMessageBytes = Buffer.from( + '3fdb82ac2a879b647f4f27f3fbd1c27e0d4e278f830b76295604035330163b79', + 'hex', + ); + return expect(msgBytes).to.be.eql(expectedMessageBytes); + }); + it('should create message digest for message in length range 1 - 253', () => { + const msgBytes = digestMessage(strGenerator(250, 'a')); + const expectedMessageBytes = Buffer.from( + '12832c687d950513aa5db6198b84809eb8fd7ff1c8963dca48ea57278523ec67', + 'hex', + ); + return expect(msgBytes).to.be.eql(expectedMessageBytes); + }); + it('should create message digest for message in length range 254 - 65536', () => { + const msgBytes = digestMessage(strGenerator(65535, 'a')); + const expectedMessageBytes = Buffer.from( + '73da94220312e71eb5c55c94fdddca3c06a6c18cb74a4a4a2cee1a82875c2450', + 'hex', + ); + return expect(msgBytes).to.be.eql(expectedMessageBytes); + }); + it('should create message digest for message in length range 65537 - 4294967296', () => { + const msgBytes = digestMessage(strGenerator(6710886, 'a')); + const expectedMessageBytes = Buffer.from( + '7c51817b5c31c4d04e9ffcf2e78859d6522b124f218c789a8f721b5f3e6b295d', + 'hex', + ); + return expect(msgBytes).to.be.eql(expectedMessageBytes); + }); + // higest range (length > 4294967296) is not practical to test + // but it is covered by `varuint-bitcoin` library + }); + + describe('#signMessageWithPassphrase', () => { + it('should create a signed message using a secret passphrase', () => { + const signedMessage = signMessageWithPassphrase( + defaultMessage, + defaultPassphrase, + ); + return expect(signedMessage).to.be.eql(defaultSignedMessage); + }); + }); + + describe('#verifyMessageWithPublicKey', () => { + it('should detect invalid publicKeys', () => { + return expect( + verifyMessageWithPublicKey.bind(null, { + message: defaultMessage, + signature: defaultSignature, + publicKey: changeLength(defaultPublicKey), + }), + ).to.throw('Invalid publicKey, expected 32-byte publicKey'); + }); + + it('should detect invalid signatures', () => { + return expect( + verifyMessageWithPublicKey.bind(null, { + message: defaultMessage, + signature: changeLength(defaultSignature), + publicKey: defaultPublicKey, + }), + ).to.throw('Invalid signature length, expected 64-byte signature'); + }); + + it('should return false if the signature is invalid', () => { + const verification = verifyMessageWithPublicKey({ + message: defaultMessage, + signature: makeInvalid(defaultSignature), + publicKey: defaultPublicKey, + }); + return expect(verification).to.be.false; + }); + + it('should return true if the signature is valid', () => { + const verification = verifyMessageWithPublicKey(defaultSignedMessage); + return expect(verification).to.be.true; + }); + }); + + describe('#signMessageWithTwoPassphrases', () => { + it('should create a message signed by two secret passphrases', () => { + const signature = signMessageWithTwoPassphrases( + defaultMessage, + defaultPassphrase, + defaultSecondPassphrase, + ); + + return expect(signature).to.be.eql(defaultDoubleSignedMessage); + }); + }); + + describe('#verifyMessageWithTwoPublicKeys', () => { + it('should throw on invalid first publicKey length', () => { + const { + publicKey, + ...messageWithoutPublicKey + } = defaultDoubleSignedMessage; + return expect( + verifyMessageWithTwoPublicKeys.bind(null, { + publicKey: changeLength(defaultPublicKey), + ...messageWithoutPublicKey, + }), + ).to.throw('Invalid first publicKey, expected 32-byte publicKey'); + }); + + it('should throw on invalid second publicKey length', () => { + const { + secondPublicKey, + ...messageWithoutSecondPublicKey + } = defaultDoubleSignedMessage; + return expect( + verifyMessageWithTwoPublicKeys.bind(null, { + secondPublicKey: changeLength(defaultSecondPublicKey), + ...messageWithoutSecondPublicKey, + }), + ).to.throw('Invalid second publicKey, expected 32-byte publicKey'); + }); + + it('should throw on invalid primary signature length', () => { + const { + signature, + ...messageWithoutSignature + } = defaultDoubleSignedMessage; + return expect( + verifyMessageWithTwoPublicKeys.bind(null, { + signature: changeLength(defaultSignature), + ...messageWithoutSignature, + }), + ).to.throw('Invalid first signature length, expected 64-byte signature'); + }); + + it('should throw on invalid secondary signature length', () => { + const { + secondSignature, + ...messageWithoutSecondSignature + } = defaultDoubleSignedMessage; + return expect( + verifyMessageWithTwoPublicKeys.bind(null, { + secondSignature: changeLength(defaultSecondSignature), + ...messageWithoutSecondSignature, + }), + ).to.throw('Invalid second signature length, expected 64-byte signature'); + }); + + it('should return false for incorrect first signature', () => { + const { + signature, + ...messageWithoutSignature + } = defaultDoubleSignedMessage; + const verified = verifyMessageWithTwoPublicKeys({ + signature: makeInvalid(defaultSignature), + ...messageWithoutSignature, + }); + return expect(verified).to.be.false; + }); + + it('should return false for incorrect second signature', () => { + const { + secondSignature, + ...messageWithoutSecondSignature + } = defaultDoubleSignedMessage; + const verified = verifyMessageWithTwoPublicKeys({ + secondSignature: makeInvalid(defaultSecondSignature), + ...messageWithoutSecondSignature, + }); + return expect(verified).to.be.false; + }); + + it('should return true for two valid signatures', () => { + const verified = verifyMessageWithTwoPublicKeys( + defaultDoubleSignedMessage, + ); + return expect(verified).to.be.true; + }); + }); + + describe('#printSignedMessage', () => { + it('should wrap a single signed message into a printed Lisk template', () => { + const printedMessage = printSignedMessage({ + message: defaultMessage, + signature: defaultSignature, + publicKey: defaultPublicKey, + }); + return expect(printedMessage).to.be.equal(defaultPrintedMessage); + }); + + it('should wrap a second signed message into a printed Lisk template', () => { + const printedMessage = printSignedMessage({ + message: defaultMessage, + signature: defaultSignature, + publicKey: defaultPublicKey, + secondSignature: defaultSecondSignature, + secondPublicKey: defaultSecondPublicKey, + }); + return expect(printedMessage).to.be.equal( + defaultSecondSignedPrintedMessage, + ); + }); + }); + + describe('#signAndPrintMessage', () => { + it('should sign the message once and wrap it into a printed Lisk template', () => { + const signedAndPrintedMessage = signAndPrintMessage( + defaultMessage, + defaultPassphrase, + ); + return expect(signedAndPrintedMessage).to.be.equal(defaultPrintedMessage); + }); + + it('should sign the message twice and wrap it into a printed Lisk template', () => { + const signedAndPrintedMessage = signAndPrintMessage( + defaultMessage, + defaultPassphrase, + defaultSecondPassphrase, + ); + return expect(signedAndPrintedMessage).to.be.equal( + defaultSecondSignedPrintedMessage, + ); + }); + }); + + describe('#signData', () => { + let signature: string; + + beforeEach(() => { + signature = signData(defaultData, defaultPassphrase); + return Promise.resolve(); + }); + + it('should sign a transaction', () => { + return expect(signature).to.be.equal(defaultDataSignature); + }); + }); + + describe('#signDataWithPassphrase', () => { + let signature: string; + + beforeEach(() => { + signature = signDataWithPassphrase(defaultData, defaultPassphrase); + return Promise.resolve(); + }); + + it('should sign a transaction', () => { + return expect(signature).to.be.equal(defaultDataSignature); + }); + }); + + describe('#signDataWithPrivateKey', () => { + let signature: string; + + beforeEach(() => { + signature = signDataWithPrivateKey( + defaultData, + Buffer.from(defaultPrivateKey, 'hex'), + ); + return Promise.resolve(); + }); + + it('should sign a transaction', () => { + return expect(signature).to.be.equal(defaultDataSignature); + }); + }); + + describe('#verifyData', () => { + it('should return false for an invalid signature', () => { + const verification = verifyData( + defaultData, + makeInvalid(defaultDataSignature), + defaultPublicKey, + ); + return expect(verification).to.be.false; + }); + + it('should return true for a valid signature', () => { + const verification = verifyData( + defaultData, + defaultDataSignature, + defaultPublicKey, + ); + return expect(verification).to.be.true; + }); + }); +}); diff --git a/elements/lisk-cryptography/test/tsconfig.json b/elements/lisk-cryptography/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-cryptography/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/test/tslint.json b/elements/lisk-cryptography/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-cryptography/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/tsconfig.browsertest.json b/elements/lisk-cryptography/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-cryptography/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/tsconfig.json b/elements/lisk-cryptography/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-cryptography/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/tslint.json b/elements/lisk-cryptography/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-cryptography/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-cryptography/types/buffer-reverse/index.d.ts b/elements/lisk-cryptography/types/buffer-reverse/index.d.ts new file mode 100644 index 00000000000..82e6d73dc12 --- /dev/null +++ b/elements/lisk-cryptography/types/buffer-reverse/index.d.ts @@ -0,0 +1,5 @@ +/// +declare module 'buffer-reverse' { + const reverse: (buffer: Buffer) => Buffer; + export = reverse; +} diff --git a/elements/lisk-cryptography/types/sodium-native/index.d.ts b/elements/lisk-cryptography/types/sodium-native/index.d.ts new file mode 100644 index 00000000000..3cb4942c2b2 --- /dev/null +++ b/elements/lisk-cryptography/types/sodium-native/index.d.ts @@ -0,0 +1,37 @@ +// tslint:disable only-arrow-functions variable-name +declare module 'sodium-native' { + export const crypto_box_MACBYTES: number; + export const crypto_sign_BYTES: number; + export const crypto_sign_PUBLICKEYBYTES: number; + export const crypto_sign_SECRETKEYBYTES: number; + export function crypto_box_easy( + cipher: Buffer, + message: Buffer, + nonce: Buffer, + publicKey: Buffer, + secretKey: Buffer, + ): void; + export function crypto_box_open_easy( + message: Buffer, + cipherText: Buffer, + nonce: Buffer, + publicKey: Buffer, + secretKey: Buffer, + ): boolean; + export function crypto_sign_detached( + signature: Buffer, + message: Buffer, + secretKey: Buffer, + ): void; + export function crypto_sign_verify_detached( + signature: Buffer, + message: Buffer, + publicKey: Buffer, + ): boolean; + export function randombytes_buf(buffer: Buffer): void; + export function crypto_sign_seed_keypair( + publicKey: Buffer, + privateKey: Buffer, + hashSeed: Buffer, + ): void; +} diff --git a/elements/lisk-cryptography/types/varuint-bitcoin/index.d.ts b/elements/lisk-cryptography/types/varuint-bitcoin/index.d.ts new file mode 100644 index 00000000000..7ef8af856ef --- /dev/null +++ b/elements/lisk-cryptography/types/varuint-bitcoin/index.d.ts @@ -0,0 +1,4 @@ +// tslint:disable only-arrow-functions +declare module 'varuint-bitcoin' { + export function encode(num: number, buffer?: Buffer, offset?: number): Buffer; +} diff --git a/elements/lisk-elements/.npmignore b/elements/lisk-elements/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-elements/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/.npmrc b/elements/lisk-elements/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-elements/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/.nycrc b/elements/lisk-elements/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-elements/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/.prettierignore b/elements/lisk-elements/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-elements/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/.prettierrc.json b/elements/lisk-elements/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-elements/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/README.md b/elements/lisk-elements/README.md new file mode 100644 index 00000000000..a21900ee605 --- /dev/null +++ b/elements/lisk-elements/README.md @@ -0,0 +1,163 @@ +# Lisk Elements + +Lisk Elements is a JavaScript library for [Lisk][Lisk Core GitHub], the blockchain application platform. + +[![Build Status](https://jenkins.lisk.io/buildStatus/icon?job=lisk-elements/development)](https://jenkins.lisk.io/job/lisk-elements/job/development/) +Dependency Status +devDependency Status +[![License: GPL v3](https://img.shields.io/badge/License-GPL%20v3-blue.svg)](http://www.gnu.org/licenses/gpl-3.0) + +## Installation + +### Installation via npm + +Add Lisk Elements as a dependency of your project: + +```sh +$ npm install --save lisk-elements +``` + +Import using ES6 modules syntax: + +```js +import lisk from 'lisk-elements'; +``` + +Or using Node.js modules: + +```js +const lisk = require('lisk-elements'); +``` + +Or import specific namespaced functionality: + +```js +import { APIClient, transactions } from 'lisk-elements'; +// or +const { APIClient, transactions } = require('lisk-elements'); +``` + +**Note:** If you are installing Lisk Elements as an npm dependency via a GitHub reference, you will need to manually build the distribution files by running the following commands from the root directory of your project: + +``` +cd node_modules/lisk-elements +npm run build +``` + +### Installation from source + +Our source code is hosted on GitHub. You can build the distribution yourself by cloning the repository, installing the relevant dependencies and running our build script as follows: + +``` +git clone https://github.com/LiskHQ/lisk-elements.git +cd lisk-elements/packages/lisk-elements +npm install +npm run build +``` + +## Usage + +Access functionality via the relevant namespace. For example, the following will create and (locally) sign a transfer (type 0) transaction, and then broadcast it to the Lisk Testnet. + +```js +const transaction = lisk.transaction.transfer({ + amount: '123000000', + recipientId: '12668885769632475474L', + passphrase: 'robust swift grocery peasant forget share enable convince deputy road keep cheap', +}); + +const client = lisk.APIClient.createTestnetAPIClient(); + +client.transactions.broadcast(transaction) + .then(console.info) + .catch(console.error); +``` + +Full documentation can be found on the [Lisk documentation site][]. + +## Packages + +| Package | Version | Description | +| ------------------------------------------------------- | :---------------------------------------------------------------------------------------------------------------: | ------------------------------------------------------------------ | +| [lisk-elements](/packages/lisk-elements) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/lisk-elements) | Package contains everything | +| [@liskhq/lisk-client](/packages/lisk-client) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-client) | A default set of Elements for use by clients of the Lisk network | +| [@liskhq/lisk-api-client](/packages/lisk-api-client) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-api-client) | An API client for the Lisk network | +| [@liskhq/lisk-constants](/packages/lisk-constants) | [![](https://img.shields.io/badge/npm-v1.2.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-constants) | General constants for use with Lisk-related software | +| [@liskhq/lisk-cryptography](/packages/lisk-cryptography) | [![](https://img.shields.io/badge/npm-v2.1.0_alpha.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-cryptography) | General cryptographic functions for use with Lisk-related software | +| [@liskhq/lisk-passphrase](/packages/lisk-passphrase) | [![](https://img.shields.io/badge/npm-v2.0.0-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-passphrase) | Mnemonic passphrase helpers for use with Lisk-related software | +| [@liskhq/lisk-transactions](/packages/lisk-transactions) | [![](https://img.shields.io/badge/npm-v2.1.0_alpha.4-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-transactions) | Everything related to transactions according to the Lisk protocol | +| [@liskhq/lisk-transaction-pool](/packages/lisk-transaction-pool) | [![](https://img.shields.io/badge/npm-v0.1.0_alpha.1-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-transaction-pool) | Transaction pool implementation for the Lisk network | +| [@liskhq/lisk-p2p](/packages/lisk-p2p) | [![](https://img.shields.io/badge/npm-v0.1.0_alpha.4-green.svg)](https://www.npmjs.com/package/@liskhq/lisk-p2p) | _unstructured_ P2P library for the Lisk protocol | + +## Tests + +To run tests for all packages in lisk-elements, run the following command in the root folder: + +``` +npm test +``` + +To run tests for a specific package, run the same command in the relevant package directory. + +Example: + +``` +cd packages/lisk-cryptography +npm test +``` + +## FAQ + +Installation is failing, what should I do? + +``` +Make sure you are installing in the root folder, not on the package level. +Run `npm run clean` and `npm run clean:node_modules`, then install again. +``` + +I can't build the package, what should I do? + +``` +Make sure you first run `npm i`, and then `npm run build` in the root directory. +``` + +Tests are failing! + +``` +Make sure you are using the correct version of node and npm. +In our current build we recommend node v8.12.0 and npm v6.4.1. +``` + + + +## Contributors + +https://github.com/LiskHQ/lisk-elements/graphs/contributors + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-elements/browsertest b/elements/lisk-elements/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-elements/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/cypress b/elements/lisk-elements/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-elements/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/cypress.json b/elements/lisk-elements/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-elements/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/index.html b/elements/lisk-elements/index.html new file mode 100644 index 00000000000..d5ddd1bd264 --- /dev/null +++ b/elements/lisk-elements/index.html @@ -0,0 +1,14 @@ + + + + + Title + + +Open the console to get started with Lisk Elements. +
+ + + + + diff --git a/elements/lisk-elements/package-lock.json b/elements/lisk-elements/package-lock.json new file mode 100644 index 00000000000..54d19b490b3 --- /dev/null +++ b/elements/lisk-elements/package-lock.json @@ -0,0 +1,4768 @@ +{ + "name": "lisk-elements", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "http://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "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" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.4.tgz", + "integrity": "sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "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" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.0.tgz", + "integrity": "sha1-kc1BfRUqv4Wzexqz6/O9Jc3GToA=", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "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-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 + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", + "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==", + "dev": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", + "dev": true + }, + "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.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", + "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=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha1-IwKlam/+9/mr6gFH2Dil6ba2p5s=", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.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-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "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 + } + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha1-bYrlCPWRZ/lA8rWzxKYSrlDJCuY=", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "portfinder": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", + "integrity": "sha512-syFcRIRzVI1BoEFOCaAiizwDolh1S1YXSodsVhncbhjzjZQulhczNRbqnUl9N31Q4dKGOXsNDqxC2BWBgSMqeQ==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "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 + }, + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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" + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha1-DBxPBwC+2NvBJM2zBNJZLKID5nc=", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha1-aWS8pnaF33wfFDDFhPB9dZeIW5w=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "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" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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 + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-elements/package.json b/elements/lisk-elements/package.json new file mode 100644 index 00000000000..f2c83dc90b4 --- /dev/null +++ b/elements/lisk-elements/package.json @@ -0,0 +1,91 @@ +{ + "name": "lisk-elements", + "version": "2.0.0", + "description": "Elements for building blockchain applications in the Lisk network", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-elements#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "prestart": "./scripts/prestart.sh", + "start": "./scripts/start.sh", + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s lisk", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s lisk", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{js,json}\" \"{src,test}/**/*.{js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/}/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11540 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11540) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11540 && cypress run --config baseUrl=http://localhost:11540 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "NODE_ENV=test nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@liskhq/lisk-api-client": "2.0.0", + "@liskhq/lisk-constants": "1.2.0", + "@liskhq/lisk-cryptography": "2.1.0-alpha.0", + "@liskhq/lisk-passphrase": "2.0.0", + "@liskhq/lisk-transactions": "2.1.0-alpha.4", + "@types/node": "10.12.21" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-elements/scripts b/elements/lisk-elements/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-elements/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/src/index.ts b/elements/lisk-elements/src/index.ts new file mode 100644 index 00000000000..e6d8b5e41e8 --- /dev/null +++ b/elements/lisk-elements/src/index.ts @@ -0,0 +1,21 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { APIClient } from '@liskhq/lisk-api-client'; +import * as constants from '@liskhq/lisk-constants'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import * as passphrase from '@liskhq/lisk-passphrase'; +import * as transaction from '@liskhq/lisk-transactions'; + +export { APIClient, constants, cryptography, passphrase, transaction }; diff --git a/elements/lisk-elements/test/_setup.ts b/elements/lisk-elements/test/_setup.ts new file mode 100644 index 00000000000..000104e6fba --- /dev/null +++ b/elements/lisk-elements/test/_setup.ts @@ -0,0 +1,17 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import 'chai/register-expect'; + +process.env.NODE_ENV = 'test'; diff --git a/elements/lisk-elements/test/index.ts b/elements/lisk-elements/test/index.ts new file mode 100644 index 00000000000..423b52a3a3e --- /dev/null +++ b/elements/lisk-elements/test/index.ts @@ -0,0 +1,44 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + APIClient, + constants, + cryptography, + passphrase, + transaction, +} from '../src'; + +describe('lisk-elements', () => { + it('APIClient should be a function', () => { + return expect(APIClient).to.be.a('function'); + }); + + it('constants should be an object', () => { + return expect(constants).to.be.an('object'); + }); + + it('cryptography should be an object', () => { + return expect(cryptography).to.be.an('object'); + }); + + it('passphrase should be an object', () => { + return expect(passphrase).to.be.an('object'); + }); + + it('transaction should be an object', () => { + return expect(transaction).to.be.an('object'); + }); +}); diff --git a/elements/lisk-elements/test/mocha.opts b/elements/lisk-elements/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-elements/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/test/tsconfig.json b/elements/lisk-elements/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-elements/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/test/tslint.json b/elements/lisk-elements/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-elements/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/tsconfig.browsertest.json b/elements/lisk-elements/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-elements/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/tsconfig.json b/elements/lisk-elements/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-elements/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-elements/tslint.json b/elements/lisk-elements/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-elements/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/.npmignore b/elements/lisk-p2p/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-p2p/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/.npmrc b/elements/lisk-p2p/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-p2p/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/.nycrc b/elements/lisk-p2p/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-p2p/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/.prettierignore b/elements/lisk-p2p/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-p2p/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/.prettierrc.json b/elements/lisk-p2p/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-p2p/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/README.md b/elements/lisk-p2p/README.md new file mode 100644 index 00000000000..86b0263f86d --- /dev/null +++ b/elements/lisk-p2p/README.md @@ -0,0 +1,37 @@ +# @liskhq/lisk-p2p + +@liskhq/lisk-p2p is containing unstructured P2P library for use with Lisk-related software + +## Installation + +```sh +$ npm install --save @liskhq/lisk-p2p +``` + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-p2p/package-lock.json b/elements/lisk-p2p/package-lock.json new file mode 100644 index 00000000000..9daa44ccad0 --- /dev/null +++ b/elements/lisk-p2p/package-lock.json @@ -0,0 +1,3999 @@ +{ + "name": "@liskhq/lisk-p2p", + "version": "0.1.0-alpha.4", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "@babel/types": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", + "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", + "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "dev": true, + "requires": { + "@sinonjs/samsam": "^2 || ^3" + } + }, + "@sinonjs/samsam": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.1.0.tgz", + "integrity": "sha512-IXio+GWY+Q8XUjHUOgK7wx8fpvr7IFffgyXb1bnJFfX3001KmHt35Zq4tp7MXZyjJPCLPuadesDYNk41LYtVjw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash.get": "^4.4.2" + } + }, + "@types/async": { + "version": "2.0.50", + "resolved": "https://registry.npmjs.org/@types/async/-/async-2.0.50.tgz", + "integrity": "sha512-VMhZMMQgV1zsR+lX/0IBfAk+8Eb7dPVMWiQGFAt3qjo5x7Ml6b77jUo0e1C3ToD+XRDXqtrfw+6AB0uUsPEr3Q==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-as-promised": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@types/chai-as-promised/-/chai-as-promised-7.1.0.tgz", + "integrity": "sha512-MFiW54UOSt+f2bRw8J7LgQeIvE/9b4oGvwU7XW30S9QGAiHGnU/fmiOprsyMkdmH2rl8xSPc0/yrQw8juXU6bQ==", + "dev": true, + "requires": { + "@types/chai": "*" + } + }, + "@types/component-emitter": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/@types/component-emitter/-/component-emitter-1.2.7.tgz", + "integrity": "sha512-xJ/RPKEg1BJ3PiwtS1OCHGACOgMt0jXjZ3Y81YVFRig/1CNmjZa2A4g+/L1MWOeFY3JkFV1ziFGh7JPpS6Rl1w==", + "dev": true + }, + "@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/expect": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/expirymanager": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/expirymanager/-/expirymanager-0.9.0.tgz", + "integrity": "sha512-xulG8b5SiBhpRE1Arfx3ji428mfhwQdas6/i+1IJhTLkyFifJ4rF+vve522ds2ZTiBKCUv9WHNuVF/V9PJCa2Q==", + "dev": true + }, + "@types/fleximap": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@types/fleximap/-/fleximap-0.9.0.tgz", + "integrity": "sha512-7VsHgMM7l3jY+MXptDgzvROcEoikVgIxu+8d/qT0WijDl6RXdwAbAQYxu5sBCwUvlf0cEQwiDC4rOvkcm3h+hw==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/jsonwebtoken": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/@types/jsonwebtoken/-/jsonwebtoken-8.3.0.tgz", + "integrity": "sha512-YKnUTR4VxwljbPORPrRon9E3uel1aD8nUdvzqArCCdMTWPvo0gnI2UZkwIHN2QATdj6HYXV/Iq3/KcecAO42Ww==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/lodash": { + "version": "4.14.123", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.123.tgz", + "integrity": "sha512-pQvPkc4Nltyx7G1Ww45OjVqUsJP4UsZm+GWJpigXgkikZqJgRm4c48g027o6tdgubWHwFRF15iFd+Y4Pmqv6+Q==", + "dev": true + }, + "@types/lodash.shuffle": { + "version": "4.2.6", + "resolved": "https://registry.npmjs.org/@types/lodash.shuffle/-/lodash.shuffle-4.2.6.tgz", + "integrity": "sha512-ucI9VswlV9jOZiIh43Nd0tJ4Z8pfXy3PbQ9cB6Re1gPds8gLbOdmB0l3UkVI2crZjnQB95bhyNZVEDH8DgglYA==", + "dev": true, + "requires": { + "@types/lodash": "*" + } + }, + "@types/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==", + "dev": true + }, + "@types/sc-auth": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/sc-auth/-/sc-auth-5.0.0.tgz", + "integrity": "sha512-V+wuOweEJDrVCMduXmS7zc60O6HGyd5Xm3ClzEXKJfQdrSuhoqvhDjOwbtRZAXCjHll12lBXECb2sht5Glp/6A==", + "dev": true, + "requires": { + "@types/jsonwebtoken": "*" + } + }, + "@types/sc-broker": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/@types/sc-broker/-/sc-broker-5.1.1.tgz", + "integrity": "sha512-71lCeHurhrxf8O4zg4kvKHjikjN6xf99xgEOk0ilmCgDjTGRwU2CvIIOTy5VaStH/lMvOQlNXYhdDToZZ64Kvw==", + "dev": true, + "requires": { + "@types/expirymanager": "*", + "@types/fleximap": "*", + "@types/socketcluster": "*", + "@types/socketcluster-server": "*" + } + }, + "@types/sc-broker-cluster": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/@types/sc-broker-cluster/-/sc-broker-cluster-6.1.1.tgz", + "integrity": "sha512-iGGqHqiBUl0TPzZRQ7RaUiaPXiHfqA3sP1Az5GZjvTv5zxBdhvzXI/EmfZIDTKRk9ADE21l/qYtNbAftvHkzmg==", + "dev": true, + "requires": { + "@types/async": "*", + "@types/expirymanager": "*", + "@types/fleximap": "*", + "@types/sc-broker": "*", + "@types/sc-channel": "*", + "@types/socketcluster": "*", + "@types/socketcluster-server": "*" + } + }, + "@types/sc-channel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/sc-channel/-/sc-channel-1.2.0.tgz", + "integrity": "sha512-n3vGT7m65A7p1vY1lRPiHW8D9/Mv+aV1vayVwve2b0vrb4RNSCb+EZIuHTYY7XWvla8R+/6qkkwRc6T5WP2gcw==", + "dev": true, + "requires": { + "@types/component-emitter": "*", + "@types/sc-broker-cluster": "*" + } + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==", + "dev": true + }, + "@types/sinon": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.5.tgz", + "integrity": "sha512-4DShbH857bZVOY4tPi1RQJNrLcf89hEtU0klZ9aYTMbtt95Ok4XdPqqcbtGOHIbAHMLSzQP8Uw/6qtBBqyloww==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "@types/socketcluster": { + "version": "14.0.1", + "resolved": "https://registry.npmjs.org/@types/socketcluster/-/socketcluster-14.0.1.tgz", + "integrity": "sha512-FONA85Q8W82gbZ64rTKQgJ4m3mLX2X+vRauZhmlhhqG0q/op5ZEqHHFLtSzt3JBiM9n31ii2GkXcbgnuB5fUXA==", + "dev": true, + "requires": { + "@types/sc-auth": "*", + "@types/sc-broker-cluster": "*", + "@types/socketcluster-server": "*" + } + }, + "@types/socketcluster-client": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@types/socketcluster-client/-/socketcluster-client-13.0.0.tgz", + "integrity": "sha512-r9aXj6Zkw65pH+qEYMfjSHtBjFnAPsdT8OAb5kaMHpcK0xiqNBiCSl7XlgSgWg1vuwiTgsdUglHkjSOf0bdrOQ==", + "dev": true, + "requires": { + "@types/component-emitter": "*", + "@types/sc-auth": "*", + "@types/sc-channel": "*", + "@types/socketcluster-server": "*", + "@types/ws": "*" + } + }, + "@types/socketcluster-server": { + "version": "14.2.2", + "resolved": "https://registry.npmjs.org/@types/socketcluster-server/-/socketcluster-server-14.2.2.tgz", + "integrity": "sha512-GZJEyKqheFtojJI8dQy20VcEpNBpLzMod/KrixfbyPYg++mS6d+JIE0m+lxjWIVFnsCIRI4hZG+mFuigOE1BLA==", + "dev": true, + "requires": { + "@types/component-emitter": "*", + "@types/jsonwebtoken": "*", + "@types/sc-auth": "*", + "@types/sc-broker-cluster": "*", + "@types/ws": "*" + } + }, + "@types/validator": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-10.9.0.tgz", + "integrity": "sha512-mf0VpXk+NoTmkUmuJCsdwBYxjYZW41amCSzd4t/fABMKl+qGMViwFP0pR7ukFdZRXWI1LIkca3VIbXVBmWZ4kQ==", + "dev": true + }, + "@types/verror": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.3.tgz", + "integrity": "sha512-7Jz0MPsW2pWg5dJfEp9nJYI0RDCYfgjg2wIo5HfQ8vOJvUq0/BxT7Mv2wNQvkKBmV9uT++6KF3reMnLmh/0HrA==", + "dev": true + }, + "@types/ws": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-6.0.1.tgz", + "integrity": "sha512-EzH8k1gyZ4xih/MaZTXwT2xOkPiIMSrhQ9b8wrlX88L0T02eYsddatQlwVFlEPyEqV0ChpdpNnE51QPH6NVT4Q==", + "dev": true, + "requires": { + "@types/events": "*", + "@types/node": "*" + } + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-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": "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" + } + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.3.0.tgz", + "integrity": "sha1-EBPRBRBH3TIP4k5JTVxm7K9hR9k=", + "requires": { + "lodash": "^4.14.0" + } + }, + "async-limiter": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", + "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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" + } + }, + "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 + }, + "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 + } + } + }, + "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-64": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", + "integrity": "sha1-eAqZyE59YAJgNhURxId2E78k9rs=" + }, + "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 + }, + "base64id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz", + "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY=" + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", + "dev": true + }, + "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" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chai-as-promised": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz", + "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==", + "dev": true, + "requires": { + "check-error": "^1.0.2" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "clone": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", + "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=" + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "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=" + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.4.tgz", + "integrity": "sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.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==", + "dev": true, + "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==", + "dev": true, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "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 + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecdsa-sig-formatter": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.10.tgz", + "integrity": "sha1-HFlQAPBKiJffuFAAiSoPTDOvhsM=", + "requires": { + "safe-buffer": "^5.0.1" + } + }, + "elliptic": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "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 + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "dev": true + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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=", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.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-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz", + "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM=", + "dev": true + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "dev": true + }, + "jsonwebtoken": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.4.0.tgz", + "integrity": "sha512-coyXjRTCy0pw5WYBpMvWOMN+Kjaik2MwTUIq9cna/W7NpO9E+iYbumZONAz3hcr+tXFJECoQVrtmIoC3Oz0gvg==", + "requires": { + "jws": "^3.1.5", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1" + } + }, + "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" + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "jwa": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.2.0.tgz", + "integrity": "sha512-Grku9ZST5NNQ3hqNUodSkDfEBqAmGA1R8yiyPHOnLzEKI0GaCQC/XhFmsheXYuXzFQJdILbh+lYBiliqG5R/Vg==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.10", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.1.tgz", + "integrity": "sha512-bGA2omSrFUkd72dhh05bIAN832znP4wOU3lfuXtRBuGTbsmNmDXMQg28f0Vsxaxgk4myF5YkKQpz6qeRpMgX9g==", + "requires": { + "jwa": "^1.2.0", + "safe-buffer": "^5.0.1" + } + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "linked-list": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/linked-list/-/linked-list-0.1.0.tgz", + "integrity": "sha1-eYsP+X0bkqT9CEgPVa6k6dSdN78=" + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==" + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, + "lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=", + "dev": true + }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, + "lodash.shuffle": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/lodash.shuffle/-/lodash.shuffle-4.2.0.tgz", + "integrity": "sha1-FFtQU8+HX29cKjP0i26ZSMbse0s=" + }, + "lolex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.0.0.tgz", + "integrity": "sha512-hcnW80h3j2lbUfFdMArd5UPA/vxZJ+G8vobd+wg3nVEQA0EigStbYcrG030FJxL6xiDDPEkoMatV9xIh5OecQQ==", + "dev": true + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "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": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==" + }, + "nise": { + "version": "1.4.8", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.8.tgz", + "integrity": "sha512-kGASVhuL4tlAV0tvA34yJYZIVihrUt/5bDwpp4tTluigxUr2bBlJeDXmivb6NuEdFkqvdv/Ybb9dm16PSKUhtw==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.1.0", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0", + "text-encoding": "^0.6.4" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + } + } + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "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 + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "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 + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=" + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + } + } + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "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==" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sc-auth": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/sc-auth/-/sc-auth-5.0.2.tgz", + "integrity": "sha512-Le3YBsFjzv5g6wIH6Y+vD+KFkK0HDXiaWy1Gm4nXtYebMQUyNYSf1cS83MtHrYzVEMlhYElRva1b0bvZ0hBqQw==", + "requires": { + "jsonwebtoken": "^8.3.0", + "sc-errors": "^1.4.1" + } + }, + "sc-channel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/sc-channel/-/sc-channel-1.2.0.tgz", + "integrity": "sha512-M3gdq8PlKg0zWJSisWqAsMmTVxYRTpVRqw4CWAdKBgAfVKumFcTjoCV0hYu7lgUXccCtCD8Wk9VkkE+IXCxmZA==", + "requires": { + "component-emitter": "1.2.1" + } + }, + "sc-errors": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sc-errors/-/sc-errors-1.4.1.tgz", + "integrity": "sha512-dBn92iIonpChTxYLgKkIT/PCApvmYT6EPIbRvbQKTgY6tbEbIy8XVUv4pGyKwEK4nCmvX4TKXcN0iXC6tNW6rQ==" + }, + "sc-formatter": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/sc-formatter/-/sc-formatter-3.0.2.tgz", + "integrity": "sha512-9PbqYBpCq+OoEeRQ3QfFIGE6qwjjBcd2j7UjgDlhnZbtSnuGgHdcRklPKYGuYFH82V/dwd+AIpu8XvA1zqTd+A==" + }, + "sc-simple-broker": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/sc-simple-broker/-/sc-simple-broker-2.1.3.tgz", + "integrity": "sha512-ldt0ybOS5fVZSMea5Z8qVu7lmDBTy0qO9BD6TseJjRuPx+g+stfSqmPAb0RsCsQUXRH8A1koCbwsuUnI9BOxvw==", + "requires": { + "sc-channel": "^1.2.0" + } + }, + "sc-uws": { + "version": "10.148.2", + "resolved": "https://registry.npmjs.org/sc-uws/-/sc-uws-10.148.2.tgz", + "integrity": "sha512-wGXiwsORev5O3OOewsAYi1WVyMeNFMQ4bw/Qg/6g0C0J9vsEs8xnxf19hovAAQrOq6sMVrcxCNa2k1rBiDsDzw==" + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "sinon": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", + "integrity": "sha512-i6j7sqcLEqTYqUcMV327waI745VASvYuSuQMCjbAwlpAeuCgKZ3LtrjDxAbu+GjNQR0FEDpywtwGCIh8GicNyg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/samsam": "^3.0.2", + "diff": "^3.5.0", + "lolex": "^3.0.0", + "nise": "^1.4.8", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "sinon-chai": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.3.0.tgz", + "integrity": "sha512-r2JhDY7gbbmh5z3Q62pNbrjxZdOAjpsqW/8yxAZRSqLZqowmfGZPGUZPFf3UX36NLis0cv8VEM5IJh9HgkSOAA==", + "dev": true + }, + "socketcluster-client": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/socketcluster-client/-/socketcluster-client-14.2.1.tgz", + "integrity": "sha512-peCBfewW1silqvLecFpLz5u2xr85r8b7A24mXaNTsXLnG9QR3zxecYtKS/odszzJSu2j2YyQPR4avy77tZSjZw==", + "requires": { + "base-64": "0.1.0", + "clone": "2.1.1", + "component-emitter": "1.2.1", + "linked-list": "0.1.0", + "querystring": "0.2.0", + "sc-channel": "^1.2.0", + "sc-errors": "^1.4.1", + "sc-formatter": "^3.0.1", + "uuid": "3.2.1", + "ws": "5.1.1" + } + }, + "socketcluster-server": { + "version": "14.4.0", + "resolved": "https://registry.npmjs.org/socketcluster-server/-/socketcluster-server-14.4.0.tgz", + "integrity": "sha512-qG4XVFsm9SXZNQZWUA2++LO+/n6nHC0FKCHHlSkXk2At7rM82TR0DXBr+Nll2H4IcWt+bfqZ8Z2H3rVTp+vpbg==", + "requires": { + "async": "2.3.0", + "base64id": "1.0.0", + "component-emitter": "1.2.1", + "lodash.clonedeep": "4.5.0", + "sc-auth": "^5.0.2", + "sc-errors": "^1.4.1", + "sc-formatter": "^3.0.2", + "sc-simple-broker": "^2.1.3", + "sc-uws": "^10.148.2", + "uuid": "3.2.1", + "ws": "6.1.2" + }, + "dependencies": { + "ws": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.2.tgz", + "integrity": "sha512-rfUqzvz0WxmSXtJpPMX2EeASXabOrSMk1ruMOV3JBTBjo4ac2lDjGGsbQSyxj8Odhw5fBib8ZKEjDNvgouNKYw==", + "requires": { + "async-limiter": "~1.0.0" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "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" + } + }, + "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" + } + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "text-encoding": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "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" + }, + "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 + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "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 + } + } + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==" + }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "5.1.1", + "resolved": "http://registry.npmjs.org/ws/-/ws-5.1.1.tgz", + "integrity": "sha512-bOusvpCb09TOBLbpMKszd45WKC2KPtxiyiHanv+H2DE3Az+1db5a/L7sVJZVDPUC1Br8f0SKRr1KjLpD1U/IAw==", + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-p2p/package.json b/elements/lisk-p2p/package.json new file mode 100644 index 00000000000..81b85c10813 --- /dev/null +++ b/elements/lisk-p2p/package.json @@ -0,0 +1,91 @@ +{ + "name": "@liskhq/lisk-p2p", + "version": "0.1.0-alpha.4", + "description": "Unstructured P2P library for use with Lisk-related software", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain", + "p2p" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-p2p#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=3 <=6" + }, + "main": "dist-node/index.js", + "scripts": { + "transpile": "tsc", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/}/*.ts", + "test:integration": "USE_REAL_TIMERS=true TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/integration/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild": "npm run prebuild:node", + "build": "npm run build:node", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "lodash.shuffle": "4.2.0", + "semver": "5.6.0", + "socketcluster-client": "14.2.1", + "socketcluster-server": "14.4.0", + "validator": "10.11.0", + "verror": "1.10.0" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/chai-as-promised": "7.1.0", + "@types/component-emitter": "1.2.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/jsonwebtoken": "8.3.0", + "@types/lodash.shuffle": "4.2.6", + "@types/mocha": "5.2.5", + "@types/node": "10.12.21", + "@types/semver": "5.5.0", + "@types/sinon": "7.0.5", + "@types/sinon-chai": "3.2.2", + "@types/socketcluster-client": "13.0.0", + "@types/socketcluster-server": "14.2.2", + "@types/validator": "10.9.0", + "@types/verror": "1.10.3", + "@types/ws": "6.0.1", + "browserify": "16.2.3", + "chai": "4.2.0", + "chai-as-promised": "7.1.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "sinon": "7.2.3", + "sinon-chai": "3.3.0", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-p2p/scripts b/elements/lisk-p2p/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-p2p/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/src/disconnect_status_codes.ts b/elements/lisk-p2p/src/disconnect_status_codes.ts new file mode 100644 index 00000000000..cedbf4c0758 --- /dev/null +++ b/elements/lisk-p2p/src/disconnect_status_codes.ts @@ -0,0 +1,18 @@ +export const INVALID_CONNECTION_URL_CODE = 4501; +export const INVALID_CONNECTION_URL_REASON = + 'Peer did not provide a valid URL as part of the WebSocket connection'; + +export const INVALID_CONNECTION_QUERY_CODE = 4502; +export const INVALID_CONNECTION_QUERY_REASON = + 'Peer did not provide valid query parameters as part of the WebSocket connection'; + +export const INCOMPATIBLE_NETWORK_CODE = 4102; +export const INCOMPATIBLE_NETWORK_REASON = 'Peer nethash did not match our own'; + +export const INCOMPATIBLE_PROTOCOL_VERSION_CODE = 4103; +export const INCOMPATIBLE_PROTOCOL_VERSION_REASON = + 'Peer has incompatible protocol version'; + +export const INCOMPATIBLE_PEER_CODE = 4104; +export const INCOMPATIBLE_PEER_UNKNOWN_REASON = + 'Peer is incompatible with the node for unknown reasons'; diff --git a/elements/lisk-p2p/src/errors.ts b/elements/lisk-p2p/src/errors.ts new file mode 100644 index 00000000000..82138de5406 --- /dev/null +++ b/elements/lisk-p2p/src/errors.ts @@ -0,0 +1,108 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +/* tslint:disable: max-classes-per-file */ +import * as VError from 'verror'; + +export class PeerInboundHandshakeError extends VError { + public statusCode: number; + public remoteAddress: string; + public handshakeURL?: string; + + public constructor( + message: string, + statusCode: number, + remoteAddress: string, + handshakeURL?: string, + ) { + super(message); + this.name = 'PeerInboundHandshakeError'; + this.statusCode = statusCode; + this.remoteAddress = remoteAddress; + this.handshakeURL = handshakeURL; + } +} + +export class NotEnoughPeersError extends VError { + public constructor(message: string) { + super(message); + this.name = 'NotEnoughPeersError'; + } +} + +export class RPCResponseError extends VError { + public peerIp: string; + public peerPort: number; + + public constructor( + message: string, + cause: Error, + peerIp: string, + peerPort: number, + ) { + super(cause, message); + this.name = 'RPCResponseError'; + this.peerIp = peerIp; + this.peerPort = peerPort; + } +} + +export class FetchPeerStatusError extends VError { + public constructor(message: string, cause: Error) { + super(cause, message); + this.name = 'FetchPeerStatusError'; + } +} + +export class InvalidRPCResponseError extends VError { + public constructor(message: string) { + super(message); + this.name = 'InvalidRPCResponseError'; + } +} + +export class RPCResponseAlreadySentError extends VError { + public constructor(message: string) { + super(message); + this.name = 'ResponseAlreadySentError'; + } +} + +export class InvalidPeerError extends VError { + public constructor(message: string) { + super(message); + this.name = 'InvalidPeerError'; + } +} + +export class RequestFailError extends VError { + public constructor(message: string) { + super(message); + this.name = 'RequestFailError'; + } +} + +export class InvalidRPCRequestError extends VError { + public constructor(message: string) { + super(message); + this.name = 'InvalidRPCRequestError'; + } +} + +export class InvalidProtocolMessageError extends VError { + public constructor(message: string) { + super(message); + this.name = 'InvalidProtocolMessageError'; + } +} diff --git a/elements/lisk-p2p/src/index.ts b/elements/lisk-p2p/src/index.ts new file mode 100644 index 00000000000..2e7b4f3201a --- /dev/null +++ b/elements/lisk-p2p/src/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export * from './disconnect_status_codes'; +export * from './errors'; +export * from './p2p'; diff --git a/elements/lisk-p2p/src/p2p.ts b/elements/lisk-p2p/src/p2p.ts new file mode 100644 index 00000000000..6f00f968198 --- /dev/null +++ b/elements/lisk-p2p/src/p2p.ts @@ -0,0 +1,614 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +import { EventEmitter } from 'events'; +import * as http from 'http'; +// tslint:disable-next-line no-require-imports +import shuffle = require('lodash.shuffle'); +import { attach, SCServer, SCServerSocket } from 'socketcluster-server'; +import * as url from 'url'; + +interface SCServerUpdated extends SCServer { + readonly isReady: boolean; +} + +import { + constructPeerId, + constructPeerIdFromPeerInfo, + REMOTE_RPC_GET_ALL_PEERS_LIST, +} from './peer'; + +import { + INCOMPATIBLE_PEER_CODE, + INCOMPATIBLE_PEER_UNKNOWN_REASON, + INVALID_CONNECTION_QUERY_CODE, + INVALID_CONNECTION_QUERY_REASON, + INVALID_CONNECTION_URL_CODE, + INVALID_CONNECTION_URL_REASON, +} from './disconnect_status_codes'; + +import { PeerInboundHandshakeError } from './errors'; + +import { + P2PCheckPeerCompatibility, + P2PClosePacket, + P2PConfig, + P2PDiscoveredPeerInfo, + P2PMessagePacket, + P2PNetworkStatus, + P2PNodeInfo, + P2PPeerInfo, + P2PPeerSelectionForRequest, + P2PPeerSelectionForSend, + P2PPenalty, + P2PRequestPacket, + P2PResponsePacket, + ProtocolPeerInfo, + ProtocolPeerInfoList, +} from './p2p_types'; + +import { P2PRequest } from './p2p_request'; +export { P2PRequest }; +import { selectForConnection, selectPeers } from './peer_selection'; + +import { + EVENT_CLOSE_OUTBOUND, + EVENT_CONNECT_ABORT_OUTBOUND, + EVENT_CONNECT_OUTBOUND, + EVENT_DISCOVERED_PEER, + EVENT_FAILED_PEER_INFO_UPDATE, + EVENT_FAILED_TO_FETCH_PEER_INFO, + EVENT_FAILED_TO_PUSH_NODE_INFO, + EVENT_INBOUND_SOCKET_ERROR, + EVENT_MESSAGE_RECEIVED, + EVENT_OUTBOUND_SOCKET_ERROR, + EVENT_REQUEST_RECEIVED, + EVENT_UPDATED_PEER_INFO, + MAX_PEER_LIST_BATCH_SIZE, + PeerPool, +} from './peer_pool'; +import { checkPeerCompatibility } from './validation'; + +export { + EVENT_CLOSE_OUTBOUND, + EVENT_CONNECT_ABORT_OUTBOUND, + EVENT_CONNECT_OUTBOUND, + EVENT_DISCOVERED_PEER, + EVENT_FAILED_TO_FETCH_PEER_INFO, + EVENT_FAILED_TO_PUSH_NODE_INFO, + EVENT_REQUEST_RECEIVED, + EVENT_MESSAGE_RECEIVED, + EVENT_OUTBOUND_SOCKET_ERROR, + EVENT_INBOUND_SOCKET_ERROR, + EVENT_UPDATED_PEER_INFO, + EVENT_FAILED_PEER_INFO_UPDATE, +}; + +export const EVENT_NEW_INBOUND_PEER = 'newInboundPeer'; +export const EVENT_FAILED_TO_ADD_INBOUND_PEER = 'failedToAddInboundPeer'; +export const EVENT_NEW_PEER = 'newPeer'; + +export const NODE_HOST_IP = '0.0.0.0'; +export const DEFAULT_DISCOVERY_INTERVAL = 30000; + +const BASE_10_RADIX = 10; + +const selectRandomPeerSample = ( + peerList: ReadonlyArray, + count: number, +): ReadonlyArray => shuffle(peerList).slice(0, count); + +export class P2P extends EventEmitter { + private readonly _config: P2PConfig; + private readonly _httpServer: http.Server; + private _isActive: boolean; + private readonly _newPeers: Map; + private readonly _triedPeers: Map; + private readonly _discoveryInterval: number; + private _discoveryIntervalId: NodeJS.Timer | undefined; + + private _nodeInfo: P2PNodeInfo; + private readonly _peerPool: PeerPool; + private readonly _scServer: SCServerUpdated; + + private readonly _handlePeerPoolRPC: (request: P2PRequest) => void; + private readonly _handlePeerPoolMessage: (message: P2PMessagePacket) => void; + private readonly _handleDiscoveredPeer: ( + discoveredPeerInfo: P2PDiscoveredPeerInfo, + ) => void; + private readonly _handleFailedToPushNodeInfo: (error: Error) => void; + private readonly _handleFailedToFetchPeerInfo: (error: Error) => void; + private readonly _handlePeerConnect: ( + peerInfo: P2PDiscoveredPeerInfo, + ) => void; + private readonly _handlePeerConnectAbort: ( + peerInfo: P2PDiscoveredPeerInfo, + ) => void; + private readonly _handlePeerClose: (closePacket: P2PClosePacket) => void; + private readonly _handlePeerInfoUpdate: ( + peerInfo: P2PDiscoveredPeerInfo, + ) => void; + private readonly _handleFailedPeerInfoUpdate: (error: Error) => void; + private readonly _handleOutboundSocketError: (error: Error) => void; + private readonly _handleInboundSocketError: (error: Error) => void; + private readonly _peerHandshakeCheck: P2PCheckPeerCompatibility; + + public constructor(config: P2PConfig) { + super(); + this._config = config; + this._isActive = false; + this._newPeers = new Map(); + this._triedPeers = new Map(); + + this._httpServer = http.createServer(); + this._scServer = attach(this._httpServer) as SCServerUpdated; + + // This needs to be an arrow function so that it can be used as a listener. + this._handlePeerPoolRPC = (request: P2PRequest) => { + if (request.procedure === REMOTE_RPC_GET_ALL_PEERS_LIST) { + this._handleGetPeersRequest(request); + } + // Re-emit the request for external use. + this.emit(EVENT_REQUEST_RECEIVED, request); + }; + + // This needs to be an arrow function so that it can be used as a listener. + this._handlePeerPoolMessage = (message: P2PMessagePacket) => { + // Re-emit the message for external use. + this.emit(EVENT_MESSAGE_RECEIVED, message); + }; + + this._handlePeerConnect = (peerInfo: P2PPeerInfo) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_CONNECT_OUTBOUND, peerInfo); + }; + + this._handlePeerConnectAbort = (peerInfo: P2PPeerInfo) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + const peerId = constructPeerIdFromPeerInfo(peerInfo); + if (this._triedPeers.has(peerId)) { + this._triedPeers.delete(peerId); + } + this.emit(EVENT_CONNECT_ABORT_OUTBOUND, peerInfo); + }; + + this._handlePeerClose = (closePacket: P2PClosePacket) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_CLOSE_OUTBOUND, closePacket); + }; + + this._handlePeerInfoUpdate = (peerInfo: P2PPeerInfo) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_UPDATED_PEER_INFO, peerInfo); + }; + + this._handleFailedPeerInfoUpdate = (error: Error) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_FAILED_PEER_INFO_UPDATE, error); + }; + + this._handleDiscoveredPeer = (detailedPeerInfo: P2PDiscoveredPeerInfo) => { + const peerId = constructPeerIdFromPeerInfo(detailedPeerInfo); + if (!this._triedPeers.has(peerId)) { + if (this._newPeers.has(peerId)) { + this._newPeers.delete(peerId); + } + this._triedPeers.set(peerId, detailedPeerInfo); + } + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_DISCOVERED_PEER, detailedPeerInfo); + }; + + this._handleFailedToPushNodeInfo = (error: Error) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_FAILED_TO_PUSH_NODE_INFO, error); + }; + + this._handleFailedToFetchPeerInfo = (error: Error) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_FAILED_TO_FETCH_PEER_INFO, error); + }; + + this._handleOutboundSocketError = (error: Error) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_OUTBOUND_SOCKET_ERROR, error); + }; + + this._handleInboundSocketError = (error: Error) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_INBOUND_SOCKET_ERROR, error); + }; + + this._peerPool = new PeerPool({ + connectTimeout: config.connectTimeout, + ackTimeout: config.ackTimeout, + peerSelectionForSend: config.peerSelectionForSend + ? config.peerSelectionForSend + : (selectPeers as P2PPeerSelectionForSend), + peerSelectionForRequest: config.peerSelectionForRequest + ? config.peerSelectionForRequest + : (selectPeers as P2PPeerSelectionForRequest), + peerSelectionForConnection: config.peerSelectionForConnection + ? config.peerSelectionForConnection + : selectForConnection, + }); + + this._bindHandlersToPeerPool(this._peerPool); + + this._nodeInfo = config.nodeInfo; + this._peerPool.applyNodeInfo(this._nodeInfo); + + this._discoveryInterval = config.discoveryInterval + ? config.discoveryInterval + : DEFAULT_DISCOVERY_INTERVAL; + + this._peerHandshakeCheck = config.peerHandshakeCheck + ? config.peerHandshakeCheck + : checkPeerCompatibility; + } + + public get config(): P2PConfig { + return this._config; + } + + public get isActive(): boolean { + return this._isActive; + } + + /** + * This is not a declared as a setter because this method will need + * invoke an async RPC on Peers to give them our new node status. + */ + public applyNodeInfo(nodeInfo: P2PNodeInfo): void { + this._nodeInfo = { + ...nodeInfo, + }; + + this._peerPool.applyNodeInfo(this._nodeInfo); + } + + public get nodeInfo(): P2PNodeInfo { + return this._nodeInfo; + } + + /* tslint:disable:next-line: prefer-function-over-method */ + public applyPenalty(penalty: P2PPenalty): void { + penalty; + } + + public getNetworkStatus(): P2PNetworkStatus { + return { + newPeers: [...this._newPeers.values()], + triedPeers: [...this._triedPeers.values()], + connectedPeers: this._peerPool.getAllPeerInfos(), + }; + } + + public async request(packet: P2PRequestPacket): Promise { + const response = await this._peerPool.requestFromPeer(packet); + + return response; + } + + public send(message: P2PMessagePacket): void { + this._peerPool.sendToPeers(message); + } + + private _disconnectSocketDueToFailedHandshake( + socket: SCServerSocket, + statusCode: number, + closeReason: string, + ): void { + socket.disconnect(statusCode, closeReason); + this.emit( + EVENT_FAILED_TO_ADD_INBOUND_PEER, + new PeerInboundHandshakeError( + closeReason, + statusCode, + socket.remoteAddress, + socket.request.url, + ), + ); + } + + private async _startPeerServer(): Promise { + this._scServer.on( + 'connection', + (socket: SCServerSocket): void => { + if (!socket.request.url) { + this._disconnectSocketDueToFailedHandshake( + socket, + INVALID_CONNECTION_URL_CODE, + INVALID_CONNECTION_URL_REASON, + ); + + return; + } + const queryObject = url.parse(socket.request.url, true).query; + + if ( + typeof queryObject.wsPort !== 'string' || + typeof queryObject.version !== 'string' || + typeof queryObject.nethash !== 'string' + ) { + this._disconnectSocketDueToFailedHandshake( + socket, + INVALID_CONNECTION_QUERY_CODE, + INVALID_CONNECTION_QUERY_REASON, + ); + + return; + } + + const wsPort: number = parseInt(queryObject.wsPort, BASE_10_RADIX); + const peerId = constructPeerId(socket.remoteAddress, wsPort); + + // tslint:disable-next-line no-let + let queryOptions; + + try { + queryOptions = + typeof queryObject.options === 'string' + ? JSON.parse(queryObject.options) + : undefined; + } catch (error) { + this._disconnectSocketDueToFailedHandshake( + socket, + INVALID_CONNECTION_QUERY_CODE, + INVALID_CONNECTION_QUERY_REASON, + ); + + return; + } + + const incomingPeerInfo: P2PDiscoveredPeerInfo = { + ...queryObject, + ...queryOptions, + ipAddress: socket.remoteAddress, + wsPort, + height: queryObject.height ? +queryObject.height : 0, + version: queryObject.version, + }; + + const { success, errors } = this._peerHandshakeCheck( + incomingPeerInfo, + this._nodeInfo, + ); + + if (!success) { + const incompatibilityReason = + errors && Array.isArray(errors) + ? errors.join(',') + : INCOMPATIBLE_PEER_UNKNOWN_REASON; + + this._disconnectSocketDueToFailedHandshake( + socket, + INCOMPATIBLE_PEER_CODE, + incompatibilityReason, + ); + + return; + } + + const isNewPeer = this._peerPool.addInboundPeer( + peerId, + incomingPeerInfo, + socket, + ); + + if (isNewPeer) { + this.emit(EVENT_NEW_INBOUND_PEER, incomingPeerInfo); + this.emit(EVENT_NEW_PEER, incomingPeerInfo); + } + + if (!this._newPeers.has(peerId) && !this._triedPeers.has(peerId)) { + this._newPeers.set(peerId, incomingPeerInfo); + } + }, + ); + + this._httpServer.listen(this._nodeInfo.wsPort, NODE_HOST_IP); + if (this._scServer.isReady) { + this._isActive = true; + + return; + } + + return new Promise(resolve => { + this._scServer.once('ready', () => { + this._isActive = true; + resolve(); + }); + }); + } + + private async _stopHTTPServer(): Promise { + return new Promise(resolve => { + this._httpServer.close(() => { + resolve(); + }); + }); + } + + private async _stopWSServer(): Promise { + return new Promise(resolve => { + this._scServer.close(() => { + resolve(); + }); + }); + } + + private async _stopPeerServer(): Promise { + await this._stopWSServer(); + await this._stopHTTPServer(); + this._isActive = false; + } + + private async _discoverPeers( + knownPeers: ReadonlyArray = [], + ): Promise { + // Make sure that we do not try to connect to peers if the P2P node is no longer active. + if (!this._isActive) { + return; + } + + const discoveredPeers = await this._peerPool.runDiscovery( + knownPeers, + this._config.blacklistedPeers, + ); + + // Stop discovery if node is no longer active. That way we don't try to connect to peers. + // We need to check again because of the previous asynchronous await statement. + if (!this._isActive) { + return; + } + + discoveredPeers.forEach((peerInfo: P2PDiscoveredPeerInfo) => { + const peerId = constructPeerIdFromPeerInfo(peerInfo); + if (!this._triedPeers.has(peerId) && !this._newPeers.has(peerId)) { + this._newPeers.set(peerId, peerInfo); + } + }); + + this._peerPool.selectPeersAndConnect([...this._newPeers.values()]); + } + + private async _startDiscovery( + knownPeers: ReadonlyArray = [], + ): Promise { + if (this._discoveryIntervalId) { + throw new Error('Discovery is already running'); + } + this._discoveryIntervalId = setInterval(async () => { + await this._discoverPeers(knownPeers); + }, this._discoveryInterval); + + await this._discoverPeers(knownPeers); + } + + private _stopDiscovery(): void { + if (!this._discoveryIntervalId) { + throw new Error('Discovery is not running'); + } + clearInterval(this._discoveryIntervalId); + } + + private async _fetchSeedPeerStatus( + seedPeers: ReadonlyArray, + ): Promise> { + const peerConfig = { + ackTimeout: this._config.ackTimeout, + connectTimeout: this._config.connectTimeout, + }; + const seedPeerUpdatedInfos = await this._peerPool.fetchStatusAndCreatePeers( + seedPeers, + this._nodeInfo, + peerConfig, + ); + + return seedPeerUpdatedInfos; + } + + private _pickRandomDiscoveredPeers( + count: number, + ): ReadonlyArray { + const discoveredPeerList: ReadonlyArray = [ + ...this._newPeers.values(), + ...this._triedPeers.values(), + ]; // Peers whose values has been updated atleast once. + + return selectRandomPeerSample(discoveredPeerList, count); + } + + private _handleGetPeersRequest(request: P2PRequest): void { + // TODO later: Remove fields that are specific to the current Lisk protocol. + const peers = this._pickRandomDiscoveredPeers(MAX_PEER_LIST_BATCH_SIZE).map( + (peerInfo: P2PDiscoveredPeerInfo): ProtocolPeerInfo => { + const { ipAddress, ...peerInfoWithoutIp } = peerInfo; + + // The options property is not read by the current legacy protocol but it should be added anyway for future compatibility. + return { + ...peerInfoWithoutIp, + ip: ipAddress, + broadhash: peerInfoWithoutIp.broadhash + ? (peerInfoWithoutIp.broadhash as string) + : '', + nonce: peerInfoWithoutIp.nonce + ? (peerInfoWithoutIp.nonce as string) + : '', + }; + }, + ); + const protocolPeerInfoList: ProtocolPeerInfoList = { + success: true, + peers, + }; + + request.end(protocolPeerInfoList); + } + + public async start(): Promise { + if (this._isActive) { + throw new Error('Cannot start the node because it is already active'); + } + await this._startPeerServer(); + // Fetch status of all the seed peers and then start the discovery + const seedPeerInfos = await this._fetchSeedPeerStatus( + this._config.seedPeers, + ); + // Add seed's peerinfos in tried peer as we already tried them to fetch status + seedPeerInfos.forEach(seedInfo => { + const peerId = constructPeerIdFromPeerInfo(seedInfo); + if (!this._triedPeers.has(peerId)) { + this._triedPeers.set(peerId, seedInfo); + } + }); + + await this._startDiscovery(seedPeerInfos); + } + + public async stop(): Promise { + if (!this._isActive) { + throw new Error('Cannot stop the node because it is not active'); + } + this._stopDiscovery(); + this._peerPool.removeAllPeers(); + await this._stopPeerServer(); + } + + private _bindHandlersToPeerPool(peerPool: PeerPool): void { + peerPool.on(EVENT_REQUEST_RECEIVED, this._handlePeerPoolRPC); + peerPool.on(EVENT_MESSAGE_RECEIVED, this._handlePeerPoolMessage); + peerPool.on(EVENT_CONNECT_OUTBOUND, this._handlePeerConnect); + peerPool.on(EVENT_CONNECT_ABORT_OUTBOUND, this._handlePeerConnectAbort); + peerPool.on(EVENT_CLOSE_OUTBOUND, this._handlePeerClose); + peerPool.on(EVENT_UPDATED_PEER_INFO, this._handlePeerInfoUpdate); + peerPool.on( + EVENT_FAILED_PEER_INFO_UPDATE, + this._handleFailedPeerInfoUpdate, + ); + peerPool.on(EVENT_DISCOVERED_PEER, this._handleDiscoveredPeer); + peerPool.on( + EVENT_FAILED_TO_PUSH_NODE_INFO, + this._handleFailedToPushNodeInfo, + ); + peerPool.on( + EVENT_FAILED_TO_FETCH_PEER_INFO, + this._handleFailedToFetchPeerInfo, + ); + peerPool.on(EVENT_OUTBOUND_SOCKET_ERROR, this._handleOutboundSocketError); + peerPool.on(EVENT_INBOUND_SOCKET_ERROR, this._handleInboundSocketError); + } +} diff --git a/elements/lisk-p2p/src/p2p_request.ts b/elements/lisk-p2p/src/p2p_request.ts new file mode 100644 index 00000000000..35c653cd960 --- /dev/null +++ b/elements/lisk-p2p/src/p2p_request.ts @@ -0,0 +1,57 @@ +import { RPCResponseAlreadySentError } from './errors'; +import { P2PResponsePacket } from './p2p_types'; + +export class P2PRequest { + private readonly _procedure: string; + private readonly _data: unknown; + private readonly _respondCallback: ( + responseError?: Error, + responseData?: P2PResponsePacket, + ) => void; + private _wasResponseSent: boolean; + + public constructor( + procedure: string, + data: unknown, + respondCallback: (responseError?: Error, responseData?: unknown) => void, + ) { + this._procedure = procedure; + this._data = data; + this._respondCallback = ( + responseError?: Error, + responsePacket?: P2PResponsePacket, + ) => { + if (this._wasResponseSent) { + throw new RPCResponseAlreadySentError( + 'A response has already been sent for this request', + ); + } + this._wasResponseSent = true; + respondCallback(responseError, responsePacket); + }; + this._wasResponseSent = false; + } + + public get procedure(): string { + return this._procedure; + } + + public get data(): unknown { + return this._data; + } + + public get wasResponseSent(): boolean { + return this._wasResponseSent; + } + + public end(responseData?: unknown): void { + const responsePacket: P2PResponsePacket = { + data: responseData, + }; + this._respondCallback(undefined, responsePacket); + } + + public error(responseError: Error): void { + this._respondCallback(responseError); + } +} diff --git a/elements/lisk-p2p/src/p2p_types.ts b/elements/lisk-p2p/src/p2p_types.ts new file mode 100644 index 00000000000..c87d4eba7fd --- /dev/null +++ b/elements/lisk-p2p/src/p2p_types.ts @@ -0,0 +1,179 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +/* tslint:disable:no-empty-interface*/ + +export interface P2PPacket { + readonly data?: unknown; +} + +export interface P2PRequestPacket extends P2PPacket { + readonly data?: unknown; + readonly procedure: string; +} + +export interface P2PResponsePacket extends P2PPacket { + readonly data: unknown; +} + +export interface P2PMessagePacket extends P2PPacket { + readonly data?: unknown; + readonly event: string; +} + +export interface P2PPenalty {} + +// Allows the user to provide custom fields. +export interface P2PInfoOptions { + readonly [key: string]: unknown; +} + +export interface P2PPeerInfo { + readonly ipAddress: string; + readonly wsPort: number; +} + +export interface P2PDiscoveredPeerInfo extends P2PPeerInfo { + readonly height: number; + readonly updatedAt?: Date; + readonly os?: string; + readonly version: string; + // tslint:disable-next-line: no-mixed-interface + readonly [key: string]: unknown; +} + +// P2PPeerInfo and P2PNodeInfo are related. +// P2PNodeInfo is the outbound info from our node. +export interface P2PNodeInfo { + readonly os: string; + readonly version: string; + readonly nethash: string; + readonly wsPort: number; + readonly height: number; + // tslint:disable-next-line: no-mixed-interface + readonly [key: string]: unknown; +} + +export interface P2PClosePacket { + readonly peerInfo: P2PDiscoveredPeerInfo; + readonly code: number; + readonly reason?: string; +} + +export interface P2PConfig { + readonly blacklistedPeers: ReadonlyArray; + readonly connectTimeout?: number; + readonly ackTimeout?: number; + readonly hostAddress?: string; + readonly seedPeers: ReadonlyArray; + readonly nodeInfo: P2PNodeInfo; + readonly wsEngine?: string; + readonly discoveryInterval?: number; + readonly peerSelectionForSend?: P2PPeerSelectionForSend; + readonly peerSelectionForRequest?: P2PPeerSelectionForRequest; + readonly peerSelectionForConnection?: P2PPeerSelectionForConnection; + readonly peerHandshakeCheck?: P2PCheckPeerCompatibility; +} + +// Network info exposed by the P2P library. +export interface P2PNetworkStatus { + readonly newPeers: ReadonlyArray; + readonly triedPeers: ReadonlyArray; + readonly connectedPeers: ReadonlyArray; +} + +// TODO later: Switch to LIP protocol format. +// This is a representation of the outbound peer object according to the current protocol. +export interface ProtocolNodeInfo { + readonly broadhash: string; + readonly nethash: string; + readonly height: number; + readonly nonce: string; + readonly os?: string; + readonly version: string; + readonly wsPort: number; + readonly httpPort: number; + // tslint:disable-next-line:no-mixed-interface + readonly [key: string]: unknown; +} + +export type P2PPeerSelectionForSendRequest = ( + peers: ReadonlyArray, + nodeInfo?: P2PNodeInfo, + numOfPeers?: number, +) => ReadonlyArray; + +export type P2PPeerSelectionForSend = ( + peers: ReadonlyArray, + nodeInfo?: P2PNodeInfo, + numOfPeers?: number, + messagePacket?: P2PMessagePacket +) => ReadonlyArray; + +export type P2PPeerSelectionForRequest = ( + peers: ReadonlyArray, + nodeInfo?: P2PNodeInfo, + numOfPeers?: number, + requestPacket?: P2PRequestPacket +) => ReadonlyArray; + +export type P2PPeerSelectionForConnection = ( + peers: ReadonlyArray, + nodeInfo?: P2PNodeInfo, +) => ReadonlyArray; + +export interface P2PCompatibilityCheckReturnType { + readonly success: boolean; + readonly errors?: string[]; +} + +export type P2PCheckPeerCompatibility = ( + headers: P2PDiscoveredPeerInfo, + nodeInfo: P2PNodeInfo, +) => P2PCompatibilityCheckReturnType; + +// This is a representation of the inbound peer object according to the current protocol. +// TODO later: Switch to LIP protocol format. +export interface ProtocolPeerInfo { + readonly ip: string; + readonly broadhash: string; + readonly height: number; + readonly nonce: string; + readonly os?: string; + readonly version: string; + readonly wsPort: number; + readonly httpPort?: number; + // tslint:disable-next-line: no-mixed-interface + readonly [key: string]: unknown; +} + +// This is a representation of the peer list according to the current protocol. +// TODO later: Switch to LIP protocol format. +export interface ProtocolPeerInfoList { + readonly peers: ReadonlyArray; + readonly success: boolean; +} + +// TODO later: Switch to LIP protocol format. +export interface ProtocolRPCRequestPacket { + readonly data: unknown; + readonly procedure: string; + readonly type: string; +} + +// TODO later: Switch to LIP protocol format. +export interface ProtocolMessagePacket { + readonly data: unknown; + readonly event: string; +} diff --git a/elements/lisk-p2p/src/peer.ts b/elements/lisk-p2p/src/peer.ts new file mode 100644 index 00000000000..9b82f186456 --- /dev/null +++ b/elements/lisk-p2p/src/peer.ts @@ -0,0 +1,704 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +import { EventEmitter } from 'events'; +import * as querystring from 'querystring'; +import { FetchPeerStatusError, RPCResponseError } from './errors'; + +import { + P2PDiscoveredPeerInfo, + P2PMessagePacket, + P2PNodeInfo, + P2PPeerInfo, + P2PRequestPacket, + P2PResponsePacket, + ProtocolNodeInfo, +} from './p2p_types'; + +import { P2PRequest } from './p2p_request'; + +import * as socketClusterClient from 'socketcluster-client'; +import { SCServerSocket } from 'socketcluster-server'; +import { + validatePeerInfo, + validatePeerInfoList, + validateProtocolMessage, + validateRPCRequest, +} from './validation'; + +// This interface is needed because pingTimeoutDisabled is missing from ClientOptions in socketcluster-client. +interface ClientOptionsUpdated { + readonly hostname: string; + readonly port: number; + readonly query: string; + readonly autoConnect: boolean; + readonly autoReconnect: boolean; + readonly pingTimeoutDisabled: boolean; + readonly multiplex: boolean; + readonly ackTimeout?: number; + readonly connectTimeout?: number; +} + +type SCClientSocket = socketClusterClient.SCClientSocket; + +// Local emitted events. +export const EVENT_UPDATED_PEER_INFO = 'updatedPeerInfo'; +export const EVENT_FAILED_PEER_INFO_UPDATE = 'failedPeerInfoUpdate'; +export const EVENT_REQUEST_RECEIVED = 'requestReceived'; +export const EVENT_INVALID_REQUEST_RECEIVED = 'invalidRequestReceived'; +export const EVENT_MESSAGE_RECEIVED = 'messageReceived'; +export const EVENT_INVALID_MESSAGE_RECEIVED = 'invalidMessageReceived'; +export const EVENT_CONNECT_OUTBOUND = 'connectOutbound'; +export const EVENT_CONNECT_ABORT_OUTBOUND = 'connectAbortOutbound'; +export const EVENT_CLOSE_OUTBOUND = 'closeOutbound'; +export const EVENT_OUTBOUND_SOCKET_ERROR = 'outboundSocketError'; +export const EVENT_INBOUND_SOCKET_ERROR = 'inboundSocketError'; + +// Remote event or RPC names sent to or received from peers. +export const REMOTE_EVENT_RPC_REQUEST = 'rpc-request'; +export const REMOTE_EVENT_MESSAGE = 'remote-message'; + +export const REMOTE_RPC_UPDATE_PEER_INFO = 'updateMyself'; +export const REMOTE_RPC_GET_NODE_INFO = 'status'; +export const REMOTE_RPC_GET_ALL_PEERS_LIST = 'list'; + +export const DEFAULT_CONNECT_TIMEOUT = 2000; +export const DEFAULT_ACK_TIMEOUT = 2000; + +type SCServerSocketUpdated = { + destroy(code?: number, data?: string | object): void; + on(event: string | unknown, listener: (packet?: unknown) => void): void; + on(event: string, listener: (packet: any, respond: any) => void): void; +} & SCServerSocket; + +export enum ConnectionState { + CONNECTING = 0, + CONNECTED = 1, + DISCONNECTED = 2, +} + +export interface PeerConnectionState { + readonly inbound: ConnectionState; + readonly outbound: ConnectionState; +} + +export const constructPeerId = (ipAddress: string, wsPort: number): string => + `${ipAddress}:${wsPort}`; + +export const constructPeerIdFromPeerInfo = (peerInfo: P2PPeerInfo): string => + `${peerInfo.ipAddress}:${peerInfo.wsPort}`; + +// Format the node info so that it will be valid from the perspective of both new and legacy nodes. +const convertNodeInfoToLegacyFormat = ( + nodeInfo: P2PNodeInfo, +): ProtocolNodeInfo => { + const { httpPort, nonce, broadhash } = nodeInfo; + + return { + ...nodeInfo, + broadhash: broadhash ? (broadhash as string) : '', + nonce: nonce ? (nonce as string) : '', + httpPort: httpPort ? (httpPort as number) : 0 + }; +}; + +export interface PeerConfig { + readonly connectTimeout?: number; + readonly ackTimeout?: number; +} +export interface PeerSockets { + readonly outbound?: SCClientSocket; + readonly inbound?: SCServerSocket; +} + +export class Peer extends EventEmitter { + private readonly _id: string; + private readonly _ipAddress: string; + private readonly _wsPort: number; + private readonly _height: number; + private _peerInfo: P2PDiscoveredPeerInfo; + private readonly _peerConfig: PeerConfig; + private _nodeInfo: P2PNodeInfo | undefined; + private _inboundSocket: SCServerSocketUpdated | undefined; + private _outboundSocket: SCClientSocket | undefined; + private readonly _handleRawRPC: ( + packet: unknown, + respond: (responseError?: Error, responseData?: unknown) => void, + ) => void; + private readonly _handleRawMessage: (packet: unknown) => void; + private readonly _handleRawLegacyMessagePostBlock: (packet: unknown) => void; + private readonly _handleRawLegacyMessagePostTransactions: ( + packet: unknown, + ) => void; + private readonly _handleRawLegacyMessagePostSignatures: ( + packet: unknown, + ) => void; + private readonly _handleInboundSocketError: (error: Error) => void; + + public constructor( + peerInfo: P2PDiscoveredPeerInfo, + peerConfig?: PeerConfig, + peerSockets?: PeerSockets, + ) { + super(); + this._peerInfo = peerInfo; + this._peerConfig = peerConfig ? peerConfig : {}; + this._ipAddress = peerInfo.ipAddress; + this._wsPort = peerInfo.wsPort; + this._id = constructPeerId(this._ipAddress, this._wsPort); + this._height = peerInfo.height ? peerInfo.height : 0; + + // This needs to be an arrow function so that it can be used as a listener. + this._handleRawRPC = ( + packet: unknown, + respond: (responseError?: Error, responseData?: unknown) => void, + ) => { + // TODO later: Switch to LIP protocol format. + // tslint:disable-next-line:no-let + let rawRequest; + try { + rawRequest = validateRPCRequest(packet); + } catch (err) { + this.emit(EVENT_INVALID_REQUEST_RECEIVED, packet); + + return; + } + const request = new P2PRequest( + rawRequest.procedure, + rawRequest.data, + respond, + ); + + if (rawRequest.procedure === REMOTE_RPC_UPDATE_PEER_INFO) { + this._handleUpdatePeerInfo(request); + } else if (rawRequest.procedure === REMOTE_RPC_GET_NODE_INFO) { + this._handleGetNodeInfo(request); + } + + this.emit(EVENT_REQUEST_RECEIVED, request); + }; + + // This needs to be an arrow function so that it can be used as a listener. + this._handleRawMessage = (packet: unknown) => { + // TODO later: Switch to LIP protocol format. + // tslint:disable-next-line:no-let + let protocolMessage; + try { + protocolMessage = validateProtocolMessage(packet); + } catch (err) { + this.emit(EVENT_INVALID_MESSAGE_RECEIVED, packet); + + return; + } + + this.emit(EVENT_MESSAGE_RECEIVED, protocolMessage); + }; + + // TODO later: Delete the following legacy message handlers. + // For the next LIP version, the send method will always emit a 'remote-message' event on the socket. + this._handleRawLegacyMessagePostBlock = (data: unknown) => { + this._handleRawMessage({ + event: 'postBlock', + data, + }); + }; + + this._handleRawLegacyMessagePostTransactions = (data: unknown) => { + this._handleRawMessage({ + event: 'postTransactions', + data, + }); + }; + + this._handleRawLegacyMessagePostSignatures = (data: unknown) => { + this._handleRawMessage({ + event: 'postSignatures', + data, + }); + }; + + this._handleInboundSocketError = (error: Error) => { + this.emit(EVENT_INBOUND_SOCKET_ERROR, error); + }; + + this._inboundSocket = peerSockets ? peerSockets.inbound : undefined; + if (this._inboundSocket) { + this._bindHandlersToInboundSocket(this._inboundSocket); + } + this._outboundSocket = peerSockets ? peerSockets.outbound : undefined; + if (this._outboundSocket) { + this._bindHandlersToOutboundSocket(this._outboundSocket); + } + } + + public get height(): number { + return this._height; + } + + public get id(): string { + return this._id; + } + + public set inboundSocket(scServerSocket: SCServerSocket) { + if (this._inboundSocket) { + this._unbindHandlersFromInboundSocket(this._inboundSocket); + } + this._inboundSocket = scServerSocket as SCServerSocketUpdated; + this._bindHandlersToInboundSocket(this._inboundSocket); + } + + public get ipAddress(): string { + return this._ipAddress; + } + + public set outboundSocket(scClientSocket: SCClientSocket) { + this._outboundSocket = scClientSocket; + } + + public updatePeerInfo(newPeerInfo: P2PDiscoveredPeerInfo): void { + // The ipAddress and wsPort properties cannot be updated after the initial discovery. + this._peerInfo = { + ...newPeerInfo, + ipAddress: this._ipAddress, + wsPort: this._wsPort, + }; + } + + public get peerInfo(): P2PDiscoveredPeerInfo { + return this._peerInfo; + } + + public get state(): PeerConnectionState { + const inbound = this._inboundSocket + ? this._inboundSocket.state === this._inboundSocket.OPEN + ? ConnectionState.CONNECTED + : ConnectionState.DISCONNECTED + : ConnectionState.DISCONNECTED; + const outbound = this._outboundSocket + ? this._outboundSocket.state === this._outboundSocket.OPEN + ? ConnectionState.CONNECTED + : ConnectionState.DISCONNECTED + : ConnectionState.DISCONNECTED; + + return { + inbound, + outbound, + }; + } + + public get wsPort(): number { + return this._wsPort; + } + + /** + * This is not a declared as a setter because this method will need + * invoke an async RPC on the socket to pass it the new node status. + */ + public async applyNodeInfo(nodeInfo: P2PNodeInfo): Promise { + this._nodeInfo = nodeInfo; + // TODO later: This conversion step will not be needed after switching to the new LIP protocol version. + const legacyNodeInfo = convertNodeInfoToLegacyFormat(this._nodeInfo); + // TODO later: Consider using send instead of request for updateMyself for the next LIP protocol version. + await this.request({ + procedure: REMOTE_RPC_UPDATE_PEER_INFO, + data: legacyNodeInfo, + }); + } + + public get nodeInfo(): P2PNodeInfo | undefined { + return this._nodeInfo; + } + + public connect(): void { + if (!this._outboundSocket) { + this._outboundSocket = this._createOutboundSocket(); + } + this._outboundSocket.connect(); + } + + public disconnect(code: number = 1000, reason?: string): void { + this.dropInboundConnection(code, reason); + this.dropOutboundConnection(code, reason); + } + + public dropInboundConnection(code: number = 1000, reason?: string): void { + if (this._inboundSocket) { + this._inboundSocket.destroy(code, reason); + this._unbindHandlersFromInboundSocket(this._inboundSocket); + } + } + + public dropOutboundConnection(code: number = 1000, reason?: string): void { + if (this._outboundSocket) { + this._outboundSocket.destroy(code, reason); + this._unbindHandlersFromOutboundSocket(this._outboundSocket); + } + } + + public send(packet: P2PMessagePacket): void { + if (!this._outboundSocket) { + this._outboundSocket = this._createOutboundSocket(); + } + + const legacyEvents = ['postBlock', 'postTransactions', 'postSignatures']; + // TODO later: Legacy events will no longer be required after migrating to the LIP protocol version. + if (legacyEvents.includes(packet.event)) { + // Emit legacy remote events. + this._outboundSocket.emit(packet.event, packet.data); + } else { + this._outboundSocket.emit(REMOTE_EVENT_MESSAGE, { + event: packet.event, + data: packet.data, + }); + } + } + + public async request(packet: P2PRequestPacket): Promise { + return new Promise( + ( + resolve: (result: P2PResponsePacket) => void, + reject: (result: Error) => void, + ): void => { + if (!this._outboundSocket) { + this._outboundSocket = this._createOutboundSocket(); + } + this._outboundSocket.emit( + REMOTE_EVENT_RPC_REQUEST, + { + type: '/RPCRequest', + procedure: packet.procedure, + data: packet.data, + }, + (err: Error | undefined, responseData: unknown) => { + if (err) { + reject(err); + + return; + } + + if (responseData) { + resolve(responseData as P2PResponsePacket); + + return; + } + + reject( + new RPCResponseError( + `Failed to handle response for procedure ${packet.procedure}`, + new Error('RPC response format was invalid'), + this.ipAddress, + this.wsPort, + ), + ); + }, + ); + }, + ); + } + + public async fetchPeers(): Promise> { + try { + const response: P2PResponsePacket = await this.request({ + procedure: REMOTE_RPC_GET_ALL_PEERS_LIST, + }); + + return validatePeerInfoList(response.data); + } catch (error) { + throw new RPCResponseError( + 'Failed to fetch peer list of peer', + error, + this.ipAddress, + this.wsPort, + ); + } + } + + public async fetchStatus(): Promise { + try { + const response: P2PResponsePacket = await this.request({ + procedure: REMOTE_RPC_GET_NODE_INFO, + }); + + this._updateFromProtocolPeerInfo(response.data); + } catch (error) { + this.emit(EVENT_FAILED_PEER_INFO_UPDATE, error); + + throw new RPCResponseError( + 'Failed to fetch peer info of peer', + error, + this.ipAddress, + this.wsPort, + ); + } + + this.emit(EVENT_UPDATED_PEER_INFO, this._peerInfo); + + // Return the updated detailed peer info. + return this._peerInfo; + } + + private _createOutboundSocket(): SCClientSocket { + const legacyNodeInfo = this._nodeInfo + ? convertNodeInfoToLegacyFormat(this._nodeInfo) + : undefined; + + const connectTimeout = this._peerConfig.connectTimeout + ? this._peerConfig.connectTimeout + : DEFAULT_CONNECT_TIMEOUT; + const ackTimeout = this._peerConfig.ackTimeout + ? this._peerConfig.ackTimeout + : DEFAULT_ACK_TIMEOUT; + + // Ideally, we should JSON-serialize the whole NodeInfo object but this cannot be done for compatibility reasons, so instead we put it inside an options property. + const clientOptions: ClientOptionsUpdated = { + hostname: this._ipAddress, + port: this._wsPort, + query: querystring.stringify({ + ...legacyNodeInfo, + options: JSON.stringify(legacyNodeInfo), + }), + connectTimeout, + ackTimeout, + multiplex: false, + autoConnect: false, + autoReconnect: false, + pingTimeoutDisabled: true, + }; + + const outboundSocket = socketClusterClient.create(clientOptions); + + this._bindHandlersToOutboundSocket(outboundSocket); + + return outboundSocket; + } + + // All event handlers for the outbound socket should be bound in this method. + private _bindHandlersToOutboundSocket(outboundSocket: SCClientSocket): void { + outboundSocket.on('error', (error: Error) => { + this.emit(EVENT_OUTBOUND_SOCKET_ERROR, error); + }); + + outboundSocket.on('connect', () => { + this.emit(EVENT_CONNECT_OUTBOUND, this._peerInfo); + }); + + outboundSocket.on('connectAbort', () => { + this.emit(EVENT_CONNECT_ABORT_OUTBOUND, this._peerInfo); + }); + + outboundSocket.on('close', (code, reason) => { + this.emit(EVENT_CLOSE_OUTBOUND, { + peerInfo: this._peerInfo, + code, + reason, + }); + }); + } + + // All event handlers for the outbound socket should be unbound in this method. + /* tslint:disable-next-line:prefer-function-over-method*/ + private _unbindHandlersFromOutboundSocket( + outboundSocket: SCClientSocket, + ): void { + // Do not unbind the error handler because error could still throw after disconnect. + // We don't want to have uncaught errors. + outboundSocket.off('connect'); + outboundSocket.off('connectAbort'); + outboundSocket.off('close'); + } + + // All event handlers for the inbound socket should be bound in this method. + private _bindHandlersToInboundSocket( + inboundSocket: SCServerSocketUpdated, + ): void { + inboundSocket.on(REMOTE_EVENT_RPC_REQUEST, this._handleRawRPC); + inboundSocket.on(REMOTE_EVENT_MESSAGE, this._handleRawMessage); + inboundSocket.on('error', this._handleInboundSocketError); + inboundSocket.on('postBlock', this._handleRawLegacyMessagePostBlock); + inboundSocket.on( + 'postSignatures', + this._handleRawLegacyMessagePostSignatures, + ); + inboundSocket.on( + 'postTransactions', + this._handleRawLegacyMessagePostTransactions, + ); + } + + // All event handlers for the inbound socket should be unbound in this method. + private _unbindHandlersFromInboundSocket( + inboundSocket: SCServerSocket, + ): void { + inboundSocket.off(REMOTE_EVENT_RPC_REQUEST, this._handleRawRPC); + inboundSocket.off(REMOTE_EVENT_MESSAGE, this._handleRawMessage); + inboundSocket.off('postBlock', this._handleRawLegacyMessagePostBlock); + inboundSocket.off( + 'postSignatures', + this._handleRawLegacyMessagePostSignatures, + ); + inboundSocket.off( + 'postTransactions', + this._handleRawLegacyMessagePostTransactions, + ); + } + + private _updateFromProtocolPeerInfo(rawPeerInfo: unknown): void { + const protocolPeerInfo = { ...rawPeerInfo, ip: this._ipAddress }; + const newPeerInfo = validatePeerInfo(protocolPeerInfo); + this.updatePeerInfo(newPeerInfo); + } + + private _handleUpdatePeerInfo(request: P2PRequest): void { + // Update peerInfo with the latest values from the remote peer. + try { + this._updateFromProtocolPeerInfo(request.data); + } catch (error) { + this.emit(EVENT_FAILED_PEER_INFO_UPDATE, error); + request.error(error); + + return; + } + + this.emit(EVENT_UPDATED_PEER_INFO, this._peerInfo); + request.end(); + } + + private _handleGetNodeInfo(request: P2PRequest): void { + const legacyNodeInfo = this._nodeInfo + ? convertNodeInfoToLegacyFormat(this._nodeInfo) + : {}; + request.end(legacyNodeInfo); + } +} + +export interface ConnectAndFetchResponse { + readonly responsePacket: P2PResponsePacket; + readonly socket: SCClientSocket; +} + +export interface PeerInfoAndOutboundConnection { + readonly peerInfo: P2PDiscoveredPeerInfo; + readonly socket: SCClientSocket; +} + +export const connectAndRequest = async ( + basicPeerInfo: P2PPeerInfo, + procedure: string, + nodeInfo?: P2PNodeInfo, + peerConfig?: PeerConfig, +): Promise => + new Promise( + (resolve, reject): void => { + const legacyNodeInfo = nodeInfo + ? convertNodeInfoToLegacyFormat(nodeInfo) + : undefined; + // Add a new field discovery to tell the receiving side that the connection will be short lived + const requestPacket = { + procedure, + }; + // Ideally, we should JSON-serialize the whole NodeInfo object but this cannot be done for compatibility reasons, so instead we put it inside an options property. + const clientOptions: ClientOptionsUpdated = { + hostname: basicPeerInfo.ipAddress, + port: basicPeerInfo.wsPort, + query: querystring.stringify({ + ...legacyNodeInfo, + options: JSON.stringify(legacyNodeInfo), + }), + connectTimeout: peerConfig + ? peerConfig.connectTimeout + ? peerConfig.connectTimeout + : DEFAULT_CONNECT_TIMEOUT + : DEFAULT_CONNECT_TIMEOUT, + ackTimeout: peerConfig + ? peerConfig.connectTimeout + ? peerConfig.connectTimeout + : DEFAULT_CONNECT_TIMEOUT + : DEFAULT_ACK_TIMEOUT, + multiplex: false, + autoConnect: false, + autoReconnect: false, + pingTimeoutDisabled: true, + }; + + const outboundSocket = socketClusterClient.create(clientOptions); + // Attaching handlers for various events that could be used future for logging or any other application + outboundSocket.emit( + REMOTE_EVENT_RPC_REQUEST, + { + type: '/RPCRequest', + procedure: requestPacket.procedure, + }, + (err: Error | undefined, responseData: unknown) => { + if (err) { + reject(err); + + return; + } + if (responseData) { + const responsePacket = responseData as P2PResponsePacket; + resolve({ + responsePacket, + socket: outboundSocket, + }); + + return; + } + + reject( + new RPCResponseError( + `Failed to handle response for procedure ${ + requestPacket.procedure + }`, + new Error('RPC response format was invalid'), + basicPeerInfo.ipAddress, + basicPeerInfo.wsPort, + ), + ); + }, + ); + }, + ); + +export const connectAndFetchPeerInfo = async ( + basicPeerInfo: P2PPeerInfo, + nodeInfo?: P2PNodeInfo, + peerConfig?: PeerConfig, +): Promise => { + try { + const { responsePacket, socket } = await connectAndRequest( + basicPeerInfo, + REMOTE_RPC_GET_NODE_INFO, + nodeInfo, + peerConfig, + ); + + const protocolPeerInfo = responsePacket.data; + const rawPeerInfo = { + ...protocolPeerInfo, + ip: basicPeerInfo.ipAddress, + wsPort: basicPeerInfo.wsPort, + }; + const peerInfo = validatePeerInfo(rawPeerInfo); + + return { peerInfo, socket }; + } catch (error) { + throw new FetchPeerStatusError( + `Error occurred while fetching information from ${ + basicPeerInfo.ipAddress + }:${basicPeerInfo.wsPort}`, + error, + ); + } +}; diff --git a/elements/lisk-p2p/src/peer_discovery.ts b/elements/lisk-p2p/src/peer_discovery.ts new file mode 100644 index 00000000000..5e74751a05e --- /dev/null +++ b/elements/lisk-p2p/src/peer_discovery.ts @@ -0,0 +1,74 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { P2PDiscoveredPeerInfo } from './p2p_types'; +import { constructPeerIdFromPeerInfo, Peer } from './peer'; +// For Lips, this will be used for fixed and white lists +export interface FilterPeerOptions { + readonly blacklist: ReadonlyArray; +} + +// TODO later: Implement LIPS to handle fixed and white list +export const discoverPeers = async ( + knownPeers: ReadonlyArray, + filterPeerOptions: FilterPeerOptions = { blacklist: [] }, +): Promise> => { + const peersOfPeer: ReadonlyArray< + ReadonlyArray + > = await Promise.all( + knownPeers.map(async peer => { + try { + return await peer.fetchPeers(); + } catch (error) { + return []; + } + }), + ); + + const peersOfPeerFlat = peersOfPeer.reduce( + (flattenedPeersList: ReadonlyArray, peersList) => + Array.isArray(peersList) + ? [...flattenedPeersList, ...peersList] + : flattenedPeersList, + [], + ); + + // Remove duplicates + const discoveredPeers = peersOfPeerFlat.reduce( + ( + uniquePeersArray: ReadonlyArray, + peer: P2PDiscoveredPeerInfo, + ) => { + const found = uniquePeersArray.find( + findPeer => + constructPeerIdFromPeerInfo(findPeer) === + constructPeerIdFromPeerInfo(peer), + ); + + return found ? uniquePeersArray : [...uniquePeersArray, peer]; + }, + [], + ); + + if (filterPeerOptions.blacklist.length === 0) { + return discoveredPeers; + } + // Remove blacklist ids + const discoveredPeersFiltered = discoveredPeers.filter( + (peer: P2PDiscoveredPeerInfo) => + !filterPeerOptions.blacklist.includes(peer.ipAddress), + ); + + return discoveredPeersFiltered; +}; diff --git a/elements/lisk-p2p/src/peer_pool.ts b/elements/lisk-p2p/src/peer_pool.ts new file mode 100644 index 00000000000..6c1c5f7e54e --- /dev/null +++ b/elements/lisk-p2p/src/peer_pool.ts @@ -0,0 +1,543 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +/** + * The purpose of the PeerPool is to provide a simple interface for selecting, + * interacting with and handling aggregated events from a collection of peers. + */ + +import { EventEmitter } from 'events'; +// tslint:disable-next-line no-require-imports +import shuffle = require('lodash.shuffle'); +import { SCClientSocket } from 'socketcluster-client'; +import { SCServerSocket } from 'socketcluster-server'; +import { RequestFailError } from './errors'; +import { P2PRequest } from './p2p_request'; +import { + P2PClosePacket, + P2PDiscoveredPeerInfo, + P2PMessagePacket, + P2PNodeInfo, + P2PPeerInfo, + P2PPeerSelectionForConnection, + P2PPeerSelectionForRequest, + P2PPeerSelectionForSend, + P2PRequestPacket, + P2PResponsePacket, +} from './p2p_types'; +import { + connectAndFetchPeerInfo, + ConnectionState, + constructPeerIdFromPeerInfo, + EVENT_CLOSE_OUTBOUND, + EVENT_CONNECT_ABORT_OUTBOUND, + EVENT_CONNECT_OUTBOUND, + EVENT_FAILED_PEER_INFO_UPDATE, + EVENT_INBOUND_SOCKET_ERROR, + EVENT_MESSAGE_RECEIVED, + EVENT_OUTBOUND_SOCKET_ERROR, + EVENT_REQUEST_RECEIVED, + EVENT_UPDATED_PEER_INFO, + Peer, + PeerConfig, +} from './peer'; +import { discoverPeers } from './peer_discovery'; + +export const EVENT_FAILED_TO_PUSH_NODE_INFO = 'failedToPushNodeInfo'; +export const EVENT_DISCOVERED_PEER = 'discoveredPeer'; +export const EVENT_FAILED_TO_FETCH_PEER_INFO = 'failedToFetchPeerInfo'; + +export { + EVENT_CLOSE_OUTBOUND, + EVENT_CONNECT_OUTBOUND, + EVENT_CONNECT_ABORT_OUTBOUND, + EVENT_REQUEST_RECEIVED, + EVENT_MESSAGE_RECEIVED, + EVENT_OUTBOUND_SOCKET_ERROR, + EVENT_INBOUND_SOCKET_ERROR, + EVENT_UPDATED_PEER_INFO, + EVENT_FAILED_PEER_INFO_UPDATE, +}; + +interface PeerPoolConfig { + readonly connectTimeout?: number; + readonly ackTimeout?: number; + readonly peerSelectionForSend: P2PPeerSelectionForSend; + readonly peerSelectionForRequest: P2PPeerSelectionForRequest; + readonly peerSelectionForConnection: P2PPeerSelectionForConnection; +} + +export const MAX_PEER_LIST_BATCH_SIZE = 100; +export const MAX_PEER_DISCOVERY_PROBE_SAMPLE_SIZE = 100; + +const selectRandomPeerSample = ( + peerList: ReadonlyArray, + count: number, +): ReadonlyArray => shuffle(peerList).slice(0, count); + +export class PeerPool extends EventEmitter { + private readonly _peerMap: Map; + private readonly _peerPoolConfig: PeerPoolConfig; + private readonly _handlePeerRPC: (request: P2PRequest) => void; + private readonly _handlePeerMessage: (message: P2PMessagePacket) => void; + private readonly _handlePeerConnect: ( + peerInfo: P2PDiscoveredPeerInfo, + ) => void; + private readonly _handlePeerConnectAbort: ( + peerInfo: P2PDiscoveredPeerInfo, + ) => void; + private readonly _handlePeerClose: (closePacket: P2PClosePacket) => void; + private readonly _handlePeerOutboundSocketError: (error: Error) => void; + private readonly _handlePeerInboundSocketError: (error: Error) => void; + private readonly _handlePeerInfoUpdate: ( + peerInfo: P2PDiscoveredPeerInfo, + ) => void; + private readonly _handleFailedPeerInfoUpdate: (error: Error) => void; + private _nodeInfo: P2PNodeInfo | undefined; + private readonly _peerSelectForSend: P2PPeerSelectionForSend; + private readonly _peerSelectForRequest: P2PPeerSelectionForRequest; + private readonly _peerSelectForConnection: P2PPeerSelectionForConnection; + + public constructor(peerPoolConfig: PeerPoolConfig) { + super(); + this._peerMap = new Map(); + this._peerPoolConfig = peerPoolConfig; + this._peerSelectForSend = peerPoolConfig.peerSelectionForSend; + this._peerSelectForRequest = peerPoolConfig.peerSelectionForRequest; + this._peerSelectForConnection = peerPoolConfig.peerSelectionForConnection; + // This needs to be an arrow function so that it can be used as a listener. + this._handlePeerRPC = (request: P2PRequest) => { + // Re-emit the request to allow it to bubble up the class hierarchy. + this.emit(EVENT_REQUEST_RECEIVED, request); + }; + + // This needs to be an arrow function so that it can be used as a listener. + this._handlePeerMessage = (message: P2PMessagePacket) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_MESSAGE_RECEIVED, message); + }; + this._handlePeerConnect = async (peerInfo: P2PDiscoveredPeerInfo) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_CONNECT_OUTBOUND, peerInfo); + const peerId = constructPeerIdFromPeerInfo(peerInfo); + const peer = this.getPeer(peerId); + + if (!peer) { + this.emit( + EVENT_FAILED_TO_FETCH_PEER_INFO, + new RequestFailError( + 'Failed to fetch peer status because the relevant peer could not be found', + ), + ); + + return; + } + + // tslint:disable-next-line no-let + let detailedPeerInfo; + try { + detailedPeerInfo = await peer.fetchStatus(); + } catch (error) { + this.emit(EVENT_FAILED_TO_FETCH_PEER_INFO, error); + + return; + } + this.emit(EVENT_DISCOVERED_PEER, detailedPeerInfo); + }; + this._handlePeerConnectAbort = (peerInfo: P2PDiscoveredPeerInfo) => { + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_CONNECT_ABORT_OUTBOUND, peerInfo); + }; + this._handlePeerClose = (closePacket: P2PClosePacket) => { + // If we disconnect from a peer outbound, we should remove them to conserve our resources (especially in case of a malicious peer). + // A peer which was removed may added back later during the next round of discovery. + const peerId = constructPeerIdFromPeerInfo(closePacket.peerInfo); + this.removePeer(peerId); + // Re-emit the message to allow it to bubble up the class hierarchy. + this.emit(EVENT_CLOSE_OUTBOUND, closePacket); + }; + this._handlePeerOutboundSocketError = (error: Error) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_OUTBOUND_SOCKET_ERROR, error); + }; + this._handlePeerInboundSocketError = (error: Error) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_INBOUND_SOCKET_ERROR, error); + }; + this._handlePeerInfoUpdate = (peerInfo: P2PDiscoveredPeerInfo) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_UPDATED_PEER_INFO, peerInfo); + }; + this._handleFailedPeerInfoUpdate = (error: Error) => { + // Re-emit the error to allow it to bubble up the class hierarchy. + this.emit(EVENT_FAILED_PEER_INFO_UPDATE, error); + }; + } + + public applyNodeInfo(nodeInfo: P2PNodeInfo): void { + this._nodeInfo = nodeInfo; + const peerList = this.getAllPeers(); + peerList.forEach(peer => { + this._applyNodeInfoOnPeer(peer, nodeInfo); + }); + } + + public get nodeInfo(): P2PNodeInfo | undefined { + return this._nodeInfo; + } + + public selectPeersForRequest( + requestPacket?: P2PRequestPacket, + numOfPeers?: number, + ): ReadonlyArray { + const listOfPeerInfo = [...this._peerMap.values()].map( + (peer: Peer) => peer.peerInfo, + ); + const selectedPeers = this._peerSelectForRequest( + listOfPeerInfo, + this._nodeInfo, + numOfPeers, + requestPacket, + ); + + return selectedPeers; + } + + public selectPeersForSend( + messagePacket?: P2PMessagePacket, + numOfPeers?: number, + ): ReadonlyArray { + const listOfPeerInfo = [...this._peerMap.values()].map( + (peer: Peer) => peer.peerInfo, + ); + const selectedPeers = this._peerSelectForSend( + listOfPeerInfo, + this._nodeInfo, + numOfPeers, + messagePacket, + ); + + return selectedPeers; + } + + public async requestFromPeer( + packet: P2PRequestPacket, + ): Promise { + const selectedPeer = this.selectPeersForRequest(packet, 1); + + if (selectedPeer.length <= 0) { + throw new RequestFailError( + 'Request failed due to no peers found in peer selection', + ); + } + + const selectedPeerId = constructPeerIdFromPeerInfo(selectedPeer[0]); + const peer = this._peerMap.get(selectedPeerId); + + if (!peer) { + throw new RequestFailError( + `No such Peer exist in PeerPool with the selected peer with Id: ${selectedPeerId}`, + ); + } + + const response: P2PResponsePacket = await peer.request(packet); + + return response; + } + + public sendToPeers(message: P2PMessagePacket): void { + const selectedPeers = this.selectPeersForSend(message); + + selectedPeers.forEach((peerInfo: P2PDiscoveredPeerInfo) => { + const selectedPeerId = constructPeerIdFromPeerInfo(peerInfo); + const peer = this._peerMap.get(selectedPeerId); + + if (peer) { + peer.send(message); + } + }); + } + + public async fetchStatusAndCreatePeers( + seedPeers: ReadonlyArray, + nodeInfo: P2PNodeInfo, + peerConfig: PeerConfig, + ): Promise> { + const listOfPeerInfos = await Promise.all( + seedPeers.map(async seedPeer => { + try { + const seedFetchStatusResponse = await connectAndFetchPeerInfo( + seedPeer, + nodeInfo, + peerConfig, + ); + const peerId = constructPeerIdFromPeerInfo( + seedFetchStatusResponse.peerInfo, + ); + + this.addOutboundPeer( + peerId, + seedFetchStatusResponse.peerInfo, + seedFetchStatusResponse.socket, + ); + + return seedFetchStatusResponse.peerInfo; + } catch (error) { + this.emit(EVENT_FAILED_TO_FETCH_PEER_INFO, error); + + return undefined; + } + }), + ); + const filteredListOfPeers = listOfPeerInfos.filter( + peerInfo => peerInfo !== undefined, + ) as ReadonlyArray; + + return filteredListOfPeers; + } + + public async runDiscovery( + knownPeers: ReadonlyArray, + blacklist: ReadonlyArray, + ): Promise> { + const peersForDiscovery = knownPeers.map(peerInfo => { + const peerId = constructPeerIdFromPeerInfo(peerInfo); + const existingPeer = this.getPeer(peerId); + if (existingPeer) { + existingPeer.updatePeerInfo(peerInfo); + + return existingPeer; + } + + return this.addPeer(peerInfo); + }); + + const peerSampleToProbe = selectRandomPeerSample( + peersForDiscovery, + MAX_PEER_DISCOVERY_PROBE_SAMPLE_SIZE, + ); + + const discoveredPeers = await discoverPeers(peerSampleToProbe, { + blacklist: blacklist.map(peer => peer.ipAddress), + }); + + // Check for received discovery info and then find it in peer pool and then update it + discoveredPeers.forEach((peerInfo: P2PDiscoveredPeerInfo) => { + const peerId = constructPeerIdFromPeerInfo(peerInfo); + const existingPeer = this.getPeer(peerId); + + if (existingPeer) { + existingPeer.updatePeerInfo(peerInfo); + } + }); + + return discoveredPeers; + } + + public selectPeersAndConnect( + peers: ReadonlyArray, + ): ReadonlyArray { + const peersToConnect = this._peerSelectForConnection(peers); + + peersToConnect.forEach((peerInfo: P2PDiscoveredPeerInfo) => { + const peerId = constructPeerIdFromPeerInfo(peerInfo); + const existingPeer = this.getPeer(peerId); + if (!existingPeer) { + return this.addPeer(peerInfo); + } + + existingPeer.updatePeerInfo(peerInfo); + + return existingPeer; + }); + + return peersToConnect; + } + + public addPeer( + peerInfo: P2PDiscoveredPeerInfo, + inboundSocket?: SCServerSocket, + ): Peer { + const peerConfig = { + connectTimeout: this._peerPoolConfig.connectTimeout, + ackTimeout: this._peerPoolConfig.ackTimeout, + }; + const peer = new Peer(peerInfo, peerConfig, { inbound: inboundSocket }); + + // Throw an error because adding a peer multiple times is a common developer error which is very difficult to identify and debug. + if (this._peerMap.has(peer.id)) { + throw new Error(`Peer ${peer.id} was already in the peer pool`); + } + this._peerMap.set(peer.id, peer); + this._bindHandlersToPeer(peer); + if (this._nodeInfo) { + this._applyNodeInfoOnPeer(peer, this._nodeInfo); + } + peer.connect(); + + return peer; + } + + public addDiscoveredPeer( + detailedPeerInfo: P2PDiscoveredPeerInfo, + inboundSocket?: SCServerSocket, + ): Peer { + const peerConfig = { + connectTimeout: this._peerPoolConfig.connectTimeout, + ackTimeout: this._peerPoolConfig.ackTimeout, + }; + const peer = new Peer(detailedPeerInfo, peerConfig, { + inbound: inboundSocket, + }); + this._peerMap.set(peer.id, peer); + this._bindHandlersToPeer(peer); + if (this._nodeInfo) { + this._applyNodeInfoOnPeer(peer, this._nodeInfo); + } + peer.updatePeerInfo(detailedPeerInfo); + peer.connect(); + + return peer; + } + + public addInboundPeer( + peerId: string, + peerInfo: P2PDiscoveredPeerInfo, + socket: SCServerSocket, + ): boolean { + const existingPeer = this.getPeer(peerId); + + if (existingPeer) { + // Update the peerInfo from the latest inbound socket. + existingPeer.updatePeerInfo(peerInfo); + if (existingPeer.state.inbound === ConnectionState.DISCONNECTED) { + existingPeer.inboundSocket = socket; + + return false; + } + + return false; + } + + this.addPeer(peerInfo, socket); + + return true; + } + + public addOutboundPeer( + peerId: string, + peerInfo: P2PDiscoveredPeerInfo, + socket: SCClientSocket, + ): boolean { + const existingPeer = this.getPeer(peerId); + + if (existingPeer) { + // Update the peerInfo from the latest inbound socket. + existingPeer.updatePeerInfo(peerInfo); + if (existingPeer.state.outbound === ConnectionState.DISCONNECTED) { + existingPeer.outboundSocket = socket; + + return false; + } + + return false; + } + + const peerConfig = { + connectTimeout: this._peerPoolConfig.connectTimeout, + ackTimeout: this._peerPoolConfig.ackTimeout, + }; + const peer = new Peer(peerInfo, peerConfig, { outbound: socket }); + + this._peerMap.set(peer.id, peer); + this._bindHandlersToPeer(peer); + if (this._nodeInfo) { + this._applyNodeInfoOnPeer(peer, this._nodeInfo); + } + + return true; + } + + public removeAllPeers(): void { + this._peerMap.forEach((peer: Peer) => { + this.removePeer(peer.id); + }); + } + + public getAllPeerInfos(): ReadonlyArray { + return this.getAllPeers().map(peer => peer.peerInfo); + } + + public getAllPeers(): ReadonlyArray { + return [...this._peerMap.values()]; + } + + public getPeer(peerId: string): Peer | undefined { + return this._peerMap.get(peerId); + } + + public hasPeer(peerId: string): boolean { + return this._peerMap.has(peerId); + } + + public removePeer(peerId: string): boolean { + const peer = this._peerMap.get(peerId); + if (peer) { + peer.disconnect(); + this._unbindHandlersFromPeer(peer); + } + + return this._peerMap.delete(peerId); + } + + private _applyNodeInfoOnPeer(peer: Peer, nodeInfo: P2PNodeInfo): void { + // tslint:disable-next-line no-floating-promises + (async () => { + try { + await peer.applyNodeInfo(nodeInfo); + } catch (error) { + this.emit(EVENT_FAILED_TO_PUSH_NODE_INFO, error); + } + })(); + } + + private _bindHandlersToPeer(peer: Peer): void { + peer.on(EVENT_REQUEST_RECEIVED, this._handlePeerRPC); + peer.on(EVENT_MESSAGE_RECEIVED, this._handlePeerMessage); + peer.on(EVENT_CONNECT_OUTBOUND, this._handlePeerConnect); + peer.on(EVENT_CONNECT_ABORT_OUTBOUND, this._handlePeerConnectAbort); + peer.on(EVENT_CLOSE_OUTBOUND, this._handlePeerClose); + peer.on(EVENT_OUTBOUND_SOCKET_ERROR, this._handlePeerOutboundSocketError); + peer.on(EVENT_INBOUND_SOCKET_ERROR, this._handlePeerInboundSocketError); + peer.on(EVENT_UPDATED_PEER_INFO, this._handlePeerInfoUpdate); + peer.on(EVENT_FAILED_PEER_INFO_UPDATE, this._handleFailedPeerInfoUpdate); + } + + private _unbindHandlersFromPeer(peer: Peer): void { + peer.removeListener(EVENT_REQUEST_RECEIVED, this._handlePeerRPC); + peer.removeListener(EVENT_MESSAGE_RECEIVED, this._handlePeerMessage); + peer.removeListener(EVENT_CONNECT_OUTBOUND, this._handlePeerConnect); + peer.removeListener( + EVENT_CONNECT_ABORT_OUTBOUND, + this._handlePeerConnectAbort, + ); + peer.removeListener(EVENT_CLOSE_OUTBOUND, this._handlePeerClose); + peer.removeListener(EVENT_UPDATED_PEER_INFO, this._handlePeerInfoUpdate); + peer.removeListener( + EVENT_FAILED_PEER_INFO_UPDATE, + this._handleFailedPeerInfoUpdate, + ); + } +} diff --git a/elements/lisk-p2p/src/peer_selection.ts b/elements/lisk-p2p/src/peer_selection.ts new file mode 100644 index 00000000000..583905e425d --- /dev/null +++ b/elements/lisk-p2p/src/peer_selection.ts @@ -0,0 +1,122 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { NotEnoughPeersError } from './errors'; +import { P2PDiscoveredPeerInfo, P2PNodeInfo } from './p2p_types'; +/* tslint:disable: readonly-keyword*/ +interface Histogram { + [key: number]: number; +} +interface HistogramValues { + height: number; + histogram: Histogram; + max: number; +} + +/* tslint:enable: readonly-keyword */ +export const selectPeers = ( + peers: ReadonlyArray, + nodeInfo?: P2PNodeInfo, + numOfPeers: number = 0, +): ReadonlyArray => { + const nodeHeight = nodeInfo ? nodeInfo.height : 0; + const filteredPeers = peers.filter( + // Remove unreachable peers or heights below last block height + (peer: P2PDiscoveredPeerInfo) => peer.height >= nodeHeight, + ); + + if (filteredPeers.length === 0) { + return []; + } + + // Order peers by descending height + const sortedPeers = filteredPeers.sort((a, b) => b.height - a.height); + + const aggregation = 2; + + const calculatedHistogramValues = sortedPeers.reduce( + (histogramValues: HistogramValues, peer: P2PDiscoveredPeerInfo) => { + const val = Math.floor(peer.height / aggregation) * aggregation; + histogramValues.histogram[val] = + (histogramValues.histogram[val] ? histogramValues.histogram[val] : 0) + + 1; + if (histogramValues.histogram[val] > histogramValues.max) { + histogramValues.max = histogramValues.histogram[val]; + histogramValues.height = val; + } + + return histogramValues; + }, + { height: 0, histogram: {}, max: -1 }, + ); + + // Perform histogram cut of peers too far from histogram maximum + const processedPeers = sortedPeers.filter( + peer => + peer && + Math.abs(calculatedHistogramValues.height - peer.height) < + aggregation + 1, + ); + + if (numOfPeers <= 0) { + return processedPeers; + } + + // Select n number of peers + if (numOfPeers > processedPeers.length) { + throw new NotEnoughPeersError( + `Requested number of peers: '${numOfPeers}' is more than the available number of good peers: '${ + processedPeers.length + }'`, + ); + } + + if (numOfPeers === processedPeers.length) { + return processedPeers; + } + + if (numOfPeers === 1) { + const goodPeer: ReadonlyArray = [ + processedPeers[Math.floor(Math.random() * processedPeers.length)], + ]; + + return goodPeer; + } + + const { peerList } = new Array(numOfPeers).fill(0).reduce( + peerListObject => { + const index = Math.floor( + Math.random() * peerListObject.processedPeersArray.length, + ); + const peer = peerListObject.processedPeersArray[index]; + // This will ensure that the selected peer is not choosen again by the random function above + const tempProcessedPeers = peerListObject.processedPeersArray.filter( + (findPeer: P2PDiscoveredPeerInfo) => findPeer !== peer, + ); + + return { + peerList: [...peerListObject.peerList, peer], + processedPeersArray: tempProcessedPeers, + }; + }, + { peerList: [], processedPeersArray: processedPeers }, + ); + + return peerList; +}; + +export const selectForConnection = ( + peerInfoList: ReadonlyArray, + _nodeInfo?: P2PNodeInfo, +) => peerInfoList; diff --git a/elements/lisk-p2p/src/validation.ts b/elements/lisk-p2p/src/validation.ts new file mode 100644 index 00000000000..2bc0dcc4a49 --- /dev/null +++ b/elements/lisk-p2p/src/validation.ts @@ -0,0 +1,193 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { valid as isValidVersion } from 'semver'; +import { isIP, isNumeric, isPort } from 'validator'; +import { + InvalidPeerError, + InvalidProtocolMessageError, + InvalidRPCRequestError, + InvalidRPCResponseError, +} from './errors'; + +import { + INCOMPATIBLE_NETWORK_REASON, + INCOMPATIBLE_PROTOCOL_VERSION_REASON, +} from './disconnect_status_codes'; +import { + P2PCompatibilityCheckReturnType, + P2PDiscoveredPeerInfo, + P2PNodeInfo, + ProtocolMessagePacket, + ProtocolPeerInfo, + ProtocolRPCRequestPacket, +} from './p2p_types'; + +const IPV4_NUMBER = 4; +const IPV6_NUMBER = 6; + +interface RPCPeerListResponse { + readonly peers: ReadonlyArray; + readonly success?: boolean; // Could be used in future +} + +export const validatePeerAddress = (ip: string, wsPort: number): boolean => { + if ( + (!isIP(ip, IPV4_NUMBER) && !isIP(ip, IPV6_NUMBER)) || + !isPort(wsPort.toString()) + ) { + return false; + } + + return true; +}; + +export const validatePeerInfo = ( + rawPeerInfo: unknown, +): P2PDiscoveredPeerInfo => { + if (!rawPeerInfo) { + throw new InvalidPeerError(`Invalid peer object`); + } + + const protocolPeer = rawPeerInfo as ProtocolPeerInfo; + if ( + !protocolPeer.ip || + !protocolPeer.wsPort || + !validatePeerAddress(protocolPeer.ip, protocolPeer.wsPort) + ) { + throw new InvalidPeerError(`Invalid peer ip or port`); + } + + if (!protocolPeer.version || !isValidVersion(protocolPeer.version)) { + throw new InvalidPeerError(`Invalid peer version`); + } + + const version = protocolPeer.version; + const wsPort = +protocolPeer.wsPort; + const os = protocolPeer.os ? protocolPeer.os : ''; + const height = + protocolPeer.height && isNumeric(protocolPeer.height.toString()) + ? +protocolPeer.height + : 0; + const { options, ...protocolPeerWithoutOptions } = protocolPeer; + + const peerInfo: P2PDiscoveredPeerInfo = { + ...(options as object), + ...protocolPeerWithoutOptions, + ipAddress: protocolPeerWithoutOptions.ip, + wsPort, + height, + os, + version, + }; + + const { ip, ...peerInfoUpdated } = peerInfo; + + return peerInfoUpdated; +}; + +export const validatePeerInfoList = ( + rawPeerInfoList: unknown, +): ReadonlyArray => { + if (!rawPeerInfoList) { + throw new InvalidRPCResponseError('Invalid response type'); + } + const { peers } = rawPeerInfoList as RPCPeerListResponse; + + if (Array.isArray(peers)) { + const peerList = peers.map(validatePeerInfo); + + return peerList; + } else { + throw new InvalidRPCResponseError('Invalid response type'); + } +}; + +export const validateRPCRequest = ( + request: unknown, +): ProtocolRPCRequestPacket => { + if (!request) { + throw new InvalidRPCRequestError('Invalid request'); + } + + const rpcRequest = request as ProtocolRPCRequestPacket; + if (typeof rpcRequest.procedure !== 'string') { + throw new InvalidRPCRequestError('Request procedure name is not a string'); + } + + return rpcRequest; +}; + +export const validateProtocolMessage = ( + message: unknown, +): ProtocolMessagePacket => { + if (!message) { + throw new InvalidProtocolMessageError('Invalid message'); + } + + const protocolMessage = message as ProtocolMessagePacket; + if (typeof protocolMessage.event !== 'string') { + throw new InvalidProtocolMessageError('Protocol message is not a string'); + } + + return protocolMessage; +}; + +export const checkNetworkCompatibility = ( + peerInfo: P2PDiscoveredPeerInfo, + nodeInfo: P2PNodeInfo, +): boolean => { + if (!peerInfo.nethash) { + return false; + } + + return peerInfo.nethash === nodeInfo.nethash; +}; + +export const checkProtocolVersionCompatibility = ( + peerInfo: P2PDiscoveredPeerInfo, + nodeInfo: P2PNodeInfo, +): boolean => { + if (!peerInfo.protocolVersion) { + return false; + } + + const peerHardForks = +(peerInfo.protocolVersion as string).split('.')[0]; + const systemHardForks = +(nodeInfo.protocolVersion as string).split('.')[0]; + + return systemHardForks === peerHardForks && peerHardForks >= 1; +}; + +export const checkPeerCompatibility = ( + peerInfo: P2PDiscoveredPeerInfo, + nodeInfo: P2PNodeInfo, +): P2PCompatibilityCheckReturnType => { + if (!checkNetworkCompatibility(peerInfo, nodeInfo)) { + return { + success: false, + errors: [INCOMPATIBLE_NETWORK_REASON], + }; + } + + if (!checkProtocolVersionCompatibility(peerInfo, nodeInfo)) { + return { + success: false, + errors: [INCOMPATIBLE_PROTOCOL_VERSION_REASON], + }; + } + + return { + success: true, + }; +}; diff --git a/elements/lisk-p2p/test/_global_hooks.ts b/elements/lisk-p2p/test/_global_hooks.ts new file mode 100644 index 00000000000..230fac15eac --- /dev/null +++ b/elements/lisk-p2p/test/_global_hooks.ts @@ -0,0 +1,17 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +afterEach(() => { + return sandbox.restore(); +}); diff --git a/elements/lisk-p2p/test/_setup.ts b/elements/lisk-p2p/test/_setup.ts new file mode 100644 index 00000000000..5b11c96c975 --- /dev/null +++ b/elements/lisk-p2p/test/_setup.ts @@ -0,0 +1,27 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as chai from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import 'chai/register-expect'; +import * as sinonChai from 'sinon-chai'; +import * as sinon from 'sinon'; + +process.env.NODE_ENV = 'test'; + +[sinonChai, chaiAsPromised].forEach(plugin => chai.use(plugin)); + +global.sandbox = sinon.createSandbox({ + useFakeTimers: process.env.USE_REAL_TIMERS !== 'true', +}); diff --git a/elements/lisk-p2p/test/integration/p2p.ts b/elements/lisk-p2p/test/integration/p2p.ts new file mode 100644 index 00000000000..b92d25658ae --- /dev/null +++ b/elements/lisk-p2p/test/integration/p2p.ts @@ -0,0 +1,996 @@ +import { expect } from 'chai'; +import { P2P } from '../../src/index'; +import { wait } from '../utils/helpers'; +import { platform } from 'os'; +import { + P2PPeerSelectionForSendRequest, + P2PPeerSelectionForSend, + P2PPeerSelectionForRequest, + P2PNodeInfo, + P2PDiscoveredPeerInfo, + P2PPeerSelectionForConnection, +} from '../../src/p2p_types'; + +describe('Integration tests for P2P library', () => { + const NETWORK_START_PORT = 5000; + const NETWORK_PEER_COUNT = 10; + const ALL_NODE_PORTS: ReadonlyArray = [ + ...new Array(NETWORK_PEER_COUNT).keys(), + ].map(index => NETWORK_START_PORT + index); + const NO_PEERS_FOUND_ERROR = `Request failed due to no peers found in peer selection`; + + let p2pNodeList: ReadonlyArray = []; + + describe('Disconnected network: All nodes launch at the same time. Each node has an empty seedPeers list', () => { + beforeEach(async () => { + p2pNodeList = ALL_NODE_PORTS.map(nodePort => { + return new P2P({ + blacklistedPeers: [], + connectTimeout: 5000, + seedPeers: [], + wsEngine: 'ws', + nodeInfo: { + wsPort: nodePort, + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + version: '1.0.1', + protocolVersion: '1.0.1', + minVersion: '1.0.0', + os: platform(), + height: 0, + broadhash: + '2768b267ae621a9ed3b3034e2e8a1bed40895c621bbb1bbd613d92b9d24e54b5', + nonce: 'O2wTkjqplHII5wPv', + }, + }); + }); + + const peerStartPromises: ReadonlyArray> = p2pNodeList.map( + p2p => p2p.start(), + ); + await Promise.all(peerStartPromises); + }); + + afterEach(async () => { + await Promise.all( + p2pNodeList + .filter(p2p => p2p.isActive) + .map(async p2p => await p2p.stop()), + ); + }); + + it('should set the isActive property to true for all nodes', () => { + p2pNodeList.forEach(p2p => { + expect(p2p).to.have.property('isActive', true); + }); + }); + + describe('P2P.request', () => { + it('should throw an error when not able to get any peer in peer selection', async () => { + const firstP2PNode = p2pNodeList[0]; + const response = firstP2PNode.request({ + procedure: 'foo', + data: 'bar', + }); + + expect(response).to.be.rejectedWith(Error, NO_PEERS_FOUND_ERROR); + }); + }); + }); + + describe('Partially connected network which becomes fully connected: All nodes launch at the same time. The seedPeers list of each node contains the next node in the sequence. Discovery interval runs multiple times.', () => { + const DISCOVERY_INTERVAL = 200; + + beforeEach(async () => { + p2pNodeList = [...new Array(NETWORK_PEER_COUNT).keys()].map(index => { + // Each node will have the next node in the sequence as a seed peer. + const seedPeers = [ + { + ipAddress: '127.0.0.1', + wsPort: NETWORK_START_PORT + ((index + 1) % NETWORK_PEER_COUNT), + }, + ]; + + return new P2P({ + blacklistedPeers: [], + seedPeers, + wsEngine: 'ws', + // A short connectTimeout and ackTimeout will make the node to give up on discovery quicker for our test. + connectTimeout: 1000, + ackTimeout: 1000, + // Set a different discoveryInterval for each node; that way they don't keep trying to discover each other at the same time. + discoveryInterval: DISCOVERY_INTERVAL + index * 11, + nodeInfo: { + wsPort: NETWORK_START_PORT + index, + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + minVersion: '1.0.1', + version: '1.0.1', + protocolVersion: '1.0.1', + os: platform(), + height: 0, + broadhash: + '2768b267ae621a9ed3b3034e2e8a1bed40895c621bbb1bbd613d92b9d24e54b5', + nonce: 'O2wTkjqplHII5wPv', + }, + }); + }); + + const peerStartPromises: ReadonlyArray> = p2pNodeList.map( + p2p => p2p.start(), + ); + await Promise.all(peerStartPromises); + await wait(100); + }); + + afterEach(async () => { + await Promise.all( + p2pNodeList + .filter(p2p => p2p.isActive) + .map(async p2p => await p2p.stop()), + ); + }); + + describe('Peer discovery', () => { + it('should discover all peers in the network after a few cycles of discovery', async () => { + // Wait for a few cycles of discovery. + await wait(DISCOVERY_INTERVAL * 5); + + p2pNodeList.forEach(p2p => { + const { connectedPeers } = p2p.getNetworkStatus(); + + const peerPorts = connectedPeers + .map(peerInfo => peerInfo.wsPort) + .sort(); + const expectedPeerPorts = ALL_NODE_PORTS; + + expect(peerPorts).to.be.eql(expectedPeerPorts); + }); + }); + }); + + describe('P2P.send', () => { + describe('P2P.send when peers are at same height', () => { + let collectedMessages: Array = []; + + beforeEach(async () => { + collectedMessages = []; + p2pNodeList.forEach(p2p => { + p2p.on('messageReceived', message => { + collectedMessages.push({ + nodePort: p2p.nodeInfo.wsPort, + message, + }); + }); + }); + }); + + it('should send messages to subset of peers within the network; should reach multiple peers with even distribution', async () => { + const TOTAL_SENDS = 100; + const randomPeerIndex = Math.floor( + Math.random() * NETWORK_PEER_COUNT, + ); + const randomP2PNode = p2pNodeList[randomPeerIndex]; + const nodePortToMessagesMap: any = {}; + + const expectedAverageMessagesPerNode = TOTAL_SENDS; + const expectedMessagesLowerBound = + expectedAverageMessagesPerNode * 0.5; + const expectedMessagesUpperBound = + expectedAverageMessagesPerNode * 1.5; + + for (let i = 0; i < TOTAL_SENDS; i++) { + randomP2PNode.send({ event: 'bar', data: i }); + } + await wait(100); + + collectedMessages.forEach((receivedMessageData: any) => { + if (!nodePortToMessagesMap[receivedMessageData.nodePort]) { + nodePortToMessagesMap[receivedMessageData.nodePort] = []; + } + nodePortToMessagesMap[receivedMessageData.nodePort].push( + receivedMessageData, + ); + }); + + Object.values(nodePortToMessagesMap).forEach( + (receivedMessages: any) => { + expect(receivedMessages).to.be.an('array'); + expect(receivedMessages.length).to.be.greaterThan( + expectedMessagesLowerBound, + ); + expect(receivedMessages.length).to.be.lessThan( + expectedMessagesUpperBound, + ); + }, + ); + }); + }); + + describe('P2P.send when peers are at different heights', () => { + const randomPeerIndex = Math.floor(Math.random() * NETWORK_PEER_COUNT); + let collectedMessages: Array = []; + let randomP2PNode: any; + + beforeEach(async () => { + collectedMessages = []; + randomP2PNode = p2pNodeList[randomPeerIndex]; + p2pNodeList.forEach(async p2p => { + p2p.on('messageReceived', message => { + collectedMessages.push({ + nodePort: p2p.nodeInfo.wsPort, + message, + }); + }); + }); + }); + + it('should send messages to subset of peers within the network with updated heights; should reach multiple peers with even distribution', async () => { + const TOTAL_SENDS = 100; + const nodePortToMessagesMap: any = {}; + + p2pNodeList.forEach(p2p => { + p2p.applyNodeInfo({ + os: platform(), + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + version: p2p.nodeInfo.version, + wsPort: p2p.nodeInfo.wsPort, + height: 1000 + (p2p.nodeInfo.wsPort % 5000), + options: p2p.nodeInfo.options, + }); + }); + + await wait(200); + + const expectedAverageMessagesPerNode = TOTAL_SENDS; + const expectedMessagesLowerBound = + expectedAverageMessagesPerNode * 0.5; + const expectedMessagesUpperBound = + expectedAverageMessagesPerNode * 1.5; + + for (let i = 0; i < TOTAL_SENDS; i++) { + randomP2PNode.send({ event: 'bar', data: i }); + } + await wait(100); + + collectedMessages.forEach((receivedMessageData: any) => { + if (!nodePortToMessagesMap[receivedMessageData.nodePort]) { + nodePortToMessagesMap[receivedMessageData.nodePort] = []; + } + nodePortToMessagesMap[receivedMessageData.nodePort].push( + receivedMessageData, + ); + }); + + Object.values(nodePortToMessagesMap).forEach( + (receivedMessages: any) => { + expect(receivedMessages).to.be.an('array'); + expect(receivedMessages.length).to.be.greaterThan( + expectedMessagesLowerBound, + ); + expect(receivedMessages.length).to.be.lessThan( + expectedMessagesUpperBound, + ); + }, + ); + }); + }); + }); + + describe('When half of the nodes crash', () => { + it('should get network status with all unresponsive nodes removed', async () => { + const firstP2PNode = p2pNodeList[0]; + // Stop all the nodes with port from 5001 to 5005 + p2pNodeList.forEach(async (p2p: any, index: number) => { + if (index !== 0 && index < NETWORK_PEER_COUNT / 2) { + await p2p.stop(); + } + }); + await wait(200); + + const connectedPeers = firstP2PNode.getNetworkStatus().connectedPeers; + const portOfLastInactivePort = ALL_NODE_PORTS[NETWORK_PEER_COUNT / 2]; + + const actualConnectedPeers = connectedPeers + .filter( + peer => + peer.wsPort !== 5000 && + peer.wsPort % 5000 > NETWORK_PEER_COUNT / 2, + ) + .map(peer => peer.wsPort); + + // Check if the connected Peers are having port greater than the last port that we crashed by index + actualConnectedPeers.forEach(port => { + expect(port).greaterThan(portOfLastInactivePort); + }); + + p2pNodeList.forEach(p2p => { + if (p2p.nodeInfo.wsPort > portOfLastInactivePort) { + expect(p2p.isActive).to.be.true; + } + }); + }); + }); + }); + + describe('Fully connected network: Nodes are started gradually, one at a time. The seedPeers list of each node contains the previously launched node', () => { + beforeEach(async () => { + p2pNodeList = [...new Array(NETWORK_PEER_COUNT).keys()].map(index => { + // Each node will have the previous node in the sequence as a seed peer except the first node. + const seedPeers = + index === 0 + ? [] + : [ + { + ipAddress: '127.0.0.1', + wsPort: + NETWORK_START_PORT + ((index - 1) % NETWORK_PEER_COUNT), + }, + ]; + + return new P2P({ + blacklistedPeers: [], + connectTimeout: 5000, + ackTimeout: 5000, + seedPeers, + wsEngine: 'ws', + nodeInfo: { + wsPort: NETWORK_START_PORT + index, + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + version: '1.0.1', + protocolVersion: '1.0.1', + minVersion: '1.0.0', + os: platform(), + height: 0, + broadhash: + '2768b267ae621a9ed3b3034e2e8a1bed40895c621bbb1bbd613d92b9d24e54b5', + nonce: 'O2wTkjqplHII5wPv', + }, + }); + }); + + // Launch nodes one at a time with a delay between each launch. + for (const p2p of p2pNodeList) { + await p2p.start(); + await wait(100); + } + await wait(100); + }); + + afterEach(async () => { + await Promise.all( + p2pNodeList + .filter(p2p => p2p.isActive) + .map(async p2p => await p2p.stop()), + ); + await wait(100); + }); + + describe('Peer discovery', () => { + it('should discover all peers and add them to the connectedPeers list within each node', async () => { + p2pNodeList.forEach(p2p => { + const { connectedPeers } = p2p.getNetworkStatus(); + + const peerPorts = connectedPeers + .map(peerInfo => peerInfo.wsPort) + .sort(); + + // Right now we do not care whether the node includes itself in its own peer list. + // TODO later: Formalize the correct approach and assert it here. + const peerPortsExcludingSelf = peerPorts.filter( + wsPort => wsPort !== p2p.nodeInfo.wsPort, + ); + + // The current node should not be in its own peer list. + const expectedPeerPorts = ALL_NODE_PORTS.filter(port => { + return port !== p2p.nodeInfo.wsPort; + }); + + expect(peerPortsExcludingSelf).to.be.eql(expectedPeerPorts); + }); + }); + + it('should discover all peers and add them to the newPeers list within each node', () => { + p2pNodeList.forEach(p2p => { + const { newPeers } = p2p.getNetworkStatus(); + + const peerPorts = newPeers.map(peerInfo => peerInfo.wsPort).sort(); + + // TODO ASAP: Make better assertions. + expect(peerPorts).to.be.an.instanceOf(Array); + }); + }); + + it('should discover all peers and add them to the triedPeers list within each node', () => { + p2pNodeList.forEach(p2p => { + const { triedPeers } = p2p.getNetworkStatus(); + + const peerPorts = triedPeers.map(peerInfo => peerInfo.wsPort).sort(); + // Right now we do not care whether the node includes itself in its own peer list. + // TODO later: Formalize the correct approach and assert it here. + const peerPortsExcludingSelf = peerPorts.filter( + wsPort => wsPort !== p2p.nodeInfo.wsPort, + ); + + // The current node should not be in its own peer list. + const expectedPeerPorts = ALL_NODE_PORTS.filter(port => { + return port !== p2p.nodeInfo.wsPort; + }); + + expect(peerPortsExcludingSelf).to.be.eql(expectedPeerPorts); + }); + }); + }); + + describe('Cleanup unresponsive peers', () => { + it('should remove inactive 2nd node from connected peer list of other', async () => { + const initialNetworkStatus = p2pNodeList[0].getNetworkStatus(); + const secondNode = p2pNodeList[1]; + const initialPeerPorts = initialNetworkStatus.connectedPeers + .map(peerInfo => peerInfo.wsPort) + .sort(); + + const expectedPeerPorts = ALL_NODE_PORTS.filter(port => { + return port !== 5000; + }); + expect(initialPeerPorts).to.be.eql(expectedPeerPorts); + await secondNode.stop(); + + await wait(200); + + const networkStatusAfterPeerCrash = p2pNodeList[0].getNetworkStatus(); + + const peerPortsAfterPeerCrash = networkStatusAfterPeerCrash.connectedPeers + .map(peerInfo => peerInfo.wsPort) + .sort(); + + const expectedPeerPortsAfterPeerCrash = ALL_NODE_PORTS.filter(port => { + return port !== 5000 && port != 5001; + }); + + expect(peerPortsAfterPeerCrash).to.be.eql( + expectedPeerPortsAfterPeerCrash, + ); + }); + }); + + describe('P2P.request', () => { + beforeEach(async () => { + p2pNodeList.forEach(p2p => { + // Collect port numbers to check which peer handled which request. + p2p.on('requestReceived', request => { + request.end({ + nodePort: p2p.nodeInfo.wsPort, + requestProcedure: request.procedure, + requestData: request.data, + }); + }); + }); + }); + + it('should make request to the network; it should reach a single peer', async () => { + const firstP2PNode = p2pNodeList[0]; + const response = await firstP2PNode.request({ + procedure: 'foo', + data: 'bar', + }); + expect(response).to.have.property('data'); + expect(response.data) + .to.have.property('nodePort') + .which.is.a('number'); + expect(response.data) + .to.have.property('requestProcedure') + .which.is.a('string'); + expect(response.data) + .to.have.property('requestData') + .which.is.equal('bar'); + }); + + // Check for even distribution of requests across the network. Account for an error margin. + it('requests made to the network should be distributed randomly', async () => { + const TOTAL_REQUESTS = 1000; + const firstP2PNode = p2pNodeList[0]; + const nodePortToResponsesMap: any = {}; + + const expectedAverageRequestsPerNode = + TOTAL_REQUESTS / NETWORK_PEER_COUNT; + const expectedRequestsLowerBound = expectedAverageRequestsPerNode * 0.5; + const expectedRequestsUpperBound = expectedAverageRequestsPerNode * 1.5; + + for (let i = 0; i < TOTAL_REQUESTS; i++) { + const response = await firstP2PNode.request({ + procedure: 'foo', + data: i, + }); + let resultData = response.data as any; + if (!nodePortToResponsesMap[resultData.nodePort]) { + nodePortToResponsesMap[resultData.nodePort] = []; + } + nodePortToResponsesMap[resultData.nodePort].push(resultData); + } + + Object.values(nodePortToResponsesMap).forEach( + (requestsHandled: any) => { + expect(requestsHandled).to.be.an('array'); + expect(requestsHandled.length).to.be.greaterThan( + expectedRequestsLowerBound, + ); + expect(requestsHandled.length).to.be.lessThan( + expectedRequestsUpperBound, + ); + }, + ); + }); + }); + + describe('P2P.send', () => { + let collectedMessages: Array = []; + + beforeEach(async () => { + collectedMessages = []; + p2pNodeList.forEach(p2p => { + p2p.on('messageReceived', message => { + collectedMessages.push({ + nodePort: p2p.nodeInfo.wsPort, + message, + }); + }); + }); + }); + + it('should send a message to a subset of peers within the network; should reach multiple peers with even distribution', async () => { + const TOTAL_SENDS = 100; + const firstP2PNode = p2pNodeList[0]; + const nodePortToMessagesMap: any = {}; + + const expectedAverageMessagesPerNode = TOTAL_SENDS; + const expectedMessagesLowerBound = expectedAverageMessagesPerNode * 0.5; + const expectedMessagesUpperBound = expectedAverageMessagesPerNode * 1.5; + + for (let i = 0; i < TOTAL_SENDS; i++) { + firstP2PNode.send({ event: 'bar', data: i }); + } + + await wait(100); + + collectedMessages.forEach((receivedMessageData: any) => { + if (!nodePortToMessagesMap[receivedMessageData.nodePort]) { + nodePortToMessagesMap[receivedMessageData.nodePort] = []; + } + nodePortToMessagesMap[receivedMessageData.nodePort].push( + receivedMessageData, + ); + }); + + Object.values(nodePortToMessagesMap).forEach( + (receivedMessages: any) => { + expect(receivedMessages).to.be.an('array'); + expect(receivedMessages.length).to.be.greaterThan( + expectedMessagesLowerBound, + ); + expect(receivedMessages.length).to.be.lessThan( + expectedMessagesUpperBound, + ); + }, + ); + }); + }); + + describe('P2P.applyNodeInfo', () => { + let collectedMessages: Array = []; + + beforeEach(async () => { + collectedMessages = []; + p2pNodeList.forEach(p2p => { + p2p.on('requestReceived', request => { + collectedMessages.push({ + nodePort: p2p.nodeInfo.wsPort, + request, + }); + }); + }); + }); + + it('should send the node info to a subset of peers within the network.', async () => { + const firstP2PNode = p2pNodeList[0]; + const nodePortToMessagesMap: any = {}; + + firstP2PNode.applyNodeInfo({ + os: platform(), + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + version: firstP2PNode.nodeInfo.version, + wsPort: firstP2PNode.nodeInfo.wsPort, + height: 10, + options: firstP2PNode.nodeInfo.options, + }); + + await wait(100); + + // Each peer of firstP2PNode should receive a message. + expect(collectedMessages.length).to.equal(9); + + collectedMessages.forEach((receivedMessageData: any) => { + if (!nodePortToMessagesMap[receivedMessageData.nodePort]) { + nodePortToMessagesMap[receivedMessageData.nodePort] = []; + } + nodePortToMessagesMap[receivedMessageData.nodePort].push( + receivedMessageData, + ); + }); + + // Check that each message contains the updated P2PNodeInfo. + Object.values(nodePortToMessagesMap) + .filter( + (receivedMessages: any) => + receivedMessages && + receivedMessages[0] && + receivedMessages[0].nodePort !== firstP2PNode.nodeInfo.wsPort, + ) + .forEach((receivedMessages: any) => { + expect(receivedMessages.length).to.be.equal(1); + expect(receivedMessages[0].request).to.have.property('data'); + expect(receivedMessages[0].request.data) + .to.have.property('height') + .which.equals(10); + }); + + // For each peer of firstP2PNode, check that the firstP2PNode's P2PPeerInfo was updated with the new height. + p2pNodeList.slice(1).forEach(p2pNode => { + const networkStatus = p2pNode.getNetworkStatus(); + const firstP2PNodePeerInfo = networkStatus.connectedPeers.find( + peerInfo => peerInfo.wsPort === firstP2PNode.nodeInfo.wsPort, + ); + expect(firstP2PNodePeerInfo).to.exist; + expect(firstP2PNodePeerInfo) + .to.have.property('height') + .which.equals(10); + }); + }); + }); + + describe('when couple of node shuts down and are unresponsive', () => { + it('should remove the unresponsive nodes from network status of other nodes', async () => { + const initialNetworkStatus = p2pNodeList[0].getNetworkStatus(); + const initialPeerPorts = initialNetworkStatus.connectedPeers + .map(peerInfo => peerInfo.wsPort) + .sort(); + + expect(initialPeerPorts).to.be.eql( + ALL_NODE_PORTS.filter(port => port != 5000), + ); + + await p2pNodeList[1].stop(); + await wait(100); + await p2pNodeList[2].stop(); + await wait(100); + + const networkStatusAfterPeerCrash = p2pNodeList[0].getNetworkStatus(); + + const peerPortsAfterPeerCrash = networkStatusAfterPeerCrash.connectedPeers + .map(peerInfo => peerInfo.wsPort) + .sort(); + + const expectedPeerPortsAfterPeerCrash = ALL_NODE_PORTS.filter(port => { + return port !== 5001 && port !== 5002 && port !== 5000; + }); + + expect(peerPortsAfterPeerCrash).to.be.eql( + expectedPeerPortsAfterPeerCrash, + ); + }); + }); + }); + + describe('Connected network: User custom selection algorithm is passed to each node', () => { + // Custom selection function that finds peers having common values for modules field for example. + const peerSelectionForSendRequest: P2PPeerSelectionForSendRequest = ( + peersList: ReadonlyArray, + nodeInfo?: P2PNodeInfo, + _numOfPeer?: number, + ) => { + const filteredPeers = peersList.filter(peer => { + if (nodeInfo && nodeInfo.height <= peer.height) { + const nodesModules = nodeInfo.modules + ? (nodeInfo.modules as ReadonlyArray) + : undefined; + const peerModules = peer.modules + ? (peer.modules as ReadonlyArray) + : undefined; + + if ( + nodesModules && + peerModules && + nodesModules.filter(value => peerModules.includes(value)).length > 0 + ) { + return true; + } + } + + return false; + }); + + // In case there are no peers with same modules or less than 30% of the peers are selected then use only height to select peers + if ( + filteredPeers.length === 0 || + (filteredPeers.length / peersList.length) * 100 < 30 + ) { + return peersList.filter( + peer => peer.height >= (nodeInfo ? nodeInfo.height : 0), + ); + } + + return filteredPeers; + }; + // Custom Peer selection for connection that returns all the peers + const peerSelectionForConnection: P2PPeerSelectionForConnection = ( + peersList: ReadonlyArray, + ) => peersList; + + beforeEach(async () => { + p2pNodeList = [...new Array(NETWORK_PEER_COUNT).keys()].map(index => { + // Each node will have the previous node in the sequence as a seed peer except the first node. + const seedPeers = + index === 0 + ? [] + : [ + { + ipAddress: '127.0.0.1', + wsPort: + NETWORK_START_PORT + ((index - 1) % NETWORK_PEER_COUNT), + }, + ]; + + return new P2P({ + blacklistedPeers: [], + connectTimeout: 5000, + ackTimeout: 5000, + peerSelectionForSend: peerSelectionForSendRequest as P2PPeerSelectionForSend, + peerSelectionForRequest: peerSelectionForSendRequest as P2PPeerSelectionForRequest, + peerSelectionForConnection, + seedPeers, + wsEngine: 'ws', + nodeInfo: { + wsPort: NETWORK_START_PORT + index, + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + version: '1.0.1', + protocolVersion: '1.0.1', + os: platform(), + height: 1000 + index, + broadhash: + '2768b267ae621a9ed3b3034e2e8a1bed40895c621bbb1bbd613d92b9d24e54b5', + nonce: 'O2wTkjqplHII5wPv', + modules: index % 2 === 0 ? ['fileTransfer'] : ['socialSite'], + }, + }); + }); + + // Launch nodes one at a time with a delay between each launch. + for (const p2p of p2pNodeList) { + await p2p.start(); + await wait(100); + } + await wait(100); + }); + + afterEach(async () => { + await Promise.all( + p2pNodeList + .filter(p2p => p2p.isActive) + .map(async p2p => await p2p.stop()), + ); + }); + + it('should start all the nodes with custom selection functions without fail', async () => { + p2pNodeList.forEach(p2p => + expect(p2p).to.have.property('isActive', true), + ); + }); + + describe('Peer Discovery', () => { + it('should run peer discovery successfully', async () => { + p2pNodeList.forEach(p2p => { + const connectedPeers = p2p.getNetworkStatus().connectedPeers; + + expect(p2p.isActive).to.be.true; + expect(connectedPeers.length).to.gt(1); + }); + }); + }); + + describe('P2P.request', () => { + beforeEach(async () => { + p2pNodeList.forEach(async p2p => { + // Collect port numbers to check which peer handled which request. + p2p.on('requestReceived', request => { + request.end({ + nodePort: p2p.nodeInfo.wsPort, + requestProcedure: request.procedure, + requestData: request.data, + }); + }); + }); + }); + + it('should make a request to the network; it should reach a single peer based on custom selection function', async () => { + const firstP2PNode = p2pNodeList[0]; + const response = await firstP2PNode.request({ + procedure: 'foo', + data: 'bar', + }); + + expect(response).to.have.property('data'); + expect(response.data) + .to.have.property('nodePort') + .which.is.a('number'); + expect(response.data) + .to.have.property('requestProcedure') + .which.is.a('string'); + expect(response.data) + .to.have.property('requestData') + .which.is.equal('bar'); + }); + }); + describe('P2P.send', () => { + let collectedMessages: Array = []; + + beforeEach(async () => { + collectedMessages = []; + p2pNodeList.forEach(async p2p => { + p2p.on('messageReceived', message => { + collectedMessages.push({ + nodePort: p2p.nodeInfo.wsPort, + message, + }); + }); + }); + }); + + it('should send a message to a subset of peers within the network; should reach multiple peers with even distribution', async () => { + const TOTAL_SENDS = 100; + const firstP2PNode = p2pNodeList[0]; + const nodePortToMessagesMap: any = {}; + + const expectedAverageMessagesPerNode = TOTAL_SENDS; + const expectedMessagesLowerBound = expectedAverageMessagesPerNode * 0.5; + const expectedMessagesUpperBound = expectedAverageMessagesPerNode * 1.5; + + for (let i = 0; i < TOTAL_SENDS; i++) { + firstP2PNode.send({ event: 'bar', data: i }); + } + + await wait(100); + + collectedMessages.forEach((receivedMessageData: any) => { + if (!nodePortToMessagesMap[receivedMessageData.nodePort]) { + nodePortToMessagesMap[receivedMessageData.nodePort] = []; + } + nodePortToMessagesMap[receivedMessageData.nodePort].push( + receivedMessageData, + ); + }); + + Object.values(nodePortToMessagesMap).forEach( + (receivedMessages: any) => { + expect(receivedMessages).to.be.an('array'); + expect(receivedMessages.length).to.be.greaterThan( + expectedMessagesLowerBound, + ); + expect(receivedMessages.length).to.be.lessThan( + expectedMessagesUpperBound, + ); + }, + ); + }); + }); + }); + + describe('Partially connected network of 4 nodes: All nodes launch at the same time. The custom fields that are passed in nodeinfo is captured by other nodes.', () => { + const DISCOVERY_INTERVAL = 200; + + beforeEach(async () => { + p2pNodeList = [...Array(4).keys()].map(index => { + // Each node will have the next node in the sequence as a seed peer. + const seedPeers = [ + { + ipAddress: '127.0.0.1', + wsPort: NETWORK_START_PORT + ((index + 1) % 4), + }, + ]; + + return new P2P({ + blacklistedPeers: [], + seedPeers, + wsEngine: 'ws', + // A short connectTimeout and ackTimeout will make the node to give up on discovery quicker for our test. + connectTimeout: 1000, + ackTimeout: 1000, + // Set a different discoveryInterval for each node; that way they don't keep trying to discover each other at the same time. + discoveryInterval: DISCOVERY_INTERVAL + index * 11, + nodeInfo: { + wsPort: NETWORK_START_PORT + index, + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + version: '1.0.1', + protocolVersion: '1.0.1', + minVersion: '1.0.0', + os: platform(), + height: 0, + broadhash: + '2768b267ae621a9ed3b3034e2e8a1bed40895c621bbb1bbd613d92b9d24e54b5', + nonce: 'O2wTkjqplHII5wPv', + modules: { + names: ['test', 'crypto'], + active: true, + }, + }, + }); + }); + + const peerStartPromises: ReadonlyArray> = p2pNodeList.map( + p2p => p2p.start(), + ); + await Promise.all(peerStartPromises); + await wait(100); + }); + + afterEach(async () => { + await Promise.all( + p2pNodeList + .filter(p2p => p2p.isActive) + .map(async p2p => await p2p.stop()), + ); + }); + + describe('all the nodes should be able to communicate and receive custom fields passed in nodeinfo', () => { + it('should have tried peers with custom test field "modules" that was passed as nodeinfo', async () => { + p2pNodeList.forEach(p2p => { + const { + connectedPeers, + newPeers, + triedPeers, + } = p2p.getNetworkStatus(); + + triedPeers.forEach(peer => { + expect(peer) + .has.property('modules') + .has.property('names') + .is.an('array'); + + expect(peer) + .has.property('modules') + .has.property('active') + .is.a('boolean'); + }); + + newPeers.forEach(peer => { + expect(peer) + .has.property('modules') + .has.property('names') + .is.an('array'); + + expect(peer) + .has.property('modules') + .has.property('active') + .is.a('boolean'); + }); + + connectedPeers.forEach(peer => { + expect(peer) + .has.property('modules') + .has.property('names') + .is.an('array'); + + expect(peer) + .has.property('modules') + .has.property('active') + .is.a('boolean'); + }); + }); + }); + }); + }); +}); diff --git a/elements/lisk-p2p/test/mocha.opts b/elements/lisk-p2p/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-p2p/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/test/tsconfig.json b/elements/lisk-p2p/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-p2p/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/test/tslint.json b/elements/lisk-p2p/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-p2p/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-p2p/test/unit/errors.ts b/elements/lisk-p2p/test/unit/errors.ts new file mode 100644 index 00000000000..f52bc7d44be --- /dev/null +++ b/elements/lisk-p2p/test/unit/errors.ts @@ -0,0 +1,278 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + InvalidPeerError, + NotEnoughPeersError, + PeerInboundHandshakeError, + RPCResponseError, + InvalidRPCResponseError, + InvalidProtocolMessageError, + InvalidRPCRequestError, + RPCResponseAlreadySentError, + RequestFailError, +} from '../../src'; + +describe('errors', () => { + describe('#NotEnoughPeersError', () => { + const defaultMessage = + 'Requested number of peers is greater than available good peers'; + let notEnoughPeersError: NotEnoughPeersError; + + beforeEach(async () => { + notEnoughPeersError = new NotEnoughPeersError(defaultMessage); + }); + + it('should create a new instance of NotEnoughPeersError', async () => { + expect(notEnoughPeersError) + .to.be.an('object') + .and.be.instanceof(NotEnoughPeersError); + }); + + it('should set error name to `NotEnoughPeersError`', async () => { + expect(notEnoughPeersError.name).to.eql('NotEnoughPeersError'); + }); + + it('should set error message when passed an argument', async () => { + expect(notEnoughPeersError.message).to.eql(defaultMessage); + }); + }); + + describe('#PeerInboundHandshakeError', () => { + const remoteAddress = '127.0.0.1'; + const statusCode = 4501; + const defaultMessage = `Received inbound connection from peer ${remoteAddress} which is already in our triedPeers map.`; + let peerTransportError: PeerInboundHandshakeError; + + beforeEach(async () => { + peerTransportError = new PeerInboundHandshakeError( + defaultMessage, + statusCode, + remoteAddress, + ); + }); + + it('should create a new instance of PeerInboundHandshakeError', async () => { + expect(peerTransportError) + .to.be.an('object') + .and.be.instanceof(PeerInboundHandshakeError); + }); + + it('should set error name to `PeerInboundHandshakeError`', async () => { + expect(peerTransportError.name).to.eql('PeerInboundHandshakeError'); + }); + + it('should set error property remoteAddress when passed as an argument', async () => { + expect(peerTransportError.remoteAddress).to.eql(remoteAddress); + }); + }); + + describe('#RPCResponseError', () => { + const peerIp = '127.0.0.1:5001'; + const peerPort = 5001; + const defaultMessage = `Error when fetching peerlist of peer with peer ip ${peerIp} and port ${peerPort}`; + const defaultError = new Error('Peer not available'); + let rpcGetPeersFailed: RPCResponseError; + + beforeEach(async () => { + rpcGetPeersFailed = new RPCResponseError( + defaultMessage, + defaultError, + peerIp, + peerPort, + ); + }); + + it('should create a new instance of RPCResponseError', async () => { + expect(rpcGetPeersFailed) + .to.be.an('object') + .and.be.instanceof(RPCResponseError); + }); + + it('should set error name to `RPCResponseError`', async () => { + expect(rpcGetPeersFailed.name).to.eql('RPCResponseError'); + }); + + it('should set error property peer ip when passed as an argument', async () => { + expect(rpcGetPeersFailed) + .and.to.have.property('peerIp') + .which.is.eql(peerIp); + }); + + it('should set error property peer port when passed as an argument', async () => { + expect(rpcGetPeersFailed) + .and.to.have.property('peerPort') + .which.is.eql(peerPort); + }); + + it('should set error property cause when passed as an argument', async () => { + expect(rpcGetPeersFailed) + .and.to.have.property('cause') + .and.to.be.a('function'); + + expect(rpcGetPeersFailed.cause()) + .is.instanceOf(Error) + .has.property('message') + .and.eql('Peer not available'); + }); + }); + + describe('#InvalidPeer', () => { + const defaultMessage = 'Invalid peer ip or port'; + let invalidPeer: InvalidPeerError; + + beforeEach(async () => { + invalidPeer = new InvalidPeerError(defaultMessage); + }); + + it('should create a new instance of InvalidPeerError', async () => { + expect(invalidPeer) + .to.be.an('object') + .and.be.instanceof(InvalidPeerError); + }); + + it('should set error name to `InvalidPeer`', async () => { + expect(invalidPeer.name).to.eql('InvalidPeerError'); + }); + + it('should set error message when passed an argument', async () => { + expect(invalidPeer.message).to.eql(defaultMessage); + }); + }); + + describe('#InvalidRPCResponse', () => { + const defaultMessage = 'Invalid response type'; + let invalidRPCResponse: InvalidRPCResponseError; + + beforeEach(async () => { + invalidRPCResponse = new InvalidRPCResponseError(defaultMessage); + }); + + it('should create a new instance of InvalidRPCResponse', async () => { + expect(invalidRPCResponse) + .to.be.an('object') + .and.be.instanceof(InvalidRPCResponseError); + }); + + it('should set error name to `InvalidRPCResponseError`', async () => { + expect(invalidRPCResponse.name).to.eql('InvalidRPCResponseError'); + }); + + it('should set error message when passed an argument', async () => { + expect(invalidRPCResponse.message).to.eql(defaultMessage); + }); + }); + + describe('#InvalidProtocolMessageError', () => { + const defaultMessage = 'Invalid protocol message'; + let invalidProtocolMessageError: InvalidProtocolMessageError; + + beforeEach(async () => { + invalidProtocolMessageError = new InvalidProtocolMessageError( + defaultMessage, + ); + }); + + it('should create a new instance of InvalidProtocolMessageError', async () => { + expect(invalidProtocolMessageError) + .to.be.an('object') + .and.be.instanceof(InvalidProtocolMessageError); + }); + + it('should set error name to `InvalidProtocolMessageError`', async () => { + expect(invalidProtocolMessageError.name).to.eql( + 'InvalidProtocolMessageError', + ); + }); + + it('should set error message when passed an argument', async () => { + expect(invalidProtocolMessageError.message).to.eql(defaultMessage); + }); + }); + + describe('#InvalidRPCRequestError', () => { + let invalidRPCRequestError: InvalidRPCRequestError; + const defaultMessage = 'Invalid RPC request error'; + + beforeEach(async () => { + invalidRPCRequestError = new InvalidRPCRequestError(defaultMessage); + }); + + it('should create a new instance of InvalidRPCRequestError', async () => { + expect(invalidRPCRequestError) + .to.be.an('object') + .and.be.instanceof(InvalidRPCRequestError); + }); + + it('should set error name to `InvalidRPCRequestError`', async () => { + expect(invalidRPCRequestError.name).to.eql('InvalidRPCRequestError'); + }); + + it('should set error message when passed an argument', async () => { + expect(invalidRPCRequestError.message).to.eql(defaultMessage); + }); + }); + + describe('#RPCResponseAlreadySentError', () => { + const defaultMessage = 'Response was already sent'; + let rpcResponseAlreadySentError: RPCResponseAlreadySentError; + + beforeEach(async () => { + rpcResponseAlreadySentError = new RPCResponseAlreadySentError( + defaultMessage, + ); + }); + + it('should create a new instance of RPCResponseAlreadySentError', async () => { + expect(rpcResponseAlreadySentError) + .to.be.an('object') + .and.be.instanceof(RPCResponseAlreadySentError); + }); + + it('should set error name to `RPCResponseAlreadySentError`', async () => { + expect(rpcResponseAlreadySentError.name).to.eql( + 'ResponseAlreadySentError', + ); + }); + + it('should set error message when passed an argument', async () => { + expect(rpcResponseAlreadySentError.message).to.eql(defaultMessage); + }); + }); + + describe('#RequestFailError', () => { + const defaultMessage = + 'Request failed due to no peers found in peer selection'; + let requestFailError: RequestFailError; + + beforeEach(async () => { + requestFailError = new RequestFailError(defaultMessage); + }); + + it('should create a new instance of RequestFailError', async () => { + expect(requestFailError) + .to.be.an('object') + .and.be.instanceof(RequestFailError); + }); + + it('should set error name to `RequestFailError`', async () => { + expect(requestFailError.name).to.eql('RequestFailError'); + }); + + it('should set error message when passed an argument', async () => { + expect(requestFailError.message).to.eql(defaultMessage); + }); + }); +}); diff --git a/elements/lisk-p2p/test/unit/p2p.ts b/elements/lisk-p2p/test/unit/p2p.ts new file mode 100644 index 00000000000..0f6b65704ae --- /dev/null +++ b/elements/lisk-p2p/test/unit/p2p.ts @@ -0,0 +1,49 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { P2P } from '../../src'; + +describe('p2p', () => { + describe('#constructor', () => { + const lisk = new P2P({ + blacklistedPeers: [], + connectTimeout: 5000, + seedPeers: [], + wsEngine: 'ws', + nodeInfo: { + wsPort: 5000, + nethash: + 'da3ed6a45429278bac2666961289ca17ad86595d33b31037615d4b8e8f158bba', + version: '1.1.1', + os: 'darwin', + height: 0, + options: { + broadhash: + '2768b267ae621a9ed3b3034e2e8a1bed40895c621bbb1bbd613d92b9d24e54b5', + }, + }, + }); + + it('should be an object', () => { + return expect(lisk).to.be.an('object'); + }); + + it('should be an instance of P2P blockchain', () => { + return expect(lisk) + .to.be.an('object') + .and.be.instanceof(P2P); + }); + }); +}); diff --git a/elements/lisk-p2p/test/unit/peer.ts b/elements/lisk-p2p/test/unit/peer.ts new file mode 100644 index 00000000000..86cdbe989a5 --- /dev/null +++ b/elements/lisk-p2p/test/unit/peer.ts @@ -0,0 +1,66 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; + +import { Peer } from '../../src/peer'; +import { P2PDiscoveredPeerInfo } from '../../src/p2p_types'; + +describe('peer', () => { + const defaultPeerInfo: P2PDiscoveredPeerInfo = { + ipAddress: '12.12.12.12', + wsPort: 5001, + height: 545776, + isDiscoveredPeer: true, + version: '1.1.1', + }; + + const defaultPeer = new Peer(defaultPeerInfo); + + describe('#constructor', () => { + it('should be an object', () => { + return expect(defaultPeer).to.be.an('object'); + }); + + it('should be an instance of P2P blockchain', () => { + return expect(defaultPeer) + .to.be.an('object') + .and.be.instanceof(Peer); + }); + }); + + describe('#instanceProperties', () => { + it('should get height property', () => { + return expect(defaultPeer.height) + .to.be.a('number') + .and.be.eql(545776); + }); + + it('should get ip property', () => { + return expect(defaultPeer.ipAddress) + .to.be.a('string') + .and.be.eql('12.12.12.12'); + }); + + it('should get wsPort property', () => { + return expect(defaultPeer.wsPort) + .to.be.a('number') + .and.be.eql(5001); + }); + + it('should get inboundSocket property', () => { + return expect(defaultPeer.inboundSocket).to.be.undefined; + }); + }); +}); diff --git a/elements/lisk-p2p/test/unit/peer_discovery.ts b/elements/lisk-p2p/test/unit/peer_discovery.ts new file mode 100644 index 00000000000..856c4bda367 --- /dev/null +++ b/elements/lisk-p2p/test/unit/peer_discovery.ts @@ -0,0 +1,101 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { P2PDiscoveredPeerInfo } from '../../src/p2p_types'; +import { initializePeerList } from '../utils/peers'; +import * as discoverPeersModule from '../../src/peer_discovery'; + +describe('peer discovery', () => { + const samplePeers = initializePeerList(); + const seedPeer1 = samplePeers[0]; + const seedPeer2 = samplePeers[1]; + const seedList = [seedPeer1, seedPeer2]; + + const validatedPeer1: P2PDiscoveredPeerInfo = { + ipAddress: '196.34.89.90', + wsPort: 5393, + height: 23232, + isDiscoveredPeer: true, + version: '1.2.1', + }; + + const validatedPeer2: P2PDiscoveredPeerInfo = { + ipAddress: '128.38.75.9', + wsPort: 5393, + height: 23232, + isDiscoveredPeer: true, + version: '1.2.1', + }; + + const validatedPeer3: P2PDiscoveredPeerInfo = { + ipAddress: '12.23.11.31', + wsPort: 5393, + height: 23232, + isDiscoveredPeer: true, + version: '1.3.1', + }; + + describe('#discoverPeer', () => { + const peerList1 = [validatedPeer1, validatedPeer2]; + const peerList2 = [validatedPeer1, validatedPeer3]; + + const expectedResult = [validatedPeer1, validatedPeer2]; + + describe('return an array with all the peers of input peers', () => { + let discoveredPeers: ReadonlyArray; + const blacklist = ['12.23.11.31']; + beforeEach(async () => { + sandbox.stub(seedPeer1, 'fetchPeers').resolves(peerList1); + sandbox.stub(seedPeer2, 'fetchPeers').resolves(peerList2); + + discoveredPeers = await discoverPeersModule.discoverPeers(seedList, { + blacklist, + }); + }); + + it('should return an array for a given seed list', () => { + return expect(discoveredPeers).to.be.an('array'); + }); + + it('should return an array with length of [2]', () => { + return expect(discoveredPeers) + .to.be.an('array') + .of.length(2); + }); + + it('should return an array with discovered peers', () => { + return expect(discoveredPeers) + .to.be.an('array') + .and.eql(expectedResult); + }); + + it('should return an array with discovered peers for blank blacklist', async () => { + discoveredPeers = await discoverPeersModule.discoverPeers(seedList, { + blacklist: [], + }); + + const withoutBlacklistResult = [ + validatedPeer1, + validatedPeer2, + validatedPeer3, + ]; + + return expect(discoveredPeers) + .to.be.an('array') + .and.eql(withoutBlacklistResult); + }); + }); + }); +}); diff --git a/elements/lisk-p2p/test/unit/peer_selection.ts b/elements/lisk-p2p/test/unit/peer_selection.ts new file mode 100644 index 00000000000..9e0501e9db7 --- /dev/null +++ b/elements/lisk-p2p/test/unit/peer_selection.ts @@ -0,0 +1,125 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { initializePeerInfoList } from '../utils/peers'; +import { selectForConnection, selectPeers } from '../../src/peer_selection'; +import { P2PNodeInfo } from '../../src/p2p_types'; + +describe('peer selector', () => { + describe('#selectPeer', () => { + let peerList = initializePeerInfoList(); + const nodeInfo: P2PNodeInfo = { + height: 545777, + nethash: '73458irc3yb7rg37r7326dbt7236', + os: 'linux', + version: '1.1.1', + wsPort: 5000, + }; + + describe('get a list of n number of good peers', () => { + beforeEach(async () => { + peerList = initializePeerInfoList(); + }); + + it('should return an array without optional arguments', () => { + return expect(selectPeers(peerList)).to.be.an('array'); + }); + + it('should return an array', () => { + return expect(selectPeers(peerList, nodeInfo)).to.be.an('array'); + }); + + it('returned array should contain good peers according to algorithm', () => { + return expect(selectPeers(peerList, nodeInfo)) + .and.be.an('array') + .and.of.length(3); + }); + + it('return empty peer list for no peers as an argument', () => { + return expect(selectPeers([], nodeInfo)) + .and.be.an('array') + .and.to.be.eql([]); + }); + + it('should return an array having one good peer', () => { + return expect(selectPeers(peerList, nodeInfo, 1)) + .and.be.an('array') + .and.of.length(1); + }); + + it('should return an array having 2 good peers', () => { + return expect(selectPeers(peerList, nodeInfo, 2)) + .and.be.an('array') + .and.of.length(2); + }); + + it('should return an array having all good peers', () => { + return expect(selectPeers(peerList, nodeInfo, 0)) + .and.be.an('array') + .and.of.length(3); + }); + + it('should return an array having all good peers ignoring requested negative number of peers', () => { + return expect(selectPeers(peerList, nodeInfo, -1)) + .and.be.an('array') + .and.of.length(3); + }); + + it('should return an array of equal length equal to requested number of peers', () => { + return expect(selectPeers(peerList, nodeInfo, 3)) + .and.be.an('array') + .and.of.length(3); + }); + + it('should throw an error when requested peers are greater than available good peers', () => { + return expect(selectPeers.bind(selectPeers, peerList, nodeInfo, 4)) + .to.throw( + `Requested number of peers: '4' is more than the available number of good peers: '3'`, + ) + .to.have.property('name') + .eql('NotEnoughPeersError'); + }); + }); + + describe('peers with lower blockheight', () => { + beforeEach(async () => { + peerList = initializePeerInfoList(); + }); + const lowHeightPeers = peerList.filter( + peer => peer.height < nodeInfo.height, + ); + + it('should return an array with 0 good peers', () => { + return expect(selectPeers(lowHeightPeers, nodeInfo, 2)) + .and.be.an('array') + .and.of.length(0); + }); + }); + }); + + describe('#selectForConnection', () => { + const peerList = initializePeerInfoList(); + const numberOfPeers = peerList.length; + + describe('get all the peers for selection', () => { + it('should return all the peers given as argument for connection', () => { + return expect(selectForConnection(peerList)) + .be.an('array') + .and.is.eql(peerList) + .of.length(numberOfPeers); + }); + }); + }); +}); diff --git a/elements/lisk-p2p/test/unit/validation.ts b/elements/lisk-p2p/test/unit/validation.ts new file mode 100644 index 00000000000..aa5f8aa1de8 --- /dev/null +++ b/elements/lisk-p2p/test/unit/validation.ts @@ -0,0 +1,346 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + validatePeerAddress, + validatePeerInfo, + validatePeerInfoList, + validateRPCRequest, + validateProtocolMessage, +} from '../../src/validation'; +import { P2PPeerInfo, ProtocolPeerInfo } from '../../src/p2p_types'; +import { + ProtocolRPCRequestPacket, + ProtocolMessagePacket, +} from '../../src/p2p_types'; + +describe('response handlers', () => { + describe('#validatePeerInfo', () => { + describe('for valid peer response object', () => { + const peer: ProtocolPeerInfo = { + ip: '12.23.54.3', + wsPort: 5393, + os: 'darwin', + height: 23232, + version: '1.1.2', + broadhash: '92hdbcwsdjcosi', + nonce: '89wsufhucsdociuds', + httpPort: 2000, + }; + + const peerWithInvalidHeightValue: unknown = { + ip: '12.23.54.3', + wsPort: 5393, + os: '778', + height: '2323wqdqd2', + version: '3.4.5-alpha.9', + broadhash: '92hdbcwsdjcosi', + nonce: '89wsufhucsdociuds', + httpPort: 2000, + }; + + it('should return P2PPeerInfo object', async () => { + expect(validatePeerInfo(peer)) + .to.be.an('object') + .eql({ + ipAddress: '12.23.54.3', + wsPort: 5393, + height: 23232, + os: 'darwin', + version: '1.1.2', + broadhash: '92hdbcwsdjcosi', + httpPort: 2000, + nonce: '89wsufhucsdociuds', + }); + }); + + it('should return P2PPeerInfo object with height value set to 0', async () => { + expect(validatePeerInfo(peerWithInvalidHeightValue)) + .to.be.an('object') + .eql({ + ipAddress: '12.23.54.3', + wsPort: 5393, + height: 0, + os: '778', + version: '3.4.5-alpha.9', + broadhash: '92hdbcwsdjcosi', + httpPort: 2000, + nonce: '89wsufhucsdociuds', + }); + }); + }); + + describe('for invalid peer response object', () => { + it('should throw an InvalidPeer error for invalid peer', async () => { + const peerInvalid: unknown = null; + + expect(validatePeerInfo.bind(null, peerInvalid)).to.throw( + 'Invalid peer object', + ); + }); + + it('should throw InvalidPeer error for invalid peer ip or port', async () => { + const peerInvalid: unknown = { + ip: '12.23.54.uhig3', + wsPort: 53937888, + height: '23232', + discoveredInfo: { + os: 'darwin', + }, + }; + + expect(validatePeerInfo.bind(null, peerInvalid)).to.throw( + 'Invalid peer ip or port', + ); + }); + + it('should throw an InvalidPeer error for invalid peer version', async () => { + const peerInvalid: unknown = { + ip: '12.23.54.23', + wsPort: 5390, + os: 'darwin', + height: '23232', + version: '1222.22', + }; + + expect(validatePeerInfo.bind(null, peerInvalid)).to.throw( + 'Invalid peer version', + ); + }); + }); + }); + + describe('#validatePeerAddress', () => { + it('should return true for correct IPv4', async () => { + const peer = { + ip: '12.12.12.12', + wsPort: 4001, + }; + + expect(validatePeerAddress(peer.ip, peer.wsPort)).to.be.true; + }); + + it('should return true for correct IPv6', async () => { + const peer = { + ip: '2001:0db8:85a3:0000:0000:8a2e:0370:7334', + wsPort: 4001, + }; + + expect(validatePeerAddress(peer.ip, peer.wsPort)).to.be.true; + }); + + it('should return false for incorrect ip', async () => { + const peerWithIncorrectIp = { + ip: '12.12.hh12.12', + wsPort: 4001, + }; + + expect( + validatePeerAddress(peerWithIncorrectIp.ip, peerWithIncorrectIp.wsPort), + ).to.be.false; + }); + + it('should return false for incorrect port', async () => { + const peerWithIncorrectPort = { + ip: '12.12.12.12', + wsPort: NaN, + }; + + expect( + validatePeerAddress( + peerWithIncorrectPort.ip, + peerWithIncorrectPort.wsPort, + ), + ).to.be.false; + }); + }); + + describe('#validatePeerInfoList', () => { + const peer1 = { + ip: '12.12.12.12', + wsPort: 5001, + height: '545776', + version: '1.0.1', + os: 'darwin', + }; + + const peer2 = { + ip: '127.0.0.1', + wsPort: 5002, + height: '545981', + version: '1.0.1', + os: 'darwin', + }; + const peerList = [peer1, peer2]; + + const rawPeerInfoList: unknown = { + success: true, + peers: peerList, + }; + let validatedPeerInfoArray: ReadonlyArray; + + beforeEach(async () => { + validatedPeerInfoArray = validatePeerInfoList(rawPeerInfoList); + }); + + it('should throw an error for an undefined rawPeerInfoList object', async () => { + expect( + validatePeerInfoList.bind(validatePeerInfoList, undefined), + ).to.throw(`Invalid response type`); + }); + + it('should throw an error for an invalid value of peers property', async () => { + const inValidPeerInfoList = { + peers: 'random text', + success: true, + }; + + expect( + validatePeerInfoList.bind(validatePeerInfoList, inValidPeerInfoList), + ).to.throw(`Invalid response type`); + }); + + it('should throw an error for an invalid port number', async () => { + const inValidPeerInfoList = { + peers: [ + { + ip: '127.0.0.1', + wsPort: NaN, + height: '545981', + version: '1.0.1', + os: 'darwin', + }, + ], + success: true, + }; + + expect( + validatePeerInfoList.bind(validatePeerInfoList, inValidPeerInfoList), + ).to.throw(`Invalid peer ip or port`); + }); + + it('should return peer info list array', async () => { + expect(validatedPeerInfoArray).to.be.an('array'); + }); + + it('should return peer info list array of length 2', async () => { + expect(validatedPeerInfoArray).to.be.of.length(2); + }); + + it('should return deserialised P2PPeerInfo list', async () => { + const sanitizedPeerInfoList = peerList.map((peer: any) => { + peer['ipAddress'] = peer.ip; + peer.wsPort = +peer.wsPort; + peer.height = +peer.height; + + delete peer.ip; + + return peer; + }); + + expect(validatedPeerInfoArray).to.be.eql(sanitizedPeerInfoList); + }); + }); + + describe('#validateRPCRequest', () => { + const validRPCRequest: unknown = { + data: {}, + procedure: 'list', + type: '', + }; + let validatedRPCRequest: ProtocolRPCRequestPacket; + + beforeEach(async () => { + validatedRPCRequest = validateRPCRequest(validRPCRequest); + }); + + it('should throw an error for an invalid procedure value', async () => { + expect(validateRPCRequest.bind(validateRPCRequest, undefined)).to.throw( + 'Invalid request', + ); + }); + + it('should throw an error for an invalid procedure value', async () => { + const inValidRequest: unknown = { + data: {}, + procedure: {}, + }; + + expect( + validateRPCRequest.bind(validateRPCRequest, inValidRequest), + ).to.throw('Request procedure name is not a string'); + }); + + it('should pass and return an object', async () => { + expect(validatedRPCRequest).to.be.an('object'); + }); + + it('should return a valid rpc request', async () => { + expect(validatedRPCRequest) + .to.be.an('object') + .has.property('data') + .to.be.an('object'); + expect(validatedRPCRequest) + .to.be.an('object') + .has.property('procedure').to.be.string; + + expect(validatedRPCRequest) + .to.be.an('object') + .has.property('type').to.be.string; + }); + }); + + describe('#validateProtocolMessage', () => { + const validProtocolMessage: unknown = { + data: {}, + event: 'newPeer', + }; + let returnedValidatedMessage: ProtocolMessagePacket; + + beforeEach(async () => { + returnedValidatedMessage = validateProtocolMessage(validProtocolMessage); + }); + + it('should throw an error for an invalid event value type', async () => { + expect( + validateProtocolMessage.bind(validateProtocolMessage, undefined), + ).to.throw('Invalid message'); + }); + + it('should throw an error for an invalid event value type', async () => { + const inValidMessage: unknown = { + data: {}, + event: 6788, + }; + expect( + validateProtocolMessage.bind(validateProtocolMessage, inValidMessage), + ).to.throw('Protocol message is not a string'); + }); + + it('should return an object', async () => { + expect(returnedValidatedMessage).to.be.an('object'); + }); + + it('should return a valid protocol message object', async () => { + expect(returnedValidatedMessage) + .to.be.an('object') + .has.property('data'); + + expect(returnedValidatedMessage) + .to.be.an('object') + .has.property('data').to.be.string; + }); + }); +}); diff --git a/elements/lisk-p2p/test/utils/helpers.ts b/elements/lisk-p2p/test/utils/helpers.ts new file mode 100644 index 00000000000..3f7716790c5 --- /dev/null +++ b/elements/lisk-p2p/test/utils/helpers.ts @@ -0,0 +1,7 @@ +export function wait(duration: number): Promise { + return new Promise(resolve => { + setTimeout(() => { + resolve(); + }, duration); + }); +} diff --git a/elements/lisk-p2p/test/utils/peers.ts b/elements/lisk-p2p/test/utils/peers.ts new file mode 100644 index 00000000000..2a719d49143 --- /dev/null +++ b/elements/lisk-p2p/test/utils/peers.ts @@ -0,0 +1,67 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { Peer } from '../../src/peer'; +import { P2PDiscoveredPeerInfo } from '../../src/p2p_types'; + +export const initializePeerInfoList = (): ReadonlyArray< + P2PDiscoveredPeerInfo +> => { + const peerOption1: P2PDiscoveredPeerInfo = { + ipAddress: '12.12.12.12', + wsPort: 5001, + height: 545776, + isDiscoveredPeer: false, + version: '1.1.1', + }; + + const peerOption2: P2PDiscoveredPeerInfo = { + ipAddress: '127.0.0.1', + wsPort: 5002, + height: 545981, + isDiscoveredPeer: false, + version: '1.1.1', + }; + + const peerOption3: P2PDiscoveredPeerInfo = { + ipAddress: '18.28.48.1', + wsPort: 5008, + height: 645980, + isDiscoveredPeer: false, + version: '1.3.1', + }; + + const peerOption4: P2PDiscoveredPeerInfo = { + ipAddress: '192.28.138.1', + wsPort: 5006, + height: 645982, + isDiscoveredPeer: false, + version: '1.2.1', + }; + + const peerOption5: P2PDiscoveredPeerInfo = { + ipAddress: '178.21.90.199', + wsPort: 5001, + height: 645980, + isDiscoveredPeer: false, + version: '1.1.1', + }; + + return [peerOption1, peerOption2, peerOption3, peerOption4, peerOption5]; +}; + +export const initializePeerList = (): ReadonlyArray => + initializePeerInfoList().map( + (peerInfo: P2PDiscoveredPeerInfo) => new Peer(peerInfo), + ); diff --git a/elements/lisk-p2p/tsconfig.json b/elements/lisk-p2p/tsconfig.json new file mode 100644 index 00000000000..db550527a7a --- /dev/null +++ b/elements/lisk-p2p/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "declaration": true, + "outDir": "dist-node", + "rootDir": "./src" + }, + "include": ["../../types/**/*", "types/**/*", "src/**/*"] +} diff --git a/elements/lisk-p2p/tslint.json b/elements/lisk-p2p/tslint.json new file mode 100644 index 00000000000..cf3b99edcc1 --- /dev/null +++ b/elements/lisk-p2p/tslint.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tslint.json", + "rules": { + // We need this temporarily until we get more type definitions for external modules. + "no-any": false, + // We need this temporarily while some methods are not fully implemented. + "no-unused-expression": false + } +} diff --git a/elements/lisk-passphrase/.npmignore b/elements/lisk-passphrase/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-passphrase/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/.npmrc b/elements/lisk-passphrase/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-passphrase/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/.nycrc b/elements/lisk-passphrase/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-passphrase/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/.prettierignore b/elements/lisk-passphrase/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-passphrase/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/.prettierrc.json b/elements/lisk-passphrase/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-passphrase/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/LICENSE b/elements/lisk-passphrase/LICENSE new file mode 100644 index 00000000000..9cecc1d4669 --- /dev/null +++ b/elements/lisk-passphrase/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/elements/lisk-passphrase/README.md b/elements/lisk-passphrase/README.md new file mode 100644 index 00000000000..5f1566fab7d --- /dev/null +++ b/elements/lisk-passphrase/README.md @@ -0,0 +1,37 @@ +# @liskhq/lisk-passphrase + +@liskhq/lisk-passphrase is containing mnemonic passphrase helpers for use with Lisk-related software + +## Installation + +```sh +$ npm install --save @liskhq/lisk-passphrase +``` + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-passphrase/browsertest b/elements/lisk-passphrase/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-passphrase/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/cypress b/elements/lisk-passphrase/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-passphrase/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/cypress.json b/elements/lisk-passphrase/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-passphrase/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/package-lock.json b/elements/lisk-passphrase/package-lock.json new file mode 100644 index 00000000000..9ae5c2b48b6 --- /dev/null +++ b/elements/lisk-passphrase/package-lock.json @@ -0,0 +1,4782 @@ +{ + "name": "@liskhq/lisk-passphrase", + "version": "2.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.2.tgz", + "integrity": "sha512-f3QCuPppXxtZOEm5GWPra/uYUjmNQlu9pbAD8D/9jze4pTY83rTtB1igTBSwvkeNlC5gR24zFFkz+2WHLFQhqQ==", + "dev": true, + "requires": { + "@babel/types": "^7.3.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.10", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.2.tgz", + "integrity": "sha512-QzNUC2RO1gadg+fs21fi0Uu0OuGNzRKEmgCxoLNzbCdoprLwjfmZwzUrpUNfJPaVRwBpDY47A17yYEGWyRelnQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.2.tgz", + "integrity": "sha512-3Y6H8xlUlpbGR+XvawiH0UXehqydTmNmEpozWcXymqwcrwYAl5KMvKtQ+TF6f6E08V6Jur7v/ykdDSF+WDEIXQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.10", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@types/bip39": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/@types/bip39/-/bip39-2.4.1.tgz", + "integrity": "sha512-QHx0qI6JaTIW/S3zxE/bXrwOWu6Boos+LZ4438xmFAHY5k+qHkExMdAnb/DENEt2RBnOdZ6c5J+SHrnLEhUohQ==", + "requires": { + "@types/node": "*" + } + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "http://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.0.7", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.7.tgz", + "integrity": "sha512-HNJNgE60C9eOTgn974Tlp3dpLZdUr+SoxxDwPaY9J/kDNOLQTkaDgwBUXAF4SSsrAwD9RpdxuHK/EbuF+W9Ahw==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "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" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bip39": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", + "integrity": "sha1-UcvVF5RgUEpj6jwADbP3h8oFEjU=", + "requires": { + "create-hash": "^1.1.0", + "pbkdf2": "^3.0.9", + "randombytes": "^2.0.1", + "safe-buffer": "^5.0.1", + "unorm": "^1.3.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha1-PH/L9SnYcibz0vUrlm/1Jx60Qd0=", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha1-uqVZ7hTO1zRSIputcyZGfGH6vWA=", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha1-h2Dk7MJy9MNjUy+SbYdKriwTl94=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.4.tgz", + "integrity": "sha512-05qQ5hXShcqGkPZpXEFLIpxayZscVD2kuMBZewxiIPPEagukO4mqgPA9CWhUvFBJfy3ODdK2p9xyHh7FTU9/7A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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": "http://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": "http://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "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" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha1-XRKFFd8TT/Mn6QpMk/Tgd6U2NB8=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha1-gAwN0eCov7yVg1wgKtIg/jF+WhI=", + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.0.tgz", + "integrity": "sha1-kc1BfRUqv4Wzexqz6/O9Jc3GToA=", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha1-CQtNbNvWRe0Qv3UNS1QHlC17oWM=", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "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-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 + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.5.8", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.8.tgz", + "integrity": "sha512-sy1mXPmv7kLAMKW/8XofG7o9T+6gAjzdZK4AJF6ryqQYUa/hnzgiypoeUecZ53x7XiqKNEpNqLtS97MshW2nxg==", + "dev": true, + "requires": { + "debug": "=3.1.0" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.10.0.tgz", + "integrity": "sha512-0GZF1RiPKU97IHUO5TORo9w1PwrH/NBPl+fS7oMLdaTRiYmYbwK4NWoZWrAdd0/abG9R2BU+OiwyQpTpE6pdfQ==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha1-8nNdwig2dPpnR4sQGBBZNVw2nl4=", + "dev": true + }, + "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.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha1-hK5l+n6vsWX922FWauFLrwVmTw8=", + "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=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha1-etOElGWPhGBeL220Q230EPTlvpo=", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha1-IwKlam/+9/mr6gFH2Dil6ba2p5s=", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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 + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.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-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "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": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "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 + } + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha1-tdB7jjIW4+J81yjXL3DR5qNCAF8=", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha1-Ms2eXGRVO9WNGaVor0Uqz/BJgbE=", + "dev": true + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha1-UWbihkV/AzBgZL5Ul+jbsMPTIIM=", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha1-bYrlCPWRZ/lA8rWzxKYSrlDJCuY=", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "commander": { + "version": "2.15.1", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha1-wZyd+aAocC1nhhI4SmVSQExjbRU=", + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha1-HGszdALCE3YF7+GfEP7DkPb6q1Q=", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", + "integrity": "sha512-6i0HVbUfcKaTv+EG8ZTr75az7GFXcLYk9UyLEg7Notv/Ma+z/UG3TCoz6GiNeOrn1E/e63I0X/Hpw18jHOTUnA==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.3.tgz", + "integrity": "sha512-VrPoetlz7B/FqjBLD2f5wBVZvsZVLnRUrxVLfRYhGXCODa/NWE4p3Wp+6+aV3ZPL3KM7/OZmxDIwwijD7yuucg==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha1-l2wgZTBhexTrsyEUI597CTNuk6Y=", + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "portfinder": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.17.tgz", + "integrity": "sha512-syFcRIRzVI1BoEFOCaAiizwDolh1S1YXSodsVhncbhjzjZQulhczNRbqnUl9N31Q4dKGOXsNDqxC2BWBgSMqeQ==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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 + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz", + "integrity": "sha1-0wLFIpSFiISKjTAMkytEwkIx2oA=", + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha1-ocGm9iR1FXe6XQeRTLyShQWFiQw=", + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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": "sha1-mR7GnSluAxN0fVm9/St0XDX4go0=" + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "http://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" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "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 + }, + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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" + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "dev": true + }, + "uglify-es": { + "version": "3.3.9", + "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz", + "integrity": "sha1-DBxPBwC+2NvBJM2zBNJZLKID5nc=", + "dev": true, + "requires": { + "commander": "~2.13.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz", + "integrity": "sha1-aWS8pnaF33wfFDDFhPB9dZeIW5w=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha1-dHIq8y6WFOnCh6jQu95IteLxomM=", + "dev": true + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.2.tgz", + "integrity": "sha512-13EaeocO4edF/3JKime9rD7oB6QI8llAGhgn5fKOPyfkJbRb6NFv9pYV6dFEmpa4uRjKeBqLZP8GpuzqHlKDMQ==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unorm": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz", + "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA=" + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + }, + "dependencies": { + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + } + } + }, + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "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" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "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 + }, + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-passphrase/package.json b/elements/lisk-passphrase/package.json new file mode 100644 index 00000000000..8811ae12bdd --- /dev/null +++ b/elements/lisk-passphrase/package.json @@ -0,0 +1,88 @@ +{ + "name": "@liskhq/lisk-passphrase", + "version": "2.0.0", + "description": "Mnemonic passphrase helpers for use with Lisk-related software", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-passphrase#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "prestart": "./scripts/prestart.sh", + "start": "./scripts/start.sh", + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s liskPassphrase", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s liskPassphrase", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/**/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11544 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11544) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11544 && cypress run --config baseUrl=http://localhost:11544 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@types/bip39": "2.4.1", + "@types/node": "10.12.21", + "bip39": "2.5.0" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-passphrase/scripts b/elements/lisk-passphrase/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-passphrase/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/src/index.ts b/elements/lisk-passphrase/src/index.ts new file mode 100644 index 00000000000..8b77a344348 --- /dev/null +++ b/elements/lisk-passphrase/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as Mnemonic from 'bip39'; +import * as validation from './validation'; + +export { Mnemonic, validation }; diff --git a/elements/lisk-passphrase/src/validation.ts b/elements/lisk-passphrase/src/validation.ts new file mode 100644 index 00000000000..4d7902b77be --- /dev/null +++ b/elements/lisk-passphrase/src/validation.ts @@ -0,0 +1,194 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as Mnemonic from 'bip39'; + +interface PassphraseRegularExpression { + readonly uppercaseRegExp: RegExp; + readonly whitespaceRegExp: RegExp; +} +interface PassphraseError { + readonly actual: number | boolean | string; + readonly code: string; + readonly expected: number | boolean | string; + readonly location?: ReadonlyArray; + readonly message: string; +} + +const passphraseRegularExpression: PassphraseRegularExpression = { + uppercaseRegExp: /[A-Z]/g, + whitespaceRegExp: /\s/g, +}; + +export const countPassphraseWhitespaces = (passphrase: string): number => { + const whitespaceMatches = passphrase.match( + passphraseRegularExpression.whitespaceRegExp, + ); + + return whitespaceMatches !== null ? whitespaceMatches.length : 0; +}; + +export const countPassphraseWords = (passphrase: string): number => + passphrase.split(' ').filter(Boolean).length; + +export const countUppercaseCharacters = (passphrase: string): number => { + const uppercaseCharacterMatches = passphrase.match( + passphraseRegularExpression.uppercaseRegExp, + ); + + return uppercaseCharacterMatches !== null + ? uppercaseCharacterMatches.length + : 0; +}; + +export const locateUppercaseCharacters = ( + passphrase: string, +): ReadonlyArray => + passphrase + .split('') + .reduce( + ( + upperCaseIndexes: ReadonlyArray, + character: string, + index: number, + ) => { + if ( + character.match(passphraseRegularExpression.uppercaseRegExp) !== null + ) { + return [...upperCaseIndexes, index]; + } + + return upperCaseIndexes; + }, + [], + ); + +export const locateConsecutiveWhitespaces = ( + passphrase: string, +): ReadonlyArray => + passphrase + .split('') + .reduce( + ( + whitespaceIndexes: ReadonlyArray, + character: string, + index: number, + ) => { + if ( + index === 0 && + character.match(passphraseRegularExpression.whitespaceRegExp) !== null + ) { + return [...whitespaceIndexes, index]; + } + if ( + index !== passphrase.length - 1 && + character.match(passphraseRegularExpression.whitespaceRegExp) !== + null && + passphrase + .split('') + [index - 1].match(passphraseRegularExpression.whitespaceRegExp) !== + null + ) { + return [...whitespaceIndexes, index]; + } + if ( + index === passphrase.length - 1 && + character.match(passphraseRegularExpression.whitespaceRegExp) !== null + ) { + return [...whitespaceIndexes, index]; + } + + return whitespaceIndexes; + }, + [], + ); + +export const getPassphraseValidationErrors = ( + passphrase: string, + wordlists?: ReadonlyArray, + expectedWords: number = 12, +): ReadonlyArray => { + const expectedWhitespaces = expectedWords - 1; + const expectedUppercaseCharacterCount = 0; + const wordsInPassphrase = countPassphraseWords(passphrase); + const whiteSpacesInPassphrase = countPassphraseWhitespaces(passphrase); + const uppercaseCharacterInPassphrase = countUppercaseCharacters(passphrase); + const passphraseWordError: PassphraseError = { + actual: wordsInPassphrase, + code: 'INVALID_AMOUNT_OF_WORDS', + expected: expectedWords, + message: `Passphrase contains ${wordsInPassphrase} words instead of expected ${expectedWords}. Please check the passphrase.`, + }; + const whiteSpaceError: PassphraseError = { + actual: whiteSpacesInPassphrase, + code: 'INVALID_AMOUNT_OF_WHITESPACES', + expected: expectedWhitespaces, + location: locateConsecutiveWhitespaces(passphrase), + message: `Passphrase contains ${whiteSpacesInPassphrase} whitespaces instead of expected ${expectedWhitespaces}. Please check the passphrase.`, + }; + const uppercaseCharacterError: PassphraseError = { + actual: uppercaseCharacterInPassphrase, + code: 'INVALID_AMOUNT_OF_UPPERCASE_CHARACTER', + expected: expectedUppercaseCharacterCount, + location: locateUppercaseCharacters(passphrase), + message: `Passphrase contains ${uppercaseCharacterInPassphrase} uppercase character instead of expected ${expectedUppercaseCharacterCount}. Please check the passphrase.`, + }; + const validationError: PassphraseError = { + actual: false, + code: 'INVALID_MNEMONIC', + expected: true, + message: + 'Passphrase is not a valid mnemonic passphrase. Please check the passphrase.', + }; + + const finalWordList = + wordlists !== undefined ? [...wordlists] : Mnemonic.wordlists.english; + + return [ + passphraseWordError, + whiteSpaceError, + uppercaseCharacterError, + validationError, + ].reduce( + (errorArray: ReadonlyArray, error: PassphraseError) => { + if ( + error.code === passphraseWordError.code && + wordsInPassphrase !== expectedWords + ) { + return [...errorArray, error]; + } + if ( + error.code === whiteSpaceError.code && + whiteSpacesInPassphrase !== expectedWhitespaces + ) { + return [...errorArray, error]; + } + if ( + error.code === uppercaseCharacterError.code && + uppercaseCharacterInPassphrase !== expectedUppercaseCharacterCount + ) { + return [...errorArray, error]; + } + if ( + error.code === validationError.code && + !Mnemonic.validateMnemonic(passphrase, finalWordList) + ) { + return [...errorArray, error]; + } + + return errorArray; + }, + [], + ); +}; diff --git a/elements/lisk-passphrase/test/_setup.ts b/elements/lisk-passphrase/test/_setup.ts new file mode 100644 index 00000000000..5932774a733 --- /dev/null +++ b/elements/lisk-passphrase/test/_setup.ts @@ -0,0 +1,45 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { Assertion } from 'chai'; + +process.env.NODE_ENV = 'test'; + +Assertion.addProperty('hexString', function handleAssert( + this: Chai.ChaiStatic, +) { + const actual = this._obj; + + new Assertion(actual).to.be.a('string'); + + const expected = Buffer.from(actual, 'hex').toString('hex'); + this.assert( + expected === actual, + 'expected #{this} to be a hexString', + 'expected #{this} not to be a hexString', + ); +}); + +Assertion.addProperty('integer', function handleAssert(this: Chai.ChaiStatic) { + const actual = this._obj; + + new Assertion(actual).to.be.a('number'); + + const expected = parseInt(actual, 10); + this.assert( + actual === expected, + 'expected #{this} to be an integer', + 'expected #{this} not to be an integer', + ); +}); diff --git a/elements/lisk-passphrase/test/index.ts b/elements/lisk-passphrase/test/index.ts new file mode 100644 index 00000000000..f658e002a31 --- /dev/null +++ b/elements/lisk-passphrase/test/index.ts @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as passphrase from '../src'; + +describe('passphrase index.js', () => { + it('should export an object', () => { + return expect(passphrase).to.be.an('object'); + }); + + describe('menmonic module', () => { + it('should have the BIP39 Mnemonic module', () => { + return expect(passphrase.Mnemonic).to.be.ok; + }); + }); + + describe('validation module', () => { + it('should have the validation module', () => { + return expect(passphrase.validation).to.be.ok; + }); + }); +}); diff --git a/elements/lisk-passphrase/test/mocha.opts b/elements/lisk-passphrase/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-passphrase/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/test/tsconfig.json b/elements/lisk-passphrase/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-passphrase/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/test/tslint.json b/elements/lisk-passphrase/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-passphrase/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/test/validation.ts b/elements/lisk-passphrase/test/validation.ts new file mode 100644 index 00000000000..db45abbd888 --- /dev/null +++ b/elements/lisk-passphrase/test/validation.ts @@ -0,0 +1,608 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as Mnemonic from 'bip39'; +import { expect } from 'chai'; +import { + countPassphraseWhitespaces, + countPassphraseWords, + countUppercaseCharacters, + getPassphraseValidationErrors, + locateUppercaseCharacters, + locateConsecutiveWhitespaces, +} from '../src/validation'; + +/* tslint:disable: no-magic-numbers */ +describe('passphrase validation', () => { + describe('countPassphraseWhitespaces', () => { + describe('given a valid passphrase', () => { + const expectedAmountOfWhitespaces = 11; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with an extra whitespace at the end', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge '; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with an extra whitespace at the beginning', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + ' model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with extra whitespaces between the first words', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with extra whitespaces between all words', () => { + const expectedAmountOfWhitespaces = 22; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with tab in the beginning', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + '\tmodel actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with vertical tab in the beginning', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + '\vmodel actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with form feed in the beginning', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + '\fmodel actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with nonbreaking space in the beginning', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + '\u00A0model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with byte order mark in the beginning', () => { + const expectedAmountOfWhitespaces = 12; + const passphrase = + '\uFEFFmodel actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + + describe('given a passphrase with no whitespaces', () => { + const expectedAmountOfWhitespaces = 0; + const passphrase = + 'modelactorshalloweightglueupperseatlobsterreasonlabelenlistbridge'; + + it('should return the expected amount of whitespaces', () => { + return expect(countPassphraseWhitespaces(passphrase)).to.be.equal( + expectedAmountOfWhitespaces, + ); + }); + }); + }); + + describe('countPassphraseWords', () => { + describe('given a valid passphrase', () => { + const expectedAmountOfWords = 12; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the amount of words', () => { + return expect(countPassphraseWords(passphrase)).to.be.equal( + expectedAmountOfWords, + ); + }); + }); + + describe('given a passphrase with 13 words', () => { + const expectedAmountOfWords = 13; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge model'; + + it('should return the amount of words', () => { + return expect(countPassphraseWords(passphrase)).to.be.equal( + expectedAmountOfWords, + ); + }); + }); + + describe('given a passphrase with 9 words', () => { + const expectedAmountOfWords = 9; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason'; + + it('should return the amount of words', () => { + return expect(countPassphraseWords(passphrase)).to.be.equal( + expectedAmountOfWords, + ); + }); + }); + + describe('given a passphrase with 12 words and extra whitespaces', () => { + const expectedAmountOfWords = 12; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should ignore the whitespaces and return the amount of words', () => { + return expect(countPassphraseWords(passphrase)).to.be.equal( + expectedAmountOfWords, + ); + }); + }); + + describe('given a passphrase with no words but whitespaces', () => { + const expectedAmountOfWords = 0; + const passphrase = ' '; + + it('should ignore the whitespaces and return the amount of words', () => { + return expect(countPassphraseWords(passphrase)).to.be.equal( + expectedAmountOfWords, + ); + }); + }); + + describe('given an empty string passphrase', () => { + const expectedAmountOfWords = 0; + const passphrase = ''; + + it('should return the amount of words', () => { + return expect(countPassphraseWords(passphrase)).to.be.equal( + expectedAmountOfWords, + ); + }); + }); + }); + + describe('countUppercaseCharacters', () => { + describe('given a passphrase without uppercase character', () => { + const expectedAmountUppercaseCharacter = 0; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return the number of uppercase characters', () => { + const uppercased = countUppercaseCharacters(passphrase); + + return expect(uppercased).to.be.equal(expectedAmountUppercaseCharacter); + }); + }); + + describe('given a passphrase with uppercase character', () => { + const expectedAmountOfCapitalCharacters = 4; + const passphrase = + 'Model Actor shallow eight glue upPer seat lobSter reason label enlist bridge'; + + it('should return the amount of uppercase character', () => { + const uppercased = countUppercaseCharacters(passphrase); + + return expect(uppercased).to.be.equal( + expectedAmountOfCapitalCharacters, + ); + }); + }); + + describe('given a passphrase with all uppercase character', () => { + const expectedAmountOfCapitalCharacters = 65; + const passphrase = + 'MODEL ACTOR SHALLOW EIGHT GLUE UPPER SEAT LOBSTER REASON LABEL ENLIST BRIDGE'; + + it('should return the amount of uppercase character', () => { + return expect(countUppercaseCharacters(passphrase)).to.be.equal( + expectedAmountOfCapitalCharacters, + ); + }); + }); + }); + + describe('locateUppercaseCharacters', () => { + describe('given a string without uppercase character', () => { + const testString = 'a string without uppercase character'; + it('should return an empty array', () => { + return expect(locateUppercaseCharacters(testString)).to.be.eql([]); + }); + }); + + describe('given a string with uppercase character', () => { + const testString = 'a String with SOME uppercase characteR'; + const uppercaseCharacters = [2, 14, 15, 16, 17, 37]; + it('should return the array with the location of the uppercase character', () => { + return expect(locateUppercaseCharacters(testString)).to.be.eql( + uppercaseCharacters, + ); + }); + }); + }); + + describe('locateConsecutiveWhitespaces', () => { + describe('given a string without whitespaces', () => { + const testString = 'abcdefghijklkmnop'; + it('should return an empty array', () => { + return expect(locateConsecutiveWhitespaces(testString)).to.be.eql([]); + }); + }); + + describe('given a string with whitespaces', () => { + const testString = 'abc defghijk lkmnop'; + it('should return an empty array', () => { + return expect(locateConsecutiveWhitespaces(testString)).to.be.eql([]); + }); + }); + + describe('given a string with a whitespace in the beginning', () => { + const testString = ' abc defghijk lkmnop'; + const expectedWhitespaceLocation = [0]; + it('should return the array with the location of the whitespace', () => { + return expect(locateConsecutiveWhitespaces(testString)).to.be.eql( + expectedWhitespaceLocation, + ); + }); + }); + + describe('given a string with a whitespace in the end', () => { + const testString = 'abc defghijk lkmnop '; + const expectedWhitespaceLocation = [19]; + it('should return the array with the location of the whitespace', () => { + return expect(locateConsecutiveWhitespaces(testString)).to.be.eql( + expectedWhitespaceLocation, + ); + }); + }); + + describe('given a string with extra whitespaces', () => { + const testString = 'abc defghijk lkmnop '; + const expectedWhitespaceLocation = [4, 14, 21]; + it('should return the array with the location of the whitespaces', () => { + return expect(locateConsecutiveWhitespaces(testString)).to.be.eql( + expectedWhitespaceLocation, + ); + }); + }); + + describe('given a string with extra whitespaces with special characters', () => { + const testString = 'abc defghijk\t \nlkmnop \u00A0'; + const expectedWhitespaceLocation = [4, 14, 15, 23]; + it('should return the array with the location of the whitespaces', () => { + return expect(locateConsecutiveWhitespaces(testString)).to.be.eql( + expectedWhitespaceLocation, + ); + }); + }); + }); + + describe('getPassphraseValidationErrors', () => { + describe('given a valid passphrase', () => { + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return an empty array', () => { + return expect(getPassphraseValidationErrors(passphrase)).to.be.eql([]); + }); + }); + + describe('given a passphrase with valid 15 words passphrase', () => { + const passphrase = + 'post dumb recycle buddy round normal scrap better people corn crystal again never shrimp kidney'; + + it('should return an array with the errors when validating with default expectedWords', () => { + const errors = [ + { + actual: 15, + code: 'INVALID_AMOUNT_OF_WORDS', + expected: 12, + message: + 'Passphrase contains 15 words instead of expected 12. Please check the passphrase.', + }, + { + actual: 14, + code: 'INVALID_AMOUNT_OF_WHITESPACES', + expected: 11, + location: [], + message: + 'Passphrase contains 14 whitespaces instead of expected 11. Please check the passphrase.', + }, + ]; + return expect(getPassphraseValidationErrors(passphrase)).to.be.eql( + errors, + ); + }); + + it('should return an array with the errors when validating with lower expectedWords', () => { + const errors = [ + { + actual: 15, + code: 'INVALID_AMOUNT_OF_WORDS', + expected: 12, + message: + 'Passphrase contains 15 words instead of expected 12. Please check the passphrase.', + }, + { + actual: 14, + code: 'INVALID_AMOUNT_OF_WHITESPACES', + expected: 11, + location: [], + message: + 'Passphrase contains 14 whitespaces instead of expected 11. Please check the passphrase.', + }, + ]; + return expect( + getPassphraseValidationErrors(passphrase, undefined, 12), + ).to.be.eql(errors); + }); + + it('should return an array with the errors when validating with higher expectedWords', () => { + const errors = [ + { + actual: 15, + code: 'INVALID_AMOUNT_OF_WORDS', + expected: 18, + message: + 'Passphrase contains 15 words instead of expected 18. Please check the passphrase.', + }, + { + actual: 14, + code: 'INVALID_AMOUNT_OF_WHITESPACES', + expected: 17, + location: [], + message: + 'Passphrase contains 14 whitespaces instead of expected 17. Please check the passphrase.', + }, + ]; + return expect( + getPassphraseValidationErrors( + passphrase, + Mnemonic.wordlists.english, + 18, + ), + ).to.be.eql(errors); + }); + + it('should return an empty array when validating with exact expectedWords', () => { + return expect( + getPassphraseValidationErrors(passphrase, undefined, 15), + ).to.be.eql([]); + }); + }); + + describe('given a passphrase with an extra whitespace in the beginning', () => { + const passphrase = + ' model actor shallow eight glue upper seat lobster reason label enlist bridge'; + const passphraseInvalidMnemonicErrors = [ + { + actual: 12, + code: 'INVALID_AMOUNT_OF_WHITESPACES', + expected: 11, + location: [0], + message: + 'Passphrase contains 12 whitespaces instead of expected 11. Please check the passphrase.', + }, + { + actual: false, + code: 'INVALID_MNEMONIC', + expected: true, + message: + 'Passphrase is not a valid mnemonic passphrase. Please check the passphrase.', + }, + ]; + + it('should return the array with the errors', () => { + return expect(getPassphraseValidationErrors(passphrase)).to.be.eql( + passphraseInvalidMnemonicErrors, + ); + }); + }); + + describe('given a passphrase with an extra whitespace in the end', () => { + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge '; + const passphraseInvalidMnemonicErrors = [ + { + actual: 12, + code: 'INVALID_AMOUNT_OF_WHITESPACES', + expected: 11, + location: [76], + message: + 'Passphrase contains 12 whitespaces instead of expected 11. Please check the passphrase.', + }, + { + actual: false, + code: 'INVALID_MNEMONIC', + expected: true, + message: + 'Passphrase is not a valid mnemonic passphrase. Please check the passphrase.', + }, + ]; + + it('should return the array with the errors', () => { + return expect(getPassphraseValidationErrors(passphrase)).to.be.eql( + passphraseInvalidMnemonicErrors, + ); + }); + }); + + describe('given a passphrase with too many whitespaces in between words', () => { + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + const passphraseInvalidMnemonicErrors = [ + { + actual: 13, + code: 'INVALID_AMOUNT_OF_WHITESPACES', + expected: 11, + location: [31, 43], + message: + 'Passphrase contains 13 whitespaces instead of expected 11. Please check the passphrase.', + }, + { + actual: false, + code: 'INVALID_MNEMONIC', + expected: true, + message: + 'Passphrase is not a valid mnemonic passphrase. Please check the passphrase.', + }, + ]; + + it('should return the array with the errors', () => { + return expect(getPassphraseValidationErrors(passphrase)).to.be.eql( + passphraseInvalidMnemonicErrors, + ); + }); + }); + + describe('given a passphrase with uppercase characters', () => { + const passphrase = + 'modEl actor shallow eight glue upper sEat lobster reaSon label enlist bridge'; + const passphraseWithUppercaseCharacterErrors = [ + { + actual: 3, + code: 'INVALID_AMOUNT_OF_UPPERCASE_CHARACTER', + expected: 0, + location: [3, 38, 53], + message: + 'Passphrase contains 3 uppercase character instead of expected 0. Please check the passphrase.', + }, + { + actual: false, + code: 'INVALID_MNEMONIC', + expected: true, + message: + 'Passphrase is not a valid mnemonic passphrase. Please check the passphrase.', + }, + ]; + + it('should return the array with the errors', () => { + return expect(getPassphraseValidationErrors(passphrase)).to.be.eql( + passphraseWithUppercaseCharacterErrors, + ); + }); + }); + + describe('given a passphrase that is an invalid mnemonic passphrase', () => { + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label engage bridge'; + const passphraseInvalidMnemonicError = [ + { + actual: false, + code: 'INVALID_MNEMONIC', + expected: true, + message: + 'Passphrase is not a valid mnemonic passphrase. Please check the passphrase.', + }, + ]; + + it('should return the array with the error', () => { + return expect(getPassphraseValidationErrors(passphrase)).to.be.eql( + passphraseInvalidMnemonicError, + ); + }); + }); + + describe('given a passphrase that uses the correct wordlist for the passphrase', () => { + const wordlist = Mnemonic.wordlists.english; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + + it('should return an empty array', () => { + return expect( + getPassphraseValidationErrors(passphrase, wordlist), + ).to.be.eql([]); + }); + }); + + describe('given a passphrase that uses a different wordlist for the passphrase', () => { + const wordlist = Mnemonic.wordlists.spanish; + const passphrase = + 'model actor shallow eight glue upper seat lobster reason label enlist bridge'; + const passphraseInvalidMnemonicError = [ + { + actual: false, + code: 'INVALID_MNEMONIC', + expected: true, + message: + 'Passphrase is not a valid mnemonic passphrase. Please check the passphrase.', + }, + ]; + + it('should return the array with the error', () => { + return expect( + getPassphraseValidationErrors(passphrase, wordlist), + ).to.be.eql(passphraseInvalidMnemonicError); + }); + }); + }); +}); diff --git a/elements/lisk-passphrase/tsconfig.browsertest.json b/elements/lisk-passphrase/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-passphrase/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/tsconfig.json b/elements/lisk-passphrase/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-passphrase/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-passphrase/tslint.json b/elements/lisk-passphrase/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-passphrase/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transaction-pool/.nycrc b/elements/lisk-transaction-pool/.nycrc new file mode 100644 index 00000000000..c47f12ce6df --- /dev/null +++ b/elements/lisk-transaction-pool/.nycrc @@ -0,0 +1,4 @@ +{ + "exclude": ["test/**", "**/*.d.ts"], + "extension": [".ts"] +} diff --git a/elements/lisk-transaction-pool/LICENSE b/elements/lisk-transaction-pool/LICENSE new file mode 100644 index 00000000000..9cecc1d4669 --- /dev/null +++ b/elements/lisk-transaction-pool/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/elements/lisk-transaction-pool/README.md b/elements/lisk-transaction-pool/README.md new file mode 100644 index 00000000000..7ca753459db --- /dev/null +++ b/elements/lisk-transaction-pool/README.md @@ -0,0 +1,37 @@ +# lisk-transaction-pool + +Transaction pool library for use with Lisk-related software + +## Installation + +```sh +$ npm install --save @liskhq/lisk-transaction-pool +``` + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-transaction-pool/fixtures/transactions.json b/elements/lisk-transaction-pool/fixtures/transactions.json new file mode 100644 index 00000000000..fcf6f0d6955 --- /dev/null +++ b/elements/lisk-transaction-pool/fixtures/transactions.json @@ -0,0 +1,16202 @@ +[ + { + "amount": "1000000", + "recipientId": "12298336625069163905L", + "senderPublicKey": "25215f583d93ad13b51cf3f74b521fd00a0fba8b650974305dcd786e80e83008", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "3ee6989bafbc0067e49f1dc78cbe01f9bc45ae8f7aaf73498de39ca0ca91ce09801a612ab58669ede8fed82b22ff23cbaa7520fe04945c5c847a6a71355e740e", + "id": "3620997417076306539", + "senderId": "12298336625069163905L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "25215f583d93ad13b51cf3f74b521fd00a0fba8b650974305dcd786e80e83008", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "08d965a7bc84dde44acbfff90a17e963fbec1ac56a04227c4b52e15f75614927" + } + }, + "signature": "5fca407faf4adbb8958aa9cc91a255649419c5aa58e02e4515b42934edd025c9ac40de8fdbba0d2cd34cb871f15f4a85489594db8b735b01732a15740ba78f0a", + "id": "10598147892864969716", + "senderId": "12298336625069163905L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "25215f583d93ad13b51cf3f74b521fd00a0fba8b650974305dcd786e80e83008", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "forum" + } + }, + "signature": "9448f966f81d995ed50b359ebaa959e07bcf47d44386b993e14837ef625c0f8d4befd53cb7a0add31e57a88ab4421f30e8ed0489c92db15c144bf07d0c4a060c", + "id": "11745161032885507025", + "senderId": "12298336625069163905L" + }, + { + "amount": "0", + "recipientId": "12298336625069163905L", + "senderPublicKey": "25215f583d93ad13b51cf3f74b521fd00a0fba8b650974305dcd786e80e83008", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+25215f583d93ad13b51cf3f74b521fd00a0fba8b650974305dcd786e80e83008" + ] + }, + "signature": "f3de8ea503e2296ffb27382ea60e8fa4131d53a06bc050fbe5b1627f09011b6c489eaf76ce0f9d21831d832496a60d49fb2efcc560f2aac0275eb3b4876b3f08", + "id": "6905035685643511951", + "senderId": "12298336625069163905L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "25215f583d93ad13b51cf3f74b521fd00a0fba8b650974305dcd786e80e83008", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+25215f583d93ad13b51cf3f74b521fd00a0fba8b650974305dcd786e80e83008", + "+08d965a7bc84dde44acbfff90a17e963fbec1ac56a04227c4b52e15f75614927" + ] + } + }, + "signature": "1ce7903b49016f8bc7efe24ec167d4cce61b381899d1931cc871243ca6d3fcb4566abbcf6de8a2bc8d2463e3a52deeac95dfb6425b0a3db9ffbc7c3872cc1605", + "id": "15553637428794557690", + "senderId": "12298336625069163905L" + }, + { + "amount": "1000000", + "recipientId": "3747847319783711194L", + "senderPublicKey": "9bb41fce7cae8b2a248ef46aa6f617ab899d71f6e0927d0557b39a1fb749bcb4", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "648c6477582bd4a96e84d7d3f2db55e25fae060b4421974e546a012f8dc15dd575b2d83616ebfa73ab909caa9c7fc153eb1779b0ffccdb9ab9dfac26b1182502", + "id": "10560075731819072228", + "senderId": "3747847319783711194L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9bb41fce7cae8b2a248ef46aa6f617ab899d71f6e0927d0557b39a1fb749bcb4", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4eeaa5b80eec5ac7cf4fd68816318985f8a686550065b09a12f9f29884d694ab" + } + }, + "signature": "b2bee75630b531a991992d9c6d90f429db5727d2d2a3548dac58f21e961b9355565b5ca52a94f18cafb90196647ced1ca210dee4e5ad0073d017dfe55483070b", + "id": "4461753350784912963", + "senderId": "3747847319783711194L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9bb41fce7cae8b2a248ef46aa6f617ab899d71f6e0927d0557b39a1fb749bcb4", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "april" + } + }, + "signature": "a531349523aa646758744cf7146a187e90608959b0237cdaf3c7e8ed4d289820cc0a7fff6fa86bf28ff59ec2c20e0b99bdf586c83234890ac3fff018f7143402", + "id": "14944568175309770180", + "senderId": "3747847319783711194L" + }, + { + "amount": "0", + "recipientId": "3747847319783711194L", + "senderPublicKey": "9bb41fce7cae8b2a248ef46aa6f617ab899d71f6e0927d0557b39a1fb749bcb4", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+9bb41fce7cae8b2a248ef46aa6f617ab899d71f6e0927d0557b39a1fb749bcb4" + ] + }, + "signature": "bd3d9c8ee9c68eed968b6a1801c968eaffcb07083318ebe01e603573321cee203ea0364f84cee70969808f495f6852c30fc23a62b3b1fad123c3bce707a74901", + "id": "9413804612646400788", + "senderId": "3747847319783711194L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9bb41fce7cae8b2a248ef46aa6f617ab899d71f6e0927d0557b39a1fb749bcb4", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+9bb41fce7cae8b2a248ef46aa6f617ab899d71f6e0927d0557b39a1fb749bcb4", + "+4eeaa5b80eec5ac7cf4fd68816318985f8a686550065b09a12f9f29884d694ab" + ] + } + }, + "signature": "1392eb2cef2d1deb77432643658802e03c58bddc405c39c45239be3f001271ae1f96dc138701e9acdc5549971ed74ee7b378ea0531bc97a3f763f3d4da81900c", + "id": "13305615867950270000", + "senderId": "3747847319783711194L" + }, + { + "amount": "1000000", + "recipientId": "5794491185452817986L", + "senderPublicKey": "5ce189eebf2e55818f198cca0d0496ca23a4eaf0fd815cce161703518e0e3a63", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a03ba644ab91cb7f71fcdd0fc9a92442c18fd559fff03ec232444f1ef67998c528de3e199eef4c4acc391b7356f59cb01bdfe25ec45aeccf6059841ccd79410a", + "id": "15622640554084836889", + "senderId": "5794491185452817986L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5ce189eebf2e55818f198cca0d0496ca23a4eaf0fd815cce161703518e0e3a63", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "704c50b2e03b1ad266260c061b47611769bc4bd264242ec3b5f9b19f14597efe" + } + }, + "signature": "73e47f942edeb231e208a221227c9f4100422f53b74d5fdaa964d5c65b8060e6522203ac52920c6a9b52a81282b129b3ad0872acf8fb6c6cb8a072a77bf5cf05", + "id": "5546231617464252226", + "senderId": "5794491185452817986L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5ce189eebf2e55818f198cca0d0496ca23a4eaf0fd815cce161703518e0e3a63", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "crew" + } + }, + "signature": "c83bfeb22799037e9ffda80bb159b3e0b9b96e4279316664955646f861845385dc3ed36000e08dd0e706d34a7caf65804afc381511755c9ed46079ae0f8dea05", + "id": "8925402405647908568", + "senderId": "5794491185452817986L" + }, + { + "amount": "0", + "recipientId": "5794491185452817986L", + "senderPublicKey": "5ce189eebf2e55818f198cca0d0496ca23a4eaf0fd815cce161703518e0e3a63", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5ce189eebf2e55818f198cca0d0496ca23a4eaf0fd815cce161703518e0e3a63" + ] + }, + "signature": "2d8d42944f294e5070cc3627c11204d3c6e8dd3d7ee4b3817352751c6390114a4beeeccb9766753334c5381cc77847e1e712d1a0cb0cc8c32206c76408482304", + "id": "12946542152614715508", + "senderId": "5794491185452817986L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5ce189eebf2e55818f198cca0d0496ca23a4eaf0fd815cce161703518e0e3a63", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5ce189eebf2e55818f198cca0d0496ca23a4eaf0fd815cce161703518e0e3a63", + "+704c50b2e03b1ad266260c061b47611769bc4bd264242ec3b5f9b19f14597efe" + ] + } + }, + "signature": "81ecde6eb42571a47c8cfe8a491a24480e6175f1178329b09e938013b5a73159d0824d7464cff593689badbea206d56e7811adfaeda5ff33616a035c90338108", + "id": "2034133653129066908", + "senderId": "5794491185452817986L" + }, + { + "amount": "1000000", + "recipientId": "8523266721081721849L", + "senderPublicKey": "c628ad9fd25034436280be095a114ddaf08267d4edb069671cf563f4c7ffd9ee", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "61b93a1e4622fa56de0ff9b8e1349afe65556deef8457d92d29692770c7641013d2a76b745dbfe8b05b4f367763dd2ca6c8cfc23970d2439377d071a07df8300", + "id": "5438128389976588291", + "senderId": "8523266721081721849L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c628ad9fd25034436280be095a114ddaf08267d4edb069671cf563f4c7ffd9ee", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c46b0f32908ce627f223883d49912ee5abcea49e5609121cb18a9cd6b5b6f544" + } + }, + "signature": "870d62025dc09a79b6a6a6345f77587df3b21b709754929bdc405d550f53510fa6a1524f7ec863b93e23e7651897435a5f8e36080c98f2ed0f437790c697f805", + "id": "9745431201427202070", + "senderId": "8523266721081721849L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c628ad9fd25034436280be095a114ddaf08267d4edb069671cf563f4c7ffd9ee", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "guard" + } + }, + "signature": "a76164396aa02318f9f6d4027cdfb9ea36d17d055236a31072718961cbb74ec77c5669aa22ba9ae2878af36e245beaf75edbd517abe5de8807ee6df4da048b08", + "id": "1658287883727779252", + "senderId": "8523266721081721849L" + }, + { + "amount": "0", + "recipientId": "8523266721081721849L", + "senderPublicKey": "c628ad9fd25034436280be095a114ddaf08267d4edb069671cf563f4c7ffd9ee", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c628ad9fd25034436280be095a114ddaf08267d4edb069671cf563f4c7ffd9ee" + ] + }, + "signature": "9b41368b5834fa90c61dc320177e35139507a095db7a79692456b065559dffbb6187486926024d5292fcfcaf4f9d8af837cdaa5b3b65e2dcadac4e59d473eb0e", + "id": "17701643640841539295", + "senderId": "8523266721081721849L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c628ad9fd25034436280be095a114ddaf08267d4edb069671cf563f4c7ffd9ee", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c628ad9fd25034436280be095a114ddaf08267d4edb069671cf563f4c7ffd9ee", + "+c46b0f32908ce627f223883d49912ee5abcea49e5609121cb18a9cd6b5b6f544" + ] + } + }, + "signature": "bd6481a1ee0686aa625ed9b3c659c6ff60aae874abe827893076683114d32bbbd10047526e6e952cd26504caedd225f7eba9a7c120e787d6bc0962d62d06460d", + "id": "16947093868773359960", + "senderId": "8523266721081721849L" + }, + { + "amount": "1000000", + "recipientId": "2632346862538514441L", + "senderPublicKey": "a1cc98d89088b4aae6279f33f6b488e20e9022c2942a3ad9a45049205a412f74", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "af4610f07da76d035f7c26bfb61d6d2efd9f4c2b83d7681e4711ecef2a27cd69e23f38b3ccdc3feeec35a3a56130b444eb12502405860e5eb5eec374910dbd0f", + "id": "12890497220594135408", + "senderId": "2632346862538514441L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a1cc98d89088b4aae6279f33f6b488e20e9022c2942a3ad9a45049205a412f74", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "098f024ce13b7995858d5157c00271af4dd9fd92e3dabdafd4cf6ffa813fd944" + } + }, + "signature": "b6b2f939b1ea57e9c0dc70e24177f3df5debc1fe5b9c32139a014e01e0a0fedb1414da00976da3eeec05e23ebafe267d0a1979f3f1236fe22e1cf79f3b0a6b0b", + "id": "2216330975087527864", + "senderId": "2632346862538514441L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a1cc98d89088b4aae6279f33f6b488e20e9022c2942a3ad9a45049205a412f74", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "size" + } + }, + "signature": "44986d5b0706cb0361efc046c363869acec49d2bbf75efdf56ef54ae642bf05456136f858f4350e64065ed65da666b1ce2d3969d71b1ab4c2154c89871ea3f04", + "id": "3915189215137846925", + "senderId": "2632346862538514441L" + }, + { + "amount": "0", + "recipientId": "2632346862538514441L", + "senderPublicKey": "a1cc98d89088b4aae6279f33f6b488e20e9022c2942a3ad9a45049205a412f74", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a1cc98d89088b4aae6279f33f6b488e20e9022c2942a3ad9a45049205a412f74" + ] + }, + "signature": "1f6ccc5990750350f6b33cfde19b9c3e6e3568e21980c63303c11905ad54d49118efb4e559c82a4363c8861f43f7aef9141f02bc02ca5c3afe72827edc7c3d0d", + "id": "13431264036427464991", + "senderId": "2632346862538514441L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a1cc98d89088b4aae6279f33f6b488e20e9022c2942a3ad9a45049205a412f74", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a1cc98d89088b4aae6279f33f6b488e20e9022c2942a3ad9a45049205a412f74", + "+098f024ce13b7995858d5157c00271af4dd9fd92e3dabdafd4cf6ffa813fd944" + ] + } + }, + "signature": "12d7b67a4fcad29b5015f8e7d334e3bd701540c770b1087c8c387acd7012335d0b6d4f4c191b6d0c726c7bc83f9c3eed7505b2d738dd63cad7551a0114663308", + "id": "594718629648746539", + "senderId": "2632346862538514441L" + }, + { + "amount": "1000000", + "recipientId": "17266829266570849889L", + "senderPublicKey": "d4b99185cf0307954be1f093b74fed64c0a22bd054bf92a0e74190e13208e3d9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "461caf27dcbfcf518b45513a8f325e5b9d79cde91a66fca79bccad20993e8096d627134ad51a881f95517c05e9022b769ab65896497da5b3f4e0db19c7f9a506", + "id": "14976550472317624458", + "senderId": "17266829266570849889L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d4b99185cf0307954be1f093b74fed64c0a22bd054bf92a0e74190e13208e3d9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "01d2b302d6ce87e0d92daa546ceacaece0efea4d0e04d2b8a80bf3bccdfb8972" + } + }, + "signature": "b134fc3f61b96608b6df599c2cedba174109614c99febd5311272e6af47fefd4222bfe9c5483df51d9cfaaac42af2997e3b0bd2be9615a2f9343da3f5ae82f0d", + "id": "8290291264997657461", + "senderId": "17266829266570849889L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d4b99185cf0307954be1f093b74fed64c0a22bd054bf92a0e74190e13208e3d9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "join" + } + }, + "signature": "8c141a8e13d55833b628dcc245aa06df668144b4d10da14e0199a6b5a6946cbe8d17eb7f57e5d967bcb9d54fa4d15005272305800b23fe439b2ec0476f8f260a", + "id": "11676918963698508417", + "senderId": "17266829266570849889L" + }, + { + "amount": "0", + "recipientId": "17266829266570849889L", + "senderPublicKey": "d4b99185cf0307954be1f093b74fed64c0a22bd054bf92a0e74190e13208e3d9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+d4b99185cf0307954be1f093b74fed64c0a22bd054bf92a0e74190e13208e3d9" + ] + }, + "signature": "f3abe667524186f656329b19ee3437b8d67cac8f7064f910a33e9ee0379be57e43910480ad48a1808dcfb87a6873e0833feb0a2ff687457e13a75783281ae20e", + "id": "8780073507062015396", + "senderId": "17266829266570849889L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d4b99185cf0307954be1f093b74fed64c0a22bd054bf92a0e74190e13208e3d9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+d4b99185cf0307954be1f093b74fed64c0a22bd054bf92a0e74190e13208e3d9", + "+01d2b302d6ce87e0d92daa546ceacaece0efea4d0e04d2b8a80bf3bccdfb8972" + ] + } + }, + "signature": "ce7c334667a1d0c0d0d2e9f7efd7297211821617f1d673879aaf6feefb2e47dd9e868d9eae3f709ed2c73f2adc99b23f0e9f0d46299be58ea872750498e8ab08", + "id": "16414279707432010814", + "senderId": "17266829266570849889L" + }, + { + "amount": "1000000", + "recipientId": "10909963504503064046L", + "senderPublicKey": "b1e4e7b6a34ae07ccf0ee5c80c6d5e6582dcca9bdd5f40b3d1698bf9355c67ff", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "56c3c715fb142fcf3caf1caaf25562eeabc9be32f7afeff47d74168751e55523bb13ee11d4c8c23fd1df887fd6d3d54fd048e7dd6a6b9aa74d1df31e6c25800a", + "id": "3908140961038095076", + "senderId": "10909963504503064046L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b1e4e7b6a34ae07ccf0ee5c80c6d5e6582dcca9bdd5f40b3d1698bf9355c67ff", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "a8310a7c1a02a1abd2bfe4b464cc32f00779213db4116f3933b1e0b64bba4c05" + } + }, + "signature": "4914ba21d01e0b0968bcd400e92134fc3e9cc88d375725588f442f627d5537aed372c92e5f6c4a004669b319602990bf7bcbed46b90a821aa0613a885f6d440a", + "id": "8710069572286829180", + "senderId": "10909963504503064046L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b1e4e7b6a34ae07ccf0ee5c80c6d5e6582dcca9bdd5f40b3d1698bf9355c67ff", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "kingdom" + } + }, + "signature": "819f09b4a9a57562e52fc311eb4103c17860f7faaf11e1032a8c33ccbd7658652f3086b351d955fad80d6caf2bba6fff40441e379310081c45b26bebb2fa2a0e", + "id": "16927820811097323461", + "senderId": "10909963504503064046L" + }, + { + "amount": "0", + "recipientId": "10909963504503064046L", + "senderPublicKey": "b1e4e7b6a34ae07ccf0ee5c80c6d5e6582dcca9bdd5f40b3d1698bf9355c67ff", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b1e4e7b6a34ae07ccf0ee5c80c6d5e6582dcca9bdd5f40b3d1698bf9355c67ff" + ] + }, + "signature": "ceff2b0b99c8f22656d03fc581d6732848a1ae337af465dc8b0038b51d8decb3623d1760014d658b199367307da0eb2186b59a0eeb2907893d2bd18cf28a190c", + "id": "6365444827350365768", + "senderId": "10909963504503064046L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b1e4e7b6a34ae07ccf0ee5c80c6d5e6582dcca9bdd5f40b3d1698bf9355c67ff", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b1e4e7b6a34ae07ccf0ee5c80c6d5e6582dcca9bdd5f40b3d1698bf9355c67ff", + "+a8310a7c1a02a1abd2bfe4b464cc32f00779213db4116f3933b1e0b64bba4c05" + ] + } + }, + "signature": "30ce03635908ec4639b5e1131492ac190add317106f8faec49e91f6df5c94387d278717ceaab1420ec66cdd65f2be580697c7f93dc460e0c6fef8679a9042709", + "id": "8599344948402695992", + "senderId": "10909963504503064046L" + }, + { + "amount": "1000000", + "recipientId": "3488588871520979421L", + "senderPublicKey": "700498d3b049a31a0fe89f0e1690b843981f327e9550be758bbeca90da114238", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "10d27a96a79f35b42309d9049a24896363435d6f943b030e712fdf05488370f7d4f46ffecf725461c7726d93651fe9c1beb82189fa35213e533cfff4563f660c", + "id": "8265952013034362092", + "senderId": "3488588871520979421L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "700498d3b049a31a0fe89f0e1690b843981f327e9550be758bbeca90da114238", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d79ccc3f31f4ab3fc7d480e25507e715e44c68ef23722586bbb04f4176b9de0d" + } + }, + "signature": "8afde4eaa4f14dda2a0ac4dea9b8b1af95311e93d0dd02f5bee444509da68a483ad7b953efd9635ac14a43389145c8097b2f245aff73d7e520cccd69bf501c02", + "id": "5695081401213550068", + "senderId": "3488588871520979421L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "700498d3b049a31a0fe89f0e1690b843981f327e9550be758bbeca90da114238", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "volcano" + } + }, + "signature": "5852fa93ad49df0e6face08a38722347bfdda7891c04e937ec48fcb93d844ef6110f02c25d71c85a8c20426329a825926efcb91d6cb90723eb39040368978205", + "id": "3497457653219665438", + "senderId": "3488588871520979421L" + }, + { + "amount": "0", + "recipientId": "3488588871520979421L", + "senderPublicKey": "700498d3b049a31a0fe89f0e1690b843981f327e9550be758bbeca90da114238", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+700498d3b049a31a0fe89f0e1690b843981f327e9550be758bbeca90da114238" + ] + }, + "signature": "8530858e1c9aa851064c923b5fe85873f5a7c44eeb72d18ad7fdac28803da2384bdfc1949e50f0fed34463463676b5722d53f66cf97b8f6aedeb628b61ca5306", + "id": "193746958083408843", + "senderId": "3488588871520979421L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "700498d3b049a31a0fe89f0e1690b843981f327e9550be758bbeca90da114238", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+700498d3b049a31a0fe89f0e1690b843981f327e9550be758bbeca90da114238", + "+d79ccc3f31f4ab3fc7d480e25507e715e44c68ef23722586bbb04f4176b9de0d" + ] + } + }, + "signature": "d1cb578fd8d00eb989aae04a31cc4d3310c4229fbdcb8ed75f518eb6d5b78e06cd42e2ee98fcfd68ed5269aa2f333953b3da3c040e23aa67c96dcb7b87b6800f", + "id": "4617911892062479642", + "senderId": "3488588871520979421L" + }, + { + "amount": "1000000", + "recipientId": "4337829998959396793L", + "senderPublicKey": "b98cbf431b38f5778eeeda14967485d74794e75dd641ae2fc293e811bb2336ea", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a6ae2bb8be04f3d7761b91520d7b42418c652bf827227215567284cac05449e81087a0d3e0461ab9a503ca3fe739a29005e8909b40e11312279235e26e4de509", + "id": "4766156496934964541", + "senderId": "4337829998959396793L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b98cbf431b38f5778eeeda14967485d74794e75dd641ae2fc293e811bb2336ea", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3dc6fceade54e282a429e1112ae444da49ab03f9ba2f359357fc34e1045ed8ff" + } + }, + "signature": "346bfb4382c336b2c9b2b66c72d7de2d0df4d8b40e5a8af6019e4345ba23922254cce2162e77065ae84cf103a6ce248ffbea59a0e3bb3cbc2b5b08fbcb7ff90a", + "id": "13249118235908972252", + "senderId": "4337829998959396793L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b98cbf431b38f5778eeeda14967485d74794e75dd641ae2fc293e811bb2336ea", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "trick" + } + }, + "signature": "fc3a5c20d2228efb3a2a388ab8fbe88d85cf446605c0016c2b25406a46c7dd1b676a5184be05e55849299a248aaf7c8f2237eb8c954515a8a4ae9095bf847002", + "id": "9357198428788910480", + "senderId": "4337829998959396793L" + }, + { + "amount": "0", + "recipientId": "4337829998959396793L", + "senderPublicKey": "b98cbf431b38f5778eeeda14967485d74794e75dd641ae2fc293e811bb2336ea", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b98cbf431b38f5778eeeda14967485d74794e75dd641ae2fc293e811bb2336ea" + ] + }, + "signature": "76328d5c1ce678f62bffb1acea5ac3e5e0545afcb3a44eb84f70c0581216f363d04bcc6b512ee7c380c72059eadfae223d022faf86c4ecaa42687fd79faf880f", + "id": "4318726233947206361", + "senderId": "4337829998959396793L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b98cbf431b38f5778eeeda14967485d74794e75dd641ae2fc293e811bb2336ea", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b98cbf431b38f5778eeeda14967485d74794e75dd641ae2fc293e811bb2336ea", + "+3dc6fceade54e282a429e1112ae444da49ab03f9ba2f359357fc34e1045ed8ff" + ] + } + }, + "signature": "8c14c0c6e8f7e83641f5be5e84886b472b166a46bf3d291c67165883867ef0a1b0a6abc690ef920211405c8c65cc70db6565104cd77580b5cf2f53cddc93c40a", + "id": "4809685464162520724", + "senderId": "4337829998959396793L" + }, + { + "amount": "1000000", + "recipientId": "7618215462200321783L", + "senderPublicKey": "6cbef623057bded813a69576a8d8888c3e7079d1f7814b36ba4a3ca1c91f7179", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "41df88a1240b1a6a39969ce9a5045bfe9a906a4b94e527738f2c54e99829e28f34372123d9071dbe52602a7aaf6c5f70b9293c4d0cfc5b29b6d1183be0599306", + "id": "4769745215172199788", + "senderId": "7618215462200321783L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "6cbef623057bded813a69576a8d8888c3e7079d1f7814b36ba4a3ca1c91f7179", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f240a81d515dbac0054d773b49ead67aef11589c3b54abb30225831f584450fd" + } + }, + "signature": "f9f0b9d526f6c2b5297b30221351ea9e092b957474bbcc751fada87824e6728c1d51c54d831b6d6ebb7fe744958671d07a886ee6dfe2767ed2da9c2cf0e85807", + "id": "784048976439884364", + "senderId": "7618215462200321783L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "6cbef623057bded813a69576a8d8888c3e7079d1f7814b36ba4a3ca1c91f7179", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "turkey" + } + }, + "signature": "d8d656b41f738446201b5dfcfba6724e0f332cdaf6708e3f8eff096c8e68c5ff6e8d23a04c0223083a96bbd1a8b6d0b45b333983373a10c9ac01de857fc80904", + "id": "2484293964886603371", + "senderId": "7618215462200321783L" + }, + { + "amount": "0", + "recipientId": "7618215462200321783L", + "senderPublicKey": "6cbef623057bded813a69576a8d8888c3e7079d1f7814b36ba4a3ca1c91f7179", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+6cbef623057bded813a69576a8d8888c3e7079d1f7814b36ba4a3ca1c91f7179" + ] + }, + "signature": "8c0d35547fd2c8cb21fa4fb8eff8dfda59959149806708a3a90e60f4409584eb855389bf0c41a602a047d801dcc78e62dc2826d561fc6b7ce1556aba1fcc9803", + "id": "9334290678626291074", + "senderId": "7618215462200321783L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "6cbef623057bded813a69576a8d8888c3e7079d1f7814b36ba4a3ca1c91f7179", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+6cbef623057bded813a69576a8d8888c3e7079d1f7814b36ba4a3ca1c91f7179", + "+f240a81d515dbac0054d773b49ead67aef11589c3b54abb30225831f584450fd" + ] + } + }, + "signature": "adfaa5f93fa99c371840fd027acb469ba2a2bb77cf58e6f7ed5d7ff81a500a956de6947df2adaa4afbb231a65fad9d76177792d37b024939e3cbb23121f9380f", + "id": "4438448019178268106", + "senderId": "7618215462200321783L" + }, + { + "amount": "1000000", + "recipientId": "13643066146532836068L", + "senderPublicKey": "004d53519837c3289f0a2889b89b26390408700f228787c2242029f99c3a4bd4", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f6a8a75349f3ba6eff17aa10c3d75aeeda695c08f0d1600d2e0cfe7cf2a167372cda7ce75ca547845e17d2f7d9002b3eb6c1ebf55e11ee205683bde547a5d604", + "id": "4317956990522652293", + "senderId": "13643066146532836068L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "004d53519837c3289f0a2889b89b26390408700f228787c2242029f99c3a4bd4", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c88221d81e5896d02cc861607d3c1d8ee4af8bae279087f14b41151d6de13a51" + } + }, + "signature": "b55c4805e4f26cc9d5957732b80df498117cdc4dc56ce456d4dde0cc39f4c7779bb04a5627a985fe1cd86ce0036544d2921f2b2804e5c965b08fdf1e6c5a7308", + "id": "8172828472772593375", + "senderId": "13643066146532836068L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "004d53519837c3289f0a2889b89b26390408700f228787c2242029f99c3a4bd4", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "rotate" + } + }, + "signature": "c0ae4a7a08a7ecfaa2ce4bec17378440a560f7c51d7bf8da112a46c03f0f5a72c495c31045a1fc3eca01242cc594ee83307399e38cedac775a364fea77d8c50f", + "id": "14636103345862078210", + "senderId": "13643066146532836068L" + }, + { + "amount": "0", + "recipientId": "13643066146532836068L", + "senderPublicKey": "004d53519837c3289f0a2889b89b26390408700f228787c2242029f99c3a4bd4", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+004d53519837c3289f0a2889b89b26390408700f228787c2242029f99c3a4bd4" + ] + }, + "signature": "75f8ca10304fa9fa95e1ee7e71532b6ea77ec82888b7116d11c67a0eb2e461016755f55fdca1fa45240a972845e3239354852063b8b4bab82dcd34119e979c0a", + "id": "12061409637528787000", + "senderId": "13643066146532836068L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "004d53519837c3289f0a2889b89b26390408700f228787c2242029f99c3a4bd4", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+004d53519837c3289f0a2889b89b26390408700f228787c2242029f99c3a4bd4", + "+c88221d81e5896d02cc861607d3c1d8ee4af8bae279087f14b41151d6de13a51" + ] + } + }, + "signature": "7a21890061e95c05397b26e2f6ff5d0e5a52a6bbd3b12009e6bc548937ee1da533b7eef2c597046b4880d462787a0330b15cbefb6e80f9f14db459f437587101", + "id": "7633230841013084772", + "senderId": "13643066146532836068L" + }, + { + "amount": "1000000", + "recipientId": "5282964883603386230L", + "senderPublicKey": "f7de68db8819ec135c6c53131ede8442532f01c8bef4adeeaa3d747b29270ce3", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "6cae86e67c8a594c4c9466aac011e3acfe1c39e02ce33383bbd6d1f1bd2d7b809f0330224e26f4c8983e08caab1b3b0a613f1740617b227762200c6737da8705", + "id": "13850824041189661923", + "senderId": "5282964883603386230L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f7de68db8819ec135c6c53131ede8442532f01c8bef4adeeaa3d747b29270ce3", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "beab8dee9c96056f343dcb3534ccfe2cbd50de0e3ea45f7ebf3a25bdbd572040" + } + }, + "signature": "a43c3a5a7b68c634c5f03926665ab826b6074c2115ac551158ffed5902f0944bea605438d5c1d8f3e1e279eac821129de4d705200ebdc85b73878526d0bae70d", + "id": "1686495958686730813", + "senderId": "5282964883603386230L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f7de68db8819ec135c6c53131ede8442532f01c8bef4adeeaa3d747b29270ce3", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "random" + } + }, + "signature": "ee0a7e50987c642c552a977c9b06f402351cb9de319287d4c093d1bcb57f48441279d4ee3b805bb931d35ebea4c3e19c691f92896e9fc13e901d30146cb92c06", + "id": "14557422215474736777", + "senderId": "5282964883603386230L" + }, + { + "amount": "0", + "recipientId": "5282964883603386230L", + "senderPublicKey": "f7de68db8819ec135c6c53131ede8442532f01c8bef4adeeaa3d747b29270ce3", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f7de68db8819ec135c6c53131ede8442532f01c8bef4adeeaa3d747b29270ce3" + ] + }, + "signature": "e482f93d4065299bd3ff9cb914711d953be18cdf99ccc50eb1af1f4a542a60e3ad7d6f2e86fd47d7952d46c3e6d2e8059c054bb2de3d235ab3306fd3f7166406", + "id": "8083406030216001325", + "senderId": "5282964883603386230L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f7de68db8819ec135c6c53131ede8442532f01c8bef4adeeaa3d747b29270ce3", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f7de68db8819ec135c6c53131ede8442532f01c8bef4adeeaa3d747b29270ce3", + "+beab8dee9c96056f343dcb3534ccfe2cbd50de0e3ea45f7ebf3a25bdbd572040" + ] + } + }, + "signature": "a5684126bc4f6049c3893e35a3eda8d7c52074970a9e8635e1c353a642d07b53e55fe23ae38740ea087f0bf7d99cdabb2a38627e141a0f1f88fbf5c1581e1f0e", + "id": "3716376141002715727", + "senderId": "5282964883603386230L" + }, + { + "amount": "1000000", + "recipientId": "5875215186750376849L", + "senderPublicKey": "04c4fcc82aa7aac403f58dca0840ba702b169d7ffe7d137e80df683453639d24", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "587923deae95b418687a492cdda2e1cbf116bf163e66b95cba3d068b1f5cf3d258c5568289ae5e12e64a84ec4d3f7e6ca4df6beeb2237c294e81285a6e393003", + "id": "11709132260230414950", + "senderId": "5875215186750376849L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "04c4fcc82aa7aac403f58dca0840ba702b169d7ffe7d137e80df683453639d24", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "241e198376a6eec4a93d82509da8e9624258ada0f39932c50fe6cab4d95ad4b5" + } + }, + "signature": "9c09ef1d93644ad457dac4ebf8b2b23502af6bf70028fa04c1bf862f17c6147252d7722077ab5b7005df28e964474e7b629e64dd7a6d875532a85bac25ba1e0e", + "id": "8323095186803386063", + "senderId": "5875215186750376849L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "04c4fcc82aa7aac403f58dca0840ba702b169d7ffe7d137e80df683453639d24", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "inject" + } + }, + "signature": "0cd8db476ee5c727f674dec108e213b895e0b157384a589909a0187c0326b332fe573ad34d2641133ccc640e53e42741d75b19c60c3a93b11a7b0d6519d6ac0b", + "id": "6250968334531525035", + "senderId": "5875215186750376849L" + }, + { + "amount": "0", + "recipientId": "5875215186750376849L", + "senderPublicKey": "04c4fcc82aa7aac403f58dca0840ba702b169d7ffe7d137e80df683453639d24", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+04c4fcc82aa7aac403f58dca0840ba702b169d7ffe7d137e80df683453639d24" + ] + }, + "signature": "07b73d0ad6ce3620ac13b8456e52e66b3294a115967469420089134300ea1225a3f50d738697e9de872b71c84d25d97b08d6bba1b3f817a27556ec8a9608d20e", + "id": "10722029762287405146", + "senderId": "5875215186750376849L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "04c4fcc82aa7aac403f58dca0840ba702b169d7ffe7d137e80df683453639d24", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+04c4fcc82aa7aac403f58dca0840ba702b169d7ffe7d137e80df683453639d24", + "+241e198376a6eec4a93d82509da8e9624258ada0f39932c50fe6cab4d95ad4b5" + ] + } + }, + "signature": "35618fcdf8b125a5caa14760b6b742e90587a17beabc65ec8f473397a42ad660495ea546fa36e02337fc60c85e75a2a2b782876f17e72cee8e0b20ece4a09702", + "id": "12745625218855514758", + "senderId": "5875215186750376849L" + }, + { + "amount": "1000000", + "recipientId": "372406364815696347L", + "senderPublicKey": "edc243c7415f3b701e16b52e84c96f812d5981302cda699baed3428cbba9f905", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "2698a842f508452892a9b752c2887e6282a4ee4da71d3d4116141eb1ee380034620136d202867c590e3591cbd08bc097390ab13850dc6064ebc02742ca554502", + "id": "8052199917262694295", + "senderId": "372406364815696347L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "edc243c7415f3b701e16b52e84c96f812d5981302cda699baed3428cbba9f905", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "67fa3c9cc56a2d5c36a4d379f1350e1d7a35f9f7a6702bc3cda3705a0b07769d" + } + }, + "signature": "c307af3b33032236f5745ed329c29a46a427fe2a4543e5fe993691363e51eaa7f003916041f783173cb9ecce0ff39d97f8594bed059a56a832fd1065f7c98705", + "id": "17576472321089472390", + "senderId": "372406364815696347L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "edc243c7415f3b701e16b52e84c96f812d5981302cda699baed3428cbba9f905", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "age" + } + }, + "signature": "d6b220bae9b0a97c617cbfeecb3f895fbd0d4c86c71eececeebe5f367c48d6fe58ed5b5b83de22c7047e332762225f588cda989dff0d5399548c2d349bd0ed03", + "id": "13730630488169720211", + "senderId": "372406364815696347L" + }, + { + "amount": "0", + "recipientId": "372406364815696347L", + "senderPublicKey": "edc243c7415f3b701e16b52e84c96f812d5981302cda699baed3428cbba9f905", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+edc243c7415f3b701e16b52e84c96f812d5981302cda699baed3428cbba9f905" + ] + }, + "signature": "5e9bbf8c29a586f10b99a83a95a1423199a8a58c4902dc8f1a7ffefe12421c5fbed8f2e8969d69795e91d8be629ea1d2a32caa642446f2da4c5811fa1a0bf501", + "id": "12473565092196649026", + "senderId": "372406364815696347L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "edc243c7415f3b701e16b52e84c96f812d5981302cda699baed3428cbba9f905", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+edc243c7415f3b701e16b52e84c96f812d5981302cda699baed3428cbba9f905", + "+67fa3c9cc56a2d5c36a4d379f1350e1d7a35f9f7a6702bc3cda3705a0b07769d" + ] + } + }, + "signature": "63d93f4df9031c4c3691123fedab5a207773fb1a89bc10fbba81c9bf62949fe3bb828efabf6bf45d2802f006473ef2de89b54b9c6e6558e9bdb412c230defc0d", + "id": "15871879006774275379", + "senderId": "372406364815696347L" + }, + { + "amount": "1000000", + "recipientId": "11261259397990416889L", + "senderPublicKey": "b39a7a2d4e5fe0fb2a85fc35ae85bfbed5e8e08c45df0a9050157778d77be706", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "984e6df2ee273eef273317b94139ca9091b7ab2bb4557f373c021832dc10e36b3ea2c91a373385880908c0caa091b6025ce007256576b005dffea9f11f76f90f", + "id": "3057159345035537425", + "senderId": "11261259397990416889L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b39a7a2d4e5fe0fb2a85fc35ae85bfbed5e8e08c45df0a9050157778d77be706", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "fe9e72bba2d0f87c8023cdc3fdc32eba5de9d2bfbd1c03630367dafb9f74ebbf" + } + }, + "signature": "b28a5f66ef902cc7a8fe618c4ee48748fb4696c3e272b21345d6f599f83ebf9ea97e04a34e142921215a5c908da66be9393f6ae6e7dbc26f5da4935c3974d101", + "id": "12938521856466736922", + "senderId": "11261259397990416889L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b39a7a2d4e5fe0fb2a85fc35ae85bfbed5e8e08c45df0a9050157778d77be706", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "crack" + } + }, + "signature": "2989f8a6c5b28f092a2f4433f763c99124c9677db454386dded5e2bcb0a5bd7fbb0698f14ad14bc08002d30531ad9ff020255ed42245b76d8e8a0a3e67f6b70c", + "id": "10357583458445907240", + "senderId": "11261259397990416889L" + }, + { + "amount": "0", + "recipientId": "11261259397990416889L", + "senderPublicKey": "b39a7a2d4e5fe0fb2a85fc35ae85bfbed5e8e08c45df0a9050157778d77be706", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b39a7a2d4e5fe0fb2a85fc35ae85bfbed5e8e08c45df0a9050157778d77be706" + ] + }, + "signature": "8dc45b263b5b9290283f7d023d07dc15eaeca1e93411398ad514a15a00b982e1cb381074fa4590d5331e0ba77e6c78891ac43006a8d643c87a882eaad9628905", + "id": "17282702949471788332", + "senderId": "11261259397990416889L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b39a7a2d4e5fe0fb2a85fc35ae85bfbed5e8e08c45df0a9050157778d77be706", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b39a7a2d4e5fe0fb2a85fc35ae85bfbed5e8e08c45df0a9050157778d77be706", + "+fe9e72bba2d0f87c8023cdc3fdc32eba5de9d2bfbd1c03630367dafb9f74ebbf" + ] + } + }, + "signature": "bc9d6cc634c2a2c8572ae444db9dd87ebfb512d1c9d8216b38bd81e6a0d1a5febfce8fad2365737aa5c0855f2c83c0f6088755ccdbf6e7669c9a8bc0c7dd7407", + "id": "5147469011270218258", + "senderId": "11261259397990416889L" + }, + { + "amount": "1000000", + "recipientId": "1257244595675313090L", + "senderPublicKey": "77d10770940304342a225ac52f82d14f644b7abaf8b73964c72cb9c9cfc79dfc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "11e1505534cd3732d6210300143fa810b8585396366837b4e8f6194cc361f63fad943e727816e6236edee3d8d3dcefa3d81ddf2749731baaf09b2a05e71cdc01", + "id": "2516282868633835178", + "senderId": "1257244595675313090L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "77d10770940304342a225ac52f82d14f644b7abaf8b73964c72cb9c9cfc79dfc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "cfca7c1d1dbf53683b92b1d6848f2546610f83bd65216efbd4f4e06bebe9af7d" + } + }, + "signature": "e319842656a8a446157ea570dab5dea688d136adebbef6efd17bc602383ff44fe33a53d18096191e17df3969a2d7fab2f82db8bb02e3d19a7de242d4bc2a6706", + "id": "11686125193105515444", + "senderId": "1257244595675313090L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "77d10770940304342a225ac52f82d14f644b7abaf8b73964c72cb9c9cfc79dfc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "asset" + } + }, + "signature": "17f6135d6b15169ecc9550c93297ddd0aea55734cc92f89d6fd31362068da6244f9aefad317a87b305c6b49cc2db9b4d4640e1c24bc6d5546aef99e9f124a100", + "id": "315822412242591866", + "senderId": "1257244595675313090L" + }, + { + "amount": "0", + "recipientId": "1257244595675313090L", + "senderPublicKey": "77d10770940304342a225ac52f82d14f644b7abaf8b73964c72cb9c9cfc79dfc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+77d10770940304342a225ac52f82d14f644b7abaf8b73964c72cb9c9cfc79dfc" + ] + }, + "signature": "466ae628cc4eb7fd2330966190221b01f0fb91af1126412583ed443fc69f39bd29fc62903697ed4ceeb8ed5f149166c34d042aa3fc28354129bc42d2d842480d", + "id": "9329524290360756926", + "senderId": "1257244595675313090L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "77d10770940304342a225ac52f82d14f644b7abaf8b73964c72cb9c9cfc79dfc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+77d10770940304342a225ac52f82d14f644b7abaf8b73964c72cb9c9cfc79dfc", + "+cfca7c1d1dbf53683b92b1d6848f2546610f83bd65216efbd4f4e06bebe9af7d" + ] + } + }, + "signature": "9ab0ecdd2103d0004d85e9f2a27f2cd5faee8021b46f26b12a6f686e7722b6ca5c0ac3e5a76b992366d8c33efc8e0c39fca87ebf177782ad4d86e1d1c90c290d", + "id": "11993683750915464196", + "senderId": "1257244595675313090L" + }, + { + "amount": "1000000", + "recipientId": "17023349411286843752L", + "senderPublicKey": "c69fbafbc32a175e9606f2faf317a4ab0f7882fda7e0be13a7ea856aa3273892", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "60c068d45696e8612f168f5e0521832a7484fe54882f7ff11a11ff307b49c4929c968e73357cbbd268bee57637c5bbcbdb6b19753b198829146a0aae1dd58301", + "id": "259840614607419564", + "senderId": "17023349411286843752L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c69fbafbc32a175e9606f2faf317a4ab0f7882fda7e0be13a7ea856aa3273892", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "10cf06675f574414837d2891200cbd7b63a169984faa49eeec5ae965605c46fb" + } + }, + "signature": "ed493004ecb8dc922a06f317c57f8e65c845f47e24c5e497266d71a6b2b1affde77f88893d0f4fb066b003e13e2437fa8ae9d59ca276c1ffec54feacca0d0206", + "id": "6522892831155033461", + "senderId": "17023349411286843752L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c69fbafbc32a175e9606f2faf317a4ab0f7882fda7e0be13a7ea856aa3273892", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "impose" + } + }, + "signature": "51c01eb74b9425acd54e1cab852ac153725b760b8621a2d03a546953d98aae05bf203e2ea556648edab426d6679b492937950415a4be82175a1872dbf7c7aa0e", + "id": "8797330106307485280", + "senderId": "17023349411286843752L" + }, + { + "amount": "0", + "recipientId": "17023349411286843752L", + "senderPublicKey": "c69fbafbc32a175e9606f2faf317a4ab0f7882fda7e0be13a7ea856aa3273892", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c69fbafbc32a175e9606f2faf317a4ab0f7882fda7e0be13a7ea856aa3273892" + ] + }, + "signature": "129e25c812f99db1fe25351f932a6e5706eff7a01b88e6620b471125e2cfa74408f9d7f26d34d79367a1a578a23934dc69a53003759237845bb851682e5d490e", + "id": "5140441344386891402", + "senderId": "17023349411286843752L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c69fbafbc32a175e9606f2faf317a4ab0f7882fda7e0be13a7ea856aa3273892", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c69fbafbc32a175e9606f2faf317a4ab0f7882fda7e0be13a7ea856aa3273892", + "+10cf06675f574414837d2891200cbd7b63a169984faa49eeec5ae965605c46fb" + ] + } + }, + "signature": "91f33946f208a65e07dc00567016029afde636d85870c23a7b8f5787fa17c44f1c306365d54af5633a642b8d3eeab131db4708ead0f2ce70b0c1970c3818040e", + "id": "17619769044445711821", + "senderId": "17023349411286843752L" + }, + { + "amount": "1000000", + "recipientId": "3174290987810788334L", + "senderPublicKey": "746f38653921761a3c86521a3ce7099d3750729e88800068150e12d456f58f40", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "17209ed82f67ef7f0da56b823aee2cc44fc037d939118e47816f6a981b782c3119b37ab0d12d9281aa4893cf77c12cbcd37a7ef5153dfbf7d2b81128da42d806", + "id": "7584452885184064365", + "senderId": "3174290987810788334L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "746f38653921761a3c86521a3ce7099d3750729e88800068150e12d456f58f40", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "492d85bb58eed0921dc3be5009fb94ea8d9f2f5d07ccfa3c6874db527e01925d" + } + }, + "signature": "3ff91ab27e87a9e9e2b57613ca80f1191357bd403a8e5684788a23e29dcd0b81d2865af8dc1c935bb3a7f562bf03b0deb7ae00f431095458b990c2ccc526ac0c", + "id": "12879047180446660742", + "senderId": "3174290987810788334L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "746f38653921761a3c86521a3ce7099d3750729e88800068150e12d456f58f40", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "pull" + } + }, + "signature": "f6c2f37d62e6b3e4aa1386cde307763fe657ca027270791110f40e487654b6e63fcc0620b477c3b36e0c36af7ad9f0e75c436255001a1eeb82b72cfacb82f405", + "id": "10720040152435581790", + "senderId": "3174290987810788334L" + }, + { + "amount": "0", + "recipientId": "3174290987810788334L", + "senderPublicKey": "746f38653921761a3c86521a3ce7099d3750729e88800068150e12d456f58f40", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+746f38653921761a3c86521a3ce7099d3750729e88800068150e12d456f58f40" + ] + }, + "signature": "3992a1ee9e1bdda2b8946576bb1436f940e9187fde371666c70a514cd62f1d9e3423f66669a0280ec0f814063c59c88cb6656d9878b423cbbd33eead87ac800e", + "id": "13915778598117470879", + "senderId": "3174290987810788334L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "746f38653921761a3c86521a3ce7099d3750729e88800068150e12d456f58f40", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+746f38653921761a3c86521a3ce7099d3750729e88800068150e12d456f58f40", + "+492d85bb58eed0921dc3be5009fb94ea8d9f2f5d07ccfa3c6874db527e01925d" + ] + } + }, + "signature": "b529781001cafdb9e83591cdc73d18976bc2ae6cc4900181b3934e2c152900434f13ed2de2366c00c6cc7e36da3644eac6fb70e361b19c4f82e9d62fa93bdd05", + "id": "215619638152521654", + "senderId": "3174290987810788334L" + }, + { + "amount": "1000000", + "recipientId": "13117683447059096710L", + "senderPublicKey": "222f79302bca0e8635c47b35b57be447e5a5028b8258d32644981a64347df1de", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a2b9ff65e5e948c96e955e6be9c4216e25324bdaf9b3b10e0d22f187f2c784e6441f21de970a92d9a829ef6956d927f8aec77b89202a30029852d19160159203", + "id": "13586168265278762691", + "senderId": "13117683447059096710L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "222f79302bca0e8635c47b35b57be447e5a5028b8258d32644981a64347df1de", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "efef68bec17ad93520dd02c9bc6ea568ed9077f0ebbd4550d0bfc0a46582133d" + } + }, + "signature": "b10d91f903fabcb7fc72bf9837bc6f767e7701911144a9346a96cb51768df33196ef3eb61f50c840ce78c21c0d20bd689922f8ea0cfc21812bbe76af2ffe990c", + "id": "16089923796286900562", + "senderId": "13117683447059096710L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "222f79302bca0e8635c47b35b57be447e5a5028b8258d32644981a64347df1de", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "midnight" + } + }, + "signature": "b024bb78602f0ae2804b77963a89e9ac1bc120c66be3fbf806b72b29ba0434faf9e11cf545fcc71d13468db83fa2d54e27aac668c515ea88a88fea1e6c267303", + "id": "360044942458895772", + "senderId": "13117683447059096710L" + }, + { + "amount": "0", + "recipientId": "13117683447059096710L", + "senderPublicKey": "222f79302bca0e8635c47b35b57be447e5a5028b8258d32644981a64347df1de", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+222f79302bca0e8635c47b35b57be447e5a5028b8258d32644981a64347df1de" + ] + }, + "signature": "a3f4853bcc9ff72a25d16c0743f04bc9775fdc07e46e5d62d3c4492b6fbb17cfd567314b6e0b013f5328bbc6bf60629dd148413d250902866d12512440597c0d", + "id": "11173723792103851464", + "senderId": "13117683447059096710L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "222f79302bca0e8635c47b35b57be447e5a5028b8258d32644981a64347df1de", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+222f79302bca0e8635c47b35b57be447e5a5028b8258d32644981a64347df1de", + "+efef68bec17ad93520dd02c9bc6ea568ed9077f0ebbd4550d0bfc0a46582133d" + ] + } + }, + "signature": "ae5fbea63e6c74a009a5999c6384029a3d3bfa16c3d6a7bff0d43595d2e52e7c8324257e5e7bc1b80cfd109700ee02748dcb671710f1286743b6f1dd5ff62108", + "id": "13940883170392831103", + "senderId": "13117683447059096710L" + }, + { + "amount": "1000000", + "recipientId": "10723234683574181708L", + "senderPublicKey": "07e68b72b44478c554490b5e7729170900a7948ab07fa5e75f030ac21f3c6acb", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "4a4c2253e1abd43be3e403ab0d35ce631eda78add78ae5c0d5186f979f914f48e7d36ea0c5e5e2a9bf13b30e68bedbf54cf804c8b076d75b0afcb6dbabfe8908", + "id": "133372264511444196", + "senderId": "10723234683574181708L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07e68b72b44478c554490b5e7729170900a7948ab07fa5e75f030ac21f3c6acb", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "aa2618b4ea81414f2bcd3ead03d33673c2d211870271988192146ff779dec955" + } + }, + "signature": "a5eefa1b3fa69651f5640e332328e4673b120a1659d6bd1fe476e9b3306517e3b4a3180b638dfe598e16d44a9c019155ab59bdf4b52c2f57b012e77db379fd0c", + "id": "17719716936900186363", + "senderId": "10723234683574181708L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07e68b72b44478c554490b5e7729170900a7948ab07fa5e75f030ac21f3c6acb", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "soldier" + } + }, + "signature": "3b2160b6cb56d704fac9816da86502cd1ab8b4baf7ca54e6342d70858e43006ad21871578137109199bc35303f791eed05660e2850d708d32d660514c8073905", + "id": "17807231023722520961", + "senderId": "10723234683574181708L" + }, + { + "amount": "0", + "recipientId": "10723234683574181708L", + "senderPublicKey": "07e68b72b44478c554490b5e7729170900a7948ab07fa5e75f030ac21f3c6acb", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+07e68b72b44478c554490b5e7729170900a7948ab07fa5e75f030ac21f3c6acb" + ] + }, + "signature": "da658b387fae838edc9153ccb32ca23d15bba04247d817fbf278d39240ddb15a25e4eff817774baf848e7dee85b4684520b8458ad649ccbf152ea82bb6a7eb0e", + "id": "14888417727043074975", + "senderId": "10723234683574181708L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07e68b72b44478c554490b5e7729170900a7948ab07fa5e75f030ac21f3c6acb", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+07e68b72b44478c554490b5e7729170900a7948ab07fa5e75f030ac21f3c6acb", + "+aa2618b4ea81414f2bcd3ead03d33673c2d211870271988192146ff779dec955" + ] + } + }, + "signature": "b383f64568f2d7fbe95a44a7e22a8aa22a31869ac0ade6b6e933d2c9f7ad1cf090d080c5214a597bd4d451ca1492a61ad16f3e8bb428d9f62936008a8288c601", + "id": "1297771008576024857", + "senderId": "10723234683574181708L" + }, + { + "amount": "1000000", + "recipientId": "12793954300984313557L", + "senderPublicKey": "ec5923d8db97a9cb11933450fdc491167ae1e68348edc9b37b245588ab3325ee", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "34740b16291ef42fb476867f66bc5ede77b8fa25abca7f625fdf76db17483a39162996f8c1a81685d0bbba50b95965d05bf0aff55b11b5241e32b7d6de524c0b", + "id": "2341119945034338091", + "senderId": "12793954300984313557L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ec5923d8db97a9cb11933450fdc491167ae1e68348edc9b37b245588ab3325ee", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "eb4f777d2ab4e1ebea43ae505be8ee36547c955743ee90eecd598a0262cef098" + } + }, + "signature": "1ce1d2a50609a42fe3b8c7997a805eea9573bbc9cb2b186d20f3c4507a04c26fa415276a509ea370127d9181514626043116cc11784074468439868e54d5730d", + "id": "4624026725675991825", + "senderId": "12793954300984313557L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ec5923d8db97a9cb11933450fdc491167ae1e68348edc9b37b245588ab3325ee", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "salt" + } + }, + "signature": "38757acbaba23e9b15cf39a2740f7ac9759d2ed14281cf6e36c5c68f1eb70fc7e138caa0969f3bac939e405177f0aa54991ec635d8471c9f61a3a2db8813fa05", + "id": "9640512116618830349", + "senderId": "12793954300984313557L" + }, + { + "amount": "0", + "recipientId": "12793954300984313557L", + "senderPublicKey": "ec5923d8db97a9cb11933450fdc491167ae1e68348edc9b37b245588ab3325ee", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+ec5923d8db97a9cb11933450fdc491167ae1e68348edc9b37b245588ab3325ee" + ] + }, + "signature": "95b9e4515df3c1cca5f71823949547d0fd8491c9c717675ce23b1074eaa387653c346b25b2f08d834835d9e6abd31e89d013850ea3f2bf821934ccf83552b005", + "id": "11265661045984448751", + "senderId": "12793954300984313557L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ec5923d8db97a9cb11933450fdc491167ae1e68348edc9b37b245588ab3325ee", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+ec5923d8db97a9cb11933450fdc491167ae1e68348edc9b37b245588ab3325ee", + "+eb4f777d2ab4e1ebea43ae505be8ee36547c955743ee90eecd598a0262cef098" + ] + } + }, + "signature": "d9ac5a52f63a69109d8872f9e052306a1da1908eacdf29cb487daec45ceb3757e0d122eea735624bb93abdef78d8aef5a6ca37a36932d727f19f22b4064dda06", + "id": "17502673086909907275", + "senderId": "12793954300984313557L" + }, + { + "amount": "1000000", + "recipientId": "13274387365904449694L", + "senderPublicKey": "c003576be4a81d06d8ff3ba0c362c5759b9ae65b091d25d6b25f3fac767fa994", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "3230850164348f3e5fb877952d697c201f8723d76cffad2254087f86ac55ea29df2d51385607c1a460ceae9779cff7b3c4411fed6e2d68b615acdf12d4ecac0c", + "id": "9126190512955192768", + "senderId": "13274387365904449694L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c003576be4a81d06d8ff3ba0c362c5759b9ae65b091d25d6b25f3fac767fa994", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "0d18b08bb3283666ed34f92cac75c4a8dbab50b15a0ac46d13369b897ec50c46" + } + }, + "signature": "991e61c273e9cae08b462b6dffc39b1265a1acdc4498abef727ef83f8fd0c6aa53bbdb36352c38681ac34d890f59f77ee20b78e37555f8b10a5285665dfdae00", + "id": "846388247913916770", + "senderId": "13274387365904449694L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c003576be4a81d06d8ff3ba0c362c5759b9ae65b091d25d6b25f3fac767fa994", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "apology" + } + }, + "signature": "244957f1dadf941daf8a55272323b58a259074bdaf9d612f49d5fca1cd2762ad7672ded3232d7e0f53eede9d9151528bd0761fda4784cb4048cdbb021c7d4d04", + "id": "17151888883110734077", + "senderId": "13274387365904449694L" + }, + { + "amount": "0", + "recipientId": "13274387365904449694L", + "senderPublicKey": "c003576be4a81d06d8ff3ba0c362c5759b9ae65b091d25d6b25f3fac767fa994", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c003576be4a81d06d8ff3ba0c362c5759b9ae65b091d25d6b25f3fac767fa994" + ] + }, + "signature": "4d8c1c0fcd906ce74e31835d7572655700ed659cf57fc530702ad750b7b4f243f165d3f2208a9925d0cb0e120007d5996eb93bb83a369f5bdf4b366f84beaf05", + "id": "12066911765653279462", + "senderId": "13274387365904449694L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c003576be4a81d06d8ff3ba0c362c5759b9ae65b091d25d6b25f3fac767fa994", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c003576be4a81d06d8ff3ba0c362c5759b9ae65b091d25d6b25f3fac767fa994", + "+0d18b08bb3283666ed34f92cac75c4a8dbab50b15a0ac46d13369b897ec50c46" + ] + } + }, + "signature": "7f7a43e70545a097e37c113b3e4d140792a967adc58e64b2bf0a2b85ef0a6c70286f08769d0a893ffc22791d29245e6a0b43fa5f8b41b97f4b88292a6894a807", + "id": "3098008353498151215", + "senderId": "13274387365904449694L" + }, + { + "amount": "1000000", + "recipientId": "7049365022267183222L", + "senderPublicKey": "467e86205b8aac13a824bd00cf9f48f469fe0344b577079b2bf35e967e26e680", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "efa04497afff969119ab58022eb046d86d77bfed3e04220cbeebe6bf169b45fd15cb3a676d4c1946e35f2e34edf610aeb8ffc0cf69085a269bdda4836e767905", + "id": "11704669356736634743", + "senderId": "7049365022267183222L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "467e86205b8aac13a824bd00cf9f48f469fe0344b577079b2bf35e967e26e680", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3af129bc5f98b5ceb139943f16fbb5e33dd78189a0103ad8deed95b9fb7387cc" + } + }, + "signature": "13a53b31041fdd10d691eef621e7456fc84b4fb3f36a1d9e6468d64fed93638bfdfd89a7c721d452d14bdea23236fce0175403a0bbcef221b680a068680c1204", + "id": "16713751462256638833", + "senderId": "7049365022267183222L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "467e86205b8aac13a824bd00cf9f48f469fe0344b577079b2bf35e967e26e680", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "strong" + } + }, + "signature": "da5389b54ffa1a6d96b0b99b555ae7060cf48eada4cb43fcab4931188a1988aeb78a3216ab0651c82190036809ed7cd122085e81df69de888edd82db32695d06", + "id": "8805894821939395330", + "senderId": "7049365022267183222L" + }, + { + "amount": "0", + "recipientId": "7049365022267183222L", + "senderPublicKey": "467e86205b8aac13a824bd00cf9f48f469fe0344b577079b2bf35e967e26e680", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+467e86205b8aac13a824bd00cf9f48f469fe0344b577079b2bf35e967e26e680" + ] + }, + "signature": "ca3ef1eb47cd78ccb082f363a0499d65f0e2d4caf40ef29d921dc5f66cb3142b55233e712676eeff4df9b79b247a08121b24ca6e5e23940bde920c3048dda00c", + "id": "7933125175935265565", + "senderId": "7049365022267183222L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "467e86205b8aac13a824bd00cf9f48f469fe0344b577079b2bf35e967e26e680", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+467e86205b8aac13a824bd00cf9f48f469fe0344b577079b2bf35e967e26e680", + "+3af129bc5f98b5ceb139943f16fbb5e33dd78189a0103ad8deed95b9fb7387cc" + ] + } + }, + "signature": "a9d03052548b992284d74a380b722fb1f66ff54bd104994318708113b3ffdf30ce23b5fb23d0ff3093a0c5fdaee1f9c7bf1c38e6716a890e91acd71c04c4080a", + "id": "17318120731661084998", + "senderId": "7049365022267183222L" + }, + { + "amount": "1000000", + "recipientId": "6556421469083094935L", + "senderPublicKey": "e172e5558f6f8a6d68d221b9f4f7355be72b8d952033d943226e070eee4fada7", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "3a58f558ee945ca55fd4e9cd4414dcc23cf065ab366705c271f32637a9245d78d8d2092d7168f6f35e80288a0e7b9207bee2a5657b27cbfa99399f829bcce102", + "id": "6741944457373909143", + "senderId": "6556421469083094935L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e172e5558f6f8a6d68d221b9f4f7355be72b8d952033d943226e070eee4fada7", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "54dcb7152b4e474e5e431f53c938e82c1db80641231b89ec6fdebc5c081975c1" + } + }, + "signature": "029a41ee16939d3bf463e77333503130f9126aeb2a414ee9549d8edb0994a104d386ee0255754d4e9df2bec36e8a6059946b900df6d3f58c2e46fbe48ab80c04", + "id": "17700609028744981146", + "senderId": "6556421469083094935L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e172e5558f6f8a6d68d221b9f4f7355be72b8d952033d943226e070eee4fada7", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "tackle" + } + }, + "signature": "d63e8b749ccd87c71a5b6c5fe5180aae36a824a3b60b54949639b15980c15a4e55672c27db424f23fcf29b16a0c2a053d48696b93907aa4bffe085ccf5825608", + "id": "12091518790454648570", + "senderId": "6556421469083094935L" + }, + { + "amount": "0", + "recipientId": "6556421469083094935L", + "senderPublicKey": "e172e5558f6f8a6d68d221b9f4f7355be72b8d952033d943226e070eee4fada7", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+e172e5558f6f8a6d68d221b9f4f7355be72b8d952033d943226e070eee4fada7" + ] + }, + "signature": "d7ed1038849165aa0dacee3acfe100941f51e52ab504ea2c7fceedb9591a2225cb4bc62716b2fc2dc7a8211dd6b955cad9fa0c4e36c863660aed1c2f5c5c340a", + "id": "8993787755600143006", + "senderId": "6556421469083094935L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e172e5558f6f8a6d68d221b9f4f7355be72b8d952033d943226e070eee4fada7", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e172e5558f6f8a6d68d221b9f4f7355be72b8d952033d943226e070eee4fada7", + "+54dcb7152b4e474e5e431f53c938e82c1db80641231b89ec6fdebc5c081975c1" + ] + } + }, + "signature": "1fe55e5837cedadab01097246f04ed31683f9fc5693d09370ab1826aadfff199b29b90d7ef26884692920fa0babce9d3787175a7f805d16b8d28371e4a2b2006", + "id": "5354040428534277044", + "senderId": "6556421469083094935L" + }, + { + "amount": "1000000", + "recipientId": "12436360500510125013L", + "senderPublicKey": "4ed5d92ad9fe266786034af4a1d53c7d9cf137d3ef14cd4d1f96883aecacc6bc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "d933bd183e56f083613d6b176dcf8d460c87e319012e5c58d4708c8591f742d87ec171a47000ad52905201315691fa93e50c90101ba4466bcde6106e95b0910c", + "id": "1825760563495927452", + "senderId": "12436360500510125013L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4ed5d92ad9fe266786034af4a1d53c7d9cf137d3ef14cd4d1f96883aecacc6bc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "5305abf596b5b90e2b3cde2b0ec8ccf0e6d0a25ded1f7e7027f2aa9d2f0a825e" + } + }, + "signature": "5e6c2e01d819d7759f6adcc7d5e4a261f128c449a5be52520e49d14b4b6519591b549c3ad85a373c6fae06ed1d867bb58d1fb8ca7c147276426b01ae4562f30b", + "id": "694572139812591010", + "senderId": "12436360500510125013L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4ed5d92ad9fe266786034af4a1d53c7d9cf137d3ef14cd4d1f96883aecacc6bc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "toward" + } + }, + "signature": "151d7538a86d7d70caef4830110b2bea2d52f5cede7161dfa054991a30ac39b4112bda0bb168c35e5b0b461b8aa5153b803d785d9f188aa84ff9854f8bf03f00", + "id": "7537868861759437273", + "senderId": "12436360500510125013L" + }, + { + "amount": "0", + "recipientId": "12436360500510125013L", + "senderPublicKey": "4ed5d92ad9fe266786034af4a1d53c7d9cf137d3ef14cd4d1f96883aecacc6bc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+4ed5d92ad9fe266786034af4a1d53c7d9cf137d3ef14cd4d1f96883aecacc6bc" + ] + }, + "signature": "75fa49b514e85379460e456b948f42b7243bbd7084474488204efa81908049c5ee29879d2c326fb73251e5b1dae784091dc8e2cf22c0ce56bbff861bfee12e0e", + "id": "503394875511305363", + "senderId": "12436360500510125013L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4ed5d92ad9fe266786034af4a1d53c7d9cf137d3ef14cd4d1f96883aecacc6bc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+4ed5d92ad9fe266786034af4a1d53c7d9cf137d3ef14cd4d1f96883aecacc6bc", + "+5305abf596b5b90e2b3cde2b0ec8ccf0e6d0a25ded1f7e7027f2aa9d2f0a825e" + ] + } + }, + "signature": "fa951d204a274b45b94de0680784cab611a563d2c355f0757d2cfe651a7e657c2d8a35aded1a5c8a6101678653f872abc96ad923a8480128b2eef9c73dccea03", + "id": "6377957623283943595", + "senderId": "12436360500510125013L" + }, + { + "amount": "1000000", + "recipientId": "9558693083952885061L", + "senderPublicKey": "f42eeab0a5244787c671372522470a47f721be40bbfeebc30ce7e0492233ba21", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a08b89dabeccb6b3cdb8adf277a79787a444130f88b3a106cca1534a617fce995374f5cd8314d25efc383097e6650dcf4e43f72993ccffe6d056a2e6acac0701", + "id": "17552588457505465373", + "senderId": "9558693083952885061L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f42eeab0a5244787c671372522470a47f721be40bbfeebc30ce7e0492233ba21", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "5a9d94370cffa18f0bf8a752d46d3755e14e5eab325b1aa78875fd1de6d11f0c" + } + }, + "signature": "2b6279b2d891d4d592b7185788dc75df2cce2f40d35e2c70a78dc3bb8349015aab663f82bfb314d84a75b7ae740ce19ebd04fea42717378a074964d711e2460b", + "id": "10803553506091632686", + "senderId": "9558693083952885061L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f42eeab0a5244787c671372522470a47f721be40bbfeebc30ce7e0492233ba21", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "load" + } + }, + "signature": "b62044ab1c5c22fc8bbb065a90968f4a789bc272fb74c9c342d1fb9a84d045534376a00a2a163357ac1708566256d9a3639f284182882931192e585ca97f060c", + "id": "18348667487736387269", + "senderId": "9558693083952885061L" + }, + { + "amount": "0", + "recipientId": "9558693083952885061L", + "senderPublicKey": "f42eeab0a5244787c671372522470a47f721be40bbfeebc30ce7e0492233ba21", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f42eeab0a5244787c671372522470a47f721be40bbfeebc30ce7e0492233ba21" + ] + }, + "signature": "d991921c9f574a4f522e01d8ca5f35f68c515b46d394af72e1f6b70ff985742fb9762e04ed966d048bcc485fd0c619f6b53b1da344e02c105606d43081a88202", + "id": "4469592391605118138", + "senderId": "9558693083952885061L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f42eeab0a5244787c671372522470a47f721be40bbfeebc30ce7e0492233ba21", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f42eeab0a5244787c671372522470a47f721be40bbfeebc30ce7e0492233ba21", + "+5a9d94370cffa18f0bf8a752d46d3755e14e5eab325b1aa78875fd1de6d11f0c" + ] + } + }, + "signature": "e064357640d58ef6eeff386f5cbe15fe6344e849f9a9f9912c79c0b56a5a18a773c357570b2f34bebfe7a82bdad9323c6f443411cf48c89494dbfb73c41fda07", + "id": "16427366277517720436", + "senderId": "9558693083952885061L" + }, + { + "amount": "1000000", + "recipientId": "3138991761615412204L", + "senderPublicKey": "a0d22e4809586cfacc42c802fa60b8dac04fef6e80734078d4bcce8602b2fffb", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "291ad6bbde62298adcadb84539b2053d389b0390eee48dfbfe2c2ddc39c8d8aa4793292ac07b4180ec66860c7d7ec8b8c7e6cf0a79f3fe4ac57a78330b18d004", + "id": "5784156344253866614", + "senderId": "3138991761615412204L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a0d22e4809586cfacc42c802fa60b8dac04fef6e80734078d4bcce8602b2fffb", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "cfa3fa2062f791a2585a631d1c872bc65a7995ee6b42424d3dcb3aabf7288592" + } + }, + "signature": "a512cc48c201246713c4f99c663938f7a9578af9cf8296db827e5beaa60ff1d474f8ba0908dc60c8ddce4dcda3020e391757c6cc10257e2ddb396b30260bd50d", + "id": "8835043146094391126", + "senderId": "3138991761615412204L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a0d22e4809586cfacc42c802fa60b8dac04fef6e80734078d4bcce8602b2fffb", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "inmate" + } + }, + "signature": "34e5eb6a602f27f0a971aec917f20b67ef9d2cdaa3a429403129370b6adf84fe9bef034315fb86537d446b1c55c2297b4e3e7fb3877c81d39ec55bbc6899dd02", + "id": "12621809999546983357", + "senderId": "3138991761615412204L" + }, + { + "amount": "0", + "recipientId": "3138991761615412204L", + "senderPublicKey": "a0d22e4809586cfacc42c802fa60b8dac04fef6e80734078d4bcce8602b2fffb", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a0d22e4809586cfacc42c802fa60b8dac04fef6e80734078d4bcce8602b2fffb" + ] + }, + "signature": "db2985dfbb3049fad969555346c5dae14b8f96ff1c2106f5e87e2506c3f92fe10397a6326a8d5ba9ec9fb2332a2781e45cac3fbf836a55bd2e767a40a476a003", + "id": "9787102896215516919", + "senderId": "3138991761615412204L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a0d22e4809586cfacc42c802fa60b8dac04fef6e80734078d4bcce8602b2fffb", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a0d22e4809586cfacc42c802fa60b8dac04fef6e80734078d4bcce8602b2fffb", + "+cfa3fa2062f791a2585a631d1c872bc65a7995ee6b42424d3dcb3aabf7288592" + ] + } + }, + "signature": "04db8fe8f45df43d0f19d6584e2858761eb0b4bba695d43f36858cf02f4f54f7f8917ab74d612ad8da64fc7af33467cb71be011f2285e3116decbb790ee61b04", + "id": "6464157020799189823", + "senderId": "3138991761615412204L" + }, + { + "amount": "1000000", + "recipientId": "15714118231328580921L", + "senderPublicKey": "bf69eea92f575c5acba52ebea89200cfcd71e4a22f376518b1569c00e11acf1e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ec981922297dab06338694ae1d7dba15f9dab230734e6058e092178b27d3e6076d87b96ffb3c26a64d523316259495da0ce62ec402db93c99dada6f2fbc9f505", + "id": "12968236262339979035", + "senderId": "15714118231328580921L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bf69eea92f575c5acba52ebea89200cfcd71e4a22f376518b1569c00e11acf1e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "6c2a4158da52539ce0ab173957e11d487b83caeaff3110325a744b8beeebd85f" + } + }, + "signature": "438a1d49671acf3334904465a7d5245d1ca4e15d57364a26feeed86bb82c4456167ea23f2848209a650fa7c6c01d68dda5423d633d32f949ab53e9a6e7feb103", + "id": "13769727312397332311", + "senderId": "15714118231328580921L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bf69eea92f575c5acba52ebea89200cfcd71e4a22f376518b1569c00e11acf1e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "laugh" + } + }, + "signature": "e10b63b4374b76c6a6111be69dcd609ace2c27196863932ff5fcf71c9cd8e86b653439b4f883a984535705bf1f43aa42b14e43a146a2d80dbd4a69b39a659e0a", + "id": "116190458742741138", + "senderId": "15714118231328580921L" + }, + { + "amount": "0", + "recipientId": "15714118231328580921L", + "senderPublicKey": "bf69eea92f575c5acba52ebea89200cfcd71e4a22f376518b1569c00e11acf1e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+bf69eea92f575c5acba52ebea89200cfcd71e4a22f376518b1569c00e11acf1e" + ] + }, + "signature": "2594a082d2e40cbf168553be097aa2078d9df59bf8469cbb35d102d7c54c14303a065fd57247f2bef5ee6197ccc79ae15a1c2b6f1b77a3bf5126826b9e50a20c", + "id": "401261709476916868", + "senderId": "15714118231328580921L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bf69eea92f575c5acba52ebea89200cfcd71e4a22f376518b1569c00e11acf1e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+bf69eea92f575c5acba52ebea89200cfcd71e4a22f376518b1569c00e11acf1e", + "+6c2a4158da52539ce0ab173957e11d487b83caeaff3110325a744b8beeebd85f" + ] + } + }, + "signature": "f9eaadeb7f4f3364123d3626d6c81c874628c6d126eb835407de769c52ff173161e3d6daf243c937c03b51f9ae8b806ad41670189e1d75729bcda004a957f30d", + "id": "13981030649314971089", + "senderId": "15714118231328580921L" + }, + { + "amount": "1000000", + "recipientId": "16427464421488253629L", + "senderPublicKey": "93fa6da4b06bc7082f825fc188820daa642f874ecc2149dc8641ec9ddb016415", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "00fa41304d87507120dc083561548e646cb3627afc53838f7cdebe7dc090572556df283b701ddbe3d259a161645b0fad62e811a26d6ea8c1591d1b6412ed1e08", + "id": "8164061309007530209", + "senderId": "16427464421488253629L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "93fa6da4b06bc7082f825fc188820daa642f874ecc2149dc8641ec9ddb016415", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9851360cd0aa8874a060ab22ec62003430d4c53ae973907ba62f68dd75543d1c" + } + }, + "signature": "f1f360fec9e8a310eb5957bff2da8e68563b4813218eae2a51ee2459f130ef890e2074bbe2e8313952e5ce12716aea01092ab32f62588effc6389d10425d4d01", + "id": "10294978878960770063", + "senderId": "16427464421488253629L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "93fa6da4b06bc7082f825fc188820daa642f874ecc2149dc8641ec9ddb016415", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "valid" + } + }, + "signature": "604110b6e56a0b56f660a0b2083bc187df3502e2309b1f6661369f112e233cb8df25b49c8b5031cd86c33074ffd85e150c1a8528c55cda9e83e7773222e6340c", + "id": "6227171272918058795", + "senderId": "16427464421488253629L" + }, + { + "amount": "0", + "recipientId": "16427464421488253629L", + "senderPublicKey": "93fa6da4b06bc7082f825fc188820daa642f874ecc2149dc8641ec9ddb016415", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+93fa6da4b06bc7082f825fc188820daa642f874ecc2149dc8641ec9ddb016415" + ] + }, + "signature": "b0d84a7a53a11869b42645fa8e612fab650046ee0aedb1213f01a0e5b4ceb662a737b2728dd483fa58cba7d0061a02b564530a3007509670f11d6da4e5d8a807", + "id": "1477490982740469806", + "senderId": "16427464421488253629L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "93fa6da4b06bc7082f825fc188820daa642f874ecc2149dc8641ec9ddb016415", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+93fa6da4b06bc7082f825fc188820daa642f874ecc2149dc8641ec9ddb016415", + "+9851360cd0aa8874a060ab22ec62003430d4c53ae973907ba62f68dd75543d1c" + ] + } + }, + "signature": "563be0688f7e713a1eed5ea3511441f2e927fadd9280a7d0f5f295855ce48e569e73a8eb63cb9f554cef0226f779385bc156b06f3bebce149804057bba52030e", + "id": "7560395334298563183", + "senderId": "16427464421488253629L" + }, + { + "amount": "1000000", + "recipientId": "5526525089372276814L", + "senderPublicKey": "5eaea299ffecc2292d9d30ee924566774954bddbfd48b2b725ed733325fc966c", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "db588c5d7a3e181758c587534cd4e6bc91db74517de5e6c65db0dd480a75443ea7986d09f68174b9ad0773f92e8f23d6d4589026c8b62aaeacc50d3dd49b0209", + "id": "18381391676699476865", + "senderId": "5526525089372276814L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5eaea299ffecc2292d9d30ee924566774954bddbfd48b2b725ed733325fc966c", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4b8898b906210a5e30cfdedc02e7bae131fe7614c9f25658bbb57a038f088162" + } + }, + "signature": "0e54673b777b88509632ee0cd7884315fd19a7b2d3fda1d6f312f479c98a4afd1b9a82ca59e10b360c50711df1157a1a4fe49ee103a6be68b749b0cb7e91f20d", + "id": "10504034731014122876", + "senderId": "5526525089372276814L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5eaea299ffecc2292d9d30ee924566774954bddbfd48b2b725ed733325fc966c", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "sing" + } + }, + "signature": "c05e75eb416c9c72c7daee0833d82f4b700274e3801b2f442d9e7914653576f34531b23c6487e4e1e32e23b64579bd29cf66c5615769a05ad3685f437916b001", + "id": "17804573482811057124", + "senderId": "5526525089372276814L" + }, + { + "amount": "0", + "recipientId": "5526525089372276814L", + "senderPublicKey": "5eaea299ffecc2292d9d30ee924566774954bddbfd48b2b725ed733325fc966c", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5eaea299ffecc2292d9d30ee924566774954bddbfd48b2b725ed733325fc966c" + ] + }, + "signature": "ce7de05e0a643e48558764b7c571c0fbe667a37d9182168624d8cfe9712e4fc6ea68d82e59a3e8ca57073254da588f4fe7faf656696dfcadc0e4c0c3921de305", + "id": "11389191096495577045", + "senderId": "5526525089372276814L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5eaea299ffecc2292d9d30ee924566774954bddbfd48b2b725ed733325fc966c", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5eaea299ffecc2292d9d30ee924566774954bddbfd48b2b725ed733325fc966c", + "+4b8898b906210a5e30cfdedc02e7bae131fe7614c9f25658bbb57a038f088162" + ] + } + }, + "signature": "1131a026bdbec51adc30f0938677ae1eabed93dc11137d0e702cb3f8f65a24b2844db32824709792d7bce97be03641015fa2a2e981038a38e2b2cba35843c00e", + "id": "4440398931006415537", + "senderId": "5526525089372276814L" + }, + { + "amount": "1000000", + "recipientId": "7721246606053221973L", + "senderPublicKey": "cd833691bc237fd06a49248d23fc8f9f2255fda4121eaa13b40e633704b4044d", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "0bdc051133844a2b01d9b185629a49bedaca1a408cb87c355be763f6038abb7e067d678489fb76d10eb92da6955e9b05eca8049584a22decbbc5fd652d9bb303", + "id": "2734271861626236146", + "senderId": "7721246606053221973L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "cd833691bc237fd06a49248d23fc8f9f2255fda4121eaa13b40e633704b4044d", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e610e0a3bfcfee838067c1a482c1b4831c22b3380265f539fd274e9d1fac7130" + } + }, + "signature": "5aa96cfe42733e6174f777b925e42c0f3f7a216c3ef175e1cddeec89358455249e9332a174773442f26700c8a0c3a6f8508062edf5c0d262a01372d600577606", + "id": "3822565725337864529", + "senderId": "7721246606053221973L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "cd833691bc237fd06a49248d23fc8f9f2255fda4121eaa13b40e633704b4044d", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "glue" + } + }, + "signature": "9a30973c75b20b81d10c6f9f2479bb34961446cc94a4252e3b1f550ca0834addf5786fa48ff83d22ce182ab909b86f6fdf72e961fc683eed0c995eca219d1609", + "id": "6810851216698425411", + "senderId": "7721246606053221973L" + }, + { + "amount": "0", + "recipientId": "7721246606053221973L", + "senderPublicKey": "cd833691bc237fd06a49248d23fc8f9f2255fda4121eaa13b40e633704b4044d", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+cd833691bc237fd06a49248d23fc8f9f2255fda4121eaa13b40e633704b4044d" + ] + }, + "signature": "a017884bad958dc0c11b6d2ffd57f8c053dd8e174c5163d7b632ccb9b362864c26b58c5b6fe90893ef195ed171265c97555badd1c2be85fa170527ff38871d0b", + "id": "609331688560980888", + "senderId": "7721246606053221973L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "cd833691bc237fd06a49248d23fc8f9f2255fda4121eaa13b40e633704b4044d", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+cd833691bc237fd06a49248d23fc8f9f2255fda4121eaa13b40e633704b4044d", + "+e610e0a3bfcfee838067c1a482c1b4831c22b3380265f539fd274e9d1fac7130" + ] + } + }, + "signature": "38da33f312f0776caa96e2040c1a735c2ab3cd652d6c605df1f7f1dc95040b965fb584f4ec71edc49da76c0d533af43f6aecb94ac40bbff95272b31358b8960b", + "id": "295140172843167583", + "senderId": "7721246606053221973L" + }, + { + "amount": "1000000", + "recipientId": "6582134679736962294L", + "senderPublicKey": "dccbf25d59074855d8f226b1c9bce5764684b88bebb2e97bb5f4c90d7aa2f7c8", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a0a9b46e58b0bb6eb5c60a1584b92ac5917cd56780f762414fcea35adedf7cf1cc67f8709d45cfff3f0d647bea6008550c92b9ed1ff52d245fe647bbb0bb7a0e", + "id": "7218414343461573487", + "senderId": "6582134679736962294L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dccbf25d59074855d8f226b1c9bce5764684b88bebb2e97bb5f4c90d7aa2f7c8", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d26e0d02952bfabad0d2a84a1f37c2abba2490955c71a507a7b049125fdbcf7e" + } + }, + "signature": "32f638e1e4086eff92c97a292c8f00c7b0504abc0ce9f40b0414d13a82225f874dd4ff295a6dc65e441c641366c76bd165f9e32dcb07ff349d93dbec41710103", + "id": "15802983768757082646", + "senderId": "6582134679736962294L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dccbf25d59074855d8f226b1c9bce5764684b88bebb2e97bb5f4c90d7aa2f7c8", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "gravity" + } + }, + "signature": "7bb36ee0f7533d9adabddb15c26f87a921bca68adceefacb14895fc2aadecefa78ac30ac94eb53614b3f9a871cdbca1f8a97c724101f8a9a58f03085e07f8306", + "id": "15921908508100059919", + "senderId": "6582134679736962294L" + }, + { + "amount": "0", + "recipientId": "6582134679736962294L", + "senderPublicKey": "dccbf25d59074855d8f226b1c9bce5764684b88bebb2e97bb5f4c90d7aa2f7c8", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+dccbf25d59074855d8f226b1c9bce5764684b88bebb2e97bb5f4c90d7aa2f7c8" + ] + }, + "signature": "63011be74e031f7a7bbc5f884d8f18eca7bc07dc89d7fccd72e9912e8b0500f14a5345c204919e9d99e99045d2bd1be28ed8bf74232bda15b21110fa2a5c5b07", + "id": "2326334984714520614", + "senderId": "6582134679736962294L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dccbf25d59074855d8f226b1c9bce5764684b88bebb2e97bb5f4c90d7aa2f7c8", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+dccbf25d59074855d8f226b1c9bce5764684b88bebb2e97bb5f4c90d7aa2f7c8", + "+d26e0d02952bfabad0d2a84a1f37c2abba2490955c71a507a7b049125fdbcf7e" + ] + } + }, + "signature": "d79404e0c8bf46ee50f0f5dc67cc52cd43cdc91bef19172278b1f2ec081b2f23721885082497a3e724a9831b747e1149c9a6eefebc6a7f44741822f5e9a1f90a", + "id": "2016872609649074439", + "senderId": "6582134679736962294L" + }, + { + "amount": "1000000", + "recipientId": "6313168133983998307L", + "senderPublicKey": "28bc9f8406c08f37313df4ec87519099120368dee910e3fbd3aa3a11b1208423", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "6509571a02de30b2e495ed23ca2385a7c70b283b2507ba3c0e3437e47ef21186c08736da0d4dde0e9d77095b41e1d9a1ba7b0b77953aca8d11b04d4bbdcc1609", + "id": "9153409738225539342", + "senderId": "6313168133983998307L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "28bc9f8406c08f37313df4ec87519099120368dee910e3fbd3aa3a11b1208423", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "b10e284dea8cdd6046f36aa72f8ee0acf55515e0d4fc92e7526029be92a82a87" + } + }, + "signature": "86a26b06983f990594dcc9b3a010ca50db207576540672a5cf2fd0428e3a9629071f73ad916c32c4efaa531a3188e6a8a01059ceafd4ee5824307039b7403a03", + "id": "9678783726688496030", + "senderId": "6313168133983998307L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "28bc9f8406c08f37313df4ec87519099120368dee910e3fbd3aa3a11b1208423", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "fury" + } + }, + "signature": "944b7954aac004d819ddbc3415c159432c59c0e6c8c633a03bdc407ed7f15766ef0ebef8fe8f778c73b33f0beab764a340361e21fccdeeb81ac33c93c9c2de0b", + "id": "5932952094431762143", + "senderId": "6313168133983998307L" + }, + { + "amount": "0", + "recipientId": "6313168133983998307L", + "senderPublicKey": "28bc9f8406c08f37313df4ec87519099120368dee910e3fbd3aa3a11b1208423", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+28bc9f8406c08f37313df4ec87519099120368dee910e3fbd3aa3a11b1208423" + ] + }, + "signature": "0521ed70aea485d67b2c70cef574a306ca07f6a65df47a7ac542dba09d91c28a8bbc3417fa3edc3a2fd962f719a2d966e06efc604ceb11b364938853a1da3c02", + "id": "16179020097420624683", + "senderId": "6313168133983998307L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "28bc9f8406c08f37313df4ec87519099120368dee910e3fbd3aa3a11b1208423", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+28bc9f8406c08f37313df4ec87519099120368dee910e3fbd3aa3a11b1208423", + "+b10e284dea8cdd6046f36aa72f8ee0acf55515e0d4fc92e7526029be92a82a87" + ] + } + }, + "signature": "b81b997ca29f00a44e04ad999b839b11da9976049dfb69854d1aa302333ad92c38b484545629a2161359ff55bc685cde6c2ac999a6335a3085fcb712f34c1303", + "id": "4644489214775113774", + "senderId": "6313168133983998307L" + }, + { + "amount": "1000000", + "recipientId": "8586968180834075423L", + "senderPublicKey": "07a5284e47b57d4162cd7e2b15c8bea3fe18426270497c6ac7c7d505269f79ca", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "18882e088e123ed991ac25aaa8d574d43bb058d1320ffc38f7f150445b661e801ef68f95e9daf36c76e637ee1140689a89043039870876143f23499494e67c0e", + "id": "8417077573571539229", + "senderId": "8586968180834075423L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07a5284e47b57d4162cd7e2b15c8bea3fe18426270497c6ac7c7d505269f79ca", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "6f7ecb8a9ab0dd9d5ae8559b632fce108ae058d54acaedf5c008a7ca243b7d35" + } + }, + "signature": "c0467cb8a2d9c338d23530f895d94dc5d38335f745a50b9f43ed4c2a0fdb755b55babcdbeefbbb4782cf97c837ee8b808b3d334a1dab92de57d48ec62bd50b0a", + "id": "17969812961108131692", + "senderId": "8586968180834075423L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07a5284e47b57d4162cd7e2b15c8bea3fe18426270497c6ac7c7d505269f79ca", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "stay" + } + }, + "signature": "820294b7116acf74144f76ca064b79e1de448b504308f9b504154dfad0aab46ab320718486e7e99bb2d8b5ccb5f9beb481e39a35a0b84cb2285b95b2d715aa0b", + "id": "11076287120421182655", + "senderId": "8586968180834075423L" + }, + { + "amount": "0", + "recipientId": "8586968180834075423L", + "senderPublicKey": "07a5284e47b57d4162cd7e2b15c8bea3fe18426270497c6ac7c7d505269f79ca", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+07a5284e47b57d4162cd7e2b15c8bea3fe18426270497c6ac7c7d505269f79ca" + ] + }, + "signature": "dff118dc310fa6d7a86aaa5400da07f8d3d873231bd5f488648e088123baafe27f244edee62d540ff8ca6205bf705e63c5d529c2c05c61aac7a05da359d5690a", + "id": "7098843707873975794", + "senderId": "8586968180834075423L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07a5284e47b57d4162cd7e2b15c8bea3fe18426270497c6ac7c7d505269f79ca", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+07a5284e47b57d4162cd7e2b15c8bea3fe18426270497c6ac7c7d505269f79ca", + "+6f7ecb8a9ab0dd9d5ae8559b632fce108ae058d54acaedf5c008a7ca243b7d35" + ] + } + }, + "signature": "be5b9e22f1cce8c0e4f300c07240d5d024b3fac3fa6fca15acbb61ff95fb610995c76d806016d236565dedb4bbf429e28df7c75c191feb2931c7fd79694c060f", + "id": "17428294824419198718", + "senderId": "8586968180834075423L" + }, + { + "amount": "1000000", + "recipientId": "17403211532547585358L", + "senderPublicKey": "52a2cf39e31454a9adeee343d01af8ca3ac3f21d6d8a918d7505a77b2f4839f3", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "18218fd09bdd987f9d79481704feec5378b45a4bc62cb340f66bb2c92a400c4363584e56a95fc3539217d9e639dfb2bb206e1d0abb016fd57701d20148026e0b", + "id": "1901072478027765607", + "senderId": "17403211532547585358L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "52a2cf39e31454a9adeee343d01af8ca3ac3f21d6d8a918d7505a77b2f4839f3", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "437b3435d88d95a0ebe6e34f9bea70cea9d2e1f633c562241d2a8f508e911d15" + } + }, + "signature": "93e414d3975a4164c2d5856be87bcfb281dd7d9b07d3f8300ee87a5a7740a7adacdbf81ada726305a5e958acb57db8fc4353f2c7da570c83ad1dfd646c4c0605", + "id": "13783966373782287638", + "senderId": "17403211532547585358L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "52a2cf39e31454a9adeee343d01af8ca3ac3f21d6d8a918d7505a77b2f4839f3", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "side" + } + }, + "signature": "d7f17aa4561086a2724150c811630272793bb3a8c9103f857f261f3a2bebbe17e38058ee8a2e08f23d231ddc974cf36c1d2c99cbd93da844a6923be85b246403", + "id": "6900442070317122739", + "senderId": "17403211532547585358L" + }, + { + "amount": "0", + "recipientId": "17403211532547585358L", + "senderPublicKey": "52a2cf39e31454a9adeee343d01af8ca3ac3f21d6d8a918d7505a77b2f4839f3", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+52a2cf39e31454a9adeee343d01af8ca3ac3f21d6d8a918d7505a77b2f4839f3" + ] + }, + "signature": "1953b141c513ad076c1987c53ff77376d5e8a53a4f41f1792c327623acf5c6be9277d53b9327f48df42cd8754fa400751f70ddab1dfeb3ba748dbd06e6fe870b", + "id": "8020706995568901547", + "senderId": "17403211532547585358L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "52a2cf39e31454a9adeee343d01af8ca3ac3f21d6d8a918d7505a77b2f4839f3", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+52a2cf39e31454a9adeee343d01af8ca3ac3f21d6d8a918d7505a77b2f4839f3", + "+437b3435d88d95a0ebe6e34f9bea70cea9d2e1f633c562241d2a8f508e911d15" + ] + } + }, + "signature": "40eab30de5f2a7f20772cc69a9f197a0be31f3d2d8945e6ece1602776da00e2950bba1fea7d311f7a50ff1e3f3cbb8a0fcd75b402a3a04ca373bb9263bd6fa0e", + "id": "17682304633278527943", + "senderId": "17403211532547585358L" + }, + { + "amount": "1000000", + "recipientId": "5679258470572642769L", + "senderPublicKey": "3784aca9e387484872a172ffa990f268e533823cea6b439d7d08eb083de1d2ac", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "45e375cac2fbcb6f7314e59c4a567d3cde25cb3675b7f2c098e03cc9af532439c0ffeff4b2b89eaa5e7b94d1aaad9ead6279c3a1dc0b68ac75c3ae9bfe010804", + "id": "7451538758316923779", + "senderId": "5679258470572642769L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3784aca9e387484872a172ffa990f268e533823cea6b439d7d08eb083de1d2ac", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "718019baaf66f81da6425317e4aa8dfcf0480dfdf51a383d33a27bcf50104d58" + } + }, + "signature": "902dbdecd27431d4318b7e3ab182375e7f8e12d34a98866d0ea57dbaa166f170ac772beb0d0a28220bee12e64b46aaf85676f8801891d44d5f8a50ac4ae8e007", + "id": "293430345673101657", + "senderId": "5679258470572642769L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3784aca9e387484872a172ffa990f268e533823cea6b439d7d08eb083de1d2ac", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "rule" + } + }, + "signature": "f356451d3dc6792652f2d550b5fa5744cea961f49f1dcdc2a1d445b585e9b35443d8cab8d621d172fc2263490b2e21924f044444c8bc534c28f652105d3a2f09", + "id": "8331782250202662241", + "senderId": "5679258470572642769L" + }, + { + "amount": "0", + "recipientId": "5679258470572642769L", + "senderPublicKey": "3784aca9e387484872a172ffa990f268e533823cea6b439d7d08eb083de1d2ac", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+3784aca9e387484872a172ffa990f268e533823cea6b439d7d08eb083de1d2ac" + ] + }, + "signature": "08a2b82ed0e489f5ae7e2d0b60a8934a250993da6fa4297c6b766a3cd79eeb64a2811069a8eda5c5bb20db28821296689096a6585bde27916c13295a238bf200", + "id": "16195103923701967337", + "senderId": "5679258470572642769L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3784aca9e387484872a172ffa990f268e533823cea6b439d7d08eb083de1d2ac", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+3784aca9e387484872a172ffa990f268e533823cea6b439d7d08eb083de1d2ac", + "+718019baaf66f81da6425317e4aa8dfcf0480dfdf51a383d33a27bcf50104d58" + ] + } + }, + "signature": "f496b6a864166fe9cc1b92fd01aa3c2f89ec35b54179694ee379896d93719cd6942796a1c05e7a53782c153f957f31d63e8c5c88c34f3124ef2620b0bcb15f09", + "id": "14856594774399058710", + "senderId": "5679258470572642769L" + }, + { + "amount": "1000000", + "recipientId": "3972333673817467832L", + "senderPublicKey": "642abfcd8f699dfdff65a41980dd198555fbeb2a12eb13ef5b158e970dc79141", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "c2501dd37cadaa92a0fb9b4d1d191e5eb3d20ebb5a4258d261f6f167f4632466a754deb4d995dfc7c8a440aa608a657f94c4056d2306c9ae99c966ac27f06f01", + "id": "5799082646070630366", + "senderId": "3972333673817467832L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "642abfcd8f699dfdff65a41980dd198555fbeb2a12eb13ef5b158e970dc79141", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d8f03b73710f62e8abe321813907d08bb61bcefb6f424f665bea17bb36824195" + } + }, + "signature": "2448e5ff5ff206c28f19b6ae9424c4ca50c9efcfe74bafdaecd61284a5709cdcdd332c5fe79930df7db5d4dc8a8820511ce51e258c693d5168fe7f287d4b070d", + "id": "187152140951820102", + "senderId": "3972333673817467832L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "642abfcd8f699dfdff65a41980dd198555fbeb2a12eb13ef5b158e970dc79141", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "shield" + } + }, + "signature": "4b27fee2b5e7906fa9d9f6615698dc81fa78d316d5574c669b046202380225501ae9f96609448272888b179a6d4748e45db01838189e6a362fdc36f19fd8640e", + "id": "14379901542778370234", + "senderId": "3972333673817467832L" + }, + { + "amount": "0", + "recipientId": "3972333673817467832L", + "senderPublicKey": "642abfcd8f699dfdff65a41980dd198555fbeb2a12eb13ef5b158e970dc79141", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+642abfcd8f699dfdff65a41980dd198555fbeb2a12eb13ef5b158e970dc79141" + ] + }, + "signature": "ab3f1779be683e6aa54d6a6864bfc8dc54b3a873d125a500d7713014c2e318eda051fa6cd37a07b895e6d558e924d36ccc6f3c56361e58083cc16db7eff55603", + "id": "15502268053763467147", + "senderId": "3972333673817467832L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "642abfcd8f699dfdff65a41980dd198555fbeb2a12eb13ef5b158e970dc79141", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+642abfcd8f699dfdff65a41980dd198555fbeb2a12eb13ef5b158e970dc79141", + "+d8f03b73710f62e8abe321813907d08bb61bcefb6f424f665bea17bb36824195" + ] + } + }, + "signature": "0fb01d6cfb024e498338a94e34e8d34f6d9a39ce536709d62c16459c3b13ea98bdfe38fa26a6e9bc55cc51c251ac3c43ed33f2e771348dd9041421bba9cb2c07", + "id": "14156082340943145041", + "senderId": "3972333673817467832L" + }, + { + "amount": "1000000", + "recipientId": "2817445091933172704L", + "senderPublicKey": "5a815ee6bc625aeff1499a0ecdc2632319885c55de3fdb2ce122e752357ed09c", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "34087d7d036e1513fccddcf99db4bcba404c089054ef07da6115aff83345692145c4a159f46135619de18c3c3969b8c27953e135d01a9e0295706d3397895904", + "id": "4899078210109423337", + "senderId": "2817445091933172704L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5a815ee6bc625aeff1499a0ecdc2632319885c55de3fdb2ce122e752357ed09c", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e5d1c4a6f903edfdcf5133d0cd545412ed0d6227edd5d613b220be5e9325aaa5" + } + }, + "signature": "086338ab3905b8fb782ce1c3a7250848fe5e7d63a37c246f47935d034fedecbeed359eac11c67d4c0af6aae839624092272c168e5b8007cc1b5d3a779c80ce06", + "id": "17781521753316153636", + "senderId": "2817445091933172704L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5a815ee6bc625aeff1499a0ecdc2632319885c55de3fdb2ce122e752357ed09c", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "lecture" + } + }, + "signature": "8c0690f658f60b843c886af3e659922e19323c6b30e3c3c8afa2d3784810e7fcd96757e0a7ec8eb8f3bce2cf77a85192243ad41d7c894cf0eaf6853aaa29d002", + "id": "12183861016580692371", + "senderId": "2817445091933172704L" + }, + { + "amount": "0", + "recipientId": "2817445091933172704L", + "senderPublicKey": "5a815ee6bc625aeff1499a0ecdc2632319885c55de3fdb2ce122e752357ed09c", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5a815ee6bc625aeff1499a0ecdc2632319885c55de3fdb2ce122e752357ed09c" + ] + }, + "signature": "4d79e7697b809bee1ad42cb0ded6621738fd8ebe7b9f03256406b9c2edea8c7f06b92f4fa70c131461e83d36a72fa96f3f55f4d854e6568390f3d1b688b58400", + "id": "14883118029594714433", + "senderId": "2817445091933172704L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5a815ee6bc625aeff1499a0ecdc2632319885c55de3fdb2ce122e752357ed09c", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5a815ee6bc625aeff1499a0ecdc2632319885c55de3fdb2ce122e752357ed09c", + "+e5d1c4a6f903edfdcf5133d0cd545412ed0d6227edd5d613b220be5e9325aaa5" + ] + } + }, + "signature": "bbf5c6af9528be429c445ea35866989659098279ad0ba9c79fe7e681492e89abe9e7e07bc00ef8342b2ee8bda30ce6a84a3b4a943bd92836efac2e5abad9ff0c", + "id": "9041102616866930756", + "senderId": "2817445091933172704L" + }, + { + "amount": "1000000", + "recipientId": "4633965557515166026L", + "senderPublicKey": "5b999af8fb15078d7f73056c5db9bd5022781a1a13754484cb9c21c33e9ef7cc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "067580ccba8cbbf4ab8ebb329ea458ad98295cfe294871491c89ff89c14b8f412e4c4c0e034689380aae6a1e266698c79d10de44a07f452fc20a7df5b4974506", + "id": "13236852013118728878", + "senderId": "4633965557515166026L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5b999af8fb15078d7f73056c5db9bd5022781a1a13754484cb9c21c33e9ef7cc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c69e8ce0b6f441b2d736944f574f73b74b2e73fc0fdf76b82e80f779cc5a8fa7" + } + }, + "signature": "e550585705e1b86503cbea665bd169ebdd2e2d7de173171297702a476966210b7d7b46df11221dfe9ec63608d885c1175b767f4bc5f49eb4725cdd7d63c3b409", + "id": "14421033325975526894", + "senderId": "4633965557515166026L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5b999af8fb15078d7f73056c5db9bd5022781a1a13754484cb9c21c33e9ef7cc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "wide" + } + }, + "signature": "97038f47d940240129d669345e4a170b922a398620b6efcc1cdc9128928d941e7df568236621b5f92c81ade67ea4b01da777365e59b7a13dfbdcebf59231ad0e", + "id": "8350917543555056673", + "senderId": "4633965557515166026L" + }, + { + "amount": "0", + "recipientId": "4633965557515166026L", + "senderPublicKey": "5b999af8fb15078d7f73056c5db9bd5022781a1a13754484cb9c21c33e9ef7cc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5b999af8fb15078d7f73056c5db9bd5022781a1a13754484cb9c21c33e9ef7cc" + ] + }, + "signature": "92b2c07eee7ca4bb4d113fc0660885e5ff408f0d1e78d2c5133366970f6c3ed06091eee2be34546a9f12db9226d7bb48402d861c747b0ca30219f8f1f7e29907", + "id": "5061616676693221215", + "senderId": "4633965557515166026L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5b999af8fb15078d7f73056c5db9bd5022781a1a13754484cb9c21c33e9ef7cc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5b999af8fb15078d7f73056c5db9bd5022781a1a13754484cb9c21c33e9ef7cc", + "+c69e8ce0b6f441b2d736944f574f73b74b2e73fc0fdf76b82e80f779cc5a8fa7" + ] + } + }, + "signature": "08d4d355f4a651b13571509f5a1ca5940be5eea58cdb183ed48548809646a42fcdceacfb7f1c047bf812501477b86258a78dadcbe915a55b25dbc0da04012f0e", + "id": "14207912100022979009", + "senderId": "4633965557515166026L" + }, + { + "amount": "1000000", + "recipientId": "18217296755194720663L", + "senderPublicKey": "97743b2cab1b92884c7a1823bf8c30ee34bb2b37a837657652204c56ee27ef5a", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "46acdef645b07cf14c6794d4eadfadd66fad658ea11afa104ec5d4fda87063b24e4b273f9f68818c43b8a5ca5bbb9dc40e6a5a408b29a2f2a97810544547b50d", + "id": "1704873713463526260", + "senderId": "18217296755194720663L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "97743b2cab1b92884c7a1823bf8c30ee34bb2b37a837657652204c56ee27ef5a", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "dcdf1afc2b06de0b57f9a9d833289a96a98d9a5df12b1e2fbd7ddf3be67b1aa9" + } + }, + "signature": "e082fb92fd9d04d5dd0b1e81ff419bc9c08ec677c519c71bff48c3736a7ac81b7aa8027768bac870921b29feb4db57ae2bea1e3a88851292485c29ae37287a03", + "id": "17326660208736498578", + "senderId": "18217296755194720663L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "97743b2cab1b92884c7a1823bf8c30ee34bb2b37a837657652204c56ee27ef5a", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "educate" + } + }, + "signature": "20d937d8552e1ff2c8a6e750d41865966ebec19aafa9fd9ce21a7382cbe8d21c5db63fafcf5b40ea85d1ff7cdcf3c5de0c50b6524e0b0d142eb7cfccd6649008", + "id": "13626254468014147951", + "senderId": "18217296755194720663L" + }, + { + "amount": "0", + "recipientId": "18217296755194720663L", + "senderPublicKey": "97743b2cab1b92884c7a1823bf8c30ee34bb2b37a837657652204c56ee27ef5a", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+97743b2cab1b92884c7a1823bf8c30ee34bb2b37a837657652204c56ee27ef5a" + ] + }, + "signature": "ca7f1f9a32c87cfb6b50f8c1cb4f0466170356567b62e8ba561f884f72b83bd1263e1b38a082027cd157a6219d74b72017eb48a566111840269dfe535e98f80e", + "id": "12183461920664842532", + "senderId": "18217296755194720663L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "97743b2cab1b92884c7a1823bf8c30ee34bb2b37a837657652204c56ee27ef5a", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+97743b2cab1b92884c7a1823bf8c30ee34bb2b37a837657652204c56ee27ef5a", + "+dcdf1afc2b06de0b57f9a9d833289a96a98d9a5df12b1e2fbd7ddf3be67b1aa9" + ] + } + }, + "signature": "73709e3f8d817f7c9d2d932e8c9303459b7d8c4bbab471194bccf5ed14a9af309a2a514a525070e8cceb49ca502f6f3a47fdd1f3108d0d4b0b9853a0ba837e0b", + "id": "8881375579557310025", + "senderId": "18217296755194720663L" + }, + { + "amount": "1000000", + "recipientId": "666781314329054077L", + "senderPublicKey": "3ef267f62704a1a72ad1473e61129ed2637617f98e5db73fd419f637c8a1d182", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "3de1c6272a8d4cdc93e20320694c33428734dde1fbd3697193e3b5d3efc2a68e83008ef047044eed5dc1e36211ceacffba9b54df34ebddc3309274fe305b5c04", + "id": "14514941581353616879", + "senderId": "666781314329054077L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3ef267f62704a1a72ad1473e61129ed2637617f98e5db73fd419f637c8a1d182", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "783eefdec50eed36d6120df7857aa9ea45a15af7a9d1dd2cff1939ff882918d0" + } + }, + "signature": "b4af0309ca4e3c3e7ce0238a7bb53e2879eef96b50ce21f1551ab4a4f5aa812e994bfbabcc97d29d49ed5c4dac3e9d8e1164737e950b1ae3bed55b6be62c8b0d", + "id": "3727134250102321532", + "senderId": "666781314329054077L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3ef267f62704a1a72ad1473e61129ed2637617f98e5db73fd419f637c8a1d182", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "sugar" + } + }, + "signature": "aa29a9b9b8840197b3b362fe244cb7384fa815c3eaa77e194f8f753d12d49230a5464a89fec14efc3b30f409b72081090bcd3c7f244e1284b2c65dfbd1fff600", + "id": "12667674128654069922", + "senderId": "666781314329054077L" + }, + { + "amount": "0", + "recipientId": "666781314329054077L", + "senderPublicKey": "3ef267f62704a1a72ad1473e61129ed2637617f98e5db73fd419f637c8a1d182", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+3ef267f62704a1a72ad1473e61129ed2637617f98e5db73fd419f637c8a1d182" + ] + }, + "signature": "e733eabc90e6ca1845e47ec9cf5780ffb9950534bc80069779216bd1d2d6b38f25ed4983370e9aa18d9cd75e63e193d88c340be1c9bb17e20708998a00367301", + "id": "15855161050899544964", + "senderId": "666781314329054077L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3ef267f62704a1a72ad1473e61129ed2637617f98e5db73fd419f637c8a1d182", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+3ef267f62704a1a72ad1473e61129ed2637617f98e5db73fd419f637c8a1d182", + "+783eefdec50eed36d6120df7857aa9ea45a15af7a9d1dd2cff1939ff882918d0" + ] + } + }, + "signature": "41383134acbe86474f50e2430b238b4f6684210c69a07db34321227ebc14bd6979fa2587bb05e2fceb7d86b4867bc6c164c2c2190a0b7945b40856ef6e8ae40f", + "id": "2087332564592357007", + "senderId": "666781314329054077L" + }, + { + "amount": "1000000", + "recipientId": "15453881732217608747L", + "senderPublicKey": "c10b31c7ed5587d886cb2569ee38ee27b5b44e6c1d80aecfcf2465a09f86acaf", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "30f51228bddcdf120d32abf714de703f0d7b7b344feb9c0a6cc38c3f4bfcafe129ec9a880ae22adcebd5bc5ec9fae7c18a2b96866363d649965b824fd64b7301", + "id": "11430568696030664289", + "senderId": "15453881732217608747L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c10b31c7ed5587d886cb2569ee38ee27b5b44e6c1d80aecfcf2465a09f86acaf", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "186e5eeaa86c8f5d8c1d10785fa325364288453e033de375280ee6492cabd22c" + } + }, + "signature": "8ca044990fc7f175a38882d70db9e563af3797174e0770333b41125ddd114187774dd0e901e46c36103cf68ba7c70e899b185fcff593a2cb5b58bc365c0a340c", + "id": "11316691425268695278", + "senderId": "15453881732217608747L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c10b31c7ed5587d886cb2569ee38ee27b5b44e6c1d80aecfcf2465a09f86acaf", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "dune" + } + }, + "signature": "75863a115346eaff91d6762085ca16b509d6d8a54eb49d88dfbd8c4f21e0dd44d6b42b95f43380faa8a8ab7d59cd8012ea930b10a0ffa826b2917cca99b91e01", + "id": "2928723464896992742", + "senderId": "15453881732217608747L" + }, + { + "amount": "0", + "recipientId": "15453881732217608747L", + "senderPublicKey": "c10b31c7ed5587d886cb2569ee38ee27b5b44e6c1d80aecfcf2465a09f86acaf", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c10b31c7ed5587d886cb2569ee38ee27b5b44e6c1d80aecfcf2465a09f86acaf" + ] + }, + "signature": "da91a835d2d3135d24aade118109df00afdea39d7b027f5e3c30b080ee1bc4edbbad48b08cb84a1ee4faf959b44cf36ec1d1725f192a411141eaba9670a33e06", + "id": "3183101988664663690", + "senderId": "15453881732217608747L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c10b31c7ed5587d886cb2569ee38ee27b5b44e6c1d80aecfcf2465a09f86acaf", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c10b31c7ed5587d886cb2569ee38ee27b5b44e6c1d80aecfcf2465a09f86acaf", + "+186e5eeaa86c8f5d8c1d10785fa325364288453e033de375280ee6492cabd22c" + ] + } + }, + "signature": "e625bcb16c18c7f5f3843a4259f567bfe473572c563060af7bbff1fb1a23a4fc04df75add827662bd96a24e460fad6969b1844cc4e57d3a41fa2d1665acba709", + "id": "8734302467620692105", + "senderId": "15453881732217608747L" + }, + { + "amount": "1000000", + "recipientId": "10067423873551418982L", + "senderPublicKey": "0ec2061671ef6685ecef5070ef7bf579ce986d7641f4d04be3b8201a1dc09ed3", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "13374f55be2147a85034144414189d215264f72571a386d925932861875eee47a4f92fd36e16cb4a53d1adfdb31d7157a350cd0e0b03bafc0ae94dde107adf06", + "id": "11776296594703418810", + "senderId": "10067423873551418982L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0ec2061671ef6685ecef5070ef7bf579ce986d7641f4d04be3b8201a1dc09ed3", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "01c4391a986b8b0aa144eb3674ea5f34c43cfc9da590ebf2cfd0ddcf092c4a34" + } + }, + "signature": "73b7d5744dfaadaba98c18e20570990949ab22b24f743763308f722682254b03f44b81edfdf97fee1c86bdee7d49346cf1f2416d6bb7a83dcce48d125ebae30c", + "id": "14926493405149450641", + "senderId": "10067423873551418982L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0ec2061671ef6685ecef5070ef7bf579ce986d7641f4d04be3b8201a1dc09ed3", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "cute" + } + }, + "signature": "16680d19ed3bc18e1b2879ded17723a7087efbfccfc705889b2ab7c8a05164a6bb74f2dab137ab716237490fb62590c545307cee9f0a62af12dcd0d0b986a50f", + "id": "2839859606297656248", + "senderId": "10067423873551418982L" + }, + { + "amount": "0", + "recipientId": "10067423873551418982L", + "senderPublicKey": "0ec2061671ef6685ecef5070ef7bf579ce986d7641f4d04be3b8201a1dc09ed3", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+0ec2061671ef6685ecef5070ef7bf579ce986d7641f4d04be3b8201a1dc09ed3" + ] + }, + "signature": "e5d50622ef6d40f7b266cd7564d0dfdf8690661f5839ac32ac7a3bedf9c75d00a716f6fa90a589d9a008db05d0e52d2a8bd7511377f00b3b576db60ee9059a0b", + "id": "8092212171880016719", + "senderId": "10067423873551418982L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0ec2061671ef6685ecef5070ef7bf579ce986d7641f4d04be3b8201a1dc09ed3", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+0ec2061671ef6685ecef5070ef7bf579ce986d7641f4d04be3b8201a1dc09ed3", + "+01c4391a986b8b0aa144eb3674ea5f34c43cfc9da590ebf2cfd0ddcf092c4a34" + ] + } + }, + "signature": "8736358df664a8e2520453a4870153a5030dc8b36178ccb7bc0c493284f94bf3fbe89969d26b332318dae6d7b4ec7a6fdd5fa0891a28cf413ebdd3512587b00c", + "id": "12400873356518820100", + "senderId": "10067423873551418982L" + }, + { + "amount": "1000000", + "recipientId": "15237561450427276449L", + "senderPublicKey": "8f0a1215401ef08d5ebd228198aa8dba53c6cd3aea58f42a62f84d436c2b2dc9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "757a63dd7af43a324f23f95a410b8b4aa2419687fd9a0638ffbb0a674d5cbeb55695af30508e786d7b0e286b843ad71b6556734f903d9407b4e633e3162ea808", + "id": "8034394480693503275", + "senderId": "15237561450427276449L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8f0a1215401ef08d5ebd228198aa8dba53c6cd3aea58f42a62f84d436c2b2dc9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "fc7e4be74827abdc392d95bc0c225d04eb85865d814a7318accf885866f6db56" + } + }, + "signature": "ba117aeae3dbee77fad0ed2c15e03064583ffc9e83a4ce94e9d88c09d9132f8a6ca2fd5247eb4f97bd9c928c8df047eb53ffdfe424ecf44a9cd288122fdca600", + "id": "6799629821209792873", + "senderId": "15237561450427276449L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8f0a1215401ef08d5ebd228198aa8dba53c6cd3aea58f42a62f84d436c2b2dc9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "soccer" + } + }, + "signature": "4f0db5b6f26cbc5e3c1b5f558bca3ddacb3a419c75a38822bff02661db539f3bb8982541e2bbb3dc3297c005cbd6517fa5076013d980c925348052afcf1a9200", + "id": "17433706514178719908", + "senderId": "15237561450427276449L" + }, + { + "amount": "0", + "recipientId": "15237561450427276449L", + "senderPublicKey": "8f0a1215401ef08d5ebd228198aa8dba53c6cd3aea58f42a62f84d436c2b2dc9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+8f0a1215401ef08d5ebd228198aa8dba53c6cd3aea58f42a62f84d436c2b2dc9" + ] + }, + "signature": "ae57c589e91a55127056e866a0ab50342e172b97d0a87db67c79a48d380c689ec2d4c8e809f047a14a57edeb30566594d128076f6adf92886acd57029d82f703", + "id": "15788894002673113019", + "senderId": "15237561450427276449L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8f0a1215401ef08d5ebd228198aa8dba53c6cd3aea58f42a62f84d436c2b2dc9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+8f0a1215401ef08d5ebd228198aa8dba53c6cd3aea58f42a62f84d436c2b2dc9", + "+fc7e4be74827abdc392d95bc0c225d04eb85865d814a7318accf885866f6db56" + ] + } + }, + "signature": "922942df0e4a9202ab8f850de17d9b6d7e3116706bd31a3071c1309644282e1094f824352a137ae2dd52642facbc59a1bdc5b934eb79cad6b44aded6c4b67205", + "id": "10102952059393130370", + "senderId": "15237561450427276449L" + }, + { + "amount": "1000000", + "recipientId": "13711091592225112085L", + "senderPublicKey": "a4635730b95cf45fd1a5c4e9362bb53906e0d186fa245afff055aa2e23915101", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "eb097990d21a3a60fd7e9382053a637af8a3067d167944cd512af16487032dd05cadb4bcabf17f1d265bdd7ce656eced90549257e7a07dd398ebcc3b9cba4804", + "id": "9537130195154526513", + "senderId": "13711091592225112085L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a4635730b95cf45fd1a5c4e9362bb53906e0d186fa245afff055aa2e23915101", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9d5207d2a91824123ff5a01b60397fd902f0a7e8eb8930b7363d882a686e6d24" + } + }, + "signature": "00ce072fad88de324fd5c4323e5095228e9b552ca472951ae6513279cdbbfea84170e38e035ca96af99db4a611d81d64d557dc525ae1d8aa52c52ef4608a5a00", + "id": "8161851071420836994", + "senderId": "13711091592225112085L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a4635730b95cf45fd1a5c4e9362bb53906e0d186fa245afff055aa2e23915101", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "radio" + } + }, + "signature": "da377ff4d248b88055e4260075d0aca2fd9dc4f325bc46dc90c93a87357abb5f4aab07a8b751fc7c8af4f9c20de70243d15727a8d924f359ec34bfa41b2eeb0e", + "id": "12988209884890205892", + "senderId": "13711091592225112085L" + }, + { + "amount": "0", + "recipientId": "13711091592225112085L", + "senderPublicKey": "a4635730b95cf45fd1a5c4e9362bb53906e0d186fa245afff055aa2e23915101", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a4635730b95cf45fd1a5c4e9362bb53906e0d186fa245afff055aa2e23915101" + ] + }, + "signature": "0859b9a9a18450b4c60abedb3a47cd92cbb6d0c50c7aa67c9e6073adfdbd39160cb77be5c0f54237529ddfa7259139211a6af06a8858f81e70d8a476e023d305", + "id": "13603452666477845688", + "senderId": "13711091592225112085L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a4635730b95cf45fd1a5c4e9362bb53906e0d186fa245afff055aa2e23915101", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a4635730b95cf45fd1a5c4e9362bb53906e0d186fa245afff055aa2e23915101", + "+9d5207d2a91824123ff5a01b60397fd902f0a7e8eb8930b7363d882a686e6d24" + ] + } + }, + "signature": "34ce607c61a44181ad47e26e344db3fdf492d9d1fadfa4aa6e56a615d2243dfc52d1047392263749e11b7b81db4e96a496fd83f63929b877127bf8a9027a030b", + "id": "17708690524182003875", + "senderId": "13711091592225112085L" + }, + { + "amount": "1000000", + "recipientId": "17367868322943504694L", + "senderPublicKey": "df87eaf0b919bd794246961223d41a5a9e5437dd24503ebacff08c2e7915db50", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "c2a75d7f406606184e75e237b9c5d08a1b9a70b1e6d6f4be1162b3f5784e4ed2463eb7d4ffd0aa6a3b2ba874968c19e32521529cdfa94ea11d19ffd6cc23fe07", + "id": "13962831306736295214", + "senderId": "17367868322943504694L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "df87eaf0b919bd794246961223d41a5a9e5437dd24503ebacff08c2e7915db50", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "fcd42da9b78b1b45d4c3bd25f972811927486d2fdf22e49af1a65fcf8bf0ed27" + } + }, + "signature": "6814ec985e800982f100f662459764940e5350d0c0b1e127f4a7fdc97d027c4f3b8775aa6944d8344eef25fcde33314a783c98434377427136291862947feb05", + "id": "7299111360763662650", + "senderId": "17367868322943504694L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "df87eaf0b919bd794246961223d41a5a9e5437dd24503ebacff08c2e7915db50", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "stock" + } + }, + "signature": "132044260987eb5e55ea4d08088cfe389ed5910dd336621ea7df9fe38d1534f16e4ae0da39cb6aa7c65a18f969238eab4caaee2e11f4d385a7f4347b39f72803", + "id": "15368678948979308446", + "senderId": "17367868322943504694L" + }, + { + "amount": "0", + "recipientId": "17367868322943504694L", + "senderPublicKey": "df87eaf0b919bd794246961223d41a5a9e5437dd24503ebacff08c2e7915db50", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+df87eaf0b919bd794246961223d41a5a9e5437dd24503ebacff08c2e7915db50" + ] + }, + "signature": "d2912462f54d1dded9dbae55a81db2ae9cf99f03f351041277f7ee2fcc68bc5121c49e3c706dc568cd38eeeb5b0d9010997eb7d590e14c296ed955500bc22201", + "id": "15284607262784008617", + "senderId": "17367868322943504694L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "df87eaf0b919bd794246961223d41a5a9e5437dd24503ebacff08c2e7915db50", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+df87eaf0b919bd794246961223d41a5a9e5437dd24503ebacff08c2e7915db50", + "+fcd42da9b78b1b45d4c3bd25f972811927486d2fdf22e49af1a65fcf8bf0ed27" + ] + } + }, + "signature": "2926cdac0f6225d012efb3beb7b2fc5745f7990e18ac9af8b96ada3794ae16cacb5611b414574655b02eef666ded796b9ff12e476266971d603797cbaff0f709", + "id": "16877054199891435290", + "senderId": "17367868322943504694L" + }, + { + "amount": "1000000", + "recipientId": "7600798692855975651L", + "senderPublicKey": "270f67c47251b1c422eb7a3bfd245fbd45e26fbb054d452877454f040657bac1", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "cfedd1041ce9156241580ac4d8b635f5f7f3075e4972cfb5eb8e8767cc610e2c16f2118273c5ee36e29957be2819576aaddc057536d9c717af69ad231db56d0b", + "id": "11904149882718159949", + "senderId": "7600798692855975651L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "270f67c47251b1c422eb7a3bfd245fbd45e26fbb054d452877454f040657bac1", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "92ba6256809b15bb2295417d3726861840723e5f4f651c9e5d15d0ce3cd99a55" + } + }, + "signature": "469c95472bc7c5cfef29077e8da7dc7e49dac113640f31723817afaf7daf9c1a952577ec5859143bb0256a323fd602ce5b3a05eefc45674f7e9d9a89e4dfeb02", + "id": "14122707772317160528", + "senderId": "7600798692855975651L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "270f67c47251b1c422eb7a3bfd245fbd45e26fbb054d452877454f040657bac1", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "expose" + } + }, + "signature": "855f6db7155957df7dd660c0251baf1b6add9487b3becee052848352fe94c20a1ba0d0baba0ff36b51645cbb9bcc549b87cae4f867b1980b3a0fe9ecfdb62606", + "id": "8643170981916672611", + "senderId": "7600798692855975651L" + }, + { + "amount": "0", + "recipientId": "7600798692855975651L", + "senderPublicKey": "270f67c47251b1c422eb7a3bfd245fbd45e26fbb054d452877454f040657bac1", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+270f67c47251b1c422eb7a3bfd245fbd45e26fbb054d452877454f040657bac1" + ] + }, + "signature": "91871167de35cf1bb568ecfc7cb2595c29bca0703b1c1150a7a198e2276462836c8a3139572258d56d28f5562fc407f6f9afb6618267425284eb8bbe1bba8202", + "id": "12612012802386326036", + "senderId": "7600798692855975651L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "270f67c47251b1c422eb7a3bfd245fbd45e26fbb054d452877454f040657bac1", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+270f67c47251b1c422eb7a3bfd245fbd45e26fbb054d452877454f040657bac1", + "+92ba6256809b15bb2295417d3726861840723e5f4f651c9e5d15d0ce3cd99a55" + ] + } + }, + "signature": "4fff5893749c4f618dc755edf6aa82e17fb0e7818ac908c46f69171cbfc704b382dff6fe885a4be33c864691d77a3f692aebcc485984c8abcac54c90e9726504", + "id": "4921853221591755115", + "senderId": "7600798692855975651L" + }, + { + "amount": "1000000", + "recipientId": "1600476336849154505L", + "senderPublicKey": "a71d922a869d07f35f5fc79e23065bea36b25b9b625d0248ce7386530f002729", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "855670dfee77daef150e52cea58e90a6b35ea760850ba7c950c9c8359a262f799e493db37d4fa100980ca28217915b65c80f5309f4bcdcb1eeb96fe6e07e0c0e", + "id": "18023552489257797409", + "senderId": "1600476336849154505L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a71d922a869d07f35f5fc79e23065bea36b25b9b625d0248ce7386530f002729", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e739daacb7a7a2620ea3f9ffd7489f5b3b797a149168997890dc11e4e0ba75eb" + } + }, + "signature": "7f5e75981c7b1f57aa0406af9c8fc40b85a8b860edba04b421ef9e59c82c890a822550a2ef7c7b393ee3736f40f0e355ed87873426e2760eec1231d86daf3e0c", + "id": "17757033035849977909", + "senderId": "1600476336849154505L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a71d922a869d07f35f5fc79e23065bea36b25b9b625d0248ce7386530f002729", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "situate" + } + }, + "signature": "1bbf5c12f6111c7006480af75e3241fe103d4ecfd8c30c6d3aa29b4a78809d71629a19a1be6c17328f779c34f7297860e16fcc877848df30129f736aadbfbd01", + "id": "2735668057979101290", + "senderId": "1600476336849154505L" + }, + { + "amount": "0", + "recipientId": "1600476336849154505L", + "senderPublicKey": "a71d922a869d07f35f5fc79e23065bea36b25b9b625d0248ce7386530f002729", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a71d922a869d07f35f5fc79e23065bea36b25b9b625d0248ce7386530f002729" + ] + }, + "signature": "f034fcb555f04c3369fbcebebd38281ef99d8731f4f5dc0f074d1ed3089d48d61dd46bd877999279e2f4383ce3175c588331fa2623fc0c67e3c0d0ca93ea9808", + "id": "10474875657862909755", + "senderId": "1600476336849154505L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a71d922a869d07f35f5fc79e23065bea36b25b9b625d0248ce7386530f002729", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a71d922a869d07f35f5fc79e23065bea36b25b9b625d0248ce7386530f002729", + "+e739daacb7a7a2620ea3f9ffd7489f5b3b797a149168997890dc11e4e0ba75eb" + ] + } + }, + "signature": "f75dc328949d6f715c42dcb711776960fb69b2e95dd16a6d8a8d6e2a0d59a3ed569bfeff1ae6567a4bbd33de77056d7f89ce5e330f71db2a36fd4577d8e7080e", + "id": "4562620978968301501", + "senderId": "1600476336849154505L" + }, + { + "amount": "1000000", + "recipientId": "7739449823295881692L", + "senderPublicKey": "4935adbd5ca9ad4ce6ef994d8d592e9669c78450686bad820cfb22a41cf3e217", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f696a5dd680a375d582f4ec8ccd21e7145c7c0b15cfc3bd23d0e4365e999c8a9f1fefc5e83f23abfb9e069fd5e43b1b5d88c0a600ca5ee1c76aee6e3c4c1130a", + "id": "10650082576255667800", + "senderId": "7739449823295881692L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4935adbd5ca9ad4ce6ef994d8d592e9669c78450686bad820cfb22a41cf3e217", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c8222f4f82569f72fe0cc8111585541c8b9c0b06ed88cb78309fb0fb3ba698d8" + } + }, + "signature": "01b8c2f39540a12e44d4b871d96b189c33415424678f4613f0e68693f339b8b11b83336e8f142839b28a82f65cf01f2b8c7f45187bd966562b9f1875db571606", + "id": "1488385341627218355", + "senderId": "7739449823295881692L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4935adbd5ca9ad4ce6ef994d8d592e9669c78450686bad820cfb22a41cf3e217", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "engine" + } + }, + "signature": "306bb35d48b0c483c358b742909ad56d1d9d54218bed35165fdcf2e1bc00fbd7853c761d65f58d9ed5c91c22cafdb9c8fc56a951d7cdd32416bc25d52f81d903", + "id": "4033652819399630988", + "senderId": "7739449823295881692L" + }, + { + "amount": "0", + "recipientId": "7739449823295881692L", + "senderPublicKey": "4935adbd5ca9ad4ce6ef994d8d592e9669c78450686bad820cfb22a41cf3e217", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+4935adbd5ca9ad4ce6ef994d8d592e9669c78450686bad820cfb22a41cf3e217" + ] + }, + "signature": "082e8900f08f43ffa49cdb6154916f80fbe28b9d8539f61df918b1b4878a491bebf90b5dfca50d79e82f5f0f46e9b11942e22dfcf759d497dd3b45c8b73b8101", + "id": "16406317643854542258", + "senderId": "7739449823295881692L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4935adbd5ca9ad4ce6ef994d8d592e9669c78450686bad820cfb22a41cf3e217", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+4935adbd5ca9ad4ce6ef994d8d592e9669c78450686bad820cfb22a41cf3e217", + "+c8222f4f82569f72fe0cc8111585541c8b9c0b06ed88cb78309fb0fb3ba698d8" + ] + } + }, + "signature": "98f38e781f8f45d4473365761ef29435a15b163a86bf669bdadd94a8c33a20d368d68d0f651203618b288d02af914d13fe042a91905b7d18a5526d385b9cdc03", + "id": "1700055150233987816", + "senderId": "7739449823295881692L" + }, + { + "amount": "1000000", + "recipientId": "4869611128516759332L", + "senderPublicKey": "5c368135825c854c33ee143d435ab87f22688ca1548ba0dd64522c9ace1f1475", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e3162725964384eb20215be971e29537a3869ffab5136c6264cb890b71c90ea21e2fa3a5bfccda68725d0a99a9da87ea418d7759d7b35a1da7c18e8257239406", + "id": "12323805913798065916", + "senderId": "4869611128516759332L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5c368135825c854c33ee143d435ab87f22688ca1548ba0dd64522c9ace1f1475", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "ceb2c457691f88a2e90ac408fd3cd3dfded14d371c43b2ab640da995b227c598" + } + }, + "signature": "9379ee572c28f1791396293f02c6972d3bece56b481e9659eb0ad48cdff18d107cafe04ea826432f6e76956db7fef8711beac5172c0def64f7355cd0577aa10f", + "id": "13554720470248466615", + "senderId": "4869611128516759332L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5c368135825c854c33ee143d435ab87f22688ca1548ba0dd64522c9ace1f1475", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "pulp" + } + }, + "signature": "5db3c02971dab8c34838e5f91c19c48cbd7b33a840ddd11c614b81817c6a7ab11cd4e6238e0a35aaa23b205cc6b6686af86ed2ef41c179922a129263ae5e9e06", + "id": "1377641947977747489", + "senderId": "4869611128516759332L" + }, + { + "amount": "0", + "recipientId": "4869611128516759332L", + "senderPublicKey": "5c368135825c854c33ee143d435ab87f22688ca1548ba0dd64522c9ace1f1475", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5c368135825c854c33ee143d435ab87f22688ca1548ba0dd64522c9ace1f1475" + ] + }, + "signature": "ddd9192c26c82fa58e3aabaa6f7736d10a4d6247f1c454dcfc43396d2f119021cab0a2f7fc6a7e2d17c2b454058f97e6199c356894620c5366eaded402b68109", + "id": "17014840366629199357", + "senderId": "4869611128516759332L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5c368135825c854c33ee143d435ab87f22688ca1548ba0dd64522c9ace1f1475", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5c368135825c854c33ee143d435ab87f22688ca1548ba0dd64522c9ace1f1475", + "+ceb2c457691f88a2e90ac408fd3cd3dfded14d371c43b2ab640da995b227c598" + ] + } + }, + "signature": "e8927dc2a9d9fcb7b59735a216b1429d7d5175c7054477dd827ad09aff986a536b8e114c4dc49059f43879fcbbc0682eaf9687e73846d64690ac5a9926df0609", + "id": "5862301088807667912", + "senderId": "4869611128516759332L" + }, + { + "amount": "1000000", + "recipientId": "2297631283214184578L", + "senderPublicKey": "310e1eab6db7c2081bdfdc9f4d877f8a9fae7dec7be3de9d483badaf6d3992a9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f50e30fc1b84d18cbdab5454880d4d9b3c309f7cdc803e5df9e4ae7994e323d5d5d5f177053c5b5036e6c77456642574589385b513c7e666e2a5ccb429d4dc05", + "id": "6890277476456654220", + "senderId": "2297631283214184578L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "310e1eab6db7c2081bdfdc9f4d877f8a9fae7dec7be3de9d483badaf6d3992a9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "0ad84b88efbe76d455df5d43e94ab9209fc062d8dba296e85188e425d29b2a7c" + } + }, + "signature": "3981dd7160878372df41c9428c0a2a9837e943eb3efe5081e7ab12fe6e5d2e7003ac5ee62ae1de5c064b598af86723220e6da3b14ce1315a62dac2654a391309", + "id": "16066200137032335624", + "senderId": "2297631283214184578L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "310e1eab6db7c2081bdfdc9f4d877f8a9fae7dec7be3de9d483badaf6d3992a9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "brother" + } + }, + "signature": "f0f6317cafb3a9c1e88f1ee97a2376da9f8c57908d701ce9c59629c058c70066ffc4d03267dc442e184a8c1b5b38536ce55acce83dcc93fcea5cbe53a871a702", + "id": "18066144386687978241", + "senderId": "2297631283214184578L" + }, + { + "amount": "0", + "recipientId": "2297631283214184578L", + "senderPublicKey": "310e1eab6db7c2081bdfdc9f4d877f8a9fae7dec7be3de9d483badaf6d3992a9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+310e1eab6db7c2081bdfdc9f4d877f8a9fae7dec7be3de9d483badaf6d3992a9" + ] + }, + "signature": "63d1646305b6e9630d71fb0ffaa31209248d1df83f3a0c93e0bdc5a90c4b3880e2d6b847d53bb0a6354f8e0ec66b8e521fe3360581e63058d50a0e7dc555c801", + "id": "10590093901672939139", + "senderId": "2297631283214184578L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "310e1eab6db7c2081bdfdc9f4d877f8a9fae7dec7be3de9d483badaf6d3992a9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+310e1eab6db7c2081bdfdc9f4d877f8a9fae7dec7be3de9d483badaf6d3992a9", + "+0ad84b88efbe76d455df5d43e94ab9209fc062d8dba296e85188e425d29b2a7c" + ] + } + }, + "signature": "c14884e4769a4dc9541e1d41d2fe20fd3d891cf558b858c1aebd567457ece287b156f3cad0425ed38925cb61bfc1b12e9e08ab6f190c35496773e3a0f6002303", + "id": "7212493556159692428", + "senderId": "2297631283214184578L" + }, + { + "amount": "1000000", + "recipientId": "13540625599369657033L", + "senderPublicKey": "7ba9a9f6710dc07bf77a8d53d717e2083207d158650af032e0825758516c251a", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "45035d77f9adc8c31601a24b786a664e303d7c4d6ed67d6b5a17bd7ee0f86482c88957e03c8a413da953b88b51df26c8e15a2756a73e075ce4bbbac51a1a9b05", + "id": "15129572825268943848", + "senderId": "13540625599369657033L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7ba9a9f6710dc07bf77a8d53d717e2083207d158650af032e0825758516c251a", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d1a90a4fdbca6e257fe390c5a4b89505f7df36786d0311759612c2baef241db1" + } + }, + "signature": "1a9bccb2d689df26fada1acd6faf808394cbd81cc0c10e8da1477648c7ca3fa2bce4975de8b011773412ba327601caa271f234b157f60a96498d40f39c94f700", + "id": "6987358495581053114", + "senderId": "13540625599369657033L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7ba9a9f6710dc07bf77a8d53d717e2083207d158650af032e0825758516c251a", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "undo" + } + }, + "signature": "f7c358cceea1bfd46ef220e3f09160626e09ca10496e641ae4fdc8f6816950963d4f6413e4184505b9d9536e65d8d725c374e09e22dd3895b665e256729b5309", + "id": "15034639861047971761", + "senderId": "13540625599369657033L" + }, + { + "amount": "0", + "recipientId": "13540625599369657033L", + "senderPublicKey": "7ba9a9f6710dc07bf77a8d53d717e2083207d158650af032e0825758516c251a", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+7ba9a9f6710dc07bf77a8d53d717e2083207d158650af032e0825758516c251a" + ] + }, + "signature": "18a4a57a67018c115f448bcb0ba34c50c84dddb7d3155f7889b06105dffb90bddf12db8f679c1b46061c738313e9dee0c7ec77f3d053fd192a502db027d31e00", + "id": "3579893528680379778", + "senderId": "13540625599369657033L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7ba9a9f6710dc07bf77a8d53d717e2083207d158650af032e0825758516c251a", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+7ba9a9f6710dc07bf77a8d53d717e2083207d158650af032e0825758516c251a", + "+d1a90a4fdbca6e257fe390c5a4b89505f7df36786d0311759612c2baef241db1" + ] + } + }, + "signature": "abe09f4ec91ba57c8ef78b93a6e6f6a1e338385c61fd9ed1106c9a14fce4067dc2b2fe66672f4c89da07cc992c97019d04d3bba47469169d4abee203c43d560f", + "id": "10614651192646238198", + "senderId": "13540625599369657033L" + }, + { + "amount": "1000000", + "recipientId": "864881789245260221L", + "senderPublicKey": "36a2ee4088aa6b9b7b07f86d21fb5928ec8193d26e425a98c51cde39597ee894", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "0763875759c4094eb108c7b328a3493be144f594c64049399edbbd28a837b7df0bdb0ed82b400488e285da124450d0bee4f8c78feff8d817201c79dcf6033a07", + "id": "15810569961263055129", + "senderId": "864881789245260221L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "36a2ee4088aa6b9b7b07f86d21fb5928ec8193d26e425a98c51cde39597ee894", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "59e6fef6fa43978eea5081e8ce208f652d09af2d8aee686f3fbdb15158f42ee1" + } + }, + "signature": "dc174abde3eb899f9879471b53277a10e632a1c035d8d8f56ce882475337d4b3e503de13345652711c47c7882a7f3d26ebc9684c27fc69a9f8030bea91d5e30d", + "id": "13136148802466657689", + "senderId": "864881789245260221L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "36a2ee4088aa6b9b7b07f86d21fb5928ec8193d26e425a98c51cde39597ee894", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "pride" + } + }, + "signature": "b66005ebbbe616917f09bacac904a97a42f35c818cdb8c64c46224ceda6a7a011a7a51b3cf0c7564534f10756f185805560fca9de7dc11afeb6f3f1e37162b01", + "id": "13223479716162679571", + "senderId": "864881789245260221L" + }, + { + "amount": "0", + "recipientId": "864881789245260221L", + "senderPublicKey": "36a2ee4088aa6b9b7b07f86d21fb5928ec8193d26e425a98c51cde39597ee894", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+36a2ee4088aa6b9b7b07f86d21fb5928ec8193d26e425a98c51cde39597ee894" + ] + }, + "signature": "cc1f306d80fe91466d72a8d8e0c4fb29ef58386255d1053205f853562b519391bc234096e401353241ae22ab5194840c2cfed4c48623679e2328ba888e209d0b", + "id": "3382271600265858111", + "senderId": "864881789245260221L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "36a2ee4088aa6b9b7b07f86d21fb5928ec8193d26e425a98c51cde39597ee894", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+36a2ee4088aa6b9b7b07f86d21fb5928ec8193d26e425a98c51cde39597ee894", + "+59e6fef6fa43978eea5081e8ce208f652d09af2d8aee686f3fbdb15158f42ee1" + ] + } + }, + "signature": "f8d3a83e3c207304bce78d703bcf0737f9a0ccd5a33798e79d3a1336d412a7e33e1a5efc0a4dc507f5c556d8158753693fcd89638b048d5577fe176d45ae6002", + "id": "9822525264394958349", + "senderId": "864881789245260221L" + }, + { + "amount": "1000000", + "recipientId": "573465499993194130L", + "senderPublicKey": "69e254b8f41d93d228962153ae37d83d200a06f173b5effae8a3bf4c0c28b4fc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f3b486875d62c31516f9974d9d9fa30840f2e2b659053235a42972fd3ff7c218c51392969f9967bda59128529e4a8f8bafd9991f40a92760f1f64f5c6ae9700f", + "id": "15876130068201452298", + "senderId": "573465499993194130L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "69e254b8f41d93d228962153ae37d83d200a06f173b5effae8a3bf4c0c28b4fc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "58a6297d645b273ff75e7b6602a5cd2df856c4b95434ecf37b3607115aead63f" + } + }, + "signature": "1a359cccfa4e3d0e727458145f0cd149728cb09d45836d9dc289582e2fc5b7cc4b2c0fd82988290ee7c69ec3047b05a29a97e2a9f2b1f6ed7fe3cc35d04f7a01", + "id": "17335481497286100023", + "senderId": "573465499993194130L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "69e254b8f41d93d228962153ae37d83d200a06f173b5effae8a3bf4c0c28b4fc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "topic" + } + }, + "signature": "0a0a296e59923f7ce53339373001b050773580316cc14ba9debe5d107591a6cfa63e21ef0588cca7b1337af4c661a9c1eef9816b7ed02bc3e8b162f5bca68907", + "id": "16360831037812304503", + "senderId": "573465499993194130L" + }, + { + "amount": "0", + "recipientId": "573465499993194130L", + "senderPublicKey": "69e254b8f41d93d228962153ae37d83d200a06f173b5effae8a3bf4c0c28b4fc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+69e254b8f41d93d228962153ae37d83d200a06f173b5effae8a3bf4c0c28b4fc" + ] + }, + "signature": "032ed2774b546b1e1b8519ff9cc07e3fac690d35130740147a5201c7e714264c04ce2e744bb5a22735a0e86f69efab9e44d08b3f3776d3f1d0aca5377b1a0607", + "id": "1963247852325634273", + "senderId": "573465499993194130L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "69e254b8f41d93d228962153ae37d83d200a06f173b5effae8a3bf4c0c28b4fc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+69e254b8f41d93d228962153ae37d83d200a06f173b5effae8a3bf4c0c28b4fc", + "+58a6297d645b273ff75e7b6602a5cd2df856c4b95434ecf37b3607115aead63f" + ] + } + }, + "signature": "1692984dbd555d419431cb25ce5458df0778d17ee1848447a1b75be508bdffd1588948f1ed343a0214e370c5e32d89637c42c90fe74687abcbed1fda4664e601", + "id": "12070458794638763705", + "senderId": "573465499993194130L" + }, + { + "amount": "1000000", + "recipientId": "1957993454347503616L", + "senderPublicKey": "05ebd956f173c6e6848cd1173efa91d6f1e69982b2f46982e0efecc86dd558e2", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "091317f98a298bd707c719e4d1c01fcacc0159579770dc58788ac83c796aefb0772bc93ef2ecf0b043e527e8ead01bca72682e81c0eeae6a12ba88a4f2dd560d", + "id": "7532636451972428102", + "senderId": "1957993454347503616L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "05ebd956f173c6e6848cd1173efa91d6f1e69982b2f46982e0efecc86dd558e2", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "78601094d7abba15856e7b10feb47defebacf0b78957d4c711a3defb892c25b6" + } + }, + "signature": "b496d558788e1b6411048cab2a20893a1ed1686364e32446712d9e263e7c5c8d6c2a8f6f1d8a3dbe656cbeb7137cfd137485a8747bb33e595d2a32b8e5bd7a01", + "id": "4122290949609997454", + "senderId": "1957993454347503616L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "05ebd956f173c6e6848cd1173efa91d6f1e69982b2f46982e0efecc86dd558e2", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "test" + } + }, + "signature": "53037715a52e9cb2a24e7c6152cfcc95f86110fca632728e338023da24aea3a7eed82055a25c06fb2b3ccd27330dcbe10fc105a58519f1b353c8a359ea24f201", + "id": "109847976582558655", + "senderId": "1957993454347503616L" + }, + { + "amount": "0", + "recipientId": "1957993454347503616L", + "senderPublicKey": "05ebd956f173c6e6848cd1173efa91d6f1e69982b2f46982e0efecc86dd558e2", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+05ebd956f173c6e6848cd1173efa91d6f1e69982b2f46982e0efecc86dd558e2" + ] + }, + "signature": "102f73477d5716bb1941c78b2f47ec2b87acb8b3536ab05989296bd5097027bea72b30162221aaddc16eb7dd01396102637fc05e52099c6948b79873995bf20f", + "id": "8014704931935425752", + "senderId": "1957993454347503616L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "05ebd956f173c6e6848cd1173efa91d6f1e69982b2f46982e0efecc86dd558e2", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+05ebd956f173c6e6848cd1173efa91d6f1e69982b2f46982e0efecc86dd558e2", + "+78601094d7abba15856e7b10feb47defebacf0b78957d4c711a3defb892c25b6" + ] + } + }, + "signature": "290bb681fd0073bd4409b37811425556a769bc6e89cc0113e85d3592c2e1586311fb1106840718b2f558c4ba68b9ddfd588f64c318da7f7a6852053a4ac32109", + "id": "18374667952643190624", + "senderId": "1957993454347503616L" + }, + { + "amount": "1000000", + "recipientId": "7567346131303514705L", + "senderPublicKey": "9e1665fd37a7643f5859fd91568d1783f33838b10c9dd0ebd138fe80a33fb734", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "65b58a5910cd3cbf7e6ece89c9b7c84442bb48fd2d3b50a068be4894d40c96e9c7d34f1d2d700a80dba16fd494f10f104820312e95a7a621cf5b1165c60f5706", + "id": "12830276454194994669", + "senderId": "7567346131303514705L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9e1665fd37a7643f5859fd91568d1783f33838b10c9dd0ebd138fe80a33fb734", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "0a38c26937222920c1e27a25275fcd1764aea8bbb81d71ef84bcbaf46c6c9864" + } + }, + "signature": "882be8c74898299b7f2e8c6df5cf3cd3aa09d569e3fd224c70f79f5230a4ec29b8e2bded73eb7d70ea2824c338d2d9727eab7c322193a5bcb4a83ebcd1d07a0b", + "id": "5839422969916194416", + "senderId": "7567346131303514705L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9e1665fd37a7643f5859fd91568d1783f33838b10c9dd0ebd138fe80a33fb734", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "fan" + } + }, + "signature": "405a810e753e280bcf7b07f4e2664e000ab64eb464222f4e557c9c02c5f0e5807ea09e3b2abd49bc6cc22fa40267cf335cc530d1571f04f4b5277f8580d9ee04", + "id": "17521201393534933324", + "senderId": "7567346131303514705L" + }, + { + "amount": "0", + "recipientId": "7567346131303514705L", + "senderPublicKey": "9e1665fd37a7643f5859fd91568d1783f33838b10c9dd0ebd138fe80a33fb734", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+9e1665fd37a7643f5859fd91568d1783f33838b10c9dd0ebd138fe80a33fb734" + ] + }, + "signature": "8ca7d3c1522311634503ca6581d7a76e26299482b0b0b3145481312a69b7d16d0dc22e063c0ff84329553140e57a00bd1aa0559e29bc41bc6c3db1b37311ad08", + "id": "7180613529935927699", + "senderId": "7567346131303514705L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9e1665fd37a7643f5859fd91568d1783f33838b10c9dd0ebd138fe80a33fb734", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+9e1665fd37a7643f5859fd91568d1783f33838b10c9dd0ebd138fe80a33fb734", + "+0a38c26937222920c1e27a25275fcd1764aea8bbb81d71ef84bcbaf46c6c9864" + ] + } + }, + "signature": "2b75f93ebccde241ed7bbe5afaa0de4f78d5ef38b2283bf51f252403cb2700f795d49382e0ba69c4bb45b3c1ec9ef142907398a17c429f2ef49897dfb4574b08", + "id": "485275114737187902", + "senderId": "7567346131303514705L" + }, + { + "amount": "1000000", + "recipientId": "6484331694260405055L", + "senderPublicKey": "857216773288b7f6ae72fc406e78a63d9d0d7dc1d01affde0ecc975ac15120ea", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "9ffc25264848358ab709505170a2604ce4750022ac4361a3e9ce11da2be349735a9eb83cdda758ccb78201810578517a1461eb01b9f5f1b7126107eb0ffc9c0f", + "id": "14441410077163072690", + "senderId": "6484331694260405055L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "857216773288b7f6ae72fc406e78a63d9d0d7dc1d01affde0ecc975ac15120ea", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4c7c82660b40c41f9a84a6e9267c29cecf0d04da29b2e1c231e016b532152990" + } + }, + "signature": "4f4c7dcd9f4349fcab3d913a277d8a1ad8a14ab5de60471f72b7cbe9630c6d594fb10389757278e4f377a5330e21262586ce39e42c80d788a4f79eacc500510f", + "id": "15499925231496048036", + "senderId": "6484331694260405055L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "857216773288b7f6ae72fc406e78a63d9d0d7dc1d01affde0ecc975ac15120ea", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "knee" + } + }, + "signature": "8b6a632895ac9aa6e7bf4ab1b88941373243acf83fd78d0b152046cde2a9bc7c1e828a6d456ebc1cde0fa3ccdc8f57443f504aabd23b6782d12b207a03332705", + "id": "3222905533975290298", + "senderId": "6484331694260405055L" + }, + { + "amount": "0", + "recipientId": "6484331694260405055L", + "senderPublicKey": "857216773288b7f6ae72fc406e78a63d9d0d7dc1d01affde0ecc975ac15120ea", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+857216773288b7f6ae72fc406e78a63d9d0d7dc1d01affde0ecc975ac15120ea" + ] + }, + "signature": "4f69d9eb7bf0dbf65c60222701872e46864dc32c21149a2b17c93ed6c1e6146528d4cbfd98a24a6d0ea9ee606ee29d1bd2fdf7b63d9f48c0f14f4017c1139b0b", + "id": "1439425751073469124", + "senderId": "6484331694260405055L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "857216773288b7f6ae72fc406e78a63d9d0d7dc1d01affde0ecc975ac15120ea", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+857216773288b7f6ae72fc406e78a63d9d0d7dc1d01affde0ecc975ac15120ea", + "+4c7c82660b40c41f9a84a6e9267c29cecf0d04da29b2e1c231e016b532152990" + ] + } + }, + "signature": "2893571dfb19a003781e892a0b60c07aabec2d21077a00f32a088392213ef965f74886279dce7bf479e0eddd77394de78697819366f91c6eb75f6c2caf151809", + "id": "4545481196747297352", + "senderId": "6484331694260405055L" + }, + { + "amount": "1000000", + "recipientId": "12138856705023269842L", + "senderPublicKey": "b4a0106962cf18380fbecaa7d3468e0ff8c9246dfb63c3362db1af944be5871d", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "8843a0c8f202d33f40d28e56360e3751444be82f08b05f76062e82e3c86ba9c09934cf70aeaa76820b104debb19e6a66c08121aa345d19009718d92daeb6af04", + "id": "9093167374326794884", + "senderId": "12138856705023269842L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b4a0106962cf18380fbecaa7d3468e0ff8c9246dfb63c3362db1af944be5871d", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "62b506f45191b231592970119328e170aab2588fbf479f011bca60a3a4803a46" + } + }, + "signature": "f43985f223adf4f56a563af4313b3fe97edfa593235ce9e36b4eddbf64f20df59fa01534495a312ad71bfc9525a69afc5ab096a0c0fc6271c5cc02acca2f030f", + "id": "8504715449502067283", + "senderId": "12138856705023269842L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b4a0106962cf18380fbecaa7d3468e0ff8c9246dfb63c3362db1af944be5871d", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "wasp" + } + }, + "signature": "c43f320ef6e916673185d7e7f958db5898ccf1a2687c0f8b5312da9b92cc7eac6eaa3f98439da43d815eed4887b494d0b316dfba85445b3204897d68ade55006", + "id": "5157973773729331921", + "senderId": "12138856705023269842L" + }, + { + "amount": "0", + "recipientId": "12138856705023269842L", + "senderPublicKey": "b4a0106962cf18380fbecaa7d3468e0ff8c9246dfb63c3362db1af944be5871d", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b4a0106962cf18380fbecaa7d3468e0ff8c9246dfb63c3362db1af944be5871d" + ] + }, + "signature": "435535a5250976d2d7cdf223925b0822ef8c9d08a13e397e673b8e5ea178d291e9a2adaab44bb11a962c74c04d3315d40389df57550555eb4414e954acc69c05", + "id": "9832239970687336689", + "senderId": "12138856705023269842L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b4a0106962cf18380fbecaa7d3468e0ff8c9246dfb63c3362db1af944be5871d", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b4a0106962cf18380fbecaa7d3468e0ff8c9246dfb63c3362db1af944be5871d", + "+62b506f45191b231592970119328e170aab2588fbf479f011bca60a3a4803a46" + ] + } + }, + "signature": "34187e32da72c78f8c931909f4fc5774c5a21aaad9feceb7fe17222f20738219a556529acf04ef128bf58917dcf15b0a776dd86fb5d8d11257588abdd37ae905", + "id": "3115009142026982294", + "senderId": "12138856705023269842L" + }, + { + "amount": "1000000", + "recipientId": "13628188138437539735L", + "senderPublicKey": "f7e5c8b610fe008c212bee9701acb0a34c64fed38f7fda0e15a96e37809087fe", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a80a654de643500b4cab7c454f25643ad45d2ca5d52884737a03e5774294eaebb3c945c57b9f23243f1eca573018bb2e4542d96386f64dd889eb14641b23b60b", + "id": "16980926638291005002", + "senderId": "13628188138437539735L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f7e5c8b610fe008c212bee9701acb0a34c64fed38f7fda0e15a96e37809087fe", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f77cfe5f2f404c9c1756562c009dbd65cf18c2e26d58e627401fcaca4ee7b8b0" + } + }, + "signature": "b12336d436d289a614accd90a81d6518950f9f9ab41b7cc8d4d0a2081fef01bedeb941a9869973612a27a66237a4821632a16773c279ca1ab2ba1ebb6fa48406", + "id": "10797638241308321302", + "senderId": "13628188138437539735L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f7e5c8b610fe008c212bee9701acb0a34c64fed38f7fda0e15a96e37809087fe", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "canyon" + } + }, + "signature": "1e16e8fb52221df70e50ea877eaf6bffdf5ff0df020b29fee6f2f3d206546bf38e9a7504382bb4b05fffcb288cbb5fc05f7fe2f29a6ab265b4a5c5204d787a02", + "id": "6073175265869024569", + "senderId": "13628188138437539735L" + }, + { + "amount": "0", + "recipientId": "13628188138437539735L", + "senderPublicKey": "f7e5c8b610fe008c212bee9701acb0a34c64fed38f7fda0e15a96e37809087fe", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f7e5c8b610fe008c212bee9701acb0a34c64fed38f7fda0e15a96e37809087fe" + ] + }, + "signature": "8791133dd1a93ad0895b93c593e1f166b2396c0d27a6438820fd11b7083ccf24b8a96d1cd228c124fd60ce5b03cda54634babb8c675fbd2a38b07f055e5e030b", + "id": "17880015000666112352", + "senderId": "13628188138437539735L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f7e5c8b610fe008c212bee9701acb0a34c64fed38f7fda0e15a96e37809087fe", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f7e5c8b610fe008c212bee9701acb0a34c64fed38f7fda0e15a96e37809087fe", + "+f77cfe5f2f404c9c1756562c009dbd65cf18c2e26d58e627401fcaca4ee7b8b0" + ] + } + }, + "signature": "02a8e7158669db26899b48e295ed402469512b95cffe99fa0addeab87c9f2686a9bd8379c5d88112e176b385915101cd58cad0a8a43be64754ad3ecac0337c0e", + "id": "11371241378018788465", + "senderId": "13628188138437539735L" + }, + { + "amount": "1000000", + "recipientId": "15979827488030900437L", + "senderPublicKey": "4f8976b6cb26c6d63adc9085a29cd7868a69cd222aedb0861b270eb9af55ae2b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "efabdf9c88a33303d24b5abe1f5e4bc7ea63b341c20c4098c39ea75af609afabf5203cd77894b99e4152eb10bbf626e00d047d8ad7df82e8124fe4fe66821b01", + "id": "3083640311150014317", + "senderId": "15979827488030900437L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4f8976b6cb26c6d63adc9085a29cd7868a69cd222aedb0861b270eb9af55ae2b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "28b6ad0f7f0617af17074bd3d92d3421316e7c88cb9f3e3bde38f448d60b44c9" + } + }, + "signature": "6e91b862c230a4133a7a397894ff32ff853ded30ef8fd5e1e0b01ae8c02b24ec22217471249c46c942da3e0f20ba2a5168bf0b0843c2d26ddaeffa9205bf2503", + "id": "6155001780011349221", + "senderId": "15979827488030900437L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4f8976b6cb26c6d63adc9085a29cd7868a69cd222aedb0861b270eb9af55ae2b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "paddle" + } + }, + "signature": "9cc33cd3a4ff428d0cf9db8c38f6f98f789f00be5cdde244d628ab5a03139938b24c7479dfe146f4db556314184b0b96bb8f7905daaf8b0b34815e3542e71701", + "id": "2085219846372174905", + "senderId": "15979827488030900437L" + }, + { + "amount": "0", + "recipientId": "15979827488030900437L", + "senderPublicKey": "4f8976b6cb26c6d63adc9085a29cd7868a69cd222aedb0861b270eb9af55ae2b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+4f8976b6cb26c6d63adc9085a29cd7868a69cd222aedb0861b270eb9af55ae2b" + ] + }, + "signature": "8b4e18e82172b6ae048c3adcc80383f01c5e5829c92f547ad9e1b836dd4ae74d7cc1c0911cd93f29cd748fdec606896ef876f006d07a3fd4e6f77aa55dd9d803", + "id": "2993457441689865360", + "senderId": "15979827488030900437L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4f8976b6cb26c6d63adc9085a29cd7868a69cd222aedb0861b270eb9af55ae2b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+4f8976b6cb26c6d63adc9085a29cd7868a69cd222aedb0861b270eb9af55ae2b", + "+28b6ad0f7f0617af17074bd3d92d3421316e7c88cb9f3e3bde38f448d60b44c9" + ] + } + }, + "signature": "8e5eab02afe5c4aa2b91fb1d57c7a5147c147b946f82a584ae4a80cdcd401e37b9b380d72ccfe31df3c043d58bfcb5c3e701d57ac6caf105bc3fa04549ca6400", + "id": "5459290559489632475", + "senderId": "15979827488030900437L" + }, + { + "amount": "1000000", + "recipientId": "6463707033609101884L", + "senderPublicKey": "a5ab4bc66443c0390bc3ea1d81a956af22a60848b30ffca17d966d3ab138e94e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e81674b276ef299466421d639289e489f5b1576089b6353216e5f99734633ad6a820b1e17271937c8660aae87122aa1d66fd1e1c2d3ade454caaa56a08e11a06", + "id": "6819934497538159079", + "senderId": "6463707033609101884L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a5ab4bc66443c0390bc3ea1d81a956af22a60848b30ffca17d966d3ab138e94e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "eac4142cd49c21e3e213cbf84e1f0419ed6f26104f99e6860fee404b86e2f498" + } + }, + "signature": "4d8da558a3bc4c0147e868f3c184cbc0754736195f28d613c978ba8ad0367a898d1fa1d19da1b92e6475cb5d28eefa086c164e7dc38c10a5d9e4a9f3f2ea6500", + "id": "9605682894241220583", + "senderId": "6463707033609101884L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a5ab4bc66443c0390bc3ea1d81a956af22a60848b30ffca17d966d3ab138e94e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "someone" + } + }, + "signature": "1ffc7aeaa4e112b0b8e55c8c5403b6ea25193fa7e4ebbea3dd887f8b7245835d5af9fb28cceec14bed00b5bb3f8ad904eb9208d27c113f158ca3a95598f8550c", + "id": "11515613043438979039", + "senderId": "6463707033609101884L" + }, + { + "amount": "0", + "recipientId": "6463707033609101884L", + "senderPublicKey": "a5ab4bc66443c0390bc3ea1d81a956af22a60848b30ffca17d966d3ab138e94e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a5ab4bc66443c0390bc3ea1d81a956af22a60848b30ffca17d966d3ab138e94e" + ] + }, + "signature": "bf23a3f790159d9deb798ba6e4c7d3fa0b7d8245d60e0a92647582ffe16683feac693859e907d4583dbd72b7dd1b11c08ffad1f63f8abf5c2e5f64660942a205", + "id": "6803621014735257559", + "senderId": "6463707033609101884L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a5ab4bc66443c0390bc3ea1d81a956af22a60848b30ffca17d966d3ab138e94e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a5ab4bc66443c0390bc3ea1d81a956af22a60848b30ffca17d966d3ab138e94e", + "+eac4142cd49c21e3e213cbf84e1f0419ed6f26104f99e6860fee404b86e2f498" + ] + } + }, + "signature": "6d211ecab16a350628e4296ffd4ff40d73737b5ef91e617934da07ec0733eed305da675af60f12a530bcac5dc4fd7c4de4265d910a3a81f033bfe5b68fc72a08", + "id": "13224939353551211816", + "senderId": "6463707033609101884L" + }, + { + "amount": "1000000", + "recipientId": "2620728400056693845L", + "senderPublicKey": "9f00ebd27711d06ef917809e59553ab8d4464d1bacd48315881562a6df9312ce", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "22db9aaee342c885155ca08b57f14bd2cbef7937d8c2c81ffea17b6fcd599e28281a65008b2850696c1641fcfc4644a731e53e5c0443333d158397d6e446520f", + "id": "8751755043205664610", + "senderId": "2620728400056693845L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9f00ebd27711d06ef917809e59553ab8d4464d1bacd48315881562a6df9312ce", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "84534502343f3c4d8b3577a5c6428d650be76d744f76372557c2f33f85ae7dab" + } + }, + "signature": "d39a3bf4dfb0f41af5a8fa98289f4126db41d2802a42f157d434c66d8f232be75f031e6b8c6734104e062ba1dfd4be8e2e3c17544ae0dc6adbd0b2f8db1b6f03", + "id": "13917036938387173847", + "senderId": "2620728400056693845L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9f00ebd27711d06ef917809e59553ab8d4464d1bacd48315881562a6df9312ce", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "faith" + } + }, + "signature": "e3963fb640bfb82fe88216bc785733cd3a355695b076144795308f1470054133e18bdfebfc9b2305620307d28f008b1626cc53dde2675dfdce106c8708d5f702", + "id": "1181790226313704768", + "senderId": "2620728400056693845L" + }, + { + "amount": "0", + "recipientId": "2620728400056693845L", + "senderPublicKey": "9f00ebd27711d06ef917809e59553ab8d4464d1bacd48315881562a6df9312ce", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+9f00ebd27711d06ef917809e59553ab8d4464d1bacd48315881562a6df9312ce" + ] + }, + "signature": "c6d15ca2b19f8fa41782c6630115b3fdb50c25ec7a4e7dcdabd10cdfbfdee3eff65cddc98478600c5bc68667049c9f246d4ed5a1e984ec40dc71599da46ccb04", + "id": "9035566158481652333", + "senderId": "2620728400056693845L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9f00ebd27711d06ef917809e59553ab8d4464d1bacd48315881562a6df9312ce", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+9f00ebd27711d06ef917809e59553ab8d4464d1bacd48315881562a6df9312ce", + "+84534502343f3c4d8b3577a5c6428d650be76d744f76372557c2f33f85ae7dab" + ] + } + }, + "signature": "c7fb8086d554b88c98112de79f976a4e71af4c99c7a157c624292a10a57c653178ba64e8d7a11dca61461fab461dcdbd8fd9fd94a9c4260a3421dd260ef9ba03", + "id": "16104280632236319124", + "senderId": "2620728400056693845L" + }, + { + "amount": "1000000", + "recipientId": "7092421626858565089L", + "senderPublicKey": "2cbcd6eeeb208363e71de31e9f77d069bb153e551eb5db5a7f014906d3b4155b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "c7313fe5ee0f636cde72ddca6c2e200f50caff6a678e700fa6050c9257b098102fad850e2bba9cf04a77c36e4c54e8ee02f5476e3b41b027ac1072157896ef0e", + "id": "13187226823601406059", + "senderId": "7092421626858565089L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2cbcd6eeeb208363e71de31e9f77d069bb153e551eb5db5a7f014906d3b4155b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "de067d48f669321bbb73a748b088c0367b8eedccfd2aceeb5da5d465a9e2e9bf" + } + }, + "signature": "53a21199ca4f3fcc146515b400fb1617de91009dbc240d819f18fd24bbd13a223aa1be8a0734036b28f841718c3dcb641935507202fb41b7ad07f57f00009709", + "id": "5711484869345147870", + "senderId": "7092421626858565089L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2cbcd6eeeb208363e71de31e9f77d069bb153e551eb5db5a7f014906d3b4155b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "want" + } + }, + "signature": "d27b8976e392ff27820737cc52031fb8d53cc8412c849dd94f39c7798ef5f41057a596fb5456792f048c43abcfc8e6e24592217249c363f4ff2bce0aa746e60a", + "id": "3567716536836440510", + "senderId": "7092421626858565089L" + }, + { + "amount": "0", + "recipientId": "7092421626858565089L", + "senderPublicKey": "2cbcd6eeeb208363e71de31e9f77d069bb153e551eb5db5a7f014906d3b4155b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+2cbcd6eeeb208363e71de31e9f77d069bb153e551eb5db5a7f014906d3b4155b" + ] + }, + "signature": "8531d210cf749412ba93974ce7692a371b1cb75e479fc0fbadc968e1703ec2d890292483de4f61991a3e0796086d80eafec473bf2d96f7c6e5e4d03fd7d8c505", + "id": "8994401988479954719", + "senderId": "7092421626858565089L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2cbcd6eeeb208363e71de31e9f77d069bb153e551eb5db5a7f014906d3b4155b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+2cbcd6eeeb208363e71de31e9f77d069bb153e551eb5db5a7f014906d3b4155b", + "+de067d48f669321bbb73a748b088c0367b8eedccfd2aceeb5da5d465a9e2e9bf" + ] + } + }, + "signature": "99c3fbe0aa6bebbd41e576d08e7dea0c1feeeb1e4969a83249209d068e42db26704127ea47f11fcf9fa90931b553237aaca119cbe01c715b1811c7c042686009", + "id": "1851026226580955458", + "senderId": "7092421626858565089L" + }, + { + "amount": "1000000", + "recipientId": "8991647492352376810L", + "senderPublicKey": "a5ec20fda5c263eed32bb7f4af640a6f3865077c2801b2a56af8a28ebd6701ec", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "8510bd0ba6eb61f0745713ae145d332b35ce4fe84d5f638b96b5e54422da9c253356d8bfef1d5f4668991c18cd80402eeb9fc67ea1179f79bc8559c234dfee09", + "id": "6990823051075565282", + "senderId": "8991647492352376810L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a5ec20fda5c263eed32bb7f4af640a6f3865077c2801b2a56af8a28ebd6701ec", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "15b150223721e29f158ffbe2715462de9b52255f6ec9b411174f263d5eb06f51" + } + }, + "signature": "01c906250b1baa030d3f299ec64e112e7e79d8e3c156004acdd36b045fb9407e00e0cd0d7535a30995d6e99e8b969a92cc4ef6137a909f49c208994b4b0ac70a", + "id": "17779888953583143139", + "senderId": "8991647492352376810L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a5ec20fda5c263eed32bb7f4af640a6f3865077c2801b2a56af8a28ebd6701ec", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "baby" + } + }, + "signature": "8ae1e55da88480fdb546cbbd5b28bcfd03534438b691d735120d6054e1e4280816a38962a7839d6549b31adfc5879d3bd0b1e9e4884343a656c275f4c9dcaf01", + "id": "15189548850663561575", + "senderId": "8991647492352376810L" + }, + { + "amount": "0", + "recipientId": "8991647492352376810L", + "senderPublicKey": "a5ec20fda5c263eed32bb7f4af640a6f3865077c2801b2a56af8a28ebd6701ec", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a5ec20fda5c263eed32bb7f4af640a6f3865077c2801b2a56af8a28ebd6701ec" + ] + }, + "signature": "0a38f054d9f1b5906dbee3607a6c48464807d7f56f358da66114f6bc70fd9853f250bc809dfa8001267c918afaa62a8fe1ce3af83eb311ca488e6908a3dda004", + "id": "9104835860366737223", + "senderId": "8991647492352376810L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a5ec20fda5c263eed32bb7f4af640a6f3865077c2801b2a56af8a28ebd6701ec", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a5ec20fda5c263eed32bb7f4af640a6f3865077c2801b2a56af8a28ebd6701ec", + "+15b150223721e29f158ffbe2715462de9b52255f6ec9b411174f263d5eb06f51" + ] + } + }, + "signature": "bdbc1091881315c05460d03cc48031895e43b870be46ce3c3ed3d74d162e661b124a30fa9f2999db475cd6181fe99f7932e9f9b1312b5e670f926ad9faa0a204", + "id": "17068574297881951605", + "senderId": "8991647492352376810L" + }, + { + "amount": "1000000", + "recipientId": "10592856102130455468L", + "senderPublicKey": "fd0aedad4fcf996eadab8f64c2a549360ae880597c6e6d536646063aae359d11", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "b4929f5fa69106c05e40c8ed33e02ec6512ca7931c73030d712683d8295f9c60df300287feb626d78f88ab551296596957fbb4bd741a7160cb5439b43331a708", + "id": "59713028563780081", + "senderId": "10592856102130455468L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "fd0aedad4fcf996eadab8f64c2a549360ae880597c6e6d536646063aae359d11", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "bb64cd281dbf3b59a97f573cef5f6bf4c55478b93ed07c763ae2f2b5d3ab0b9c" + } + }, + "signature": "9848fd6fcf95e1b99db5c3de7d82ab9d74deaaaf890eafb3ec08951bb3671ebe59ca8f8a7f028ee5c4b8cbb980ad5470efc1689d8c40aa0475015e3c51a66508", + "id": "15171375347031193858", + "senderId": "10592856102130455468L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "fd0aedad4fcf996eadab8f64c2a549360ae880597c6e6d536646063aae359d11", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "blush" + } + }, + "signature": "3f2cae8adc82546503f0f32dd40a18ae921e8e258f11898f449eba826ef20ede8754d922bd9a401f9bab0a9bb895c8ff3d5d8f0a13f5dd13b5fb1cacdadd0009", + "id": "3346867766501774809", + "senderId": "10592856102130455468L" + }, + { + "amount": "0", + "recipientId": "10592856102130455468L", + "senderPublicKey": "fd0aedad4fcf996eadab8f64c2a549360ae880597c6e6d536646063aae359d11", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+fd0aedad4fcf996eadab8f64c2a549360ae880597c6e6d536646063aae359d11" + ] + }, + "signature": "34cde9d4aa36ef6988d92788da6f376cffbd80698c543f6f8bd714319cf7e8bb9215d1e7a6131c15ed3e31a407f91b9fa5e8601fbca47efcef9c3296d6872f0a", + "id": "2055161057368621334", + "senderId": "10592856102130455468L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "fd0aedad4fcf996eadab8f64c2a549360ae880597c6e6d536646063aae359d11", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+fd0aedad4fcf996eadab8f64c2a549360ae880597c6e6d536646063aae359d11", + "+bb64cd281dbf3b59a97f573cef5f6bf4c55478b93ed07c763ae2f2b5d3ab0b9c" + ] + } + }, + "signature": "ce58a17aade6525df7fedd8942fa57f75cb5060e01d707164a695c6dadd1aa58f7d650fc47cd9c7894dcca939d301195d873f92958022f85e34cfae90d379c07", + "id": "17731443220331141976", + "senderId": "10592856102130455468L" + }, + { + "amount": "1000000", + "recipientId": "15076415483326273316L", + "senderPublicKey": "dfb9e7398bea08f7e7535eff06155284fd890ed96d3daa20c910e8d9e84f4a18", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e55fcf3c5b00bf3fb65d51be294b3e3431d4922b7f7e67ad52f579dd8692897f9755ebe8d8c26edf7fe73be5902036b8675559e5d1f579b654697fc791e3150f", + "id": "2314933010100479006", + "senderId": "15076415483326273316L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dfb9e7398bea08f7e7535eff06155284fd890ed96d3daa20c910e8d9e84f4a18", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "2a6bf06dd82b3586d068302304654664e01af33166189adaa00ffde322926b48" + } + }, + "signature": "6696a4588df91cf377d506cdc8ea1943270381be91b84ed41ecc8176a41f2e769439d962655f824dc3602d0dd9962b78d88add1073b1275ea919ad07e896d50e", + "id": "17889782091844898552", + "senderId": "15076415483326273316L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dfb9e7398bea08f7e7535eff06155284fd890ed96d3daa20c910e8d9e84f4a18", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "pumpkin" + } + }, + "signature": "1a48d3648f961282c0f51e210318d6345ffd0ff1db9ffc99e0341d58adbfc737ba1f8ab8743d157026faa5966cb26c1ed92930cfc5ca4c4cfd0ead16760bab01", + "id": "10837517773106941951", + "senderId": "15076415483326273316L" + }, + { + "amount": "0", + "recipientId": "15076415483326273316L", + "senderPublicKey": "dfb9e7398bea08f7e7535eff06155284fd890ed96d3daa20c910e8d9e84f4a18", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+dfb9e7398bea08f7e7535eff06155284fd890ed96d3daa20c910e8d9e84f4a18" + ] + }, + "signature": "eb00c79fe61d0dc3297833b706527c02cbac6dc3c2a588516332aae54b094a86de530ce4f0c3959af4722c5daa199d38e82d6d4b753ff43be33e6a06cf188100", + "id": "378477043629476534", + "senderId": "15076415483326273316L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dfb9e7398bea08f7e7535eff06155284fd890ed96d3daa20c910e8d9e84f4a18", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+dfb9e7398bea08f7e7535eff06155284fd890ed96d3daa20c910e8d9e84f4a18", + "+2a6bf06dd82b3586d068302304654664e01af33166189adaa00ffde322926b48" + ] + } + }, + "signature": "7204510dadda2f6f5dc43c6a374559365109b363a7b4527b154ec471e49686811655e9ce002e6d1a07ace8700092c91e4ba0c56c49b19cc5b2122c86949e8d06", + "id": "17537049636459194242", + "senderId": "15076415483326273316L" + }, + { + "amount": "1000000", + "recipientId": "11533093589842670896L", + "senderPublicKey": "0499185401817391c9bfdde1bd4a612f7ca322bb400ae1ce0b4d3adb438e1c0a", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "fcc04a4f62a3218db472e4987d71148716342a4ad93bddd7ae9a58d9bc101e6b70566a19a97957f5185784ce0c5e936ef0530df6755ba6798d02670cf35e7c02", + "id": "13893064038222463208", + "senderId": "11533093589842670896L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0499185401817391c9bfdde1bd4a612f7ca322bb400ae1ce0b4d3adb438e1c0a", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "24080f4e09bfa9396d60d93349271a0491f1f535b3a628f083648e68f3c85b0f" + } + }, + "signature": "921c3b1f4d4f534bd5fd38654952ab2c10144d4279068456d9486de49b273da6f5d7ef31423d6b72657ee0d7bcac1ea0531be2308242321afb2b42528a0cb80c", + "id": "14271398820515470521", + "senderId": "11533093589842670896L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0499185401817391c9bfdde1bd4a612f7ca322bb400ae1ce0b4d3adb438e1c0a", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "despair" + } + }, + "signature": "c0a58bb16433c3e952023e2e590901a707ca3cf6bccb5b944dbe41b64cad50ddfb79c94d0d1963e17d5f813d9da83bb3708be43003025aeef24206209e8eb601", + "id": "385891119007479006", + "senderId": "11533093589842670896L" + }, + { + "amount": "0", + "recipientId": "11533093589842670896L", + "senderPublicKey": "0499185401817391c9bfdde1bd4a612f7ca322bb400ae1ce0b4d3adb438e1c0a", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+0499185401817391c9bfdde1bd4a612f7ca322bb400ae1ce0b4d3adb438e1c0a" + ] + }, + "signature": "ec3f8fb9f66cfae051acf931b11e33f99334a77ef643a9d0a9628725610ef6fe62287e9f9345e61aa68174821d95322857cdce03290dce4c6a397723fb683d0c", + "id": "14416151415026401835", + "senderId": "11533093589842670896L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0499185401817391c9bfdde1bd4a612f7ca322bb400ae1ce0b4d3adb438e1c0a", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+0499185401817391c9bfdde1bd4a612f7ca322bb400ae1ce0b4d3adb438e1c0a", + "+24080f4e09bfa9396d60d93349271a0491f1f535b3a628f083648e68f3c85b0f" + ] + } + }, + "signature": "be80c3a4c4ec6a4a8e0857176d62b5e475664a6fb7b65e2286c825690404875c2751e0f2be5023a4454b4db5dddd34dc6a6bae12cd09f180435781a00137990d", + "id": "6750718786599750981", + "senderId": "11533093589842670896L" + }, + { + "amount": "1000000", + "recipientId": "5239508044876751503L", + "senderPublicKey": "9607212e8d7f0b49f1cdae74e57f950c3e4c5fd5e5cae7aba55f06fcd629409b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "7dab793449216170c15a70a984c942a55d0b001563135255f0e9c1e549a05dde4126008a0218d9975969047c73b1981377a57b417d294d93142276418914ff09", + "id": "6042999577893172546", + "senderId": "5239508044876751503L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9607212e8d7f0b49f1cdae74e57f950c3e4c5fd5e5cae7aba55f06fcd629409b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "cd817fe7c566d38c69cf765950ee9f08c72c3dac40bff5aa9684f0d81877d8ee" + } + }, + "signature": "84df7078c6d183542a063c0bc9db1f44f3961a76ed53febadd2153f7e3d51760af3251876c8cb8a638fbb1ed2e8f1ccfd4088cba5b7ac2ee884eebcda064030a", + "id": "18360896177055927680", + "senderId": "5239508044876751503L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9607212e8d7f0b49f1cdae74e57f950c3e4c5fd5e5cae7aba55f06fcd629409b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "multiply" + } + }, + "signature": "1f1b157c9fd703c01ad33fc762bfd4fe777048c4dd35eff0f6165fc781685f841009a17465803d9681decb445f320d39f02befb35bdf056f65fd27449ac52606", + "id": "6808312193506550219", + "senderId": "5239508044876751503L" + }, + { + "amount": "0", + "recipientId": "5239508044876751503L", + "senderPublicKey": "9607212e8d7f0b49f1cdae74e57f950c3e4c5fd5e5cae7aba55f06fcd629409b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+9607212e8d7f0b49f1cdae74e57f950c3e4c5fd5e5cae7aba55f06fcd629409b" + ] + }, + "signature": "acdd0f7cabec7081502e6445821b5d8ca01d69b5b3a15cc23155247887f4d34808932305002e9b641351aa35927ee571783fefe7ebdc8cc402ee955e7b2d7d01", + "id": "12621347182406528361", + "senderId": "5239508044876751503L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9607212e8d7f0b49f1cdae74e57f950c3e4c5fd5e5cae7aba55f06fcd629409b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+9607212e8d7f0b49f1cdae74e57f950c3e4c5fd5e5cae7aba55f06fcd629409b", + "+cd817fe7c566d38c69cf765950ee9f08c72c3dac40bff5aa9684f0d81877d8ee" + ] + } + }, + "signature": "936bb908d4afe644bb4a2f8852b55e7dce3fb9c7f4ea56769305d36ae794588410c91fd1de0863ed1dba99559de0a18f96193b53672c7c8a967d1d329d993908", + "id": "16761796113265984019", + "senderId": "5239508044876751503L" + }, + { + "amount": "1000000", + "recipientId": "12074326587988059764L", + "senderPublicKey": "1625403fc2c9c417d1caeb104206d46c13a626d23c7d14a12ff4c032e1af2587", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "57aa23b55dae7ab8d2fa96a1002633515b3f0e9ea54ab54a6e57d9098dca395eed4de19a8a065d7bf16229192ac362fb68eeb6b433eada4e4a7f0889f6496404", + "id": "8301313716616067730", + "senderId": "12074326587988059764L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1625403fc2c9c417d1caeb104206d46c13a626d23c7d14a12ff4c032e1af2587", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f81b709e7d68eea03a8ccc253fc2e79bcf0b920563ae446fa3be4422be62160a" + } + }, + "signature": "122d6a0ebc75878c48cbdbfbb697b56c94e29100d2af8e58ede6d2269b2ac5f5d976631cb6920c546abd93edb6ca7980d2ad3c569a335bc53b294f8b1e0f9302", + "id": "16764933056478675096", + "senderId": "12074326587988059764L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1625403fc2c9c417d1caeb104206d46c13a626d23c7d14a12ff4c032e1af2587", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "average" + } + }, + "signature": "c38a4ab20923edf755cf5143cd510f4637b75b12f563b3cd5956b2e64462af6ebf081d5ef8dab0c248237cfab2fe11a9ddee50583878aff85b987b51b653ae01", + "id": "8993635352751168508", + "senderId": "12074326587988059764L" + }, + { + "amount": "0", + "recipientId": "12074326587988059764L", + "senderPublicKey": "1625403fc2c9c417d1caeb104206d46c13a626d23c7d14a12ff4c032e1af2587", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+1625403fc2c9c417d1caeb104206d46c13a626d23c7d14a12ff4c032e1af2587" + ] + }, + "signature": "f568ea0f5eb04d2d826da421f815f4bfb13c7105638817ba35fe6700bd3cc01d5c0ea7b03caa68d5902eff303feb10338be9b6fbe174843a5608f469250db202", + "id": "4492310597121162911", + "senderId": "12074326587988059764L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1625403fc2c9c417d1caeb104206d46c13a626d23c7d14a12ff4c032e1af2587", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+1625403fc2c9c417d1caeb104206d46c13a626d23c7d14a12ff4c032e1af2587", + "+f81b709e7d68eea03a8ccc253fc2e79bcf0b920563ae446fa3be4422be62160a" + ] + } + }, + "signature": "3313ef18c4c62701f16ec8f3b0f58fc95d0078f9daf24cc1b5e3d619f89e951e08b68a54d276782dd9d60a0b2482f347e5aafe01eaf583d2a1e1d04d86f2ba02", + "id": "4000145615297033284", + "senderId": "12074326587988059764L" + }, + { + "amount": "1000000", + "recipientId": "16747552654097155732L", + "senderPublicKey": "c3461d9a97f2f6b1750f7bda9532b65b6252bdaefa5a7368846490e8694d9c04", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a0370b0019043f7069736719302c02fa24f6fcb9fd73c282aaa0c79b578d827adb151b4a6626ee8521b068c48fda60206727f606b3da822829443411e9bced02", + "id": "8108156555569776700", + "senderId": "16747552654097155732L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c3461d9a97f2f6b1750f7bda9532b65b6252bdaefa5a7368846490e8694d9c04", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "6a418759d0d45e1dc9e47a5856f38d43fdc824b2cd9f64d7e0f6b0c7e70b15b9" + } + }, + "signature": "b8f977463a5fea128706221bcb5089cba6879936d446b78542da557914b22515aaa2a82c559cb732450c2d869468aa0f0b9bd77363edd94692db5f3267a67002", + "id": "16679547893350308218", + "senderId": "16747552654097155732L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c3461d9a97f2f6b1750f7bda9532b65b6252bdaefa5a7368846490e8694d9c04", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "great" + } + }, + "signature": "a6fc616b66723fbebe2155cbedb1e9a350c41de3575b824a74c08ead41aa649e1615b3040144b3ff1aede9ca6740b0319ab473ac5ef1b2a43bc22bd94930f00e", + "id": "8405331608729590326", + "senderId": "16747552654097155732L" + }, + { + "amount": "0", + "recipientId": "16747552654097155732L", + "senderPublicKey": "c3461d9a97f2f6b1750f7bda9532b65b6252bdaefa5a7368846490e8694d9c04", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c3461d9a97f2f6b1750f7bda9532b65b6252bdaefa5a7368846490e8694d9c04" + ] + }, + "signature": "205fc06a645bbe23ed38aae8b9be82b97ef735f5cc73991a6a0e0a93f717e75b36afd553b9c413e1aaa18a074fa71d4cc5fbc53e8f3c1112e427248ce9cbbe0f", + "id": "7758972057381457518", + "senderId": "16747552654097155732L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c3461d9a97f2f6b1750f7bda9532b65b6252bdaefa5a7368846490e8694d9c04", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c3461d9a97f2f6b1750f7bda9532b65b6252bdaefa5a7368846490e8694d9c04", + "+6a418759d0d45e1dc9e47a5856f38d43fdc824b2cd9f64d7e0f6b0c7e70b15b9" + ] + } + }, + "signature": "37ef9cee41904c0f3b317e4bf7df4a8e9316facf7c7296598e17bcd12de68795d37ef5c03fcc3ba05926548e4aa5b88798084be55cf86c70dfc5935de456b70e", + "id": "14502603517156248174", + "senderId": "16747552654097155732L" + }, + { + "amount": "1000000", + "recipientId": "6288876117737393283L", + "senderPublicKey": "910d802b398c096f9f68cb5dfb2f237028da9b7d25f4d997e43361bf3b9eb2a5", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "7d8686051fb94bf83e44bb06da6f93fe68deb8e18b68e9c99fe65e0dd30745cd3b5cbec5005f21b1cb4789ab68b77678c12418281b5b896076afa08241445d06", + "id": "7016054011068628206", + "senderId": "6288876117737393283L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "910d802b398c096f9f68cb5dfb2f237028da9b7d25f4d997e43361bf3b9eb2a5", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "916935d5217ef295e4a93144d04965e6ed48beebb4fb8f5a6a10b41c16dad120" + } + }, + "signature": "c1f070a421f56839403b8b22eeccb9631ef6c036b31ba1dd4520e4bab6c2532147e09c1c857fb391e814b40c453e4e334f3bc143609e47f3ad0502130d7af708", + "id": "13008030209655887441", + "senderId": "6288876117737393283L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "910d802b398c096f9f68cb5dfb2f237028da9b7d25f4d997e43361bf3b9eb2a5", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "cherry" + } + }, + "signature": "39b49f101b08db7df540a120e41ec32b728db9250796c1a7375cc91417d93e097d99dff9acf2114370fd726472bb1700fc9c52239719c436e19f318724dcd700", + "id": "694264742822792193", + "senderId": "6288876117737393283L" + }, + { + "amount": "0", + "recipientId": "6288876117737393283L", + "senderPublicKey": "910d802b398c096f9f68cb5dfb2f237028da9b7d25f4d997e43361bf3b9eb2a5", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+910d802b398c096f9f68cb5dfb2f237028da9b7d25f4d997e43361bf3b9eb2a5" + ] + }, + "signature": "86ac0663995ebb981073c20bb242f5fc22862febd50a8468a966fc28d4a5e5250a6139b165c6880c0272cff19fce1749d8e838b8a0c1f58424849071a17f050b", + "id": "10345788423839420738", + "senderId": "6288876117737393283L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "910d802b398c096f9f68cb5dfb2f237028da9b7d25f4d997e43361bf3b9eb2a5", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+910d802b398c096f9f68cb5dfb2f237028da9b7d25f4d997e43361bf3b9eb2a5", + "+916935d5217ef295e4a93144d04965e6ed48beebb4fb8f5a6a10b41c16dad120" + ] + } + }, + "signature": "a48dcffd994ed2e776eda7e76da0dcf3f3c93e004f5cb86a5e8502b75e82c0eb60f5fc407cdb91d20514c296a2b7233d7bafe0e2edc6a7a9b4028abe43d73707", + "id": "8111040001000487762", + "senderId": "6288876117737393283L" + }, + { + "amount": "1000000", + "recipientId": "10740561143240537279L", + "senderPublicKey": "f9ccf5ba72337ba4feb4ed0d7bdaccd4e609b3f1638b9a7ff082efa38486c2e7", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "b65bf82fac0321b008b6aa84e2d9cef729f74e0ee123a51d1451fac45d9f0d3a3b53401974a0d80dc36d9f4bf2ac0bb96ac26978e62717fa886533da1a13320f", + "id": "6449312427686582402", + "senderId": "10740561143240537279L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f9ccf5ba72337ba4feb4ed0d7bdaccd4e609b3f1638b9a7ff082efa38486c2e7", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "43be3233b507ea2b8b5a37c3cee600ed2c10b8e62727d7cbe18588c51ad0ae29" + } + }, + "signature": "c6917915ef61400ffaf751ed8ecee3cef149d8c9523c0fb882f44d9f0de743e326847aeea9f9c8e3b3d27b53436ec121af5bea3cb67e5489edc4b861c887f702", + "id": "9961798789289605413", + "senderId": "10740561143240537279L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f9ccf5ba72337ba4feb4ed0d7bdaccd4e609b3f1638b9a7ff082efa38486c2e7", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "february" + } + }, + "signature": "375e504a12462c6790af8ec22261cde4dd8ad586e8103781e4666aeedddf245ffa5878ba31df35eecd56d6f74535e4afbb6667af6d20198c09328829d8482a0e", + "id": "9770379414272285356", + "senderId": "10740561143240537279L" + }, + { + "amount": "0", + "recipientId": "10740561143240537279L", + "senderPublicKey": "f9ccf5ba72337ba4feb4ed0d7bdaccd4e609b3f1638b9a7ff082efa38486c2e7", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f9ccf5ba72337ba4feb4ed0d7bdaccd4e609b3f1638b9a7ff082efa38486c2e7" + ] + }, + "signature": "1ad4b9d26bcc51a2c5e5c72633f831536982d1d52f63b9fb85347dee61077743d12bf1c786d14753100068b459b7964cb2a2846fc347f05ca16b33c9ada10d08", + "id": "11369140888723254542", + "senderId": "10740561143240537279L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f9ccf5ba72337ba4feb4ed0d7bdaccd4e609b3f1638b9a7ff082efa38486c2e7", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f9ccf5ba72337ba4feb4ed0d7bdaccd4e609b3f1638b9a7ff082efa38486c2e7", + "+43be3233b507ea2b8b5a37c3cee600ed2c10b8e62727d7cbe18588c51ad0ae29" + ] + } + }, + "signature": "4469fd0c3baf71050e6675db54a3f4a961f5b95265f0dc41daac18f7fe305fad0dd02fc043745cfef6a16cc5e7491768eebc8c67cc27098db05eaff10b394502", + "id": "2306554595269875759", + "senderId": "10740561143240537279L" + }, + { + "amount": "1000000", + "recipientId": "12463861798866987577L", + "senderPublicKey": "228bbf1abfe77285541d501c0cc9dca93e386243c1d8ac62c0a7df68593bfe75", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "99642c05c45721320aaa163a47483099a532763427203166fc7cf7aa350c114bf75bfd045c3e0cb5286aadd50df1b4367c62d4e9f59744955f9de6784358a703", + "id": "6355132708213298002", + "senderId": "12463861798866987577L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "228bbf1abfe77285541d501c0cc9dca93e386243c1d8ac62c0a7df68593bfe75", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "2f47c95713a1ed22b5b8a3f4974d7b639588381ca2c5b2f03058cfeb37498f22" + } + }, + "signature": "aba58db6e04065736784f87f5a063fcc2939aef0528458db447d03c78fd2cc463bb724f7e48e3683b65fc104216bf4d9bd10c0dbc61daeac2abaf676dfcd7f04", + "id": "5024693274840121882", + "senderId": "12463861798866987577L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "228bbf1abfe77285541d501c0cc9dca93e386243c1d8ac62c0a7df68593bfe75", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "pizza" + } + }, + "signature": "ab16365c0ada7cdecbae65002239f0d37f7caee295d757d26711a06f9a3e2f6a8a980d5dab9ff0116ea2e10dcbee8255dbba92fca09b0ff4ae0921b81bffe309", + "id": "14723525949175243826", + "senderId": "12463861798866987577L" + }, + { + "amount": "0", + "recipientId": "12463861798866987577L", + "senderPublicKey": "228bbf1abfe77285541d501c0cc9dca93e386243c1d8ac62c0a7df68593bfe75", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+228bbf1abfe77285541d501c0cc9dca93e386243c1d8ac62c0a7df68593bfe75" + ] + }, + "signature": "b37c83fdd7121603d2e9811c77c1440ccd9dad490f3ffa4126670a02f1fb112ca203a70395952d6de21257b347c2f4783683b2076b2af10c50fda4eec370910c", + "id": "10400311592002226793", + "senderId": "12463861798866987577L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "228bbf1abfe77285541d501c0cc9dca93e386243c1d8ac62c0a7df68593bfe75", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+228bbf1abfe77285541d501c0cc9dca93e386243c1d8ac62c0a7df68593bfe75", + "+2f47c95713a1ed22b5b8a3f4974d7b639588381ca2c5b2f03058cfeb37498f22" + ] + } + }, + "signature": "519ccd9042d9487d0e3e5b8e23924230fe9235d8511f58d4554b013082721187ca84d1e32f612db1820a33a739cbe5e6d306ddad7c457c226cd5c82e2af58003", + "id": "11271079547458348073", + "senderId": "12463861798866987577L" + }, + { + "amount": "1000000", + "recipientId": "16512507299434191375L", + "senderPublicKey": "0582ab087459e9a003540fff3d53dc31cfc2959fe0a52aff7c6ebf4f201907f4", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "da9ac99d0991e6dcd88bcb2a7757d5309b31396b8e9053a408ad4b60c72642f1ca035cced3622cd80e15217cb3484c5289713bf8daa1ddf32b14c5cc9e79900f", + "id": "14410482460000092376", + "senderId": "16512507299434191375L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0582ab087459e9a003540fff3d53dc31cfc2959fe0a52aff7c6ebf4f201907f4", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d223616284c4819cf78f1149e2efb25244955b4969bb99247c5fe93d055d1175" + } + }, + "signature": "2f74a3c0ae0c7a8f657d0b58e7a1b40604e3b8d7215b8c30f60401bff30a666a1920482115c62bc120a9043028b6b8598303d27dd4a97443fb548d7375bc6906", + "id": "612501425221999799", + "senderId": "16512507299434191375L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0582ab087459e9a003540fff3d53dc31cfc2959fe0a52aff7c6ebf4f201907f4", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "body" + } + }, + "signature": "a824337537b0db18776436d04b98010f783b134539f267872dda27e6d3c0d4a64f61224920e421aaead44b47830aef875430b93d9e5065821f402fdaba73e10f", + "id": "10101554923763003866", + "senderId": "16512507299434191375L" + }, + { + "amount": "0", + "recipientId": "16512507299434191375L", + "senderPublicKey": "0582ab087459e9a003540fff3d53dc31cfc2959fe0a52aff7c6ebf4f201907f4", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+0582ab087459e9a003540fff3d53dc31cfc2959fe0a52aff7c6ebf4f201907f4" + ] + }, + "signature": "fed0ea5f04bcb2c6411b5e56f8f0e11343076e5cf8b47be987f7c11472c50497eac55f788c7318c4066d97d075554cd2da8037b3423a98d07f0d7419dd0ecc09", + "id": "5799945961007847292", + "senderId": "16512507299434191375L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0582ab087459e9a003540fff3d53dc31cfc2959fe0a52aff7c6ebf4f201907f4", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+0582ab087459e9a003540fff3d53dc31cfc2959fe0a52aff7c6ebf4f201907f4", + "+d223616284c4819cf78f1149e2efb25244955b4969bb99247c5fe93d055d1175" + ] + } + }, + "signature": "00daf0c41d62a9e36e00c1e9732bf52003d312f5013ce53bb07804b09048ede08d1528b00ddbfc76a0f18431593d5061094c5edcc6297bb9ad03e0299e28ba03", + "id": "1936372784403305735", + "senderId": "16512507299434191375L" + }, + { + "amount": "1000000", + "recipientId": "12855517753836685925L", + "senderPublicKey": "a4d639f3570f33a39d7c8713ea0ec9869c434a051cc0d26aa769c9c5626bae19", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "83f3c6a8f68448806b1608b3afaab9f96afc9b5d34dc0f9c0deee090a9098c4ba1dc240f2015c68b4dced6332b403982eec6095026d19ed1ee4fab23ccd00704", + "id": "6372563045601689854", + "senderId": "12855517753836685925L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a4d639f3570f33a39d7c8713ea0ec9869c434a051cc0d26aa769c9c5626bae19", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d35d86e024fc961bfb1246814cf8f2f271003018c130b9ece2d6d412aa3c5812" + } + }, + "signature": "86c11534bb4d1028cc10cdcc5acee3ff2e578eece9093668a2183caf93a42c4bfc0a78e9da9ee6062bd20b958c32872974fe6508a58a77cce898911e5bf57b06", + "id": "3807383289094868721", + "senderId": "12855517753836685925L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a4d639f3570f33a39d7c8713ea0ec9869c434a051cc0d26aa769c9c5626bae19", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "space" + } + }, + "signature": "0b208b31644b7e63d8689607a52403ced485f2d2004f7ab83d5dcb1f76d984f7b3a3e7ba8b8d72a4f1a03699fd9f0fc40edaf1a01374cad7de15cf8e4dbb6d04", + "id": "3106485615387278992", + "senderId": "12855517753836685925L" + }, + { + "amount": "0", + "recipientId": "12855517753836685925L", + "senderPublicKey": "a4d639f3570f33a39d7c8713ea0ec9869c434a051cc0d26aa769c9c5626bae19", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a4d639f3570f33a39d7c8713ea0ec9869c434a051cc0d26aa769c9c5626bae19" + ] + }, + "signature": "ddc9ea2a32b233fc4b13fd2479ecadb9b59e58832f9470ec1a02efbb1b5cee0f477a2d361f679710302c53610a3e606c7e8370ef17939db4ebe62ee48dd70b01", + "id": "12073650409296348924", + "senderId": "12855517753836685925L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a4d639f3570f33a39d7c8713ea0ec9869c434a051cc0d26aa769c9c5626bae19", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a4d639f3570f33a39d7c8713ea0ec9869c434a051cc0d26aa769c9c5626bae19", + "+d35d86e024fc961bfb1246814cf8f2f271003018c130b9ece2d6d412aa3c5812" + ] + } + }, + "signature": "8e0d03a6f858ab8e15ab0f0511649556e255fd4e1a148c1951ee0e46f832d142394290cb73bd19964c8c1a70420aeeadb8d1fdc48c33c76a28c17ce45052c703", + "id": "2573389637447274516", + "senderId": "12855517753836685925L" + }, + { + "amount": "1000000", + "recipientId": "16325501434090710761L", + "senderPublicKey": "67a9a0f490be0897f46febe1268b39998720ef3d408520443cd3312b50178015", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "5e28360deed51134fad572c9aa209b36740eb903dcfbb3ddc18725f8928d58d0ce012467d0b3978dc83345085985dbdba2faf9519c0289f9cee216254bfb220d", + "id": "5241503587489873134", + "senderId": "16325501434090710761L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "67a9a0f490be0897f46febe1268b39998720ef3d408520443cd3312b50178015", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4821c37651d2db21a68520a5e27fff1a36a7b2badad6845b111f74e8718c78be" + } + }, + "signature": "861d378a81e21744012d0e22d8c27088c22d9484212ef09dbd10cf9ea27d8e24c605b0b0e93d4012adc5b3fa5cba1b0050fef8474b55c830f86fee31fe7b110b", + "id": "9221590987550598669", + "senderId": "16325501434090710761L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "67a9a0f490be0897f46febe1268b39998720ef3d408520443cd3312b50178015", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "then" + } + }, + "signature": "b9bf65a936d9a6f57ac9f70ea98babfe18812bd44575461e4f5f277732c4e3585275058d448f68cecd5226388d2d3ef548b6d9f4ea2e2eefc8d3023e40ba4d0b", + "id": "16871812063468531387", + "senderId": "16325501434090710761L" + }, + { + "amount": "0", + "recipientId": "16325501434090710761L", + "senderPublicKey": "67a9a0f490be0897f46febe1268b39998720ef3d408520443cd3312b50178015", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+67a9a0f490be0897f46febe1268b39998720ef3d408520443cd3312b50178015" + ] + }, + "signature": "5e141038fcc97191f9dd310a53f86caf2af1814ef82d9c1d2e6bab8524dad0bf46000ec4e7962f6bbc768cce4c8555e8ccf41acc156c01015cebbe80507dd40e", + "id": "6732362152021656959", + "senderId": "16325501434090710761L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "67a9a0f490be0897f46febe1268b39998720ef3d408520443cd3312b50178015", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+67a9a0f490be0897f46febe1268b39998720ef3d408520443cd3312b50178015", + "+4821c37651d2db21a68520a5e27fff1a36a7b2badad6845b111f74e8718c78be" + ] + } + }, + "signature": "cd5b4790d7e749ee51b572602f7a627acfd8cd26c98d3592984861b9513dbf048ccba8fdbc7bc9b84485871d52b8d7c1fe9b0698381b1c822af7195ee589570f", + "id": "9994053251635524983", + "senderId": "16325501434090710761L" + }, + { + "amount": "1000000", + "recipientId": "5424660779191033983L", + "senderPublicKey": "2a4a16d25501494d00ffa49f2ecd8002f46ee1f07d4a4678fafb96780d78e143", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e23864aefc716549781253d4d6ea3b6b486a308b70e2f42341eee94024d4cc7a9a7afffc619abe25e16c7504f5a2468d645f6538cd2b41799dd9d24142820808", + "id": "17535662215569610719", + "senderId": "5424660779191033983L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2a4a16d25501494d00ffa49f2ecd8002f46ee1f07d4a4678fafb96780d78e143", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "47ca5ea9e9d854a7b21f3ff05f2c449490a70a20d690141a1d14cbe4670a08e6" + } + }, + "signature": "fe03edb22699cf3bff0ce2aece6e351d81cd58e2a2212ab7b527048073b0a2491993d046d7cf99f032a3f04916f436fe8fdfb35faeba1886c596411d7362f108", + "id": "4349504283929195607", + "senderId": "5424660779191033983L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2a4a16d25501494d00ffa49f2ecd8002f46ee1f07d4a4678fafb96780d78e143", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "oppose" + } + }, + "signature": "082f30e909bf487f7283afa8d7e404e6efbce170d74e13a0aa38606035f07f43ee8df881ce8c48525db2b92d20a93811f979e649be89e492aeeb539e2b811203", + "id": "9458452013032369613", + "senderId": "5424660779191033983L" + }, + { + "amount": "0", + "recipientId": "5424660779191033983L", + "senderPublicKey": "2a4a16d25501494d00ffa49f2ecd8002f46ee1f07d4a4678fafb96780d78e143", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+2a4a16d25501494d00ffa49f2ecd8002f46ee1f07d4a4678fafb96780d78e143" + ] + }, + "signature": "6e91f74d013c5541aaff360fe791f119c80e440cd29c40dc43f8b1dcf445a28b25616474e31a326762b60a04394b704b9dac3023b801510f79183429ca8b960e", + "id": "12925020835070004862", + "senderId": "5424660779191033983L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2a4a16d25501494d00ffa49f2ecd8002f46ee1f07d4a4678fafb96780d78e143", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+2a4a16d25501494d00ffa49f2ecd8002f46ee1f07d4a4678fafb96780d78e143", + "+47ca5ea9e9d854a7b21f3ff05f2c449490a70a20d690141a1d14cbe4670a08e6" + ] + } + }, + "signature": "1e3fb4a74e73c7353f3290a0eb6843b41a73b998a83de51149f87b8617dce5b36695564023689712c73350f290a8ade9d1f32df87c517c6906dada74b1453f03", + "id": "9802800967705315885", + "senderId": "5424660779191033983L" + }, + { + "amount": "1000000", + "recipientId": "14182590104752563275L", + "senderPublicKey": "246218b0ac0a4c1f8f5bfbfa205d6600e175d03083c98c0e0df0810e0e6055ed", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "bf6c50dda93ac93bfef26ff906b0e3ff36b3506bd28d4d5d6ccf5c06d408f73c73553df25098f99baf801ce717d3e09777c395b4876551278ee075d20963950e", + "id": "507118711542299635", + "senderId": "14182590104752563275L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "246218b0ac0a4c1f8f5bfbfa205d6600e175d03083c98c0e0df0810e0e6055ed", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "157fd96ad08d92d91ec315b9d22e99e7d71d8093b7e53bd43737b76ff5dddae3" + } + }, + "signature": "0e0cb7aa16ada383dbe90fdbaf4301e01c59550def90707d3ff8ea0273403a78a11a9a6755e039ec60088de37a340b25a4ba3e8edb5324344c710cf5ad88140e", + "id": "6636132686453793687", + "senderId": "14182590104752563275L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "246218b0ac0a4c1f8f5bfbfa205d6600e175d03083c98c0e0df0810e0e6055ed", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "chuckle" + } + }, + "signature": "263d1e9483039f98f96224d29c1678a4c20f484047ec48fd3fd4e02a98980abc32333738c03a5777d49e0898cf58f167d3777343a941679df65aa698372ba00e", + "id": "13849517454388300113", + "senderId": "14182590104752563275L" + }, + { + "amount": "0", + "recipientId": "14182590104752563275L", + "senderPublicKey": "246218b0ac0a4c1f8f5bfbfa205d6600e175d03083c98c0e0df0810e0e6055ed", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+246218b0ac0a4c1f8f5bfbfa205d6600e175d03083c98c0e0df0810e0e6055ed" + ] + }, + "signature": "666fbbc528026efc7e31bcdb5ad12fd8b388ade77a4f48e816782940adc3f45d4b719f15a7879afb99d85c16e0800e6f67402165febddd342a20cf810e4e8200", + "id": "7904971259876978689", + "senderId": "14182590104752563275L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "246218b0ac0a4c1f8f5bfbfa205d6600e175d03083c98c0e0df0810e0e6055ed", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+246218b0ac0a4c1f8f5bfbfa205d6600e175d03083c98c0e0df0810e0e6055ed", + "+157fd96ad08d92d91ec315b9d22e99e7d71d8093b7e53bd43737b76ff5dddae3" + ] + } + }, + "signature": "397b3420563e4bf0fbee34adb5da966f72a2520e3df05ef1358759552cd527bf9322f1d7137ed2fc2dcfc89f826c610f8ab589a5b9ca4cf70b1a98f7c304bb03", + "id": "12609481541932975077", + "senderId": "14182590104752563275L" + }, + { + "amount": "1000000", + "recipientId": "5893534871285256844L", + "senderPublicKey": "4644c4362150ba6476dcb25d1b2381a1e75501cd6da6c3531a388a98abe3342d", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "0526dc264e975ef4d33bbaf684db42a2a83d7de7baccfd61e512a6e9deee696968695809754af842df72637ade785cd9cae9e08626bd6dae080419ecbeffc705", + "id": "5316703002910512413", + "senderId": "5893534871285256844L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4644c4362150ba6476dcb25d1b2381a1e75501cd6da6c3531a388a98abe3342d", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f6d4f0949394bdca191250fc65cc2e634f24b764c6c09266883587a1d09effe2" + } + }, + "signature": "28a51a443795b3d9bf89ea0dc68026c27109ad62b9dbb62516cb427edeb061c526ae41d59203bbb8d7dca8a1991995d63d4d134fd8de198222bac4839b11df00", + "id": "14518261725141610153", + "senderId": "5893534871285256844L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4644c4362150ba6476dcb25d1b2381a1e75501cd6da6c3531a388a98abe3342d", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "knife" + } + }, + "signature": "ab3330e664381acad29d6b440c59b1055770495fdb6337c8d0fc87202e1bffdfc1090782e411d1254c10fc0e97905b0be7da004d6eee281228a083c447347209", + "id": "2165775003562753249", + "senderId": "5893534871285256844L" + }, + { + "amount": "0", + "recipientId": "5893534871285256844L", + "senderPublicKey": "4644c4362150ba6476dcb25d1b2381a1e75501cd6da6c3531a388a98abe3342d", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+4644c4362150ba6476dcb25d1b2381a1e75501cd6da6c3531a388a98abe3342d" + ] + }, + "signature": "08827c69e0b60e05fd44f9ed5a34749e5be2c5141f8f240f44a4e77c14003f61dbb795aebdd7b295398579b106c1afc5a752ef5f5212022ee1c4568c98742b0b", + "id": "13842070060398547631", + "senderId": "5893534871285256844L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4644c4362150ba6476dcb25d1b2381a1e75501cd6da6c3531a388a98abe3342d", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+4644c4362150ba6476dcb25d1b2381a1e75501cd6da6c3531a388a98abe3342d", + "+f6d4f0949394bdca191250fc65cc2e634f24b764c6c09266883587a1d09effe2" + ] + } + }, + "signature": "ca62405c90522f8f2a28c0c4d61a00e226032e6bccd7ef3d365e9eaff26cbd1c13973d9560515632ae6cee67572ca60a9871787b31f344fe9464181cffe65301", + "id": "7569554342370975330", + "senderId": "5893534871285256844L" + }, + { + "amount": "1000000", + "recipientId": "12010045913570566959L", + "senderPublicKey": "9e1f5fe2bb7eb8b0ceb3e42a478eadd2ba5a68cbf44401e3132349b899b52ffb", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a85fcfd3d5b0bfa1297582206d182f5971bf314acde29325497448ee86ec076098f5fc2ef35d329efd3faa445f8e3773f11d6ef82713b39f9198b82b5fc2ac04", + "id": "10578646361561468229", + "senderId": "12010045913570566959L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9e1f5fe2bb7eb8b0ceb3e42a478eadd2ba5a68cbf44401e3132349b899b52ffb", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "37650ba065b2c64e9aab09dc4fa9f9977aeac33b3ced9dc44f018ecfbf0b9c58" + } + }, + "signature": "29e25f00cb6007c0250391bb5608b6f829953117ccf096123b613ca83cf4b9018743f1cedc410ea40cb8c7d9d967b59035597f085884959f349fa92e6df43f09", + "id": "17828186896782669134", + "senderId": "12010045913570566959L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9e1f5fe2bb7eb8b0ceb3e42a478eadd2ba5a68cbf44401e3132349b899b52ffb", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "book" + } + }, + "signature": "0cc847bcfd48c31bc2a6221e5e7bd6011ef247a27cb664a80cf9eec150836bacee485e5ba5e9c22b381e97de4c43ddb36b08681ca3225435f2264796606b940b", + "id": "8559348480727931031", + "senderId": "12010045913570566959L" + }, + { + "amount": "0", + "recipientId": "12010045913570566959L", + "senderPublicKey": "9e1f5fe2bb7eb8b0ceb3e42a478eadd2ba5a68cbf44401e3132349b899b52ffb", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+9e1f5fe2bb7eb8b0ceb3e42a478eadd2ba5a68cbf44401e3132349b899b52ffb" + ] + }, + "signature": "83dfa8c578828e7d1c55295aadbd9cf39fe6bcc1adaa82d1c340f9c6fa6d5df33aea8cb66930a6501e93a73727e536f8b99b37cfe1c888c08d345bbde67f9808", + "id": "6978820628850543901", + "senderId": "12010045913570566959L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9e1f5fe2bb7eb8b0ceb3e42a478eadd2ba5a68cbf44401e3132349b899b52ffb", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+9e1f5fe2bb7eb8b0ceb3e42a478eadd2ba5a68cbf44401e3132349b899b52ffb", + "+37650ba065b2c64e9aab09dc4fa9f9977aeac33b3ced9dc44f018ecfbf0b9c58" + ] + } + }, + "signature": "889f0f10ed813c777c1db0bb48be438b17eaada2db17114a6b8d514e61d92e9809b4253730041f6515f09217479c1050ba905f9852823235d650179e4cb96608", + "id": "12110993872977260859", + "senderId": "12010045913570566959L" + }, + { + "amount": "1000000", + "recipientId": "16827243971064478236L", + "senderPublicKey": "0251d537d3278f0317f306e5cd7691363428aa502cdececbd91396aa83ce0135", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "b74ccca78e6fd2f3d39544c70a30acce9a36ffd78cb7b371468df906799b1ce71f08a9af904171cf41b9e8a264913434eda893b9adabe3cb7eff9373637d6504", + "id": "12037270275492909847", + "senderId": "16827243971064478236L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0251d537d3278f0317f306e5cd7691363428aa502cdececbd91396aa83ce0135", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "2e4c72f068cd6f0172ea92e9d343be89873ed2146c80198702d0426056aa7d1a" + } + }, + "signature": "654741a528165d6c520dcb788e25880e67db69d1b3164a12b9245a2bd0bd05c50c4d5ca0bd398342587478acaac2a43e8ef64ff69809932035c7fa73e7439a0e", + "id": "12046303791358805260", + "senderId": "16827243971064478236L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0251d537d3278f0317f306e5cd7691363428aa502cdececbd91396aa83ce0135", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "life" + } + }, + "signature": "750f47c3673fd20774fb8c24e39b1a918330ffa25638372c4524f6f91b3bec2999388990ab14f0a6849d4e7e7762d4af02018a98674dfd58bc6f553a3d1ec90d", + "id": "14240946536547154775", + "senderId": "16827243971064478236L" + }, + { + "amount": "0", + "recipientId": "16827243971064478236L", + "senderPublicKey": "0251d537d3278f0317f306e5cd7691363428aa502cdececbd91396aa83ce0135", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+0251d537d3278f0317f306e5cd7691363428aa502cdececbd91396aa83ce0135" + ] + }, + "signature": "d8d9de6e89c7938f8c2227b6440c234c70b17bdc561374edb73b21305b136ab4db046c476a16f619f531bfa309db413036145d1be7a1ef41c9d6d95a3457280a", + "id": "6723333624828496171", + "senderId": "16827243971064478236L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0251d537d3278f0317f306e5cd7691363428aa502cdececbd91396aa83ce0135", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+0251d537d3278f0317f306e5cd7691363428aa502cdececbd91396aa83ce0135", + "+2e4c72f068cd6f0172ea92e9d343be89873ed2146c80198702d0426056aa7d1a" + ] + } + }, + "signature": "51ae983544dfef40f39deff32551648238475babb5f91a89715c9c8a6af7b4f7d580ab0c4bbcc5602923b43616397f801a44cad10eaa0eeefdbc636adfc43f00", + "id": "15954335613968423214", + "senderId": "16827243971064478236L" + }, + { + "amount": "1000000", + "recipientId": "10906820577572630968L", + "senderPublicKey": "1f86c69d53d6b0d1c2a4853cc34e87dfa59c3aaabe2afcbbdb3d72ea6e9d8235", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "72142bbce6d41c4707062f1a814ca463d9560552230130d8540a038126c1f08f9ae658a861675319310ec80178a176a5feea56a475cf1b6065e6160eb3dc7f0b", + "id": "4910241357358127024", + "senderId": "10906820577572630968L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1f86c69d53d6b0d1c2a4853cc34e87dfa59c3aaabe2afcbbdb3d72ea6e9d8235", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "931e72c487310a4fa7a82ea3580750f671300b455ce6868bd146b029643a1ea6" + } + }, + "signature": "55e4bafa5f218871e5839da840721a4eb00cbf1f3db95085d1d0b132b709808c2a7317cae315baa209dd4f9e7a38d6bd13f4cc3bc67f9433e2af6b23d2b80905", + "id": "16952917244089138333", + "senderId": "10906820577572630968L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1f86c69d53d6b0d1c2a4853cc34e87dfa59c3aaabe2afcbbdb3d72ea6e9d8235", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "weapon" + } + }, + "signature": "e6ae32addd2f1bf76b0f3daaa0f268b70b7188d764176e29b1dcbf4e8f65db1bef143ac947949a7e2421d0399801147e1cdbfeea0fba9264a384294b0f859500", + "id": "11968395829275362242", + "senderId": "10906820577572630968L" + }, + { + "amount": "0", + "recipientId": "10906820577572630968L", + "senderPublicKey": "1f86c69d53d6b0d1c2a4853cc34e87dfa59c3aaabe2afcbbdb3d72ea6e9d8235", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+1f86c69d53d6b0d1c2a4853cc34e87dfa59c3aaabe2afcbbdb3d72ea6e9d8235" + ] + }, + "signature": "c5ebaf242c0c3b9b7b2ddf080f37de3bb6653274228ccbc1f3332c7d98821d920b7f1ebde8c1a94612089be50a6a196407d91624030c1cabbea9c914d4ed130f", + "id": "1245437910688457655", + "senderId": "10906820577572630968L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1f86c69d53d6b0d1c2a4853cc34e87dfa59c3aaabe2afcbbdb3d72ea6e9d8235", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+1f86c69d53d6b0d1c2a4853cc34e87dfa59c3aaabe2afcbbdb3d72ea6e9d8235", + "+931e72c487310a4fa7a82ea3580750f671300b455ce6868bd146b029643a1ea6" + ] + } + }, + "signature": "6467e55febae43c1fa6bb2cf6e3280417c636e01f034b770541ae74e7dfd4d1a386dc3d2a3b5ee0245bdd263bd554c1199c7a58947d47dcec6091da2439d2500", + "id": "8938950871706191277", + "senderId": "10906820577572630968L" + }, + { + "amount": "1000000", + "recipientId": "15699053529071456783L", + "senderPublicKey": "bbc825a2aedc3506e32dbef71c588a30010d5e59fd1eaea147db90c790acf96e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a46e8bf0144953e6c9a4ee1b878edcae585143c8d4bca6751b840b54e7c2e36e011a5e59f312c3c8504e422b65cde279169c55f11e47d61d0feaccb4e843e80c", + "id": "15658162602322182028", + "senderId": "15699053529071456783L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bbc825a2aedc3506e32dbef71c588a30010d5e59fd1eaea147db90c790acf96e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e191a99bfede2b4d6e954226e1ddc5b0967d1cb15083a7965e7d650f74ede164" + } + }, + "signature": "21d45cf07039420dfe15cbec9739d881000f86ad4b1708a923becb1667bace446434ce315e85aabb6bc8a0e414a7b672d6cade0019688d240cd55807bbc03d0e", + "id": "94394218076582699", + "senderId": "15699053529071456783L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bbc825a2aedc3506e32dbef71c588a30010d5e59fd1eaea147db90c790acf96e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "tip" + } + }, + "signature": "0d71944910ae8c7eaf470be4caab2e59cc623bf2fef07b33f97f332ceb6a43b184f782fb97377c9d784a44759c0d947375116003ce90b40894d8123931d4fd0d", + "id": "11794035744667385824", + "senderId": "15699053529071456783L" + }, + { + "amount": "0", + "recipientId": "15699053529071456783L", + "senderPublicKey": "bbc825a2aedc3506e32dbef71c588a30010d5e59fd1eaea147db90c790acf96e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+bbc825a2aedc3506e32dbef71c588a30010d5e59fd1eaea147db90c790acf96e" + ] + }, + "signature": "d219d8bc20487641ac4672696086ae8c5cc62b9d766c679c4c0840688147b18fd98fd834988b0d027a9ac38fcaf167ebda7180f71cbf8eaa30894c249093e609", + "id": "6356639751319825337", + "senderId": "15699053529071456783L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bbc825a2aedc3506e32dbef71c588a30010d5e59fd1eaea147db90c790acf96e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+bbc825a2aedc3506e32dbef71c588a30010d5e59fd1eaea147db90c790acf96e", + "+e191a99bfede2b4d6e954226e1ddc5b0967d1cb15083a7965e7d650f74ede164" + ] + } + }, + "signature": "073a641cbe2d3ff77066bb09c63f9d71889fa2fd297b3eed08d3132ec059ae5852fc0c93591331267c5d62590565d37201ea926af91bd207fab6e39e8116e702", + "id": "15870984487599331722", + "senderId": "15699053529071456783L" + }, + { + "amount": "1000000", + "recipientId": "5393322898190002128L", + "senderPublicKey": "14aeb4d00f5e68665521de7c834d4d68cc93e66c18dc8b36063c05feaf3afb24", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a105d8666bc4126f710f46c10fdf0b32cbbe3d1f0f50b3d4db51d54b1c4d9c8fa8c66c000ef9a2d1c17ed7006531db126efa299668a8e4c0c93765130057090e", + "id": "16978143908599463075", + "senderId": "5393322898190002128L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "14aeb4d00f5e68665521de7c834d4d68cc93e66c18dc8b36063c05feaf3afb24", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3f4e024de5ba4a7180c70eb0e8b36bc9ba5f77c57b84029eea3f57f4affc8fb6" + } + }, + "signature": "19f71722fea7d9425b173ec90ed89c85a6f41b85b4b1fd1d78e040d1c4f8cf7580a8f316dd16eec73cc2177a461f42bb063d4305c09dc9f25bf4707c10d6ec0a", + "id": "2519054352206649814", + "senderId": "5393322898190002128L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "14aeb4d00f5e68665521de7c834d4d68cc93e66c18dc8b36063c05feaf3afb24", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "cook" + } + }, + "signature": "62335afeb631a50d79042517220ca82edab24000de91f33c267c42c2cac722cb81a4db9c1c30a76225c5f7d8b2d2ff0190f8104471a11340a031a13732516506", + "id": "13039273773901314256", + "senderId": "5393322898190002128L" + }, + { + "amount": "0", + "recipientId": "5393322898190002128L", + "senderPublicKey": "14aeb4d00f5e68665521de7c834d4d68cc93e66c18dc8b36063c05feaf3afb24", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+14aeb4d00f5e68665521de7c834d4d68cc93e66c18dc8b36063c05feaf3afb24" + ] + }, + "signature": "db1ba3d7329a87cd516aeed8c27599cc899354dac89c26b28bc3a8ef66f054cac50a498c7fb1e50f02476edba52f645034bb73d122646a7eb134e33d4f4e1f0c", + "id": "6898062599883961646", + "senderId": "5393322898190002128L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "14aeb4d00f5e68665521de7c834d4d68cc93e66c18dc8b36063c05feaf3afb24", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+14aeb4d00f5e68665521de7c834d4d68cc93e66c18dc8b36063c05feaf3afb24", + "+3f4e024de5ba4a7180c70eb0e8b36bc9ba5f77c57b84029eea3f57f4affc8fb6" + ] + } + }, + "signature": "eea558bf3790f9b6a1f5b28ff9b295d5d1fa0d3c678321d04c9729aaca344e2673bc2ef08a37a3b0ef7c58f9fde17773756c3db3b6aff46e5ca64f6603928003", + "id": "4587713736601069606", + "senderId": "5393322898190002128L" + }, + { + "amount": "1000000", + "recipientId": "5851974412947226044L", + "senderPublicKey": "e57fc2681b64d55c688fd0870550da15f9b236a9edd12138740485b20854046d", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "610830f88e458e957dd52a7f096e98ed49813f247410742a90a638c8bae6c2b4c2c6d2d206871e9f9bcf715b2095f3456d74c7639e055b47cb9e405a7ba0e101", + "id": "9869466168248314746", + "senderId": "5851974412947226044L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e57fc2681b64d55c688fd0870550da15f9b236a9edd12138740485b20854046d", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "dac8c42cf87dfeae1cf826b9d209149f763b138cefa027b1f732bd1388897972" + } + }, + "signature": "c56f4d7ff6f70a964654160f2af6964a4bc84cce062e0c3a93108c3d228bc2b6220a92b496031cec1183aabece3b2c525561d7e4fcc5217d25dc0337098a720d", + "id": "8399055604273659975", + "senderId": "5851974412947226044L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e57fc2681b64d55c688fd0870550da15f9b236a9edd12138740485b20854046d", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "mail" + } + }, + "signature": "5181743b38d35497b1fb2f76e6a33f34e646be1d641163c07f5e7fbe937629db360e8d4db588ee491bca5ded6be8a3389b9ced465c1b398ac6fde64daf121a05", + "id": "5579480641124544077", + "senderId": "5851974412947226044L" + }, + { + "amount": "0", + "recipientId": "5851974412947226044L", + "senderPublicKey": "e57fc2681b64d55c688fd0870550da15f9b236a9edd12138740485b20854046d", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+e57fc2681b64d55c688fd0870550da15f9b236a9edd12138740485b20854046d" + ] + }, + "signature": "8eaeefdbab3c5f24c25d240d330f934f7e793f62b6ef183d4532d2edab46864e8ba11bc92fd5d7419d3278cf7b088b7215db75ef6c8dfee8b6043b752b2d7b02", + "id": "3843707144574053126", + "senderId": "5851974412947226044L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e57fc2681b64d55c688fd0870550da15f9b236a9edd12138740485b20854046d", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e57fc2681b64d55c688fd0870550da15f9b236a9edd12138740485b20854046d", + "+dac8c42cf87dfeae1cf826b9d209149f763b138cefa027b1f732bd1388897972" + ] + } + }, + "signature": "4f6a09ae4c14c9f4086eb98dcda885e2ea268bbb5a44f26d175526d9822fe20e6963a932f059e400bf4a03880da6d85faa8d11e1891ce702cded56b452f18e02", + "id": "585200395397010910", + "senderId": "5851974412947226044L" + }, + { + "amount": "1000000", + "recipientId": "6777236461751864770L", + "senderPublicKey": "49d16844a506405d10a3cd02934c7c1944ab21905791c19e5d6e0748d1229c52", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "22c65bab4634467845a98e22e4637653bcef04f3e66c256b6e083c771a4e23616e5f3cb09a389d345916962a4cd765d6b28b7ef0b5eed9455aa644a85002d30f", + "id": "12931933927720501042", + "senderId": "6777236461751864770L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49d16844a506405d10a3cd02934c7c1944ab21905791c19e5d6e0748d1229c52", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "809bcd415b85b7df78f36b169277c2f34e3aabf46cda9f9c211586e4be0ec148" + } + }, + "signature": "673c3b36853d15e59f1aab2e38b66e58bd0108443fee08e7579e12467d3ca87d00a43592183ce9ea884d762e3b23426727fc3340ae7a53b43ee516e10f84d503", + "id": "7421500445553672648", + "senderId": "6777236461751864770L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49d16844a506405d10a3cd02934c7c1944ab21905791c19e5d6e0748d1229c52", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "dune" + } + }, + "signature": "c1f900e1a6a11d3c02715b0ff600da173148b1fc84baaf2da75df1711ad58703dc9a2eda4edb9b7001c362daf0c65114a83c7f067a1b655175d9181c1a6d3e00", + "id": "967902256737593210", + "senderId": "6777236461751864770L" + }, + { + "amount": "0", + "recipientId": "6777236461751864770L", + "senderPublicKey": "49d16844a506405d10a3cd02934c7c1944ab21905791c19e5d6e0748d1229c52", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+49d16844a506405d10a3cd02934c7c1944ab21905791c19e5d6e0748d1229c52" + ] + }, + "signature": "58f6cab53a3d716ee99f17a2b5ba0d9f1159be0e7251d96e2816aad30de3598502d6f2b2d16cf2b611b9b4c387baad7aca686ac7997d62b039da78340d89370d", + "id": "10362617478891837925", + "senderId": "6777236461751864770L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49d16844a506405d10a3cd02934c7c1944ab21905791c19e5d6e0748d1229c52", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+49d16844a506405d10a3cd02934c7c1944ab21905791c19e5d6e0748d1229c52", + "+809bcd415b85b7df78f36b169277c2f34e3aabf46cda9f9c211586e4be0ec148" + ] + } + }, + "signature": "67b24064e76a071083a2e6c6c24222dfa7a3db69c22b6d2888bcb2bf92bbe2e4bd33e55c06cd5c09ae6b13351a1945005b7f7ca21d92c888387062da92a4540c", + "id": "11686277692906875017", + "senderId": "6777236461751864770L" + }, + { + "amount": "1000000", + "recipientId": "13610022076702374368L", + "senderPublicKey": "f91c6be7b1e6da47f2ce854b3e4093fd9492aac36a9966ffd1b0e5484a5d37f9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "7a5e52e985128771b922dc4129b25dabe5befb51fbea62b95a00664bd5b6164da80f4344345d1d2bc7417d340027fed4d9da153ec6a8d2fb84fb1c3a01eb9c08", + "id": "14140989606008659564", + "senderId": "13610022076702374368L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f91c6be7b1e6da47f2ce854b3e4093fd9492aac36a9966ffd1b0e5484a5d37f9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f2f13eaefae842bdddd79ce9229025192dc85649e31037bfb32430b87fcf58ec" + } + }, + "signature": "cae49ca1cece94bed4e1ca2e91933517dc9750d563d8871bf5d626f29800b6545f5d66d7ea90be125b31ee465fe58937ee968f394880e84c53d46a084081d000", + "id": "4115400068501708278", + "senderId": "13610022076702374368L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f91c6be7b1e6da47f2ce854b3e4093fd9492aac36a9966ffd1b0e5484a5d37f9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "manual" + } + }, + "signature": "70f44065712c46308ef7b0ba055fd794a8ef3a906f1e3d257ffa42b0b3d536f03d342291b69ebe627fec67150d1125a4d21f8e08f082c46b63bda2d3177fb20d", + "id": "16769646973692795972", + "senderId": "13610022076702374368L" + }, + { + "amount": "0", + "recipientId": "13610022076702374368L", + "senderPublicKey": "f91c6be7b1e6da47f2ce854b3e4093fd9492aac36a9966ffd1b0e5484a5d37f9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f91c6be7b1e6da47f2ce854b3e4093fd9492aac36a9966ffd1b0e5484a5d37f9" + ] + }, + "signature": "6fe4573917a5e79e8f2cf7c965c8ecadf197968ecc2d4245d35c1db128bd4a9ae02a729e37ce79f760151356fabf8e7a887beb8ae3a55dda96de50dbaa05b305", + "id": "10193360331227469190", + "senderId": "13610022076702374368L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f91c6be7b1e6da47f2ce854b3e4093fd9492aac36a9966ffd1b0e5484a5d37f9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f91c6be7b1e6da47f2ce854b3e4093fd9492aac36a9966ffd1b0e5484a5d37f9", + "+f2f13eaefae842bdddd79ce9229025192dc85649e31037bfb32430b87fcf58ec" + ] + } + }, + "signature": "846987ee12cf26c1d558075fd362c3f23de517d495e475377f6b77def0454e0840cfb4d11a700cb799fda109f0b7310f32dce5e0b64611fd4d91dc4718f4e906", + "id": "7923056640243452554", + "senderId": "13610022076702374368L" + }, + { + "amount": "1000000", + "recipientId": "3993995081251903465L", + "senderPublicKey": "eea4b464f99d5e0c8f6d975371b0663747207e00e939d3776902b0f67cf18db5", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "b4c565752a35b3160d0209272f812ba9efef547833a7bbbaaa45105133e948371b18fe446923e3e3d4897a2fe9d4c87ac1c9f199db91fce811d7103a8a4c1d01", + "id": "1067021626622623888", + "senderId": "3993995081251903465L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eea4b464f99d5e0c8f6d975371b0663747207e00e939d3776902b0f67cf18db5", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "05570e5edeabb0ed84a9d5c4ef9cd1e808de6cc4fcd1516352c358b6469e87f0" + } + }, + "signature": "21a2bffeafc409e246fd303cb123bb309ce1ac3b672de3ab3700bad16d7825019be347a4c5f93a0ef4d4bdf02b53a177ef52f5bfd2e6b7464e1f5ad88ff9ad08", + "id": "4304361174956911944", + "senderId": "3993995081251903465L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eea4b464f99d5e0c8f6d975371b0663747207e00e939d3776902b0f67cf18db5", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "pony" + } + }, + "signature": "0c6985fdd509f5de7ec3e05f0edbc8fa3f2b8744e17fc08c6b53b170a1983191cd838009b14153481415539af2492290f7a42c4a939d4eb27af2d66de85f7407", + "id": "14966216372834346732", + "senderId": "3993995081251903465L" + }, + { + "amount": "0", + "recipientId": "3993995081251903465L", + "senderPublicKey": "eea4b464f99d5e0c8f6d975371b0663747207e00e939d3776902b0f67cf18db5", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+eea4b464f99d5e0c8f6d975371b0663747207e00e939d3776902b0f67cf18db5" + ] + }, + "signature": "4a8e8d4094ffb369a2c8949afa97b05b6bc502d474e65e88f8b403993031ae5c3eaf24a1bf2c10658821717050121a29e7057a6b6164606e88d0ecd14a1a3406", + "id": "975345098799299138", + "senderId": "3993995081251903465L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eea4b464f99d5e0c8f6d975371b0663747207e00e939d3776902b0f67cf18db5", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+eea4b464f99d5e0c8f6d975371b0663747207e00e939d3776902b0f67cf18db5", + "+05570e5edeabb0ed84a9d5c4ef9cd1e808de6cc4fcd1516352c358b6469e87f0" + ] + } + }, + "signature": "230826332de67cb7cf7c5d370a1d7557910ec058e3f5435ee862d567b592adfe8d9be91d3e8686b99b90ff756470336b24a27857797cd04b9559f98399f4a90a", + "id": "13724484064951841368", + "senderId": "3993995081251903465L" + }, + { + "amount": "1000000", + "recipientId": "3045169695963396886L", + "senderPublicKey": "97bcf0f41eb78289d9ecf0fcb746f95b462784dd2d8f72f95663f7cafb9b3155", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ccdd5534a3187b1afecd1a1b1d145d36c3f4d9bb078ce3c68802adf870e1285b257537c00b6fa3b5358a74b6d93c946522ff92bca75eb32f4ab24f5673053c05", + "id": "17678349953895266929", + "senderId": "3045169695963396886L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "97bcf0f41eb78289d9ecf0fcb746f95b462784dd2d8f72f95663f7cafb9b3155", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "1205775dc5beb727f46ee44fc26dc08b17baa432166c53a867405509c37e1a93" + } + }, + "signature": "0b5df7ae2fa4b6c9e1f6e967dc2fee679f7cc57bcbadc20074c1392f1607916b38bc40bc098e209b7e3fff6796ff429bdd82a30cc2868c63916ba4639dcb6505", + "id": "16156063489943866543", + "senderId": "3045169695963396886L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "97bcf0f41eb78289d9ecf0fcb746f95b462784dd2d8f72f95663f7cafb9b3155", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "corn" + } + }, + "signature": "1876bdc477256eec77756b0d6521d8bbbf15fc05677767ce9ca23bb3f9f05f571a45c2fb0be5cfe95801daf45f1a3476f3e9ee21005c5fe9e9b424aad74bcb00", + "id": "6996165004712897209", + "senderId": "3045169695963396886L" + }, + { + "amount": "0", + "recipientId": "3045169695963396886L", + "senderPublicKey": "97bcf0f41eb78289d9ecf0fcb746f95b462784dd2d8f72f95663f7cafb9b3155", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+97bcf0f41eb78289d9ecf0fcb746f95b462784dd2d8f72f95663f7cafb9b3155" + ] + }, + "signature": "68b2cebccd6b235649856ecbd1b38343399af0249523aede69599942fb15881c64b1c10adbb5ebaf614780a36607bb8cf160bb17cac6fefa2920e975caa5610b", + "id": "518371319552110313", + "senderId": "3045169695963396886L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "97bcf0f41eb78289d9ecf0fcb746f95b462784dd2d8f72f95663f7cafb9b3155", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+97bcf0f41eb78289d9ecf0fcb746f95b462784dd2d8f72f95663f7cafb9b3155", + "+1205775dc5beb727f46ee44fc26dc08b17baa432166c53a867405509c37e1a93" + ] + } + }, + "signature": "13857967a286553c8fdab7156343785211d6368cdcc550cd00b2ac0d727d53a500f05c12b83d74650ea95746958c26742a008828c97e016e8221dc320c08170a", + "id": "10897720642611545234", + "senderId": "3045169695963396886L" + }, + { + "amount": "1000000", + "recipientId": "5618804553878583657L", + "senderPublicKey": "b9c0e4512141c5fc6b6f6eb9bfd4c2fc6ae6de9bd28e9fa5e4938dbd65733b08", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "c0fa5201eeb0a888d38debc58ab3cdb222acf237a9de40c4ed5d0ffa9f53357f00bb47b825ef9eb5a676dcd131c22e4e1b76304c70b25836f2deebbad9bc2e0d", + "id": "16036050933069587887", + "senderId": "5618804553878583657L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b9c0e4512141c5fc6b6f6eb9bfd4c2fc6ae6de9bd28e9fa5e4938dbd65733b08", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "fd0d3f0c19b364254c08dc095a15d6d5961ab192318d6d212c5fc85d210e4b96" + } + }, + "signature": "46a7adaa6d4f8650396fa918e30d5645da5d94bb3820d8f297d0c5695655db4be949c1deca7cb1a76e165a516579bd787acf4b03c2c27fa633095c7ef5d4e40b", + "id": "2253199203469330670", + "senderId": "5618804553878583657L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b9c0e4512141c5fc6b6f6eb9bfd4c2fc6ae6de9bd28e9fa5e4938dbd65733b08", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "photo" + } + }, + "signature": "579ad6a922f5544a991f262e90cb435ce9d5d142aee2d714405946c9d6d0fc0609264dd81e45d655a7dc9e9c66665ff30b19b6dc85bd2af3ffd659a2a4c29208", + "id": "1040712824453773543", + "senderId": "5618804553878583657L" + }, + { + "amount": "0", + "recipientId": "5618804553878583657L", + "senderPublicKey": "b9c0e4512141c5fc6b6f6eb9bfd4c2fc6ae6de9bd28e9fa5e4938dbd65733b08", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b9c0e4512141c5fc6b6f6eb9bfd4c2fc6ae6de9bd28e9fa5e4938dbd65733b08" + ] + }, + "signature": "683beeb9d81f0c7321400973e300920c4498374cf4883bce358041df51e57b07049cb4f0642c6c84918d920310d6d1b0d9df453cd5a231dc591afd5bfc79f204", + "id": "4984746613551995320", + "senderId": "5618804553878583657L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b9c0e4512141c5fc6b6f6eb9bfd4c2fc6ae6de9bd28e9fa5e4938dbd65733b08", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b9c0e4512141c5fc6b6f6eb9bfd4c2fc6ae6de9bd28e9fa5e4938dbd65733b08", + "+fd0d3f0c19b364254c08dc095a15d6d5961ab192318d6d212c5fc85d210e4b96" + ] + } + }, + "signature": "8cd2199f31e6ec700eaaad4a0058075f470fa54a0bdaac082419a92ed9d387440aca68f21ccfaba9cd9181dac457352ef4d0232eaa389b3331f0dc95779c1f00", + "id": "10235241677918247717", + "senderId": "5618804553878583657L" + }, + { + "amount": "1000000", + "recipientId": "3287133389630663844L", + "senderPublicKey": "111a6cc73528309345673de245ba99e22d06a050874538095129722a6a337435", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "28c62c088170b4cfe3137a64b216a09313790f17234425b60374373618cd49b1a23f24254a64ba130ef02ba11ff6576201b1fe40a430122fa6885fe30ef1e50c", + "id": "13113604952014846642", + "senderId": "3287133389630663844L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "111a6cc73528309345673de245ba99e22d06a050874538095129722a6a337435", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c2ff149fc54ea8e9892a2f564d9bb7e3e5b436bfc3dac28c08b041cd695bf80d" + } + }, + "signature": "a40ff02924ec99ff7a5f73d38abcdbb2b043103b455fd01c5ee5f83ed64da2f7c6da10ec909d518cf20f7998bf587a38229f25e4aedd60de109e7d78f958ce0e", + "id": "489056776838675605", + "senderId": "3287133389630663844L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "111a6cc73528309345673de245ba99e22d06a050874538095129722a6a337435", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "tank" + } + }, + "signature": "8c667cd930687407650361f46713ba2e1c24ffd2f2b2475e0f8f08a73cc443060ccd6faa28568d09e5443b2f54fdf8343e09689ad9192aad87ed97b58fccf70b", + "id": "14536251678230642900", + "senderId": "3287133389630663844L" + }, + { + "amount": "0", + "recipientId": "3287133389630663844L", + "senderPublicKey": "111a6cc73528309345673de245ba99e22d06a050874538095129722a6a337435", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+111a6cc73528309345673de245ba99e22d06a050874538095129722a6a337435" + ] + }, + "signature": "c5c65f4b69d5752c7160b90ca5b8f0e610a78ced57054db6795d83680b0cf03d5fdb0f282c0ed0c0755ce22cadaee7572b110319a2721a8d2b91f8bb286c3704", + "id": "5380653187524797543", + "senderId": "3287133389630663844L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "111a6cc73528309345673de245ba99e22d06a050874538095129722a6a337435", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+111a6cc73528309345673de245ba99e22d06a050874538095129722a6a337435", + "+c2ff149fc54ea8e9892a2f564d9bb7e3e5b436bfc3dac28c08b041cd695bf80d" + ] + } + }, + "signature": "68586902e467c07ec50917bcac346282a792410ea9869762e2d134e185a33ad3d9cd843b1e1233cb2b3e001e8db6901e5d08e579e99b911efcf31887acdb010a", + "id": "3002762593315161285", + "senderId": "3287133389630663844L" + }, + { + "amount": "1000000", + "recipientId": "8948421607304929286L", + "senderPublicKey": "832642952bb7848cef31227b68d571169d432195acae5b630a6d2ba622d12546", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f521c5f1906b99e969f7775de6c7993ffc3e3a6f225a059eb88cd97de46eaf97a1c6b604141356e606ef7ae91ef57c099f0731730303ab7810f0b34cf1c54f0d", + "id": "10348576546267589053", + "senderId": "8948421607304929286L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "832642952bb7848cef31227b68d571169d432195acae5b630a6d2ba622d12546", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "6ece065ba0aa79ba4b4be77098c856a48e486a77655ddc059de6e3bb8040702e" + } + }, + "signature": "04cab19dca54211cfbb7aa5e45601685b11a45fd2658c9b3d3695e2ac94005cfd178b54addbfcf1c89946b54677e59a9da467f7a933b92012ca20e566acc830b", + "id": "5815202759808611797", + "senderId": "8948421607304929286L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "832642952bb7848cef31227b68d571169d432195acae5b630a6d2ba622d12546", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "tomorrow" + } + }, + "signature": "a81b44bd5b851f2191b7e365e93f913d64170a53ff5d37efd874e3086aa4227a0c706d91e54f6979b9df1f78d4a38d407100a08479b133308126b2ce6357e007", + "id": "9589125942065812160", + "senderId": "8948421607304929286L" + }, + { + "amount": "0", + "recipientId": "8948421607304929286L", + "senderPublicKey": "832642952bb7848cef31227b68d571169d432195acae5b630a6d2ba622d12546", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+832642952bb7848cef31227b68d571169d432195acae5b630a6d2ba622d12546" + ] + }, + "signature": "094e0f7cb6894be629766e123614a383ae10d80e0c80f5e1c1c3231ef467aecdc0269ee41e7ad89019e2501d1a56ba5e499e6a92da51ad48cb38d5f4cc226a06", + "id": "17905243006792544410", + "senderId": "8948421607304929286L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "832642952bb7848cef31227b68d571169d432195acae5b630a6d2ba622d12546", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+832642952bb7848cef31227b68d571169d432195acae5b630a6d2ba622d12546", + "+6ece065ba0aa79ba4b4be77098c856a48e486a77655ddc059de6e3bb8040702e" + ] + } + }, + "signature": "7a534e8ac8b4424325d799284ef20002004e1118b72592d1bb26f0e18cd62f7091f3bcc5ee51d1bb8b065f6bdb24cf7432011104eced256580a10a2036c61f08", + "id": "11354198470855549305", + "senderId": "8948421607304929286L" + }, + { + "amount": "1000000", + "recipientId": "7680350476340506614L", + "senderPublicKey": "74eb7469b54b87544c3865282ef64b14f9a78ebe074854d30665d155644bd7ad", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e255936ae58a9e0d58331f38f901afdac26087624ef2dbda5dd4529a33fb290f5753911e384f1c981e9cb11ffdd88fe3965ea78c6c5ff5ccd3155fd60f98570f", + "id": "13305314391197115159", + "senderId": "7680350476340506614L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "74eb7469b54b87544c3865282ef64b14f9a78ebe074854d30665d155644bd7ad", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c7ce9c469c24f11bd743d65d8ba1d0c39722cf6892f0e935fd2267967cca8f98" + } + }, + "signature": "4b70f3c7de516ed3c3c3502d23c4645123e1db05e7dee7c253048cfecce3047dcd91c433c3822b92e04df351ac975bfe77ff39362ad034caf33b7b887ced660a", + "id": "5409497706073425709", + "senderId": "7680350476340506614L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "74eb7469b54b87544c3865282ef64b14f9a78ebe074854d30665d155644bd7ad", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "tattoo" + } + }, + "signature": "22aebb7fd28fb0a6bb013521ddf5150b8329791c2c23913047372c00984c09fe0ba892cfb3cbb303def793e1c1ed6de9f20ebf98d08dae673209b63df5b21a08", + "id": "1523999306050170012", + "senderId": "7680350476340506614L" + }, + { + "amount": "0", + "recipientId": "7680350476340506614L", + "senderPublicKey": "74eb7469b54b87544c3865282ef64b14f9a78ebe074854d30665d155644bd7ad", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+74eb7469b54b87544c3865282ef64b14f9a78ebe074854d30665d155644bd7ad" + ] + }, + "signature": "54ef751275963fd1143ac8653e827767ef23a6a34164bafd80c851e4ede3a21f8ae11ecb2666d577b3c52746110a3da7acda70dabaf100bde7e29cd3d94c0b07", + "id": "9216662906429062418", + "senderId": "7680350476340506614L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "74eb7469b54b87544c3865282ef64b14f9a78ebe074854d30665d155644bd7ad", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+74eb7469b54b87544c3865282ef64b14f9a78ebe074854d30665d155644bd7ad", + "+c7ce9c469c24f11bd743d65d8ba1d0c39722cf6892f0e935fd2267967cca8f98" + ] + } + }, + "signature": "cd6369652ace91fc16da0332516dbd1ba4b1bfc13115474ab014eebbaf257b8ed5500dea9d3238a5ed94f9387d7f583700f03baf59a42c4b7bd843ada689e701", + "id": "6198084854140266285", + "senderId": "7680350476340506614L" + }, + { + "amount": "1000000", + "recipientId": "6487574859072015252L", + "senderPublicKey": "0b9130beab3528cab7c4380356cd93c7e672259355ce41a78a182f00dbbdb365", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "6ab48dcef6d3b445a96451072abdd157340709f82f8645e539a90267b902fe711c51105ca422667e6bcdbcf53357d8be5befef5f3b0837f6c5640ad3f1daf707", + "id": "3458947965505327719", + "senderId": "6487574859072015252L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0b9130beab3528cab7c4380356cd93c7e672259355ce41a78a182f00dbbdb365", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4f3d5f839c24d56276b4e7960c1098292d047609cb38ef84224fa735a5c460ce" + } + }, + "signature": "57caab5ab303c7f5e235c31865c3c0fd7dda9d42ceaba416b10cd2018439d2ac1803de14e21974efc0eadc5a10a2f713dcb90116e1202a8bce3d6861e5d53807", + "id": "9830925385484331050", + "senderId": "6487574859072015252L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0b9130beab3528cab7c4380356cd93c7e672259355ce41a78a182f00dbbdb365", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "liar" + } + }, + "signature": "843541e61733aea28b2f903053206542e69dde32be8cf2a42718263e3d5af0f3aa03bf816bde12f2f092ab4506a842bf7090e6d2f779fcc1bcbdce5f8059100e", + "id": "17172599564734559490", + "senderId": "6487574859072015252L" + }, + { + "amount": "0", + "recipientId": "6487574859072015252L", + "senderPublicKey": "0b9130beab3528cab7c4380356cd93c7e672259355ce41a78a182f00dbbdb365", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+0b9130beab3528cab7c4380356cd93c7e672259355ce41a78a182f00dbbdb365" + ] + }, + "signature": "bff2d2dcf1cf4f94aa70ce747462aa5a532211ea3659e8a58ca4563f31811c82b892d22aa01325c8c9735951fbb99347ca6892eff118178c0d5d83358203dc03", + "id": "15549817847552960998", + "senderId": "6487574859072015252L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0b9130beab3528cab7c4380356cd93c7e672259355ce41a78a182f00dbbdb365", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+0b9130beab3528cab7c4380356cd93c7e672259355ce41a78a182f00dbbdb365", + "+4f3d5f839c24d56276b4e7960c1098292d047609cb38ef84224fa735a5c460ce" + ] + } + }, + "signature": "2cad20ff84a8b05f44ae21832865692fb19a3a63d6e4eacab95cc57f89256ddbe91de9c212d4b67fd983cca0097ac2e61cc39a29bedc462d17b92e92b7fdbf00", + "id": "9428187401380335398", + "senderId": "6487574859072015252L" + }, + { + "amount": "1000000", + "recipientId": "3032920508415710378L", + "senderPublicKey": "3cff66f6ae6172b072b94405b4361bc3b418f29d5528be19cef5d0bb3bb5fa23", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ba0bd5db3125ecccce7971b394c9728e305b8db7ab716c3ebc9f62f81de6ef21547625488bdc7bf928ca1f68c906e2321a4790965f40944e16b6d6e794423c04", + "id": "9324651450126650532", + "senderId": "3032920508415710378L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3cff66f6ae6172b072b94405b4361bc3b418f29d5528be19cef5d0bb3bb5fa23", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "aff38acfe137476a01e9a33d1e143fbecb87b67c12b69d232f74f1abcb00595c" + } + }, + "signature": "1d703a281617000677d8ee0ad10dd9ac5c6cfd422d51e660e22f1f67109d7d0080cfb197b4b2d03efc274df886b5d4b4caa04f9c399a0b40199f065359139602", + "id": "13815581382416544785", + "senderId": "3032920508415710378L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3cff66f6ae6172b072b94405b4361bc3b418f29d5528be19cef5d0bb3bb5fa23", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "sadness" + } + }, + "signature": "07fc4706a72d78d2c8bd7a38e2e365ddcf8c1d006f40598752d27e65637a7a301750cfb73c7e16f8d389f37ee97cba2699ff4e322d99a7c4ec0903f0ea9e5c06", + "id": "1786441101512364793", + "senderId": "3032920508415710378L" + }, + { + "amount": "0", + "recipientId": "3032920508415710378L", + "senderPublicKey": "3cff66f6ae6172b072b94405b4361bc3b418f29d5528be19cef5d0bb3bb5fa23", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+3cff66f6ae6172b072b94405b4361bc3b418f29d5528be19cef5d0bb3bb5fa23" + ] + }, + "signature": "c0be96b55d0562af56f82d9273ff135f204aecc60637cfc5b23f4d165b895161a0ddc843975a394fee7b63bdc7b29db34010da4b7de9c17385b74ff3c3701801", + "id": "7991307457389817965", + "senderId": "3032920508415710378L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3cff66f6ae6172b072b94405b4361bc3b418f29d5528be19cef5d0bb3bb5fa23", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+3cff66f6ae6172b072b94405b4361bc3b418f29d5528be19cef5d0bb3bb5fa23", + "+aff38acfe137476a01e9a33d1e143fbecb87b67c12b69d232f74f1abcb00595c" + ] + } + }, + "signature": "f39a2c443920badc85e6654ad3ec1038a170505ae1e731aefc82f8a32d62e4ffafc29592151c70d2669135674a1fb5a4bbdf63c62af3be0ae28019fa81858c00", + "id": "4055633114398789005", + "senderId": "3032920508415710378L" + }, + { + "amount": "1000000", + "recipientId": "14131578053375283885L", + "senderPublicKey": "b69e54d21eb094c5e2974eabb6a87151bbb273189f88055ac0250b2eff10ea53", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "29368b15060ee45f8c78a81c0166938a268b8f1a60e5f835728d75f6d6abc9d0ccd5bf4364d0cc550ebd1a1415eb1901edc41265ac1a7901ea85a6b88ee31004", + "id": "10023983205949076560", + "senderId": "14131578053375283885L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b69e54d21eb094c5e2974eabb6a87151bbb273189f88055ac0250b2eff10ea53", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "8a2d82e1a027d363114e210f7b206029b3c52fb686e8bdc1edec4f7f0c6c13d6" + } + }, + "signature": "35bcf4c2eb4a4927a171f95a34f8e5aa7015d0c282759d3e88b1bd52ea9550b9ededa099558c11ae2917cf72f55abf0820845ba3f6a09d3180372f5fd9566403", + "id": "4612517547977165372", + "senderId": "14131578053375283885L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b69e54d21eb094c5e2974eabb6a87151bbb273189f88055ac0250b2eff10ea53", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "harsh" + } + }, + "signature": "089e989f551840823e798a00b0ed9f91df0002e369e615e899300ce09648ada5fc7fd43ac2cf46b603b17fb252ec45b75c98d45533e2e05673baa981c2608d04", + "id": "10595330185620428153", + "senderId": "14131578053375283885L" + }, + { + "amount": "0", + "recipientId": "14131578053375283885L", + "senderPublicKey": "b69e54d21eb094c5e2974eabb6a87151bbb273189f88055ac0250b2eff10ea53", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b69e54d21eb094c5e2974eabb6a87151bbb273189f88055ac0250b2eff10ea53" + ] + }, + "signature": "6a85887cb613bc464ba439a341b292d332f941ba98403d203f476cbdf61fc73f49293457972acaf3699d9242a15180b6b72f52423955e7146209905a56a4f000", + "id": "3992748685336128567", + "senderId": "14131578053375283885L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b69e54d21eb094c5e2974eabb6a87151bbb273189f88055ac0250b2eff10ea53", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b69e54d21eb094c5e2974eabb6a87151bbb273189f88055ac0250b2eff10ea53", + "+8a2d82e1a027d363114e210f7b206029b3c52fb686e8bdc1edec4f7f0c6c13d6" + ] + } + }, + "signature": "9a0f9a1a26efb68a3daa67a306533eabb5f3ebecc7778a9657e261919e0d4f56006d9016dc6f64a3058b8370a0bc5c77919cfc5b09b468d2dce27b250f164f08", + "id": "2609515616871673828", + "senderId": "14131578053375283885L" + }, + { + "amount": "1000000", + "recipientId": "12539770102310253441L", + "senderPublicKey": "72bd63ee2f0f4e32e32e83ea2cf40935b12d2de308df583a9bbccbb88aa73a81", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "aca9c76047295c24f81fe7762f854b4313f40788c6e51633d19719286e477f7bb2cad736540329f2d80bb8f5eac602d201bb3083937976c45478e4bb7a38b900", + "id": "9647369875303716690", + "senderId": "12539770102310253441L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "72bd63ee2f0f4e32e32e83ea2cf40935b12d2de308df583a9bbccbb88aa73a81", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4830f77d361e55b144303a369991358aea441d39b9d364553827ecbf10aad1e0" + } + }, + "signature": "a96564306e721bb4a6d794785b65371a046c9fbf277217322194f12a1e6873e37d39459bbb5757598010999e00ffc54c2b61935bcdedbfb96c1871da4fb7bc0b", + "id": "10621814510600208405", + "senderId": "12539770102310253441L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "72bd63ee2f0f4e32e32e83ea2cf40935b12d2de308df583a9bbccbb88aa73a81", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "december" + } + }, + "signature": "abdf807828bcb933f4525eb08865ed606678e01298374f80bac38e256119c01088035fb97a9f539ac2c23e324f2b4a6e1ff7d8a56842171ffb6697b92554630f", + "id": "6350514924899253457", + "senderId": "12539770102310253441L" + }, + { + "amount": "0", + "recipientId": "12539770102310253441L", + "senderPublicKey": "72bd63ee2f0f4e32e32e83ea2cf40935b12d2de308df583a9bbccbb88aa73a81", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+72bd63ee2f0f4e32e32e83ea2cf40935b12d2de308df583a9bbccbb88aa73a81" + ] + }, + "signature": "f4196751d00950bb03f8907c31c34c49e0b759438f1fc32979108df9942a24bad73a640d74dd99703b58fec13251dcf25dd489a541e1cf092de776853d81c10c", + "id": "2452121908878112026", + "senderId": "12539770102310253441L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "72bd63ee2f0f4e32e32e83ea2cf40935b12d2de308df583a9bbccbb88aa73a81", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+72bd63ee2f0f4e32e32e83ea2cf40935b12d2de308df583a9bbccbb88aa73a81", + "+4830f77d361e55b144303a369991358aea441d39b9d364553827ecbf10aad1e0" + ] + } + }, + "signature": "10dc7b5b83f6d1da74bc585311c9478c3a1b46ef34f773cf7d912ee0a7bdefc5c1110b01ca1c940e527f5d1a6f43ac14442a1abb2203291e1fc91c7a4a7ac402", + "id": "8338846941895997438", + "senderId": "12539770102310253441L" + }, + { + "amount": "1000000", + "recipientId": "7468093180593042900L", + "senderPublicKey": "4aefbc90ac0097dc3e0bd0ebade85cd82766f4685a59f31042ef1ccc626e31c0", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "45d34f91d460679f9fe10e8d4c33d68684cc3b3795611d0ee6aa9de54e48a6b0ec118ec7043749905023d4bbed3a9bcceefbbcf338bcb83d391f11b44fd7a203", + "id": "4613266351478274467", + "senderId": "7468093180593042900L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4aefbc90ac0097dc3e0bd0ebade85cd82766f4685a59f31042ef1ccc626e31c0", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "ca5f9bd984969ac5037a93ab9272d18c197d22e8dcc0451c1dc8a7b4c684a4f4" + } + }, + "signature": "d3352fccc321cd52782452aee457f3bdaae4db14fcae8186d37a6bcffb784a0e2e16f1eedfa22259546f7f1cc37340bdc425184073fcb7f4495687edbbacc40c", + "id": "14332604058075799238", + "senderId": "7468093180593042900L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4aefbc90ac0097dc3e0bd0ebade85cd82766f4685a59f31042ef1ccc626e31c0", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "ribbon" + } + }, + "signature": "17b06dafecda1832ea294bc700afd3c97296a218038c54658d08f9b1bd6eeacc38322a0e4fddaeb8ac3875dbd54c7b2e94a4904ce019e666f22f2472b2110006", + "id": "16827168966648940261", + "senderId": "7468093180593042900L" + }, + { + "amount": "0", + "recipientId": "7468093180593042900L", + "senderPublicKey": "4aefbc90ac0097dc3e0bd0ebade85cd82766f4685a59f31042ef1ccc626e31c0", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+4aefbc90ac0097dc3e0bd0ebade85cd82766f4685a59f31042ef1ccc626e31c0" + ] + }, + "signature": "b62ed95b75f4bc2da06038968f019199218e61eac4ee89588b1f823eda28707869dc4357d375e3f555294e2930f3d7a7b80935337dae60dd7e3664a608e87705", + "id": "13351145342332266367", + "senderId": "7468093180593042900L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4aefbc90ac0097dc3e0bd0ebade85cd82766f4685a59f31042ef1ccc626e31c0", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+4aefbc90ac0097dc3e0bd0ebade85cd82766f4685a59f31042ef1ccc626e31c0", + "+ca5f9bd984969ac5037a93ab9272d18c197d22e8dcc0451c1dc8a7b4c684a4f4" + ] + } + }, + "signature": "d9a2b3d62f8688bc0f2a61ffe916006c88d78c403a3a4740ece1cb7523c1a550bc400a091395d9291cf3662149f76263957b6e3a28be1b6f3667371b54d0a000", + "id": "9461675606556907547", + "senderId": "7468093180593042900L" + }, + { + "amount": "1000000", + "recipientId": "8039639842131530462L", + "senderPublicKey": "5225496e341a5960cf6ac36e90493c89bb37c1982e6c337928b5b12d31932cc6", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "7ac1144757258d0fa96a5ef585ff4f5375376bdc02d75e6782515389046cf9ee334ed4ca362b4fd9d15e07b9cf459949108ff59fbf8f845d6a85186d670da906", + "id": "7239085320299100848", + "senderId": "8039639842131530462L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5225496e341a5960cf6ac36e90493c89bb37c1982e6c337928b5b12d31932cc6", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "7e2210b4da9461613430a3561487f6ec645bd79a18e939b2a62c690c83d2cb5c" + } + }, + "signature": "e0aa5b7dd42d05f9151ae8c3aa04d0f9e11020c53897a2846d206287fd16ac97380b939d4cd959d7e33bdc7c61ba5ff9891d130707a7eea75b0a2ff6e3b65b07", + "id": "12393034212739975988", + "senderId": "8039639842131530462L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5225496e341a5960cf6ac36e90493c89bb37c1982e6c337928b5b12d31932cc6", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "ordinary" + } + }, + "signature": "2af7fb4834691215b2270311a29539d1056427e644e4514235ead1d54810952b5f256a215c50ba5374410f5423f9a06c9a8743f238903e7d15f00b0d5d601d0b", + "id": "1144554797431405112", + "senderId": "8039639842131530462L" + }, + { + "amount": "0", + "recipientId": "8039639842131530462L", + "senderPublicKey": "5225496e341a5960cf6ac36e90493c89bb37c1982e6c337928b5b12d31932cc6", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5225496e341a5960cf6ac36e90493c89bb37c1982e6c337928b5b12d31932cc6" + ] + }, + "signature": "f46d59b8229d7e04ce484a8cbdc4c6b3ce6ac8dedc384755477655b8480639aaa422c36118bd86c3b0883d7342338481b23ecb118c2491f3f614cdba6bd7ac06", + "id": "7772522079631117352", + "senderId": "8039639842131530462L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5225496e341a5960cf6ac36e90493c89bb37c1982e6c337928b5b12d31932cc6", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5225496e341a5960cf6ac36e90493c89bb37c1982e6c337928b5b12d31932cc6", + "+7e2210b4da9461613430a3561487f6ec645bd79a18e939b2a62c690c83d2cb5c" + ] + } + }, + "signature": "b5af67a23c175b70bbc5eeff4ffbace3e8ec6f3cddbad99304016e18aad0ee09b179a19089119564a2d7a664047be1be4336a78636e26cd86eea7ea2d5204e06", + "id": "14933301601267457663", + "senderId": "8039639842131530462L" + }, + { + "amount": "1000000", + "recipientId": "14912175472599030472L", + "senderPublicKey": "bad88f9f7b214135781b3a4db570a69804ee62e0e161b2c6a5b8e92b2e6bc84e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f3e33c5f2df2eb5d9a6068e951caa320bfae799b6053b1bcf5c90e7e09a9a6dea5b51ddbd0f16dded3d0715a58affc4781cf7244cbecf87358d551b8ae7e610c", + "id": "4974246102895584419", + "senderId": "14912175472599030472L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bad88f9f7b214135781b3a4db570a69804ee62e0e161b2c6a5b8e92b2e6bc84e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "7340e2d9ec36699d5b26d53c3460eb7c5dc2bc0452160cad40e68bea29731bbd" + } + }, + "signature": "fdc5b67e2eb7879c0d74676961203453e7143bf0634b4de58f3227e54c94d49ca74445a25faeb038dd464000acd76067e4e31c5a649f0c97352e0869f9c7910e", + "id": "13500436902624441074", + "senderId": "14912175472599030472L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bad88f9f7b214135781b3a4db570a69804ee62e0e161b2c6a5b8e92b2e6bc84e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "wood" + } + }, + "signature": "04716d8ffc2fefc7330299e02be8df01dc9383879d7b79d6686efd38969b81c4424888faaa8dad142f916f7842e05a25204686f684897ec4f93f1c429e369903", + "id": "10742907095612320265", + "senderId": "14912175472599030472L" + }, + { + "amount": "0", + "recipientId": "14912175472599030472L", + "senderPublicKey": "bad88f9f7b214135781b3a4db570a69804ee62e0e161b2c6a5b8e92b2e6bc84e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+bad88f9f7b214135781b3a4db570a69804ee62e0e161b2c6a5b8e92b2e6bc84e" + ] + }, + "signature": "3eecd05ef878d716e9386afb4af1be3a2185befb8f7aef16709dd18120779a4aef70ff43ff21e22d3b7d29164a814f70c8d9052d3101cf252ca87d07ae17850c", + "id": "12798910713136405251", + "senderId": "14912175472599030472L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bad88f9f7b214135781b3a4db570a69804ee62e0e161b2c6a5b8e92b2e6bc84e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+bad88f9f7b214135781b3a4db570a69804ee62e0e161b2c6a5b8e92b2e6bc84e", + "+7340e2d9ec36699d5b26d53c3460eb7c5dc2bc0452160cad40e68bea29731bbd" + ] + } + }, + "signature": "85980dc637d695356f7d2d430a5550c8e1caf8cb4ee8a5b2ebc98a7119b007d97dd5f525bdcb3e0c22f9685f326cd173a53a04ec8cae79fe6ed199f620aa6603", + "id": "12328608528097480533", + "senderId": "14912175472599030472L" + }, + { + "amount": "1000000", + "recipientId": "14500669038813455569L", + "senderPublicKey": "d074d1db8fef3953e4808ae5495ec8a2ab7467f6c7441d2bc9abcd61d95e169e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "12f13c9d9c818e56ddd1f47a90e3d6a5968f4715d1f6c57be227080ccbd0b512c825025926cbb9294042868e20b62285034cbfe18b253bc620da1fd5c1718605", + "id": "14824835356596822937", + "senderId": "14500669038813455569L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d074d1db8fef3953e4808ae5495ec8a2ab7467f6c7441d2bc9abcd61d95e169e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d01f5390ac98887c001bff370bf4c291eac171b39a93a65cd852a413ef69b793" + } + }, + "signature": "f662c6ca361f5e936978e4ac4c2a4f7265ae322002de1b0cccb38e75362fb214b1bce815f9219a9077c7cb33ef31965900a500cc501636b66ecb5223d4dd4000", + "id": "10553891007018324687", + "senderId": "14500669038813455569L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d074d1db8fef3953e4808ae5495ec8a2ab7467f6c7441d2bc9abcd61d95e169e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "brown" + } + }, + "signature": "326704ad237435a6004705c35aa62bf8d7ed676c439dd15c7f342f11c0009deee6ed446b1597f9e0afb72042abd5f6be4c38fc302caa0fae11aea93b1911e406", + "id": "1772178025658619543", + "senderId": "14500669038813455569L" + }, + { + "amount": "0", + "recipientId": "14500669038813455569L", + "senderPublicKey": "d074d1db8fef3953e4808ae5495ec8a2ab7467f6c7441d2bc9abcd61d95e169e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+d074d1db8fef3953e4808ae5495ec8a2ab7467f6c7441d2bc9abcd61d95e169e" + ] + }, + "signature": "950e68c79df8e50d2a7c771ce5ec56635c03a680b16c216eee5e455fea3cd42652c8b7bc4181046a73d7f2bad33065dc038ef1839551f0948465f45fa3a3a60a", + "id": "9293318895082117177", + "senderId": "14500669038813455569L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d074d1db8fef3953e4808ae5495ec8a2ab7467f6c7441d2bc9abcd61d95e169e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+d074d1db8fef3953e4808ae5495ec8a2ab7467f6c7441d2bc9abcd61d95e169e", + "+d01f5390ac98887c001bff370bf4c291eac171b39a93a65cd852a413ef69b793" + ] + } + }, + "signature": "51480e19a4d9f84fbba635a6edccb2c949aa4fcfa829910804389345b4498f7a85e681e2474d715a34000d56f2666b2b81d798d6d2b63ad36f50758d61c3500d", + "id": "1252392172057890262", + "senderId": "14500669038813455569L" + }, + { + "amount": "1000000", + "recipientId": "3430046214873810255L", + "senderPublicKey": "8cd1d6d0465d7272b203c6f9ca35dd664e8798ffe62209ea5af90985c081731b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "aced2eb94d0f33c51142f49d45fc742a6833b121317b8d2a5be68e362f23a145e154b6d72df2feb22b983fb35b7af2645b03ce96aba32f7ddb3e64c721026d09", + "id": "17372723751757611894", + "senderId": "3430046214873810255L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8cd1d6d0465d7272b203c6f9ca35dd664e8798ffe62209ea5af90985c081731b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3ba7fdf4c3fc56e9cc35f9547a40074fecd5cafead810c0b3c5511df5f7970ec" + } + }, + "signature": "ea0328476495304cc39cded108a7aa546b39707f408ec92a2c42ae9954b285a839ae1f0faae7cc67f2c274ef8f54883746caca44ecaf6138edfe55466ce32309", + "id": "13984407981098063009", + "senderId": "3430046214873810255L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8cd1d6d0465d7272b203c6f9ca35dd664e8798ffe62209ea5af90985c081731b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "angry" + } + }, + "signature": "d9971a02af03b7f6c28a876a8d9ff1bac71e29379224d6ccbc75482d1ec244648d10f2060d6f9c6b22bf33d12b97c058155899c837d59f619c9a5e517dfc7409", + "id": "1429877338950280504", + "senderId": "3430046214873810255L" + }, + { + "amount": "0", + "recipientId": "3430046214873810255L", + "senderPublicKey": "8cd1d6d0465d7272b203c6f9ca35dd664e8798ffe62209ea5af90985c081731b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+8cd1d6d0465d7272b203c6f9ca35dd664e8798ffe62209ea5af90985c081731b" + ] + }, + "signature": "348f7e6b2b7e5c9c21f9df784ebc7a8625170cc34b156e62b76559a4990612fe3583085f97544ce06498af080a8e63587019c99868ed9f31177dfc8fe2b1c106", + "id": "9297554317132720844", + "senderId": "3430046214873810255L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8cd1d6d0465d7272b203c6f9ca35dd664e8798ffe62209ea5af90985c081731b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+8cd1d6d0465d7272b203c6f9ca35dd664e8798ffe62209ea5af90985c081731b", + "+3ba7fdf4c3fc56e9cc35f9547a40074fecd5cafead810c0b3c5511df5f7970ec" + ] + } + }, + "signature": "ec2b81639ec228e84c5512670d7942d810820d75cd0eb2b920be904fe3107a666930d4e8ae91ec7e0c6c7a9d909dff32308eb27c227a701140d7292699253d0e", + "id": "8988788864761628128", + "senderId": "3430046214873810255L" + }, + { + "amount": "1000000", + "recipientId": "16516747851220724447L", + "senderPublicKey": "aec4e8fe9dded6937c26bdfede10d6b88946241cd87be9edc540056032c6b511", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "99ce5f36150d51c9cef52077e70d51357a411d1e0dcdad0bd7ffb822147ac3213665f98e7ec93dbe4215cefc2a3b9467d1c0776da503e5b8437a22b12b8d5201", + "id": "8261289014741956096", + "senderId": "16516747851220724447L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "aec4e8fe9dded6937c26bdfede10d6b88946241cd87be9edc540056032c6b511", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "44c73463c31f29dbb62637a37203b1440d49ade656448f5c4dad5c3d7d29d886" + } + }, + "signature": "f1d203e6ab0e415864f923d8649677eced21ca1f465af69df2169b6b362a3e32214d8265138adc31b92ba734e23cfd658189ca3dd3f34cd5da0821477d38420f", + "id": "12265032184455310841", + "senderId": "16516747851220724447L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "aec4e8fe9dded6937c26bdfede10d6b88946241cd87be9edc540056032c6b511", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "claim" + } + }, + "signature": "638b3683fd59c45c543badeb48ea2972cd3b054c008973968cc9722ed65bcc9902661e24b43b5f7b64616319927479512323d56ae16b28329b70ef5c1325750f", + "id": "13462151602542863122", + "senderId": "16516747851220724447L" + }, + { + "amount": "0", + "recipientId": "16516747851220724447L", + "senderPublicKey": "aec4e8fe9dded6937c26bdfede10d6b88946241cd87be9edc540056032c6b511", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+aec4e8fe9dded6937c26bdfede10d6b88946241cd87be9edc540056032c6b511" + ] + }, + "signature": "b9d0178569a2c1b70185d8dd7a0c6ae2bda90adbd296724c5b571c78f72589a259f7efe88ddf64345213b334cde3ad364cd495995e9a1f6cc7b9a52d4c6cc609", + "id": "5498443135773418501", + "senderId": "16516747851220724447L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "aec4e8fe9dded6937c26bdfede10d6b88946241cd87be9edc540056032c6b511", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+aec4e8fe9dded6937c26bdfede10d6b88946241cd87be9edc540056032c6b511", + "+44c73463c31f29dbb62637a37203b1440d49ade656448f5c4dad5c3d7d29d886" + ] + } + }, + "signature": "0f678283270b99fee43073e9d8d885f13870c724337faaed5ca96e8626dd8c7a30eeedf55621853e18eec9e533d7af587667365d74bd9d43a81e3920c36c7f0c", + "id": "7861013782139651826", + "senderId": "16516747851220724447L" + }, + { + "amount": "1000000", + "recipientId": "10972103432408482162L", + "senderPublicKey": "eed09f07896c16c0c94d2608b974800a09ef95be2e94b07ddd538d8bdb43aa43", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "692bba74c40b0906906b4b759d8ee8216829194e55863f5d76d96f948f657b2aac1ed4bc0d2e4340c31613b7a11f65922f48737e940ba39c6f7aca20d92e580f", + "id": "11429718247966879978", + "senderId": "10972103432408482162L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eed09f07896c16c0c94d2608b974800a09ef95be2e94b07ddd538d8bdb43aa43", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "0d34716045cf8b859bd45a785e74a186f20d488ad3e8384f58f9e16b1d1149a0" + } + }, + "signature": "eb386f406ec8934be6028315701d607cdb5824215c55a63aa7e41a0d1f1ab79a6a297456a68a50aee3a00031a11399a9ba6c1506a690a1c141e319d81cb07f0b", + "id": "13830297103787270965", + "senderId": "10972103432408482162L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eed09f07896c16c0c94d2608b974800a09ef95be2e94b07ddd538d8bdb43aa43", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "enemy" + } + }, + "signature": "6d36b4a0ce2c34cb9be53a23ccfb53aa908f29eec0b22417abc3d870c947bfa6a4b1265fd7bdfcc444c45ccafbfd7ef53d5433958a9327516ea01af0aee1fa0d", + "id": "15282155397827547671", + "senderId": "10972103432408482162L" + }, + { + "amount": "0", + "recipientId": "10972103432408482162L", + "senderPublicKey": "eed09f07896c16c0c94d2608b974800a09ef95be2e94b07ddd538d8bdb43aa43", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+eed09f07896c16c0c94d2608b974800a09ef95be2e94b07ddd538d8bdb43aa43" + ] + }, + "signature": "0a2942235069b86be56122b57e1848eb3edf9b162bc831fa5440a24585698b1c98233053bf77da155eed0693b9e0d862de02041a0285cf051e57adc69b2e3605", + "id": "14516919665893646372", + "senderId": "10972103432408482162L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eed09f07896c16c0c94d2608b974800a09ef95be2e94b07ddd538d8bdb43aa43", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+eed09f07896c16c0c94d2608b974800a09ef95be2e94b07ddd538d8bdb43aa43", + "+0d34716045cf8b859bd45a785e74a186f20d488ad3e8384f58f9e16b1d1149a0" + ] + } + }, + "signature": "8dddfe2ecbe1d8441c2219d9b43f8d5cc5a248db92c9a091fa79c58aa8488902797580ef0e9a7862fd5ef17d01c6a3434b601a8041e11089f7be5d0ac1e22007", + "id": "9634440893475315621", + "senderId": "10972103432408482162L" + }, + { + "amount": "1000000", + "recipientId": "15873561270753252877L", + "senderPublicKey": "3d7a4b522709748e8ddbc286f3109d33bee5b394a2bdb1269b065b78132a4487", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "d0e222bf0b63d72bbb74247cfa54c701d3650cf5df6b001ec0c5393df3f13addf17f1462536b730e1593844545ee7c994d78c82ce446e153dad707c9471f2702", + "id": "1825249727235416882", + "senderId": "15873561270753252877L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3d7a4b522709748e8ddbc286f3109d33bee5b394a2bdb1269b065b78132a4487", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9d780f44ff17bbfeee9845f1ced676d7f0a55bc024d57311774b9aec6b6267ed" + } + }, + "signature": "01b54584bb550babfbdeca06267075584622ead9f834416c9a209712ab467f46f3046c1feaf7df36cce80c16c8b84c9804ef2b897af0a083eb5137b2ccd67707", + "id": "17141356593983180207", + "senderId": "15873561270753252877L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3d7a4b522709748e8ddbc286f3109d33bee5b394a2bdb1269b065b78132a4487", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "three" + } + }, + "signature": "5cd9538bfc52df861226cf1cce98b9fb72307fb5d18fe012e2dc09468bec1d4227e4db531bad192b142a01c06d02bed1ee4d2f12ef3353a5ae70f695c09be502", + "id": "17767034352406781593", + "senderId": "15873561270753252877L" + }, + { + "amount": "0", + "recipientId": "15873561270753252877L", + "senderPublicKey": "3d7a4b522709748e8ddbc286f3109d33bee5b394a2bdb1269b065b78132a4487", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+3d7a4b522709748e8ddbc286f3109d33bee5b394a2bdb1269b065b78132a4487" + ] + }, + "signature": "ed8fa931b2d2257f89412e11075c9507b4f3607c91b9f727cdf153b7fe148ec1b07eeead52e38b26a565ea5d89ac24f6e6f54cf5a4674e4db4203136a3d0f604", + "id": "16043323818366179849", + "senderId": "15873561270753252877L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3d7a4b522709748e8ddbc286f3109d33bee5b394a2bdb1269b065b78132a4487", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+3d7a4b522709748e8ddbc286f3109d33bee5b394a2bdb1269b065b78132a4487", + "+9d780f44ff17bbfeee9845f1ced676d7f0a55bc024d57311774b9aec6b6267ed" + ] + } + }, + "signature": "d661f7b311ec033522a4ade34cecf6d1b18e5ec28259f29bdc761e95eb71f72cea87dcde00f044c4ae9b1273848623ebf1d6ca94b81e1d8dd2fee4742faf160e", + "id": "14460537336140278331", + "senderId": "15873561270753252877L" + }, + { + "amount": "1000000", + "recipientId": "17849699930152083990L", + "senderPublicKey": "badc5c9df73e713dfea6a99af8053f50b22b3110464c6ae58921c4c316755564", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "b27197392d0916741795111174c47bc9d737385acac852f918faac922dfb38bd0e532f7c0e4673a3c98a704d12d939bc10f4512cb849ddea885a4a937b559104", + "id": "3110735568698151611", + "senderId": "17849699930152083990L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "badc5c9df73e713dfea6a99af8053f50b22b3110464c6ae58921c4c316755564", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "eb0f21200f56266121bfc94d3eaacb3164672f61b3614f54b8b5f293cbce2346" + } + }, + "signature": "db666b731d397235aa78b83bc83f2388fb16008a4e5649a491caa0f6356187067923d423ed1393b4e7038e4f14f7bda018498462b773b8e73d64c986b0e85a0f", + "id": "11188273851375707700", + "senderId": "17849699930152083990L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "badc5c9df73e713dfea6a99af8053f50b22b3110464c6ae58921c4c316755564", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "season" + } + }, + "signature": "4f748ef2614e042b7d70fa351d02bb9ade71dc92fd1f9304e533286c27b9996632aab2b1b72b6fc47a972b099cfef0bb653dfea08b4ce6db8824cf37ddc4e908", + "id": "15400708917798644964", + "senderId": "17849699930152083990L" + }, + { + "amount": "0", + "recipientId": "17849699930152083990L", + "senderPublicKey": "badc5c9df73e713dfea6a99af8053f50b22b3110464c6ae58921c4c316755564", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+badc5c9df73e713dfea6a99af8053f50b22b3110464c6ae58921c4c316755564" + ] + }, + "signature": "d77e929f616a3b66cc332810b0660bec824d789726a9bed5c9d82515a46edef145fd7799a36e96ab7388407d5e3d2a51272569870798887ed0d25b7c2a64b001", + "id": "8979392864102288518", + "senderId": "17849699930152083990L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "badc5c9df73e713dfea6a99af8053f50b22b3110464c6ae58921c4c316755564", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+badc5c9df73e713dfea6a99af8053f50b22b3110464c6ae58921c4c316755564", + "+eb0f21200f56266121bfc94d3eaacb3164672f61b3614f54b8b5f293cbce2346" + ] + } + }, + "signature": "7327483313040d535ac636a013bc24a12b9c513c2fa94f77f27d909f27a20b74b8c26389434fe282711734859e63de9b96081a8be17545bea6c3a8eea7ff1709", + "id": "10128400331673178860", + "senderId": "17849699930152083990L" + }, + { + "amount": "1000000", + "recipientId": "7143152327339961892L", + "senderPublicKey": "7c44c88b7ae0b9dfad5cbca35f738bc826d23107d6411ab0ba2ff2d115949606", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f7795c274572daf7777d3bb52c8fce16dc6ba39d90f040a5ec4c5fabca19374fa9348997dd0f293410252cf4edfda5209fa301fb3b3c3f53770fb8c38b0e720b", + "id": "8593449154194060588", + "senderId": "7143152327339961892L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7c44c88b7ae0b9dfad5cbca35f738bc826d23107d6411ab0ba2ff2d115949606", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4fbce194a3b205cd0f05552ebb1cbca38964d371b9eb83b8f77835b427148134" + } + }, + "signature": "f169a5dc0fe704d1c5c6cc33d9043ea4445bbaac38f499c8e5fb4cabdb2bb5dabfbe336443060e64acce262fb80dea931245a6bb428f52b5fe2d40368dea8b0f", + "id": "10794540182980704048", + "senderId": "7143152327339961892L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7c44c88b7ae0b9dfad5cbca35f738bc826d23107d6411ab0ba2ff2d115949606", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "hollow" + } + }, + "signature": "fdf3e57b436e893a94ec5e4ce2d2694d4f409db3f90958dd0e863c3dbbd746dfc58e6c058787c73346f53d45d0251cdacb087df5aa542435858de434a9908c0f", + "id": "4077921156685813436", + "senderId": "7143152327339961892L" + }, + { + "amount": "0", + "recipientId": "7143152327339961892L", + "senderPublicKey": "7c44c88b7ae0b9dfad5cbca35f738bc826d23107d6411ab0ba2ff2d115949606", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+7c44c88b7ae0b9dfad5cbca35f738bc826d23107d6411ab0ba2ff2d115949606" + ] + }, + "signature": "14d5497acb5bde270fc81cdc00ac04805e714919f3c15a67470d571cedabd1498655087cff4ca56bd8900efab0e3b65a15e6f5ad9c25b54fcb59fb60e934780a", + "id": "18370295145997821996", + "senderId": "7143152327339961892L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7c44c88b7ae0b9dfad5cbca35f738bc826d23107d6411ab0ba2ff2d115949606", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+7c44c88b7ae0b9dfad5cbca35f738bc826d23107d6411ab0ba2ff2d115949606", + "+4fbce194a3b205cd0f05552ebb1cbca38964d371b9eb83b8f77835b427148134" + ] + } + }, + "signature": "acf9df505921f6f60a7b0cb27d20dca8eddbc8b28e485bb4be54e3d9d821a07073229cf3502edb994888659da26c99bac3225fa9f00821876b46d4ae7b62870d", + "id": "16242369161897766597", + "senderId": "7143152327339961892L" + }, + { + "amount": "1000000", + "recipientId": "2549133345932177907L", + "senderPublicKey": "20d1f2632be2689d4b54ff2d2c5fa2ebf14e01a897477ec462e75a1986578ce7", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "0503ca5679b7d515be1bd9efe70b395ad2d3d2b80a0c0602c39ca63b5c35f947f90389fea91391b2cce5f129d8275969cb3c8439e03c10b351db91faf9c08805", + "id": "3500529342908217555", + "senderId": "2549133345932177907L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "20d1f2632be2689d4b54ff2d2c5fa2ebf14e01a897477ec462e75a1986578ce7", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "1d3779570d0e35b5cb6e2d84ffb71d988ce2cc3cdd2898b73b800d426874d533" + } + }, + "signature": "141fb517fe1448d2d6d213092fe7c2c36cd9c8d1cef75cf9c3443019bb2fb55ef7fb9df04e00f94901ea9f8e588fbc6324b9f9c95bde00409bf8618c0b87d00e", + "id": "15149099074664125356", + "senderId": "2549133345932177907L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "20d1f2632be2689d4b54ff2d2c5fa2ebf14e01a897477ec462e75a1986578ce7", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "meadow" + } + }, + "signature": "07be84b6ece369201864ea826d8587cc95312a62dfc49cb3cbe0996ff114e58ee2e79595582e2ec11efb295807d0f0f7183269dcb346a77e09de84712fb89106", + "id": "9016313139023950590", + "senderId": "2549133345932177907L" + }, + { + "amount": "0", + "recipientId": "2549133345932177907L", + "senderPublicKey": "20d1f2632be2689d4b54ff2d2c5fa2ebf14e01a897477ec462e75a1986578ce7", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+20d1f2632be2689d4b54ff2d2c5fa2ebf14e01a897477ec462e75a1986578ce7" + ] + }, + "signature": "61aa17e9cea9ae84338d2c946a6ebb0be553d3fec43ae39cf9339a7d0ce1a51c94eaf643ed3c29813ef2d1e6909da427ebd0b656005e6de622354e7d6a9fde00", + "id": "17593823799705958223", + "senderId": "2549133345932177907L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "20d1f2632be2689d4b54ff2d2c5fa2ebf14e01a897477ec462e75a1986578ce7", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+20d1f2632be2689d4b54ff2d2c5fa2ebf14e01a897477ec462e75a1986578ce7", + "+1d3779570d0e35b5cb6e2d84ffb71d988ce2cc3cdd2898b73b800d426874d533" + ] + } + }, + "signature": "524fd8214ec84fe4a1d1931346087015debf73ab906820a04bad3be7214785039909aadc6d42f19042bcf01dbf7d352188db8e8c06669614949f792e0563010c", + "id": "9968876024105466536", + "senderId": "2549133345932177907L" + }, + { + "amount": "1000000", + "recipientId": "9438125228453050361L", + "senderPublicKey": "3c10b37399414e58e17b901b98e25bd5ae365a2376c278b3c420571b3eba9f45", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a3516808d68c6bc9b82627e3b4297a3bd8ff80f7742dec3d26e7c5cf643d864e4a569f6d6d2e48308f93aa5a7db6021fba17f5a782afc83fd357f76c1fb81e05", + "id": "11741948170351467815", + "senderId": "9438125228453050361L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3c10b37399414e58e17b901b98e25bd5ae365a2376c278b3c420571b3eba9f45", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "90890437347662f84509c748988173a11f53603b2370c14a280f8a4396ce8124" + } + }, + "signature": "1f46100f89be2e62cfa2659e48bb2ca3734dd792b0b8cbf1c53741d1ce83d778fb284141a8b91da276839fcb09af8357f21305464bbe8b6e95655850a587270b", + "id": "17147579700554825089", + "senderId": "9438125228453050361L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3c10b37399414e58e17b901b98e25bd5ae365a2376c278b3c420571b3eba9f45", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "walk" + } + }, + "signature": "324e5991c3549f3ec78b202e9e32b4f52c4cb1b6a8c129dc14f7a125fc2e393c7e519555440d0878d20413258d3cb6704a8a3de90b71e32a036fba37644f540b", + "id": "66779151530796451", + "senderId": "9438125228453050361L" + }, + { + "amount": "0", + "recipientId": "9438125228453050361L", + "senderPublicKey": "3c10b37399414e58e17b901b98e25bd5ae365a2376c278b3c420571b3eba9f45", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+3c10b37399414e58e17b901b98e25bd5ae365a2376c278b3c420571b3eba9f45" + ] + }, + "signature": "cca2b6b4bcb930eab254aff0ed6b72fbf772de8036471f1b32ae085132e14214b678470e812864844bc08edc9409593e892871989d60c222ecf560762c070507", + "id": "7925226035287998590", + "senderId": "9438125228453050361L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3c10b37399414e58e17b901b98e25bd5ae365a2376c278b3c420571b3eba9f45", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+3c10b37399414e58e17b901b98e25bd5ae365a2376c278b3c420571b3eba9f45", + "+90890437347662f84509c748988173a11f53603b2370c14a280f8a4396ce8124" + ] + } + }, + "signature": "95763ecb2ba47122b4844120e213acba076e39c16bbd546c27c0f4128add4722a1e6b402a14a7bf27f528a3793166a52dbb6a6298e65a53c69df0744ee149f00", + "id": "4243684748415585425", + "senderId": "9438125228453050361L" + }, + { + "amount": "1000000", + "recipientId": "3916024107904997998L", + "senderPublicKey": "803055ec150a3ab8aad7c06fb28e21be7ba20eb99460fe36e5fad6cbeb764399", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "cdabc48dc62fa0babe720000fb9753128f1f952fe0abe5bec8629ea4cd94dc8cd959233e476d7f1ccb230f7588f0133a05d24b41cfdc2f38fe8381aad4549408", + "id": "4486278783381603790", + "senderId": "3916024107904997998L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "803055ec150a3ab8aad7c06fb28e21be7ba20eb99460fe36e5fad6cbeb764399", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f56177148c9d758e3cfea8354228fb47a54b7157c35f9dcfa0f034b3398410e2" + } + }, + "signature": "6b8ef0d7dd77fb88a2dc496fcfde03731ddae2ef132407969ad719f2e17b9ed62f8192c72354272a57a53dbf31419afbc9f1d079830df5410582b98efd9c660b", + "id": "11643375060560841717", + "senderId": "3916024107904997998L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "803055ec150a3ab8aad7c06fb28e21be7ba20eb99460fe36e5fad6cbeb764399", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "transfer" + } + }, + "signature": "1546c174f25831d32d8f1c0fa5b1db5b58bbe1c5fa309a5f8a3c388bd3c92a582c5f5b2f700feab2ecbe4e446249e9c3e1f9c6a08f36cff80206d749a420e405", + "id": "10168049272188808770", + "senderId": "3916024107904997998L" + }, + { + "amount": "0", + "recipientId": "3916024107904997998L", + "senderPublicKey": "803055ec150a3ab8aad7c06fb28e21be7ba20eb99460fe36e5fad6cbeb764399", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+803055ec150a3ab8aad7c06fb28e21be7ba20eb99460fe36e5fad6cbeb764399" + ] + }, + "signature": "fe69ba190fa2790c442034afda497d2f69464270752f35dcb316346397694c00eb6f980cb653645f25344311902f7960ed6fb4dc30918d50641baf656b8edc04", + "id": "8758849122410374223", + "senderId": "3916024107904997998L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "803055ec150a3ab8aad7c06fb28e21be7ba20eb99460fe36e5fad6cbeb764399", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+803055ec150a3ab8aad7c06fb28e21be7ba20eb99460fe36e5fad6cbeb764399", + "+f56177148c9d758e3cfea8354228fb47a54b7157c35f9dcfa0f034b3398410e2" + ] + } + }, + "signature": "d1a0a4b32d480dbafb027c5e26fe7cbaacb6e4dc7a619397ef524f02e18582957aa07a81959ff6cb19a6b1a4b180ae6e8aa7df01bdb813a22310fba00f6c0b01", + "id": "13078158504730324149", + "senderId": "3916024107904997998L" + }, + { + "amount": "1000000", + "recipientId": "1938412918027918963L", + "senderPublicKey": "28dc06c7f9774d215a2511a0761f8dbb285418438808afb8f63b265fe0bc4ddc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ca4a018fe06b63b7664b4ac6ee77c7c14c8e6a8145f94915f5b9440cdbca01abf3ab87f8fbf3e65e018cf15d06dc207c90ae057c2a5febc36d827dfd3be2e202", + "id": "17994519112323304793", + "senderId": "1938412918027918963L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "28dc06c7f9774d215a2511a0761f8dbb285418438808afb8f63b265fe0bc4ddc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "467d80aff516bbefa3cac156e515a0ef38a44be11933edcda4fe74b5d0a9f5ac" + } + }, + "signature": "71e70f74640129f0e597fbb03e3e0540df74c2677c8511f1bf4241ba0d42acb5190c267c405fd2b16084cb0a43602417e4d285456a9a4feeea6b0d9f8a693a0e", + "id": "10457211830239982345", + "senderId": "1938412918027918963L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "28dc06c7f9774d215a2511a0761f8dbb285418438808afb8f63b265fe0bc4ddc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "ten" + } + }, + "signature": "fbcdcd63cfdc0a5720f51cfa2668b6b2af0026d7091840635c75cbc634094c9a9dc14e1f30edee76a086df1f4e8a924665cd9f7f07f75be86db64f00497a9d0d", + "id": "9921431613430989147", + "senderId": "1938412918027918963L" + }, + { + "amount": "0", + "recipientId": "1938412918027918963L", + "senderPublicKey": "28dc06c7f9774d215a2511a0761f8dbb285418438808afb8f63b265fe0bc4ddc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+28dc06c7f9774d215a2511a0761f8dbb285418438808afb8f63b265fe0bc4ddc" + ] + }, + "signature": "4959af09465f1bb6f92b473629f44222cc338e20126e57d782757b16a14e534d70c2054ca96c70a6f76bd3e22eae7dc6359b1c27fe6876942e02584ef68bc006", + "id": "13968177927521994321", + "senderId": "1938412918027918963L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "28dc06c7f9774d215a2511a0761f8dbb285418438808afb8f63b265fe0bc4ddc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+28dc06c7f9774d215a2511a0761f8dbb285418438808afb8f63b265fe0bc4ddc", + "+467d80aff516bbefa3cac156e515a0ef38a44be11933edcda4fe74b5d0a9f5ac" + ] + } + }, + "signature": "6a90700f50f24568ff8a312289ad5ccfb9e4067c84f2a259d4dbb6ba71ab8b0e951d48e3392d41bfb8af43d7d74016fddedf06afeef843436f8c4b0c908c280e", + "id": "4319984554135991701", + "senderId": "1938412918027918963L" + }, + { + "amount": "1000000", + "recipientId": "3667006431484213724L", + "senderPublicKey": "01d3afa9417499f056f73e980fb1acf6cbc3ddc5fd50ffa38715ec4f1a49a29b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "571eedc11ed18424147ef99541990beb6876227eb4f40440f79823eae9452c876496314e0e56c8bcffee4b3d3a7b1394d40f2bd60c59a74254082acae62e2d0e", + "id": "1289116272939437843", + "senderId": "3667006431484213724L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "01d3afa9417499f056f73e980fb1acf6cbc3ddc5fd50ffa38715ec4f1a49a29b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3f3f7277b036bf9aefe40cf4092adee9c7e313367e55fcf90f6fc99d1059a38f" + } + }, + "signature": "f7bace423a8c5b6ad91e90cd48b42dafcc998d746232a5f369431ff1a75d242d532a6c82780828a0da368ab3e71301b3a7c5b9f2ff7e327b22afab5cbf54dd0e", + "id": "4104063361648866567", + "senderId": "3667006431484213724L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "01d3afa9417499f056f73e980fb1acf6cbc3ddc5fd50ffa38715ec4f1a49a29b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "audit" + } + }, + "signature": "0a5a80fca1de0e22cdebdfdffbe308903d501e70d81daa8c79f2f0628538b5f7da90b76d1a299fafe84964937dfe56f73c5296f0167eac45d640f6f9f038ab06", + "id": "16475250343061882418", + "senderId": "3667006431484213724L" + }, + { + "amount": "0", + "recipientId": "3667006431484213724L", + "senderPublicKey": "01d3afa9417499f056f73e980fb1acf6cbc3ddc5fd50ffa38715ec4f1a49a29b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+01d3afa9417499f056f73e980fb1acf6cbc3ddc5fd50ffa38715ec4f1a49a29b" + ] + }, + "signature": "f2c2981a7d4e524006d70242259cc31924a60da38dc40c8731739141a4af494b729ed4afcf670975866bdb19c22084612d342cd05931442bafd7d6c7184e3709", + "id": "3657710963446868370", + "senderId": "3667006431484213724L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "01d3afa9417499f056f73e980fb1acf6cbc3ddc5fd50ffa38715ec4f1a49a29b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+01d3afa9417499f056f73e980fb1acf6cbc3ddc5fd50ffa38715ec4f1a49a29b", + "+3f3f7277b036bf9aefe40cf4092adee9c7e313367e55fcf90f6fc99d1059a38f" + ] + } + }, + "signature": "629ed1e78ea7fbe2265ff6660ec619801c3c5ee9ad6e97da7c15697c558b0ffea9dbe17762b4f446d6d962dcb20f54e30ddf928c3204ce698f86cacb2a916109", + "id": "1982559852023187178", + "senderId": "3667006431484213724L" + }, + { + "amount": "1000000", + "recipientId": "6625949790222269428L", + "senderPublicKey": "b6f0b680d976cadc763cd71caf2c3495f81c5ef07bb2518ae1ec81256bb2a360", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "c6780a1895749c72383523c2491df39ef98f28ff3cc74d8b9f38823729fb5745673d2ed3cd83c39c4f15e551babdfc6b5015f0a8b767b54c74f16f854e3b250c", + "id": "6298073514254778847", + "senderId": "6625949790222269428L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b6f0b680d976cadc763cd71caf2c3495f81c5ef07bb2518ae1ec81256bb2a360", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "b5535f6f702f0f012fe79f08c3ab51ee0387eaed06e65e2f5cc6045c7a99ef9c" + } + }, + "signature": "4e7754f1268d97d29e3ae7c71fb1eca807535af99bb2d910d0cdb7da20a48ecc0cfb646c40b8c7856cd3f26d9481f3bd3581749f69060fad6cdc7de1364e150e", + "id": "15602930576220041849", + "senderId": "6625949790222269428L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b6f0b680d976cadc763cd71caf2c3495f81c5ef07bb2518ae1ec81256bb2a360", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "vocal" + } + }, + "signature": "d796345448e0d87258e020a356b5a6a91b3c610f5702ccdff970272a5c3778486d71ec8cd2a4090294f15f4a0d8461249fb84d586212ebeee0fa8bfb398a8e03", + "id": "3178814962822377399", + "senderId": "6625949790222269428L" + }, + { + "amount": "0", + "recipientId": "6625949790222269428L", + "senderPublicKey": "b6f0b680d976cadc763cd71caf2c3495f81c5ef07bb2518ae1ec81256bb2a360", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b6f0b680d976cadc763cd71caf2c3495f81c5ef07bb2518ae1ec81256bb2a360" + ] + }, + "signature": "4279e000c16c8cce55f56a36ec02ea87ed69b9ccadab5011016184eb28b61a451cf46219b7eeaa54fba65d3d2950c074e48f10b04604e8141d6c7a50d32a0107", + "id": "15967083998817501548", + "senderId": "6625949790222269428L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b6f0b680d976cadc763cd71caf2c3495f81c5ef07bb2518ae1ec81256bb2a360", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b6f0b680d976cadc763cd71caf2c3495f81c5ef07bb2518ae1ec81256bb2a360", + "+b5535f6f702f0f012fe79f08c3ab51ee0387eaed06e65e2f5cc6045c7a99ef9c" + ] + } + }, + "signature": "967a8dcfc4b0df280795de8d18b10bb511f65d964780d8442088cb067f60e813f637cd53d4e8e946fee3ff76e6847a438590a05d2b0d3e2369974aa34464240a", + "id": "585910408815896760", + "senderId": "6625949790222269428L" + }, + { + "amount": "1000000", + "recipientId": "2532318941103971096L", + "senderPublicKey": "20b323a973d982b855bf7c373899aadea934b09e39b45e5852ee251e88f8fc2e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "623d32a73025c4f6f72009a9b3e05a1d42b936e2d7c41ca4eb5c2bd7984ce625c5e6ff728f717bb75bdd94dc43de50074676b32d7090df90d73768e5f7df4c0b", + "id": "16258935148201630763", + "senderId": "2532318941103971096L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "20b323a973d982b855bf7c373899aadea934b09e39b45e5852ee251e88f8fc2e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "a93db788c717929a2e2bd964e7e5452eb48749a19d15e7f28fc0848a89f1d63f" + } + }, + "signature": "5b7b282abe018c0898deaf03fa03894642617b9f5e72d5e40117945c1d30fbdf76e003efdeb16452baeedfeb89e66f5428a5cd86be4da15a990e72085bbd6108", + "id": "8041280313793968391", + "senderId": "2532318941103971096L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "20b323a973d982b855bf7c373899aadea934b09e39b45e5852ee251e88f8fc2e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "private" + } + }, + "signature": "7bb128d9e968e9088be148be44c63f49d0794f5f4f9210bd9a604ea1222548218a4ff38ddb7becad9ec22db79a62cc8a7522c9fdca32d0010dad1de97ceb9f0e", + "id": "5424915529824961933", + "senderId": "2532318941103971096L" + }, + { + "amount": "0", + "recipientId": "2532318941103971096L", + "senderPublicKey": "20b323a973d982b855bf7c373899aadea934b09e39b45e5852ee251e88f8fc2e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+20b323a973d982b855bf7c373899aadea934b09e39b45e5852ee251e88f8fc2e" + ] + }, + "signature": "e9f131bc442874488a6ee04c5f91ac5ea40ad0c18306536298f1afe0930d1e74155086e94b39bb4ea33b8d41eb5bed846222866b29b6d08100a5fe4a37bd0605", + "id": "3417438064088869722", + "senderId": "2532318941103971096L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "20b323a973d982b855bf7c373899aadea934b09e39b45e5852ee251e88f8fc2e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+20b323a973d982b855bf7c373899aadea934b09e39b45e5852ee251e88f8fc2e", + "+a93db788c717929a2e2bd964e7e5452eb48749a19d15e7f28fc0848a89f1d63f" + ] + } + }, + "signature": "cb32b50a2426092e784ee69258d590e92515a4efdf2f5877833d265abdba555f3206f0e177bd0b7269f3d0db170b0bdc25129a304b89a48fd2995f9454776802", + "id": "13173043832092306903", + "senderId": "2532318941103971096L" + }, + { + "amount": "1000000", + "recipientId": "12277599915277509534L", + "senderPublicKey": "c43068ed5194cc2d64068c5ebce55db5e7cc50cf8d9e1990ed794c7f98e57f07", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "3e2588aaa73269bc19843ca175fcdad7b68f4d9b32123ef2dba4360c613e7916ac4bd2dd6372a0f915d9af1e9a3d6691adb9fbc08dbcbfa6aedfd87a71a89902", + "id": "2623991513589111031", + "senderId": "12277599915277509534L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c43068ed5194cc2d64068c5ebce55db5e7cc50cf8d9e1990ed794c7f98e57f07", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "5fa58c0c7b202e075e7ca8967f17de83cffc5cce7642ee5c0bbb280495acf0ab" + } + }, + "signature": "fb2001f685c610fecf04020e901477a512cd8bb3cf693db1d112fed43cd045684597a5c097e9353d57570569ec50009b5b539318c27362dec4c8c07520fd7205", + "id": "7011782235169772249", + "senderId": "12277599915277509534L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c43068ed5194cc2d64068c5ebce55db5e7cc50cf8d9e1990ed794c7f98e57f07", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "deer" + } + }, + "signature": "b6cd9cea777331ad620bbafcfbc29b6ae0c51174a0b0c9b7a79a5cf6a1439d43928eefed4693620fe5e72095b3a37322c15bb648eb9751c7550942c32c750b08", + "id": "15523648427931555708", + "senderId": "12277599915277509534L" + }, + { + "amount": "0", + "recipientId": "12277599915277509534L", + "senderPublicKey": "c43068ed5194cc2d64068c5ebce55db5e7cc50cf8d9e1990ed794c7f98e57f07", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c43068ed5194cc2d64068c5ebce55db5e7cc50cf8d9e1990ed794c7f98e57f07" + ] + }, + "signature": "2e74e74f97d29d64ac725ebc60bd4dec2afb36dfc8cbd59be5751123fdfd9559b0bdebfcea84f213847ee4f44375c6b9890f52edf10679eaf62739495f527e05", + "id": "13364791406811516182", + "senderId": "12277599915277509534L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c43068ed5194cc2d64068c5ebce55db5e7cc50cf8d9e1990ed794c7f98e57f07", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c43068ed5194cc2d64068c5ebce55db5e7cc50cf8d9e1990ed794c7f98e57f07", + "+5fa58c0c7b202e075e7ca8967f17de83cffc5cce7642ee5c0bbb280495acf0ab" + ] + } + }, + "signature": "c8a8bdd6ce450af02b8372d3ad38e3e13ca39e1a84b2fd93d9b8ee658ac374ce30479922ccc60d1e95eb9629746bd02030c4078dd43c2968c060ce4e3135fa01", + "id": "17528295758185132410", + "senderId": "12277599915277509534L" + }, + { + "amount": "1000000", + "recipientId": "12989474873841150704L", + "senderPublicKey": "f842a88a982e2e115debdf763cf87894ae2a79fa62fa92aa18a21943212f8aa6", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "18f7b031cd4353e572005a6900c0ac05a3c14145cf53e5cd7a544a8825943ad01fe865096899c132ed4e2e549e811f051fe76f0071a53f2f983fbdf73808bc0a", + "id": "15591683621598025745", + "senderId": "12989474873841150704L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f842a88a982e2e115debdf763cf87894ae2a79fa62fa92aa18a21943212f8aa6", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9050c2ded79050927bd91fa7096358b3279ea31ee34d874e4f7172d2a391f3ed" + } + }, + "signature": "3742c67315a5917cb661d9093367ea9b3bc9f6121d473e66ec13723a17a2ef7266b7cb71dcaf67c76535fb00d7b54f95d423d263026fc304c7c32015df36f805", + "id": "7569275108430143364", + "senderId": "12989474873841150704L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f842a88a982e2e115debdf763cf87894ae2a79fa62fa92aa18a21943212f8aa6", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "under" + } + }, + "signature": "c7fc77308c0ca22d14af7fe6a6bef9cb74c5b79ab36e2b3474f23f422f62074990f067a4652b2a6f7195d3718e2af332a4a65213a4464cb1a505cd6dbe57490d", + "id": "4610022925591397524", + "senderId": "12989474873841150704L" + }, + { + "amount": "0", + "recipientId": "12989474873841150704L", + "senderPublicKey": "f842a88a982e2e115debdf763cf87894ae2a79fa62fa92aa18a21943212f8aa6", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f842a88a982e2e115debdf763cf87894ae2a79fa62fa92aa18a21943212f8aa6" + ] + }, + "signature": "03858201e7804756789be85c9d11fb6864efc21c56a690a745cf4f1340b51e1532fa23ec74109e2cf96cf57293687dd8855b2c6e991ccfb373c6f2c7c471970d", + "id": "1322158581382424081", + "senderId": "12989474873841150704L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f842a88a982e2e115debdf763cf87894ae2a79fa62fa92aa18a21943212f8aa6", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f842a88a982e2e115debdf763cf87894ae2a79fa62fa92aa18a21943212f8aa6", + "+9050c2ded79050927bd91fa7096358b3279ea31ee34d874e4f7172d2a391f3ed" + ] + } + }, + "signature": "3ad30ed9529b341ea9a4e4be370479c3142beb21233e30b0bc72241c636191d2b57679aeb2b5c80cb3387f33c623d1793c8c261258c3920ca56985002a862d0f", + "id": "3102776798078909108", + "senderId": "12989474873841150704L" + }, + { + "amount": "1000000", + "recipientId": "13315625913407116641L", + "senderPublicKey": "75e4e3ec9d84884f4251e261d8cf5ac73f1b1d80029a4f8cb1859e0664bbb625", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "0bf4e636547025d3660c034cd20a5dac3d4ff0efaa68bab1fd2e77dd95ac69033453b6752417f361d54fea14f2a36895b6ffe2185e1238bc6fd923a3632bd00c", + "id": "5046722864017278382", + "senderId": "13315625913407116641L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "75e4e3ec9d84884f4251e261d8cf5ac73f1b1d80029a4f8cb1859e0664bbb625", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "299b3c3a156d87fc7b9b482cee4e352ce4e33f9240afe8bef9e7e7081a0bf692" + } + }, + "signature": "25ecd0953dcd730f281c7e5af0ae4fa4b10362cf0188d35963e090a09b15c494f91e10304ab9f410884bb8799115b3512860173f62b55eb330d9e190e106ef0f", + "id": "18402555010822918654", + "senderId": "13315625913407116641L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "75e4e3ec9d84884f4251e261d8cf5ac73f1b1d80029a4f8cb1859e0664bbb625", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "toe" + } + }, + "signature": "511c9f4fe9ffb97cb37bdbdc2f7831027ad48b3b41c0b1df5ec302494a308990b6475cc6304a67381a3bf4bdff980b0ae32742681a423b38dfb0b4269c679109", + "id": "16111459564704055531", + "senderId": "13315625913407116641L" + }, + { + "amount": "0", + "recipientId": "13315625913407116641L", + "senderPublicKey": "75e4e3ec9d84884f4251e261d8cf5ac73f1b1d80029a4f8cb1859e0664bbb625", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+75e4e3ec9d84884f4251e261d8cf5ac73f1b1d80029a4f8cb1859e0664bbb625" + ] + }, + "signature": "c3bcbfa931162fc04edde51e2488eb75dc161f41bc8aaf8b2d6e1d0174cefaf18e0ec44159fb52a437230126c1cf0193cc5d2d4b2af7acf2f848bef47f7ab609", + "id": "1745214952204017430", + "senderId": "13315625913407116641L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "75e4e3ec9d84884f4251e261d8cf5ac73f1b1d80029a4f8cb1859e0664bbb625", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+75e4e3ec9d84884f4251e261d8cf5ac73f1b1d80029a4f8cb1859e0664bbb625", + "+299b3c3a156d87fc7b9b482cee4e352ce4e33f9240afe8bef9e7e7081a0bf692" + ] + } + }, + "signature": "ff6ab664997c4b492059d3b9cdfc6cbad1a3fbc4ba3bcfbe9d7f447dcb2b466e119956659b2697a1bf5613eeefe4f84dbf8b7d35fb1314b1812a5c96cd6bc607", + "id": "3459080478957063585", + "senderId": "13315625913407116641L" + }, + { + "amount": "1000000", + "recipientId": "4097147014844535493L", + "senderPublicKey": "49a7c781bf9a78afa071dfb1f458522d70d5026b7bd0873301a99c130c7d74fe", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "45a93b4939fdfd3c8f41c326870281b7a4061598cdb0f1363117c5bea2a3218541b09e230116d708c31bcfc3f4de031d33f4eedd718b69b9a28d23940077d706", + "id": "5502088876293062857", + "senderId": "4097147014844535493L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49a7c781bf9a78afa071dfb1f458522d70d5026b7bd0873301a99c130c7d74fe", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c7baf4cffbb68d9e860ee32ab76150615d22ad6a12260b32707ebb3ad97233d9" + } + }, + "signature": "5c8cd3be3bb7eef287057a6680b13f27d1e4f12a2d9e367b4add906074983496b3620864c755d53594081c4a7754345854f126a0da297a49127e0fcd75acf205", + "id": "11425913087683199280", + "senderId": "4097147014844535493L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49a7c781bf9a78afa071dfb1f458522d70d5026b7bd0873301a99c130c7d74fe", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "silk" + } + }, + "signature": "d9914de9fb8586d51d3152ba63c258222893aa22eb3dfda4b5ebfefc709fddac4e29ed917e76689f75902b44a2db85dc79a109a235c888331c2151bd4d643a09", + "id": "11808729887022426400", + "senderId": "4097147014844535493L" + }, + { + "amount": "0", + "recipientId": "4097147014844535493L", + "senderPublicKey": "49a7c781bf9a78afa071dfb1f458522d70d5026b7bd0873301a99c130c7d74fe", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+49a7c781bf9a78afa071dfb1f458522d70d5026b7bd0873301a99c130c7d74fe" + ] + }, + "signature": "9bf19893adc131e89472d0ded4921faaea5da38a5463941b1f7c1fbe4254d3d467e49c5614fa74a6d02ed16235f0286d30004073c39c9308b4e7c4d1f80ba70a", + "id": "4363021759605273888", + "senderId": "4097147014844535493L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49a7c781bf9a78afa071dfb1f458522d70d5026b7bd0873301a99c130c7d74fe", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+49a7c781bf9a78afa071dfb1f458522d70d5026b7bd0873301a99c130c7d74fe", + "+c7baf4cffbb68d9e860ee32ab76150615d22ad6a12260b32707ebb3ad97233d9" + ] + } + }, + "signature": "729bf3cfbc7fe81b753f3de84f77f70bffa7e47868ccf29f8c1d426df59395d2e0d1d27aa508e80a17e44b897207045fb67c0afdfc1165965e33a7bd5540ad0f", + "id": "2338030424041350278", + "senderId": "4097147014844535493L" + }, + { + "amount": "1000000", + "recipientId": "2351907297337713922L", + "senderPublicKey": "3b1027e5c95eaf4fa9e6becb0691c67f8168a2a37abff281748b0ab6a9f543fb", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "bfeb3a71bbc094a9a92a9d0a59f70634c04fb736078ef845cff2322e60ca1ecea9fae57bf1451331ef06fdf3f41cc3507341d2f9c364d94680c358d1fe06a407", + "id": "5515140961461022082", + "senderId": "2351907297337713922L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3b1027e5c95eaf4fa9e6becb0691c67f8168a2a37abff281748b0ab6a9f543fb", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "fc880fdf66326ecb148d5a434a8aae7fe1b13408ef36932eb6ba66bb1fbf9e7a" + } + }, + "signature": "aa4493736e71fb581bfa020eb9efb2e16f9a15998fc3a5d037fd6a5a4fe43e58602f53afd38b066461b2e1980098ac75d695b0ee9a5507a4d540082f916c880b", + "id": "4459636122832956070", + "senderId": "2351907297337713922L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3b1027e5c95eaf4fa9e6becb0691c67f8168a2a37abff281748b0ab6a9f543fb", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "plate" + } + }, + "signature": "f87a80b1568a3fe8da056b9c2bee8391452279441127613c003f4f41737f16a11737a48741fe597da5a7cb72e5dc8a521fa773e1f7431e4b500dbd4a588f7f07", + "id": "6256843511834839268", + "senderId": "2351907297337713922L" + }, + { + "amount": "0", + "recipientId": "2351907297337713922L", + "senderPublicKey": "3b1027e5c95eaf4fa9e6becb0691c67f8168a2a37abff281748b0ab6a9f543fb", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+3b1027e5c95eaf4fa9e6becb0691c67f8168a2a37abff281748b0ab6a9f543fb" + ] + }, + "signature": "1f594a7fc75469001a273e20ffdd72e2f21516e6d38aa52d1d80797dd2536f157af1e3cbae8b6290bd7146782e7d1e40e8b9d6b54331463bd384ac979b79bf09", + "id": "17555603548413954492", + "senderId": "2351907297337713922L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3b1027e5c95eaf4fa9e6becb0691c67f8168a2a37abff281748b0ab6a9f543fb", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+3b1027e5c95eaf4fa9e6becb0691c67f8168a2a37abff281748b0ab6a9f543fb", + "+fc880fdf66326ecb148d5a434a8aae7fe1b13408ef36932eb6ba66bb1fbf9e7a" + ] + } + }, + "signature": "bb7e2643b448ffd1d589bb42eca945bf9f89ee79e2623ec247af69dedc7746430924999a949824665c93be9764c57e923ea7203f08e7ae01ec12a71aa7d5de06", + "id": "5121940565342144822", + "senderId": "2351907297337713922L" + }, + { + "amount": "1000000", + "recipientId": "17265865472587794602L", + "senderPublicKey": "3b71d14fab58d23e5282f0f890646920e0160da0d31b858458f0b88337212343", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "7cc383271c25c392ee743d1b7afb1d453ee7e437a007b6e5fd20b44318eb5087a3b6f818d328bb499f40323bbe38c0e61937fc5ce2545df71943d9ac2993f90b", + "id": "4520644101298179214", + "senderId": "17265865472587794602L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3b71d14fab58d23e5282f0f890646920e0160da0d31b858458f0b88337212343", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "44d55cbd2a4373efd4dbf764f4c9e18e8a1aa798dc1bc920d0bb102dc9decffd" + } + }, + "signature": "295a8200f4eb1c2f1b0af8ace947686a577e8399219d4119c4446f56a0c25c4eec215b5b97f2503af5ede79e23220590f4d2fab8c9fa5ce5c8f557c3185d0f00", + "id": "8041194579780952669", + "senderId": "17265865472587794602L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3b71d14fab58d23e5282f0f890646920e0160da0d31b858458f0b88337212343", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "illness" + } + }, + "signature": "6b44448303b9ca40463938850ecdcbdbb511d6f867a0acfc1941d476c69cd39ff08b04847cc26ea142931824961693101c8ba4fed42eb667bc8531d030b5a10d", + "id": "4908145518006801804", + "senderId": "17265865472587794602L" + }, + { + "amount": "0", + "recipientId": "17265865472587794602L", + "senderPublicKey": "3b71d14fab58d23e5282f0f890646920e0160da0d31b858458f0b88337212343", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+3b71d14fab58d23e5282f0f890646920e0160da0d31b858458f0b88337212343" + ] + }, + "signature": "7d4d20d161ad7bd9de278f496a207a0df4f31b3370fda9cf2f1ac2ddf45081d37b27526ceed2654a3019fed912939d433bcbe91c2aa0562f97da759d10309406", + "id": "8386044115638231865", + "senderId": "17265865472587794602L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "3b71d14fab58d23e5282f0f890646920e0160da0d31b858458f0b88337212343", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+3b71d14fab58d23e5282f0f890646920e0160da0d31b858458f0b88337212343", + "+44d55cbd2a4373efd4dbf764f4c9e18e8a1aa798dc1bc920d0bb102dc9decffd" + ] + } + }, + "signature": "1dbc17233a4e079352275cd542b2ff08dddcd0be341fd208a53c6df1fd89fb2b137ee731f40736c195c9412447adff3de63a2a959b55d4ee82ef0af3d049ff04", + "id": "250854630033381937", + "senderId": "17265865472587794602L" + }, + { + "amount": "1000000", + "recipientId": "3182358207667693329L", + "senderPublicKey": "e0d4022efd7f873b34687d6e1f5df33f49b5a50430893d0418b4191556c39489", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "968e279c5db8ee8ebfed30d332cb50b233b56f968f4639148fdca7d3b244f09f3a235703e2f2272f559d27ecdfc29d87f0631bd649f0ed379ffbd18b2d7d860e", + "id": "17275105573512416224", + "senderId": "3182358207667693329L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e0d4022efd7f873b34687d6e1f5df33f49b5a50430893d0418b4191556c39489", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "63f8f6c7513ddc0772ec5b051766d8998b37e66a030cdff3bb90c139fc598169" + } + }, + "signature": "b1b35b982354afde21311442a5299c90ffe04789d267ddcc92f98ffafbcd2968db781e3dd77a2655176dcae0eba2227125497e7b6ecd6a3c04e47f378bede30a", + "id": "7996693888399508495", + "senderId": "3182358207667693329L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e0d4022efd7f873b34687d6e1f5df33f49b5a50430893d0418b4191556c39489", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "faint" + } + }, + "signature": "62e194fb34a455ea2a5f9bb1abdf757ddcdbdd6884bc752ddc81f014fc50239026aa556be53e9258374ec46da3d341e62490c87a2c3e6d84555a3acb39b0cf0d", + "id": "2181295679952216368", + "senderId": "3182358207667693329L" + }, + { + "amount": "0", + "recipientId": "3182358207667693329L", + "senderPublicKey": "e0d4022efd7f873b34687d6e1f5df33f49b5a50430893d0418b4191556c39489", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+e0d4022efd7f873b34687d6e1f5df33f49b5a50430893d0418b4191556c39489" + ] + }, + "signature": "acf1bb9496e1e97a078fc23cfd8e225e7425df3728e11c8d3d76fd3fb815ef76660042ba71a9b99f1d6c17e30a3b06fd25816ed4e6c7626e1b93d536c2ada20d", + "id": "16639782607563046554", + "senderId": "3182358207667693329L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e0d4022efd7f873b34687d6e1f5df33f49b5a50430893d0418b4191556c39489", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e0d4022efd7f873b34687d6e1f5df33f49b5a50430893d0418b4191556c39489", + "+63f8f6c7513ddc0772ec5b051766d8998b37e66a030cdff3bb90c139fc598169" + ] + } + }, + "signature": "297231c08e69f91247262e80d4e38de1c98e9fb7b7fdbbeef52ddc17541b74ed7034fe9d4199c0706456023684687e1636806ea814b3779b1e433d18b16bb109", + "id": "13922163255297559541", + "senderId": "3182358207667693329L" + }, + { + "amount": "1000000", + "recipientId": "12272175868892632797L", + "senderPublicKey": "f137223b815c8b0c3b7ddfbf663217cc44d4e630befe0d3acdb0251e5c324b08", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "3d9e7da2019cb081bc3722358eb725888fe817a216ef2ecce81f2a22521d84a907a8d8289c43f1c6b9b92cd31b1c2a26cdae60baf981969b0f71b762ca2bca0e", + "id": "15013131183759339477", + "senderId": "12272175868892632797L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f137223b815c8b0c3b7ddfbf663217cc44d4e630befe0d3acdb0251e5c324b08", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c17ba2ddcac95e74f4e56f79fd1bd859c1cb3ebc10b889294b158497dca0b234" + } + }, + "signature": "78732e1d75cf9341aa6f959a48c20092627e433c229b1d221a89237bae524f20149b307f8315d91436180b95d2281b45670fd86cb3cd84acda74b7050d897c00", + "id": "17358506909310772925", + "senderId": "12272175868892632797L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f137223b815c8b0c3b7ddfbf663217cc44d4e630befe0d3acdb0251e5c324b08", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "kick" + } + }, + "signature": "4a48ffe42c0ec5ca846b8a6060c06d3b6e94d635f96428345938c803882dc3bb6e1fc61c850e2806fe42c4a57478a117ad2949ea7ebc1bb4440889609fc2620d", + "id": "349322499324857615", + "senderId": "12272175868892632797L" + }, + { + "amount": "0", + "recipientId": "12272175868892632797L", + "senderPublicKey": "f137223b815c8b0c3b7ddfbf663217cc44d4e630befe0d3acdb0251e5c324b08", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f137223b815c8b0c3b7ddfbf663217cc44d4e630befe0d3acdb0251e5c324b08" + ] + }, + "signature": "edfc329eb24c56a3cc40137ed84b7b2f5daf4770310ad5cc2a0cc1dc79271ba9701664a49b07f944420217a3194c5aa7e1bebc39169d5559af1b165f80d0ef0a", + "id": "14833654902625125697", + "senderId": "12272175868892632797L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f137223b815c8b0c3b7ddfbf663217cc44d4e630befe0d3acdb0251e5c324b08", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f137223b815c8b0c3b7ddfbf663217cc44d4e630befe0d3acdb0251e5c324b08", + "+c17ba2ddcac95e74f4e56f79fd1bd859c1cb3ebc10b889294b158497dca0b234" + ] + } + }, + "signature": "7f05a19c4d4799201d9286dcf87f7819ffd18e51b3842c3439f97058ce03e510d82a41a3260651a1f93d4b377459f08f25c0b8a31044fa79e3c43b453ce29606", + "id": "9541550279928263293", + "senderId": "12272175868892632797L" + }, + { + "amount": "1000000", + "recipientId": "13431630650517718259L", + "senderPublicKey": "303b1c4ffc1a6ff979d7257468f44344b21b070adcb1909636340bb9510ff1b3", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "2fcb024b418ce96b37bfeaa60ae4f85ac0ae6885cf00bf98947b9ddeafbba32dc488c935f549502f0a4d9265f8f71fd8cf1c2ac3fa9149e967378b4262c8e60d", + "id": "4372418547671705795", + "senderId": "13431630650517718259L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "303b1c4ffc1a6ff979d7257468f44344b21b070adcb1909636340bb9510ff1b3", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "edfb408eadbe1629160b8f55633aa426c9a3a27e53d32cf2aef632ad4fb196cf" + } + }, + "signature": "fed4989b60753d4eb5b007b32df4c916a1ee2200ec737cf15efddc662218fdeb1c594f3eb8e8727df54851606bff53953491741d426072b778ec78f6d6546305", + "id": "6130333279614210830", + "senderId": "13431630650517718259L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "303b1c4ffc1a6ff979d7257468f44344b21b070adcb1909636340bb9510ff1b3", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "daring" + } + }, + "signature": "a086c7a1aa45a165f7bbd12ff93603cdf0d0ac3de1c86d4730256aaaf157066344d96bcebb6c7d3edba484d681ad68d24d60f968c9c7302f898f051a90291607", + "id": "10205996955354534713", + "senderId": "13431630650517718259L" + }, + { + "amount": "0", + "recipientId": "13431630650517718259L", + "senderPublicKey": "303b1c4ffc1a6ff979d7257468f44344b21b070adcb1909636340bb9510ff1b3", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+303b1c4ffc1a6ff979d7257468f44344b21b070adcb1909636340bb9510ff1b3" + ] + }, + "signature": "384877d39081f26b155615f84d47fa584f7d7f339cc69a699029c1ecabde4afdb4ca0a44a3e8f5e8619ed185ef8da600862f11d22ff9482b700db36479d87507", + "id": "18305996866388754899", + "senderId": "13431630650517718259L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "303b1c4ffc1a6ff979d7257468f44344b21b070adcb1909636340bb9510ff1b3", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+303b1c4ffc1a6ff979d7257468f44344b21b070adcb1909636340bb9510ff1b3", + "+edfb408eadbe1629160b8f55633aa426c9a3a27e53d32cf2aef632ad4fb196cf" + ] + } + }, + "signature": "f1d6e34802de11e32e09455875a5bc0ec49d619d20886a406cd4dfaca1c4e988ee4ef4dbc65fbc0948728696869b4d982d82c84ff1d61992f1806c39232c710f", + "id": "15145354220864547931", + "senderId": "13431630650517718259L" + }, + { + "amount": "1000000", + "recipientId": "8748614421722402938L", + "senderPublicKey": "212e4ea4cbe06c8899d79f3fad601c8ee28054622a0c674b41d8829b62cc4ebe", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a3cdb641be89711a80b723148622ad1a1bd9689b8721f489ca1b3d53608d6eb2c5b10224f64fb33c22935c93c34af948581402fa59a82b6f9c56db8a00ea0509", + "id": "17100969359293175535", + "senderId": "8748614421722402938L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "212e4ea4cbe06c8899d79f3fad601c8ee28054622a0c674b41d8829b62cc4ebe", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c4cfc1b8cac5fc6bb1cf0693474587cf9822cbfba3e07c93458b42d91cd9784d" + } + }, + "signature": "b84c2e2d52eeea6dca9ee970c9ad212f39456ce523d2a92d5f960abdf4e19970903683b6dc106b1d046316678f2432164cfe5620189d0079d944f1348c64540a", + "id": "3476789936751287330", + "senderId": "8748614421722402938L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "212e4ea4cbe06c8899d79f3fad601c8ee28054622a0c674b41d8829b62cc4ebe", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "text" + } + }, + "signature": "a202c4c785a3a536ac10d0ecd0bd517550a2d1ac3fda490d087b6b0d0f6eecde9f5430ba18db129265e789880b2727cdc1ff56ee2100ca1e2de2a9c7791e8602", + "id": "261138010985424019", + "senderId": "8748614421722402938L" + }, + { + "amount": "0", + "recipientId": "8748614421722402938L", + "senderPublicKey": "212e4ea4cbe06c8899d79f3fad601c8ee28054622a0c674b41d8829b62cc4ebe", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+212e4ea4cbe06c8899d79f3fad601c8ee28054622a0c674b41d8829b62cc4ebe" + ] + }, + "signature": "99ef8ba2248ab2829d9490b16b2c52c6cf3411dd9e9e71209eb671622b0aaef7e3cdf7357a9cd3bb71f3634c09b9632f73a177f28883fa5153c23f242586040b", + "id": "14822903507825738396", + "senderId": "8748614421722402938L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "212e4ea4cbe06c8899d79f3fad601c8ee28054622a0c674b41d8829b62cc4ebe", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+212e4ea4cbe06c8899d79f3fad601c8ee28054622a0c674b41d8829b62cc4ebe", + "+c4cfc1b8cac5fc6bb1cf0693474587cf9822cbfba3e07c93458b42d91cd9784d" + ] + } + }, + "signature": "62038ae0ff378aecf7944af3cd43244670542d6513e52ace0dd7aea6bc262e762f25a2f94484cc51c1c45fce35fcc5d1d16b75e8041cf560521a28f17619a406", + "id": "10381151294963526438", + "senderId": "8748614421722402938L" + }, + { + "amount": "1000000", + "recipientId": "13486017742700136515L", + "senderPublicKey": "8ed9ca44d7cd75e6c68311c1b7367c4ec1fe58e4e662befa055f2b9990e8596b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "8601374a6e3678ba9b040d1cad884fdb7b46e36db447187a5c1b33b98c5d4589dc43f849a5fe11bec25e1f961993ae563873263546d605d188ec23704c137b02", + "id": "59280238253157530", + "senderId": "13486017742700136515L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8ed9ca44d7cd75e6c68311c1b7367c4ec1fe58e4e662befa055f2b9990e8596b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "5ad24bc5dfc9cc64073f31baac0fbd6c6fe41ef7f916fde5864bfaae57bcd385" + } + }, + "signature": "84992b5d5426b857566272f09e2842653d814d514468ed39fa06be401ed5efdfb8ad0b054e6f5cd7c8aa6241063d0cda6661ac0c033f34d465d641b654853a09", + "id": "18190761282447356763", + "senderId": "13486017742700136515L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8ed9ca44d7cd75e6c68311c1b7367c4ec1fe58e4e662befa055f2b9990e8596b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "cycle" + } + }, + "signature": "1dce81c219dcdbaafd1b552cdfae5ebbeb5996a225af58e3db7b0b1704ebd76ded3d64ee61b6aba4bc74d484f1d8a8b2adbb5983ebed3c1d58ba7e80f1b5850a", + "id": "13699562076579305519", + "senderId": "13486017742700136515L" + }, + { + "amount": "0", + "recipientId": "13486017742700136515L", + "senderPublicKey": "8ed9ca44d7cd75e6c68311c1b7367c4ec1fe58e4e662befa055f2b9990e8596b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+8ed9ca44d7cd75e6c68311c1b7367c4ec1fe58e4e662befa055f2b9990e8596b" + ] + }, + "signature": "94ee3e79d65c353ff6841629f33408c0a4ce0126ebc41a7b0d76f9bedaae6756e3f2bc576366bc2c148af0e111f82e676a3bd83c3590a8ebd874495e8e29d80b", + "id": "18148072977819737946", + "senderId": "13486017742700136515L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8ed9ca44d7cd75e6c68311c1b7367c4ec1fe58e4e662befa055f2b9990e8596b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+8ed9ca44d7cd75e6c68311c1b7367c4ec1fe58e4e662befa055f2b9990e8596b", + "+5ad24bc5dfc9cc64073f31baac0fbd6c6fe41ef7f916fde5864bfaae57bcd385" + ] + } + }, + "signature": "0475b6bd7067f9289ab4ff7013265070cc6c5c17c140ac7fba32490d02c60a4db3803f9e11542f77b25c5d8f3d3f5c6a0f98873f06fca731fce732d214e44100", + "id": "1337690457322867501", + "senderId": "13486017742700136515L" + }, + { + "amount": "1000000", + "recipientId": "9419095812884114909L", + "senderPublicKey": "bdcfdc67cfe2b6b7f874af23f4c8d34fb5a3f95168ccfd0fe112fffd9ee342b1", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "896882a0025cada726440f3b5e632fc6b48f26fdaad9532f2f1031e0043d5d0f109d70dce9d7c6e05893a49436e756b5a7afabfde7e3ef8e3965fcf46444a408", + "id": "12374311132255863695", + "senderId": "9419095812884114909L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bdcfdc67cfe2b6b7f874af23f4c8d34fb5a3f95168ccfd0fe112fffd9ee342b1", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "082c1d7baf07cb9afb08587b3f4759db4fdac270913cd54fd3a69f36ce67a0ae" + } + }, + "signature": "230ca4ab309c62988be6669064a1365cc9ddf5af4b604a7fe09b6a81186c23070bda084882e7a4691dcc00e4aa5ab5b8128f7fbfe346eb6b69797172316eca0e", + "id": "13708270978994703243", + "senderId": "9419095812884114909L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bdcfdc67cfe2b6b7f874af23f4c8d34fb5a3f95168ccfd0fe112fffd9ee342b1", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "aware" + } + }, + "signature": "09de2ab483958a77619bd63b6f8fc419c701573f02609bbd55cdf69b34a6c7e60ecc6df30363d51319af67215ca214fc5bd7f5f1df9ae7370060e4bfa495c202", + "id": "6735222349136177088", + "senderId": "9419095812884114909L" + }, + { + "amount": "0", + "recipientId": "9419095812884114909L", + "senderPublicKey": "bdcfdc67cfe2b6b7f874af23f4c8d34fb5a3f95168ccfd0fe112fffd9ee342b1", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+bdcfdc67cfe2b6b7f874af23f4c8d34fb5a3f95168ccfd0fe112fffd9ee342b1" + ] + }, + "signature": "ffcd008516ea7899525923da3d9014838aee0a10c87a111ea394f96b182914a7c1a86af1cc046affef8f9a2e3ccbfe52c0e6e6a6abd6ec5805c66e39c2b73805", + "id": "10524069128234159220", + "senderId": "9419095812884114909L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bdcfdc67cfe2b6b7f874af23f4c8d34fb5a3f95168ccfd0fe112fffd9ee342b1", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+bdcfdc67cfe2b6b7f874af23f4c8d34fb5a3f95168ccfd0fe112fffd9ee342b1", + "+082c1d7baf07cb9afb08587b3f4759db4fdac270913cd54fd3a69f36ce67a0ae" + ] + } + }, + "signature": "c1861043f1ef4cfe4ba8bc2bae699035d4074209941bd726dcc9316eaf42a8390c9a16a5c33b6d734305d742f1e2dd56d5b8b5521f4bddd546947596c39f8401", + "id": "9592378534678610163", + "senderId": "9419095812884114909L" + }, + { + "amount": "1000000", + "recipientId": "10665749510945097506L", + "senderPublicKey": "257777e31b4879eea6f70c07428d72148e1e53c3ae6793fa613e47b4cabe09dc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "c6b600dbe75c0e3f39edaa2c14aca7f2857cc7f9179dca0206615c11493dcef4dc251872d599327246377cc856f43b3ccde56979607ff4d3a143bdc99b6bf604", + "id": "7745216173403625967", + "senderId": "10665749510945097506L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "257777e31b4879eea6f70c07428d72148e1e53c3ae6793fa613e47b4cabe09dc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e9c4e644a03b00a647e07d38e57928b24b8a93d16c7efd674ced62e544d2cc6f" + } + }, + "signature": "86d549233e0a301cb8798bcc14f595203f98f49872f5b77eb1fa0d17435ed4ebc2115b37b8ac714143397c3bc3f4fe0071e292d3c9adada5463d6de8fe08a305", + "id": "13520574710778798753", + "senderId": "10665749510945097506L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "257777e31b4879eea6f70c07428d72148e1e53c3ae6793fa613e47b4cabe09dc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "foam" + } + }, + "signature": "f0e06d487569eda4d557a259cb5168bf60aba3ab8a3776cd77a77077ce544b7766ae9a29f51a559284404977c9651e5c6dbee494daf5e19916d9406d1c5ed205", + "id": "13136689203918102504", + "senderId": "10665749510945097506L" + }, + { + "amount": "0", + "recipientId": "10665749510945097506L", + "senderPublicKey": "257777e31b4879eea6f70c07428d72148e1e53c3ae6793fa613e47b4cabe09dc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+257777e31b4879eea6f70c07428d72148e1e53c3ae6793fa613e47b4cabe09dc" + ] + }, + "signature": "615e123bfd0d00bb6c9ef9d18f314244646bc3d371c2b9fb76027e280537dc05e622b559ee2f6dd2be716ad7d6aa3ea0b24f53905ed6c5f2cb4c61e10413c90c", + "id": "1011613985156514840", + "senderId": "10665749510945097506L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "257777e31b4879eea6f70c07428d72148e1e53c3ae6793fa613e47b4cabe09dc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+257777e31b4879eea6f70c07428d72148e1e53c3ae6793fa613e47b4cabe09dc", + "+e9c4e644a03b00a647e07d38e57928b24b8a93d16c7efd674ced62e544d2cc6f" + ] + } + }, + "signature": "b41de4f0a6224ca73811ed6497f1940f5ec90c11f3315836e1ad31950b28075cdc02e5ba1b146d7c1d873431b839e39d851755f90513bfd9c0186ec4896f7103", + "id": "6862914695971359380", + "senderId": "10665749510945097506L" + }, + { + "amount": "1000000", + "recipientId": "1543378874947842209L", + "senderPublicKey": "39cc310c31327bab431b5cb5aeceb749f079c9b95181128a565b0a60aa0e3a25", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "030eee41eefca3363b18d1758a7a7cef2a2befcfa6b8e9b1be9fe81c866189cab9418e345aa2a8fad17935040d344f059fa0a145376011d90845db0d76779c09", + "id": "4444142950237405267", + "senderId": "1543378874947842209L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "39cc310c31327bab431b5cb5aeceb749f079c9b95181128a565b0a60aa0e3a25", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "8bacfb9569ac83a99c824ecc57b84e9543b26477bead48ba48009904d03a16d9" + } + }, + "signature": "9484126a32e1e059749d5333f29e5436f1aaa5b8aa956e1a1471c98db4f0a1bf54d672dbc55b3b93c3519be25d2f5f323311b497dab1fbc0ab7d1c2dcaff890e", + "id": "4763905559071174775", + "senderId": "1543378874947842209L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "39cc310c31327bab431b5cb5aeceb749f079c9b95181128a565b0a60aa0e3a25", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "slight" + } + }, + "signature": "ed82db1f5912cbbbce6a6bdf8b10f961f33f0bb761a887aa89e795dcff590ac5c3e332d75eaffbda0589bab39daed5458e2c1e3138092a566d740c6817feb70c", + "id": "9091337758361918093", + "senderId": "1543378874947842209L" + }, + { + "amount": "0", + "recipientId": "1543378874947842209L", + "senderPublicKey": "39cc310c31327bab431b5cb5aeceb749f079c9b95181128a565b0a60aa0e3a25", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+39cc310c31327bab431b5cb5aeceb749f079c9b95181128a565b0a60aa0e3a25" + ] + }, + "signature": "4396ecc453dbf8b8c02b4952aca313ab6e1002b41667024264c233b2c4c9310db575707a46f079a9e20623bd6370867a17583514d6d28d4288cb578c31b58307", + "id": "3399645677031349232", + "senderId": "1543378874947842209L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "39cc310c31327bab431b5cb5aeceb749f079c9b95181128a565b0a60aa0e3a25", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+39cc310c31327bab431b5cb5aeceb749f079c9b95181128a565b0a60aa0e3a25", + "+8bacfb9569ac83a99c824ecc57b84e9543b26477bead48ba48009904d03a16d9" + ] + } + }, + "signature": "5e340f31737fd0282f2d9c30b78e0a7a86ab74601f25422cac083259a5949401163e8b0d8d62e2124ea5fd904d5b6eb63dc2894aee67e786d5866f68213fc706", + "id": "16966459497422238597", + "senderId": "1543378874947842209L" + }, + { + "amount": "1000000", + "recipientId": "1860461577684079264L", + "senderPublicKey": "d26f3805d2eb44819101142b651d3a6def9feb5141750f55ac8cf456508b084f", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "add03db02270b4ec7095155ea0b87e5ed1fe99cf4adc074162eb2ad4dd7a5208b70b67c0f3d295c66fc1ea1c86295ff6f0af335009a4482df35ee79f8861fa06", + "id": "10571869962327127536", + "senderId": "1860461577684079264L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d26f3805d2eb44819101142b651d3a6def9feb5141750f55ac8cf456508b084f", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "49753e0efa6e585ef3739d80fa13461000ffcf679641db689d36514eb777859e" + } + }, + "signature": "22a463078d22268dbc821e408de26d1a7f118f02c6ef5683ec0077163dd0d6c366120fa068ad269542ff929388dda6fd5057ac17366c8f7ac36ca076ac8c2e08", + "id": "3464182939497669516", + "senderId": "1860461577684079264L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d26f3805d2eb44819101142b651d3a6def9feb5141750f55ac8cf456508b084f", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "rough" + } + }, + "signature": "5a3ee97e7344b4dc815ba4455d15852625941d3cacd2dc536474e10c45899c763f2a4eecbfabd314b80f392b4363b2639d87c08f7bb85220671ee0ea97a8580b", + "id": "4243976236744127233", + "senderId": "1860461577684079264L" + }, + { + "amount": "0", + "recipientId": "1860461577684079264L", + "senderPublicKey": "d26f3805d2eb44819101142b651d3a6def9feb5141750f55ac8cf456508b084f", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+d26f3805d2eb44819101142b651d3a6def9feb5141750f55ac8cf456508b084f" + ] + }, + "signature": "df68487ff70cd852bf785b85e34361e819b71a3820696bc55c0faf64593950bd7ba6ec2d73fa9faf134cde6182d5d21aa1ccf9f969a61a648893976329755606", + "id": "1953663134495667453", + "senderId": "1860461577684079264L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d26f3805d2eb44819101142b651d3a6def9feb5141750f55ac8cf456508b084f", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+d26f3805d2eb44819101142b651d3a6def9feb5141750f55ac8cf456508b084f", + "+49753e0efa6e585ef3739d80fa13461000ffcf679641db689d36514eb777859e" + ] + } + }, + "signature": "242851d0d2249df5f6768a9dfee31b35601449de0cb000baef51df2b33ea0c6af43a5fe02c2e2d6745a297d7d5332c23186c3fa2864c5ac4007ae0a751e44e06", + "id": "14868165724920373637", + "senderId": "1860461577684079264L" + }, + { + "amount": "1000000", + "recipientId": "5984792984008367575L", + "senderPublicKey": "e16bcd555f17db4e4e8966f1a4ca55f9f028f647d736b742e516873ffe43bc14", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "27c0cddca91f9d20a8a6c05e4c8d92ea80663d444d33a6430c929a53a23e48b96588a156f99492d90ad2a1fc5f858edd5faac05de1a041656532ca2b2e60f103", + "id": "10095597216794877228", + "senderId": "5984792984008367575L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e16bcd555f17db4e4e8966f1a4ca55f9f028f647d736b742e516873ffe43bc14", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "50d6b7b3fc63da42b2ce940b1efccbf415ebf048201c6397a25a01b1c01b09d9" + } + }, + "signature": "a0a1de247f3ad520f3c2638db8670fa8b565d0d293bc6547eb7d4335a7a15b06bb0846a07e8f9f4c7d18aefb3d7874fed64d7749fa0f3d74a044794128484d00", + "id": "1361843540432553327", + "senderId": "5984792984008367575L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e16bcd555f17db4e4e8966f1a4ca55f9f028f647d736b742e516873ffe43bc14", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "shallow" + } + }, + "signature": "bf5468f5fb7d502988c12bd849540c9b65d5d8cfc452b5551dbfa87ef590f7e799233e47c1546d69f603f3553f7bad3e9a07a3b80b0858d716746015a43c3908", + "id": "1919192732446528370", + "senderId": "5984792984008367575L" + }, + { + "amount": "0", + "recipientId": "5984792984008367575L", + "senderPublicKey": "e16bcd555f17db4e4e8966f1a4ca55f9f028f647d736b742e516873ffe43bc14", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+e16bcd555f17db4e4e8966f1a4ca55f9f028f647d736b742e516873ffe43bc14" + ] + }, + "signature": "4fb7104cec3b950928be0db2165650839ce547cbe411a3056e4ab3c2c92617e6211e686663c74db7af44687f710aaf9a4688baad04508c185e667a1890723b01", + "id": "1341414676745358752", + "senderId": "5984792984008367575L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e16bcd555f17db4e4e8966f1a4ca55f9f028f647d736b742e516873ffe43bc14", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e16bcd555f17db4e4e8966f1a4ca55f9f028f647d736b742e516873ffe43bc14", + "+50d6b7b3fc63da42b2ce940b1efccbf415ebf048201c6397a25a01b1c01b09d9" + ] + } + }, + "signature": "0fb3aa0e87136662d782c67044def9fe3b02a5866a68e7869d26c5d55af0097c67d61b234eec3101db1a8a31862602af972e02f50babb0859b90a872cf1c8706", + "id": "2648354527994631154", + "senderId": "5984792984008367575L" + }, + { + "amount": "1000000", + "recipientId": "17688246838540961114L", + "senderPublicKey": "9562c1a2baa92670c9afed500af66cac91409e0fad648f00bdb2b49fadc6dbdd", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "582437a8284c40c3529f7c250def7c76d37184fa47b687ae9cf4dcb4e7fdfa18ee2d2328863aa12f5ca04b7ac9cddd6eee2a9872b04e37ef3e97d245dfe6250e", + "id": "11431373614742823067", + "senderId": "17688246838540961114L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9562c1a2baa92670c9afed500af66cac91409e0fad648f00bdb2b49fadc6dbdd", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "0b14a99630d54fbbfc6cadb45b4a7e73a009d9405ee810606e4d8d39854b291c" + } + }, + "signature": "025bca8d5142be2ad9d6b6e358db0a948d545528d519c087432ef9a2ebe716a0f4102b66a077e4c9d90944bfb0ef3a7d753439db631d45c24007d2ab43db760b", + "id": "7798538289662827888", + "senderId": "17688246838540961114L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9562c1a2baa92670c9afed500af66cac91409e0fad648f00bdb2b49fadc6dbdd", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "embrace" + } + }, + "signature": "0249e1c4a012b4c7540feba8753c66c845a97454dadca6226d03e2b9888b763d6975a2ef38ae3b0a8d4f58fa3c9f2495592a0683899fa370ae87619f9ba42902", + "id": "7588941262162618148", + "senderId": "17688246838540961114L" + }, + { + "amount": "0", + "recipientId": "17688246838540961114L", + "senderPublicKey": "9562c1a2baa92670c9afed500af66cac91409e0fad648f00bdb2b49fadc6dbdd", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+9562c1a2baa92670c9afed500af66cac91409e0fad648f00bdb2b49fadc6dbdd" + ] + }, + "signature": "dda79a7da3b073cf9c7c24f8320011443077a2fce974579b3a97a7c8f980fe7cbd09e202c71182b024c833f7eef7e85f90a2ae04f600135ea82ac28eb345a809", + "id": "3282027412386033174", + "senderId": "17688246838540961114L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9562c1a2baa92670c9afed500af66cac91409e0fad648f00bdb2b49fadc6dbdd", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+9562c1a2baa92670c9afed500af66cac91409e0fad648f00bdb2b49fadc6dbdd", + "+0b14a99630d54fbbfc6cadb45b4a7e73a009d9405ee810606e4d8d39854b291c" + ] + } + }, + "signature": "f653261c6a7ed7b52c923d94bc286c361394b3db6cb210137e46e6ca59e618fbc86669eaf20c93d529d8d341c892fe405c11b0cf5a58fd74445f838d7a936107", + "id": "7459005809223167106", + "senderId": "17688246838540961114L" + }, + { + "amount": "1000000", + "recipientId": "12426322581046583489L", + "senderPublicKey": "1900fab7d59c32119bd94b0dd40de1c8c4095ddd29b9f9296a1a14930c6dfb9b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "b73b996cb613bca6e9c3e428d7e56b50cf434e96dfdbbd5e121beb9390e36c60b65876ff2635595e7043aa88d51f624247299fa3b58c7b324a9048fff95e2306", + "id": "8667682370470669475", + "senderId": "12426322581046583489L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1900fab7d59c32119bd94b0dd40de1c8c4095ddd29b9f9296a1a14930c6dfb9b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4f7133b15c02f362b59fc89752ed7c18dc9b1a4de3fd675d0b00799e1cc302b1" + } + }, + "signature": "fdb671816e69864c927ca24874806997370f73bce22f8d65f2e66c62df508906396a865c42b06ef9f7399e868f37562c0c4bb1bcac5c5151e159fcd486ff3e08", + "id": "11246143263999352892", + "senderId": "12426322581046583489L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1900fab7d59c32119bd94b0dd40de1c8c4095ddd29b9f9296a1a14930c6dfb9b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "sheriff" + } + }, + "signature": "4e9cec660235e58f8c3c4254ce2e581ab1270716375dd3137d7f7ab4e7a6b0a650c14ef400ace9050160760a05ac295e2c65dfc18c5b3da29489656a62a3d404", + "id": "7752603594827064244", + "senderId": "12426322581046583489L" + }, + { + "amount": "0", + "recipientId": "12426322581046583489L", + "senderPublicKey": "1900fab7d59c32119bd94b0dd40de1c8c4095ddd29b9f9296a1a14930c6dfb9b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+1900fab7d59c32119bd94b0dd40de1c8c4095ddd29b9f9296a1a14930c6dfb9b" + ] + }, + "signature": "d64d760ffd4abcbc913a77943de68bb56d9adf49adede3b00ae24c036da38b4ef071c0c0c307dbffdf3b0ce86a68b544ce80d224494dabdb835900e888837600", + "id": "7275122155448829999", + "senderId": "12426322581046583489L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1900fab7d59c32119bd94b0dd40de1c8c4095ddd29b9f9296a1a14930c6dfb9b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+1900fab7d59c32119bd94b0dd40de1c8c4095ddd29b9f9296a1a14930c6dfb9b", + "+4f7133b15c02f362b59fc89752ed7c18dc9b1a4de3fd675d0b00799e1cc302b1" + ] + } + }, + "signature": "4c506fd37bf1410c2d04e83c4937855e7e90055dcdcbccb140f5ceb403f64678b77fcfd7131adf036ded6be1bfb71b9e99667cdbbd0dd965cfbac4ad7477460b", + "id": "509466775562370145", + "senderId": "12426322581046583489L" + }, + { + "amount": "1000000", + "recipientId": "18361026162829954637L", + "senderPublicKey": "8fd722d05867f3b7bb866ea9a475d1fc3b0f274fc4fc7338199ba1dd135dbc40", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "bc6245e437f2070f9cd76e7c785c6f2e9154b37e4cfb5f015968b7fd457791dab2d3977d13e0f9a30a2cba2605fb1e7af24a18b102f3df1cc25486d743f08b0e", + "id": "12814014144504671675", + "senderId": "18361026162829954637L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8fd722d05867f3b7bb866ea9a475d1fc3b0f274fc4fc7338199ba1dd135dbc40", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "40ed3b51dcffc28c1c21079b8e20f0fe0aea3833086778728c820e67a60d836b" + } + }, + "signature": "b92a622d6465a1e7e8afa9697a3875a89b1882e4c17f19834066bbf51a4c2a14b9c700fba5fe443332d7529105d76d297a306ac1de334bbfdc8d9b4b7f372a02", + "id": "3427587798009150634", + "senderId": "18361026162829954637L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8fd722d05867f3b7bb866ea9a475d1fc3b0f274fc4fc7338199ba1dd135dbc40", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "option" + } + }, + "signature": "b6db9fe14587dfa8133b59fe666dd831a70c180f2d893372ce531951d537ea06caba7389e79b55622cf2c9bfb6d611332d5b4e71a7ab5c4968de182e7321b300", + "id": "6240982561307866385", + "senderId": "18361026162829954637L" + }, + { + "amount": "0", + "recipientId": "18361026162829954637L", + "senderPublicKey": "8fd722d05867f3b7bb866ea9a475d1fc3b0f274fc4fc7338199ba1dd135dbc40", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+8fd722d05867f3b7bb866ea9a475d1fc3b0f274fc4fc7338199ba1dd135dbc40" + ] + }, + "signature": "6f08caf71f40d3334a39e8323ee96a41c4d9da7f42d3dd6c6cc5ba94dcfaff76fd250dbaaf9cf472a57ac7b4388157210ffc8aeecbf6c5a9afc300bb2c9ac409", + "id": "7060156054823559212", + "senderId": "18361026162829954637L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8fd722d05867f3b7bb866ea9a475d1fc3b0f274fc4fc7338199ba1dd135dbc40", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+8fd722d05867f3b7bb866ea9a475d1fc3b0f274fc4fc7338199ba1dd135dbc40", + "+40ed3b51dcffc28c1c21079b8e20f0fe0aea3833086778728c820e67a60d836b" + ] + } + }, + "signature": "7ca6cbd4d3e5d279876aff212cbbb7ad663e1601ec1bf4dea2255b099f8c8499f2fc299ca5e4f81be68cd378d910564d53c4e1599f84f3201e3dab1a1b0eea0f", + "id": "9569741117785720968", + "senderId": "18361026162829954637L" + }, + { + "amount": "1000000", + "recipientId": "4447810648093978479L", + "senderPublicKey": "15dfdc372f7e1522bf0fff764644521de327f6076fd5f5d8ca9cf20efc6a4dff", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ec12751290a55280656738472811e414bb39897042bb31aac3dd14c16cccbe29bb3f52f11acea140783b9116a339a25e5f4a6e5b7089bd4eaa44f946e40ad70f", + "id": "11863111880572166370", + "senderId": "4447810648093978479L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "15dfdc372f7e1522bf0fff764644521de327f6076fd5f5d8ca9cf20efc6a4dff", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d69a1a44bcd42dbaab456550d5ddbf71f09e9ab8dae296dd0e6ae43cc93db3ce" + } + }, + "signature": "1544c94ee76663f2b20e33ee7b3f5c97c113a937fac6629d0057f6781be5adfdb6a3343422840a151469c4cc8c94a4920a2fabd35719cc497c3d9093e1d3850c", + "id": "15869506918609965231", + "senderId": "4447810648093978479L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "15dfdc372f7e1522bf0fff764644521de327f6076fd5f5d8ca9cf20efc6a4dff", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "seat" + } + }, + "signature": "aa67a08afb0659d4ced8c69914af394003846209f3787b5b78c4ed4159d39259b3be63a3a3ecb9a19b86cb4a55cc1383badf92ee6e320347820fce75ff50340f", + "id": "221782498626288995", + "senderId": "4447810648093978479L" + }, + { + "amount": "0", + "recipientId": "4447810648093978479L", + "senderPublicKey": "15dfdc372f7e1522bf0fff764644521de327f6076fd5f5d8ca9cf20efc6a4dff", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+15dfdc372f7e1522bf0fff764644521de327f6076fd5f5d8ca9cf20efc6a4dff" + ] + }, + "signature": "9fa91824e9f5a7de9e9b961eb7c62b6fabf9d669d60b2c811c1e42a1626d6937478924e47ec495efa074c2a7a1e73ba2190c0d80832099cb54d2a9f042e61103", + "id": "927628178134454011", + "senderId": "4447810648093978479L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "15dfdc372f7e1522bf0fff764644521de327f6076fd5f5d8ca9cf20efc6a4dff", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+15dfdc372f7e1522bf0fff764644521de327f6076fd5f5d8ca9cf20efc6a4dff", + "+d69a1a44bcd42dbaab456550d5ddbf71f09e9ab8dae296dd0e6ae43cc93db3ce" + ] + } + }, + "signature": "49ddded492d1e967276067c6ecb5f0a36019e370a528f8d6c8073abf9b6293198a10ec38add59e5ef5092f7d0b872fa6140758984a5439d40f2879908b5d7304", + "id": "2082740263018442220", + "senderId": "4447810648093978479L" + }, + { + "amount": "1000000", + "recipientId": "13937493016465070517L", + "senderPublicKey": "9b8221b4eb2977dee9a6b4e8fce06115370138c8548b8eeec635fbb6abf85563", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "fec24b61415342e14ebc3378112e4197ee1b1f25fa4ae16809848ab50a03ba35fc267dede6822cf608a67deec91b45d149292ffcb379aff2922189269ab4000b", + "id": "14639922552160042302", + "senderId": "13937493016465070517L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9b8221b4eb2977dee9a6b4e8fce06115370138c8548b8eeec635fbb6abf85563", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "09da27dac418f12dbc480dec312ef9dfd33a1728bd2e65c888450c4b36b626db" + } + }, + "signature": "d145f2e96ae9bb363ffe2d6417a97221b86b80174e90a1d392e5d49b472e584748b1b17a8506542cb5009b376d138b2fedadf542e7845d71e976337f9a7f990c", + "id": "13738469278761355886", + "senderId": "13937493016465070517L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9b8221b4eb2977dee9a6b4e8fce06115370138c8548b8eeec635fbb6abf85563", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "milk" + } + }, + "signature": "cb77e0c1651db65ac8780968c615faf36c927b3e1b50895a373a1963b95e56eb508e4f51d9b41daa5de5983a8013849ed3f73d776dd4df4286a73624a83b8908", + "id": "9028449642915075897", + "senderId": "13937493016465070517L" + }, + { + "amount": "0", + "recipientId": "13937493016465070517L", + "senderPublicKey": "9b8221b4eb2977dee9a6b4e8fce06115370138c8548b8eeec635fbb6abf85563", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+9b8221b4eb2977dee9a6b4e8fce06115370138c8548b8eeec635fbb6abf85563" + ] + }, + "signature": "2797a5fd5ed7d173bdb7a58a7b8dd13a2c1ca7c5a27ae0ffd4744daa4d79b998c5d5fe11b3a01f6d05352f64a7d80e944992355c877ce8d99c3b2afd72531b00", + "id": "7652869857449503286", + "senderId": "13937493016465070517L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "9b8221b4eb2977dee9a6b4e8fce06115370138c8548b8eeec635fbb6abf85563", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+9b8221b4eb2977dee9a6b4e8fce06115370138c8548b8eeec635fbb6abf85563", + "+09da27dac418f12dbc480dec312ef9dfd33a1728bd2e65c888450c4b36b626db" + ] + } + }, + "signature": "a5690825152af5f39b9c8285679ae29f772ff1ed11deeaed69f985bedba55bfa3d3c63b4653d8a2500676005aaade0d9e8c03a0885c11e84f558c9ac3934fc03", + "id": "10030172704825977332", + "senderId": "13937493016465070517L" + }, + { + "amount": "1000000", + "recipientId": "16739373691139928407L", + "senderPublicKey": "a6ca54255c4caa9bb12e3e4fd9d1fc4224be079cc3ee8f45a0183c026eb780d9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "26ceb31b9c9fb2e3f4668345ddb230118f5eaf79dc32fa110701a6c620234ff26d6851eac1e6c53c7c374b418ebff8c2ce72d3f6c2915511908db91fb7b62409", + "id": "15948027223725435024", + "senderId": "16739373691139928407L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a6ca54255c4caa9bb12e3e4fd9d1fc4224be079cc3ee8f45a0183c026eb780d9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "dac26d7cf6186fb01707457041c2eea23f7142b6e6e1fe7416f2ce7d355ebdc5" + } + }, + "signature": "dace1d27fba0627ffdd52efb82072a8f374b2d0787c4be35397477e24c18dcb64b122f5a228b221b751077215ffb0d803f49143fbb29efb5b244199195ffa209", + "id": "9845721169861445327", + "senderId": "16739373691139928407L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a6ca54255c4caa9bb12e3e4fd9d1fc4224be079cc3ee8f45a0183c026eb780d9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "local" + } + }, + "signature": "e14f07c84de13a1292883efc14411943be3370820edf9c8d36db9b172802e6fe6b81f272d09e6b05ae97d50a6226b8806927d76433b4b6c655fb517609684e00", + "id": "16142171295069444902", + "senderId": "16739373691139928407L" + }, + { + "amount": "0", + "recipientId": "16739373691139928407L", + "senderPublicKey": "a6ca54255c4caa9bb12e3e4fd9d1fc4224be079cc3ee8f45a0183c026eb780d9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a6ca54255c4caa9bb12e3e4fd9d1fc4224be079cc3ee8f45a0183c026eb780d9" + ] + }, + "signature": "7f31afb9e18813f164a93fa6eab45ed87b83af1b7c208dcb15653be2b216d8705ecf5ea2f0f654a6ce774c85afbf9eaa69c54978426d35b94fdc1f92e0e46901", + "id": "5228539255454571755", + "senderId": "16739373691139928407L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a6ca54255c4caa9bb12e3e4fd9d1fc4224be079cc3ee8f45a0183c026eb780d9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a6ca54255c4caa9bb12e3e4fd9d1fc4224be079cc3ee8f45a0183c026eb780d9", + "+dac26d7cf6186fb01707457041c2eea23f7142b6e6e1fe7416f2ce7d355ebdc5" + ] + } + }, + "signature": "f8dd960d81f8c7578a37e75a3aad7307ae5344713820994bc24a558e413b90ebb0f7f4758f7954066b7bbcb2b31d6e8983ae90b65d4a5a09041bbdadaddec30f", + "id": "7584121045410211591", + "senderId": "16739373691139928407L" + }, + { + "amount": "1000000", + "recipientId": "4806469903362416770L", + "senderPublicKey": "8c0f8fc5be269c1e3ca9ba297726724b01877a406847cf36e7d84dd8e44b15c5", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "0bf97868eaee815911debfd388ee3e45c060b306112118505fbf6b4e87a81bd68bb5444ca59acb1a313070d1aa505be8160c3d3465a291445a85355a4032cc01", + "id": "9628567179986140101", + "senderId": "4806469903362416770L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8c0f8fc5be269c1e3ca9ba297726724b01877a406847cf36e7d84dd8e44b15c5", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "574f045001442414fad48dadbe39bf021e5581984e440dfa59c360e61fe17768" + } + }, + "signature": "a31ffec01c5610b605ff7ecd48932831facd90e38f4f5bdbdce82cdc611ad3373592a7f3ef79709de4791ef6b482fcf8d64649e4214eca50c27e7c959a4cdb0c", + "id": "16502390263073992489", + "senderId": "4806469903362416770L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8c0f8fc5be269c1e3ca9ba297726724b01877a406847cf36e7d84dd8e44b15c5", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "seek" + } + }, + "signature": "e39c56121cea441f3ad68a0fec9db1d6e6d4544f2c2f878de0ee3a227e26d5c1460b2036bee843209c5b4b819ae32c5efec620793e512ab789bef596bc3e990f", + "id": "14623654650888254925", + "senderId": "4806469903362416770L" + }, + { + "amount": "0", + "recipientId": "4806469903362416770L", + "senderPublicKey": "8c0f8fc5be269c1e3ca9ba297726724b01877a406847cf36e7d84dd8e44b15c5", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+8c0f8fc5be269c1e3ca9ba297726724b01877a406847cf36e7d84dd8e44b15c5" + ] + }, + "signature": "43080f339ed9a9f45421e1e2816cf5d3219627918bcb9483caaac7dfe362489dc8ac1f3fd8a8d03fbbbcff78ba29d60c7399367437a2e67dfaf0d3433458c806", + "id": "671332668576188526", + "senderId": "4806469903362416770L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8c0f8fc5be269c1e3ca9ba297726724b01877a406847cf36e7d84dd8e44b15c5", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+8c0f8fc5be269c1e3ca9ba297726724b01877a406847cf36e7d84dd8e44b15c5", + "+574f045001442414fad48dadbe39bf021e5581984e440dfa59c360e61fe17768" + ] + } + }, + "signature": "bc7552bb27122201de8cb8a7ba9f400e77589b68d1c8f5f6b3f4f02e82a4ce3fc62c14e85cbcd5ae2aee7669d6de571a23343d31a4c3831f3fccc6fa57caf30a", + "id": "9865073164226815187", + "senderId": "4806469903362416770L" + }, + { + "amount": "1000000", + "recipientId": "10346253556425626732L", + "senderPublicKey": "29672a3673b1da494b9bfea408ad974a076a162f228f49611a7b57bdd1328811", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "bf6429f6a38b42ae78daf3866a4c44770819f54e9eecb394e69a7d0db0ab391d7cdeacaf042bd7321c708ca71a24765217ad9551e62f6df3967f6e68a1d30a03", + "id": "12570870140068907681", + "senderId": "10346253556425626732L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "29672a3673b1da494b9bfea408ad974a076a162f228f49611a7b57bdd1328811", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "a5a13be009811676ae773f645bcdcab66e6d4e1214e9c96b60b2c9fe94ebcbba" + } + }, + "signature": "146447af3f3a8921250cfa9c9c2e88ad574d83ac55e92be6588058ce07a5f72bcb227d41f9b21a0a7a48edb53ecb5cff61a4b84809386077bdba72e93d9df303", + "id": "12215296602828142412", + "senderId": "10346253556425626732L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "29672a3673b1da494b9bfea408ad974a076a162f228f49611a7b57bdd1328811", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "rough" + } + }, + "signature": "b6d1b18da208d2f51ae83a2b7bd9d61c128b51c0fcdd5d69a1bdd4cce6b76a28b47e18a9cf83547667fb61d2c307c9c5df946a030a1841103b4fd9301d59f109", + "id": "6455595016195059972", + "senderId": "10346253556425626732L" + }, + { + "amount": "0", + "recipientId": "10346253556425626732L", + "senderPublicKey": "29672a3673b1da494b9bfea408ad974a076a162f228f49611a7b57bdd1328811", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+29672a3673b1da494b9bfea408ad974a076a162f228f49611a7b57bdd1328811" + ] + }, + "signature": "519221a5122474b4d150ffaba445232d97a6cd289ff4cf453aa812d869f790cb7db6a8f63f12c44ada68536ce3586be43f0497ae2d506fa48d21f8269b6e5a07", + "id": "12873653090390937194", + "senderId": "10346253556425626732L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "29672a3673b1da494b9bfea408ad974a076a162f228f49611a7b57bdd1328811", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+29672a3673b1da494b9bfea408ad974a076a162f228f49611a7b57bdd1328811", + "+a5a13be009811676ae773f645bcdcab66e6d4e1214e9c96b60b2c9fe94ebcbba" + ] + } + }, + "signature": "b79c46424fef92d5f055a2ead12ad0a355a44603137888751d25dc4432ae9b50699f32f26b9669f8094938fb39ebbaddb57d8d6769b459de8f8bc93848b5a502", + "id": "6757570971657638592", + "senderId": "10346253556425626732L" + }, + { + "amount": "1000000", + "recipientId": "6643177689096071963L", + "senderPublicKey": "4bab5bb5bb1d5faf77a17e08825062324d3a0432fb565a18167f0eeced801a8f", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "89db8118762c2b2645310287e712a4b0916a154fb9c2487e7f87022be3e168f4797dae25cf077b9326ef564765bbd624199de669535b2fd55cdb8c664ad1b502", + "id": "6194309373178749979", + "senderId": "6643177689096071963L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4bab5bb5bb1d5faf77a17e08825062324d3a0432fb565a18167f0eeced801a8f", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "6d9301bbb8696459ed0247a45384993af814cf65290fdf3e20cf5b52a5f5a191" + } + }, + "signature": "937a892eeec7a03a4575351134cb9a04ab481cf03354226bd57dcea461f04acc8958216c20cb049be54fe53c58fcff4a5d32aa623cefeeaf61e181838e2feb00", + "id": "6745158573860482390", + "senderId": "6643177689096071963L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4bab5bb5bb1d5faf77a17e08825062324d3a0432fb565a18167f0eeced801a8f", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "cliff" + } + }, + "signature": "8da746cbc7a2a544c0990c1e0bfc3db80bcf59154d5fee17e083724bc5cf6742fd498171ff4cff9711fc4a4705accff33a5089054dcc0d6e2e9adaaf3db62409", + "id": "4548681994144477259", + "senderId": "6643177689096071963L" + }, + { + "amount": "0", + "recipientId": "6643177689096071963L", + "senderPublicKey": "4bab5bb5bb1d5faf77a17e08825062324d3a0432fb565a18167f0eeced801a8f", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+4bab5bb5bb1d5faf77a17e08825062324d3a0432fb565a18167f0eeced801a8f" + ] + }, + "signature": "5cbc43920f10235b73d5b3566137e1235f6c5fdcad5354a67aa962378a5fad24103b7bcf31b070ae4a814375edb98e2f806a6f32049b01139cecb4cff3e8d603", + "id": "1564437924562557908", + "senderId": "6643177689096071963L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "4bab5bb5bb1d5faf77a17e08825062324d3a0432fb565a18167f0eeced801a8f", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+4bab5bb5bb1d5faf77a17e08825062324d3a0432fb565a18167f0eeced801a8f", + "+6d9301bbb8696459ed0247a45384993af814cf65290fdf3e20cf5b52a5f5a191" + ] + } + }, + "signature": "77b5ace24253b862b3ddfd678f9615a47af1b917c8bcc3411855b89b12a73daa836ddbb56314bc646f8fb4ce3c39388c5a07654001437357fb3b35975fec7305", + "id": "9420343936733292790", + "senderId": "6643177689096071963L" + }, + { + "amount": "1000000", + "recipientId": "320853526084300214L", + "senderPublicKey": "c84ce13ca70e11ee3db85962b470a6bef9c036ceef718bfca28b2d853f0a42a9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "8929fd97724917410faafd4873bfa6025a091d3eb0a1c95900408f1377429f85645dae6d44375e4c9d23974c650918d1b33fc6b476954f91373d4506ef012d0f", + "id": "18091588052586847777", + "senderId": "320853526084300214L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c84ce13ca70e11ee3db85962b470a6bef9c036ceef718bfca28b2d853f0a42a9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9f32de89c3188bd2d03c0a8ae4d0a7eb715e0e869bfdc7229518a0e16b1b0216" + } + }, + "signature": "c6aafd1634c0c4e900ebf7beaa18e617e658b3523d85f69b84e23acaeb139f8769e8e9c135c6e4c16a515e8dbf10afadc38e4ac03df471a8d87bbcd318691b09", + "id": "6448405665350740561", + "senderId": "320853526084300214L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c84ce13ca70e11ee3db85962b470a6bef9c036ceef718bfca28b2d853f0a42a9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "blanket" + } + }, + "signature": "33e384375bbc0e274963b3b3d311d6613f86948f7aa961524934fc9a8286a477a63127f2514efc47fbc6f4453b24a29e1fe68ed6c5aa7a4d245b38ccbd4fe704", + "id": "15698365975174555236", + "senderId": "320853526084300214L" + }, + { + "amount": "0", + "recipientId": "320853526084300214L", + "senderPublicKey": "c84ce13ca70e11ee3db85962b470a6bef9c036ceef718bfca28b2d853f0a42a9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c84ce13ca70e11ee3db85962b470a6bef9c036ceef718bfca28b2d853f0a42a9" + ] + }, + "signature": "dca0657b52774c330254bd441fa1b5e2475306549bd24b56cb3550af203a8218d60293b79fd018802789ef7d27c1e0dc2ebc07d42f762b0afab1f384ba0bd106", + "id": "2981745655512203603", + "senderId": "320853526084300214L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c84ce13ca70e11ee3db85962b470a6bef9c036ceef718bfca28b2d853f0a42a9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c84ce13ca70e11ee3db85962b470a6bef9c036ceef718bfca28b2d853f0a42a9", + "+9f32de89c3188bd2d03c0a8ae4d0a7eb715e0e869bfdc7229518a0e16b1b0216" + ] + } + }, + "signature": "f825e3f05b64fe48e5794965344964382031fd0747cb11c81db19b724b02acddeb28baaa846057d13fa0b7447a5af61959c3952041d0f4d604b37557a9ce000a", + "id": "10579794301424958970", + "senderId": "320853526084300214L" + }, + { + "amount": "1000000", + "recipientId": "3904504284084393779L", + "senderPublicKey": "a35f02afa6cd32b08e1ed33b8114349eef18d9e3cb8296bc61693c31c00c46c4", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "9aadb2ed4f3e7fc8e43efaf3dfa0b6ad71c14e901062badb36598d875de6506836ec140944cbeb2a85e0dbd466d01f758ee7c12e829735790b5f4e29c4a9bf05", + "id": "4015129784368599404", + "senderId": "3904504284084393779L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a35f02afa6cd32b08e1ed33b8114349eef18d9e3cb8296bc61693c31c00c46c4", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9b6a6402014546b0a163b372477cdb28e511a648dc99169405c8e1c98f7bc0d2" + } + }, + "signature": "16a859a60d0150a79b040141714228f4aa93ad6425ee63deb423f8807d91bc6d6ed4949651be30517b86aa8d65379cd1b59fb3cd5a2f7c979374f7358aee8b06", + "id": "10792221732803119147", + "senderId": "3904504284084393779L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a35f02afa6cd32b08e1ed33b8114349eef18d9e3cb8296bc61693c31c00c46c4", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "great" + } + }, + "signature": "ec1f9cf9c77e5afdb4a232ed3e6692f8f14befb2b17bc96993295a1985ab4eacf286f873a535c7e26959c2b94feeb5fc99f6f057949720242d28c1d11bb04a06", + "id": "16593147356598876231", + "senderId": "3904504284084393779L" + }, + { + "amount": "0", + "recipientId": "3904504284084393779L", + "senderPublicKey": "a35f02afa6cd32b08e1ed33b8114349eef18d9e3cb8296bc61693c31c00c46c4", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a35f02afa6cd32b08e1ed33b8114349eef18d9e3cb8296bc61693c31c00c46c4" + ] + }, + "signature": "5095c678b11226e0ea4c6843eccd6a86fadccc9db5604b81f876797e198c81e5d46972d9e77cf261ffdf7ab8d5c804992a8272d955337cf70d71d9f513cc820c", + "id": "9552746369376281796", + "senderId": "3904504284084393779L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a35f02afa6cd32b08e1ed33b8114349eef18d9e3cb8296bc61693c31c00c46c4", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a35f02afa6cd32b08e1ed33b8114349eef18d9e3cb8296bc61693c31c00c46c4", + "+9b6a6402014546b0a163b372477cdb28e511a648dc99169405c8e1c98f7bc0d2" + ] + } + }, + "signature": "392414cc24c44456101b8702e70f4305ae2ddce69125c7d040a5f9ddefc36b42900478a8a1a812cef40ddd4fa3913e2bd6a2563b81a2ff1392b8ad99a3ba590a", + "id": "7065723645253386302", + "senderId": "3904504284084393779L" + }, + { + "amount": "1000000", + "recipientId": "5226528019016360010L", + "senderPublicKey": "ae8dde42864db63b32c65720082cf0c8cf3d80be8012e2b7ad100139a51c926c", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "7bd5d2955a6b942f5bd4bf2da582af26277f86671a4ee9859fb0626c51b3566197c8555cadc4838a4d5b084bfc9dea9a7caeccf6a0a38cec3f2c6e58a5799600", + "id": "14246321601450387583", + "senderId": "5226528019016360010L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ae8dde42864db63b32c65720082cf0c8cf3d80be8012e2b7ad100139a51c926c", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "32ac1b5089400e69fd6860ad8ad38fb2d4b34e1be08bd8756f57d6a62daa87d2" + } + }, + "signature": "4e251bffa07f5bf31b45ce2835519b47d9776c60f5d2fb9911ca4b2f0831ca9ebceb6448144981523bf6844b6c91fae259fe3997f2bb5da6596d7d7b4c48e603", + "id": "2215593145950649037", + "senderId": "5226528019016360010L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ae8dde42864db63b32c65720082cf0c8cf3d80be8012e2b7ad100139a51c926c", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "evoke" + } + }, + "signature": "f8461743183c057bf0bfa8b11c9f58d9fa19724e80e6414c2cc0bcfeee09d4536c864b2b2a40355f73096c20d2fa4d73f1762e0ce709f0176396712ed2e9d401", + "id": "10462951510556018499", + "senderId": "5226528019016360010L" + }, + { + "amount": "0", + "recipientId": "5226528019016360010L", + "senderPublicKey": "ae8dde42864db63b32c65720082cf0c8cf3d80be8012e2b7ad100139a51c926c", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+ae8dde42864db63b32c65720082cf0c8cf3d80be8012e2b7ad100139a51c926c" + ] + }, + "signature": "ab2ccff1b65daef5e90ab08c207f98b8bcae1ec8a5b9a3ea2ad62275c383a704b0fa58d68c3af763c62586d777f0509664b1eb42547e5692677964f436ceba0a", + "id": "16107361523589357206", + "senderId": "5226528019016360010L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ae8dde42864db63b32c65720082cf0c8cf3d80be8012e2b7ad100139a51c926c", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+ae8dde42864db63b32c65720082cf0c8cf3d80be8012e2b7ad100139a51c926c", + "+32ac1b5089400e69fd6860ad8ad38fb2d4b34e1be08bd8756f57d6a62daa87d2" + ] + } + }, + "signature": "af9dd364b50f8b3c56976a6ca67124fe4f955d8f2eda8a94cd62002db62eee56ed66427d583d5a9bd7a319918edbdefa20499908f5b0f3ba47e8e0a97bb8d10f", + "id": "15640114590731572787", + "senderId": "5226528019016360010L" + }, + { + "amount": "1000000", + "recipientId": "6128170150568124446L", + "senderPublicKey": "15d2e4927945fc65e7016e5a899694e54f7ad6fb9cd8c0d029866e828738450b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "30ded56ef9836d11054d60bb15b8beaf727a9e66814e3c12fe231982e396f712f48670ab6032c37038ce27024c6acdc26778dfffe093b4ade5a083948a2c750f", + "id": "17515941873893498545", + "senderId": "6128170150568124446L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "15d2e4927945fc65e7016e5a899694e54f7ad6fb9cd8c0d029866e828738450b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d9cb00493c908d27903fe5db02f947158a619b369bd72aa1b455708ed290340f" + } + }, + "signature": "88fe88e07be5f8e469da4f2aff5fe6975a7714f25ffb2e678b21f52c1cd701d8187f2e2d906adca0ac4d0fd0afe5bf2e6b636466e471179cfba5bd8f6b5b0a09", + "id": "7464792604017602288", + "senderId": "6128170150568124446L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "15d2e4927945fc65e7016e5a899694e54f7ad6fb9cd8c0d029866e828738450b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "ordinary" + } + }, + "signature": "5a8988b365ab53f53555c1f28b0817a19631e51dd331d98b4f3d553b0771489d77efc84ae2964b6b9d909bbc1fd147a11053f082d65aff21e77f75bc78dca702", + "id": "15837369081784905442", + "senderId": "6128170150568124446L" + }, + { + "amount": "0", + "recipientId": "6128170150568124446L", + "senderPublicKey": "15d2e4927945fc65e7016e5a899694e54f7ad6fb9cd8c0d029866e828738450b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+15d2e4927945fc65e7016e5a899694e54f7ad6fb9cd8c0d029866e828738450b" + ] + }, + "signature": "81963cf84516e5204aa2b7b3f7a8c3e450869af3adb3e21580250199f5c60f86a1145a78ef2c872023bfccf0daaba6dfd38a5378a8599b4fd3998bae3b10040a", + "id": "14531773182076883946", + "senderId": "6128170150568124446L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "15d2e4927945fc65e7016e5a899694e54f7ad6fb9cd8c0d029866e828738450b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+15d2e4927945fc65e7016e5a899694e54f7ad6fb9cd8c0d029866e828738450b", + "+d9cb00493c908d27903fe5db02f947158a619b369bd72aa1b455708ed290340f" + ] + } + }, + "signature": "6d1e72c369f1143fa9fd08d095c538dfc6359545fa6a885c0662d6f6a0f185469102b72140e7662801d113afcc5951e4a530d7c82b686359987ab8cfcf7f1106", + "id": "5922618224672113479", + "senderId": "6128170150568124446L" + }, + { + "amount": "1000000", + "recipientId": "15214578104668437953L", + "senderPublicKey": "42e7195c8ed019c2af2ee851a4c3bc5d7acc8f1172bedfef96bcb81018cab508", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "283e4457d6ab3529fcfc13be162d47c7bd47b62cd5c71508d1cefeca0f6c2e5701611be49a8f0663148f60a1fcc79b53f314af35a5343da98026a618f5a7990c", + "id": "6421535947223556284", + "senderId": "15214578104668437953L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "42e7195c8ed019c2af2ee851a4c3bc5d7acc8f1172bedfef96bcb81018cab508", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "2fc40f147dfb22a874235dc75d3d69dd9943c9222e7f3349b9e7eb274a720af0" + } + }, + "signature": "6e62d5e5719516ebc02e2300d2054a3e6c2773a405c4befa1e36e8e5449220d448fe9b6c3e4ad2d2a6a157614ce6f2dff0fc24db980ae567132e1c9ff07a7f01", + "id": "9143537834211749246", + "senderId": "15214578104668437953L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "42e7195c8ed019c2af2ee851a4c3bc5d7acc8f1172bedfef96bcb81018cab508", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "stand" + } + }, + "signature": "402c8c26212e40ef207e469891d9b05b664db313eb94e0c8860521be67290d9c2fdcf2d9cc95ed9dff592305139e4d791dd3a66baadf6a89661a63590b6b8b0b", + "id": "10600150780798847820", + "senderId": "15214578104668437953L" + }, + { + "amount": "0", + "recipientId": "15214578104668437953L", + "senderPublicKey": "42e7195c8ed019c2af2ee851a4c3bc5d7acc8f1172bedfef96bcb81018cab508", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+42e7195c8ed019c2af2ee851a4c3bc5d7acc8f1172bedfef96bcb81018cab508" + ] + }, + "signature": "2f1ced28bd11471b35561d62287211e6d06a5a210f6b62248eed3f346767842c66ad6a6849b27a89fe09307bebcdc26a1f8829294d7cf1da2f29f645c5628b04", + "id": "14164051425769703645", + "senderId": "15214578104668437953L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "42e7195c8ed019c2af2ee851a4c3bc5d7acc8f1172bedfef96bcb81018cab508", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+42e7195c8ed019c2af2ee851a4c3bc5d7acc8f1172bedfef96bcb81018cab508", + "+2fc40f147dfb22a874235dc75d3d69dd9943c9222e7f3349b9e7eb274a720af0" + ] + } + }, + "signature": "b8c3238669d32ec9fc8490cdd3f5f638e4b01eaedf6c04887cceb0fb2834d558b5cd1c591b62e14169770ab2bd31fe6c70534bc2bc613ab24a4f42ceff317e0c", + "id": "14031370447049137123", + "senderId": "15214578104668437953L" + }, + { + "amount": "1000000", + "recipientId": "11624639864567871688L", + "senderPublicKey": "441a57f8dc3685c4c73d28670739f11b6932545c3f65d24d893827f4fbe4fdce", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "902a43dd4f27179cef24e7856a68761ca3136630e8e31b193aedd39ab883e221fc0e85e4916aeecfbc1a6f64444c407eea98a25b02ee054b82f4118a52940708", + "id": "8929174520182438217", + "senderId": "11624639864567871688L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "441a57f8dc3685c4c73d28670739f11b6932545c3f65d24d893827f4fbe4fdce", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f2511c6a9c4cbdd496947cf8f27d7720f5671b8c9e0ac64f22215a6150da75e4" + } + }, + "signature": "5b94da8a208d920f5b9a975d2c6da34f3c9a98667d16ce9be20a9275efc92fb7c4cb0cf19dc36dbc4b7a4fc47553aef0022fe5ce31fb7078291d3943c9ce5e09", + "id": "17565039734384301444", + "senderId": "11624639864567871688L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "441a57f8dc3685c4c73d28670739f11b6932545c3f65d24d893827f4fbe4fdce", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "crater" + } + }, + "signature": "b4d4fb675da2817cc023750c820a292fc102b2938f6d7e570e2ad9760749262fe3bdb3d35f969d0993804a140b0cba408883587ad7361ec8a4b4f2b2a6187a0a", + "id": "13508819718951136402", + "senderId": "11624639864567871688L" + }, + { + "amount": "0", + "recipientId": "11624639864567871688L", + "senderPublicKey": "441a57f8dc3685c4c73d28670739f11b6932545c3f65d24d893827f4fbe4fdce", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+441a57f8dc3685c4c73d28670739f11b6932545c3f65d24d893827f4fbe4fdce" + ] + }, + "signature": "84c37b4a66394d4903b3274f77d57e780493f4b6ca55a83cb67addc83d23bce8c54020de6d05702c7d1ef66af0132b896e731a5a08ea69ceb3d65460920cdd06", + "id": "9744805537077634653", + "senderId": "11624639864567871688L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "441a57f8dc3685c4c73d28670739f11b6932545c3f65d24d893827f4fbe4fdce", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+441a57f8dc3685c4c73d28670739f11b6932545c3f65d24d893827f4fbe4fdce", + "+f2511c6a9c4cbdd496947cf8f27d7720f5671b8c9e0ac64f22215a6150da75e4" + ] + } + }, + "signature": "7084191c06a33eb6c75b780954d05989745357ae1ccd6de7bec62744b1a9c871268cc0d52cea5e56e7e5fa801437d97927eb028cc7b3c028d16e6e7b95823201", + "id": "8400788729292040542", + "senderId": "11624639864567871688L" + }, + { + "amount": "1000000", + "recipientId": "8071676643666065131L", + "senderPublicKey": "d89b7e937977843e9e247ca4adf493a018c2bfc3ad1076f2507f261335779fc0", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "b6fff57c78b22e064761286310d11c2295bd58d68bff35e11fea29ac04a38f4981ecce5a1df6deb8b1a8dca98c5573a7f2a562c3c9506be76bd524f5da2d1302", + "id": "3586048593602741450", + "senderId": "8071676643666065131L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d89b7e937977843e9e247ca4adf493a018c2bfc3ad1076f2507f261335779fc0", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "cc1cd85d5d914d8dd0b7bde8f3fcd1b5313b6961d47a25b68f06a86f8459f37f" + } + }, + "signature": "ef1ea7ccf942e75f18e53402716460425864cf386ee2c336bdfe61338f1ac5801e8bb6b07e85ab62e8e95b668e85096e0435c6e9b373948b839d305f0cd97109", + "id": "14823866789659324146", + "senderId": "8071676643666065131L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d89b7e937977843e9e247ca4adf493a018c2bfc3ad1076f2507f261335779fc0", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "travel" + } + }, + "signature": "305d95dd6d4ae33b8b6629389225cafbc1cf04506256d781dd051986507ceb0448f5052e4c6a6f746d7e724195be69d35792acefd1e82a0e538e4c7fd6732c03", + "id": "3839113283745929639", + "senderId": "8071676643666065131L" + }, + { + "amount": "0", + "recipientId": "8071676643666065131L", + "senderPublicKey": "d89b7e937977843e9e247ca4adf493a018c2bfc3ad1076f2507f261335779fc0", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+d89b7e937977843e9e247ca4adf493a018c2bfc3ad1076f2507f261335779fc0" + ] + }, + "signature": "e022bb4e3dc91e00654737f625e3872bebbfe2120aee1ab96d88d5dc78f5f6123d89f6e49f25e03ad2b033d5b207c439c238f3edeeb22746a1b8d0690edf040b", + "id": "18323791618118503270", + "senderId": "8071676643666065131L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d89b7e937977843e9e247ca4adf493a018c2bfc3ad1076f2507f261335779fc0", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+d89b7e937977843e9e247ca4adf493a018c2bfc3ad1076f2507f261335779fc0", + "+cc1cd85d5d914d8dd0b7bde8f3fcd1b5313b6961d47a25b68f06a86f8459f37f" + ] + } + }, + "signature": "de38d73c41578794c9702b93aaf4384dbd891be39ee3e156c4d718669ba2e065a1d70f868d9c2869fff8d70230f99dd19be726014bf72202120f6870bdb04803", + "id": "4451084171565749781", + "senderId": "8071676643666065131L" + }, + { + "amount": "1000000", + "recipientId": "13093347258327855019L", + "senderPublicKey": "dcbf5ba23d5e1966d13f73ff78c3fa59f7ec088c666d2c0997e96c3367cb42dd", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "456bb46436eed00ec37be9e255c0b5e38d1c370f5de2f28b6843ddf9f2b51d73134d18475c70bade19032024dd7867fcc964509cc0d949e201aa3ebcf8c5c80b", + "id": "17683918551096783691", + "senderId": "13093347258327855019L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dcbf5ba23d5e1966d13f73ff78c3fa59f7ec088c666d2c0997e96c3367cb42dd", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d720e42512d12af77b79747a24303a0fb96d58f0cadd0c21cd500e4e5cc470f1" + } + }, + "signature": "5f19bcde9d96cebe61ae8e712e1183fb4c43f8d647513dc0175eb16ec36ab5db2f58f350168a1c317e4797ca84c79d0fe29f23d8e6d29fa0f2077145983f3a0e", + "id": "17231497125042391832", + "senderId": "13093347258327855019L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dcbf5ba23d5e1966d13f73ff78c3fa59f7ec088c666d2c0997e96c3367cb42dd", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "unfair" + } + }, + "signature": "c0723b74e2fc982259ebc3d518098b97687385299360c854b74de3a040f6f68f40eb1d47c9fc6a22bc36eaf80794a883fe44e23638f6bfede98ccca8a596ca05", + "id": "13571003603071545151", + "senderId": "13093347258327855019L" + }, + { + "amount": "0", + "recipientId": "13093347258327855019L", + "senderPublicKey": "dcbf5ba23d5e1966d13f73ff78c3fa59f7ec088c666d2c0997e96c3367cb42dd", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+dcbf5ba23d5e1966d13f73ff78c3fa59f7ec088c666d2c0997e96c3367cb42dd" + ] + }, + "signature": "b4fbd28bcf566e86cd95b69eca807b880fc2be5196733250a8fe3faa26829c43246f08a8ad723a7a6d5b65bf706190da0bc79908c85f4ba4cf702f9ed6d8e403", + "id": "11676326055875180413", + "senderId": "13093347258327855019L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "dcbf5ba23d5e1966d13f73ff78c3fa59f7ec088c666d2c0997e96c3367cb42dd", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+dcbf5ba23d5e1966d13f73ff78c3fa59f7ec088c666d2c0997e96c3367cb42dd", + "+d720e42512d12af77b79747a24303a0fb96d58f0cadd0c21cd500e4e5cc470f1" + ] + } + }, + "signature": "4218c895f00570512844d7d5ec04f8568dc014a8b0dbe79f26d7bf77a79cf6aaf034468ac35bd399a26dcf14cb1886b935ed48e56686949bd6fcaeb6c2f68104", + "id": "1825002280044416444", + "senderId": "13093347258327855019L" + }, + { + "amount": "1000000", + "recipientId": "14608684293975358257L", + "senderPublicKey": "317d6c8745b99e32e07fc0429450375804eae6ed652f0afd4ebfce6bc906ab1c", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "3544255569c999fbc1169ff494a85013d15ecc5914ff85d8d4a28ddb0fa9cee0d7267963ab7d8b511affb05ad79b355db979f0a4ccad406cc0c705970b253e0b", + "id": "3191387693699172306", + "senderId": "14608684293975358257L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "317d6c8745b99e32e07fc0429450375804eae6ed652f0afd4ebfce6bc906ab1c", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "35d000fd6da211623474009e5d3d80a06ca8b19e37148f58a489a8ca44e37298" + } + }, + "signature": "938e85e1f3691e79ca82ded97d21ad818068ba6a01448657bc3b9b66a38eb45bec146f28064cf2bf1f44aa060ccd6de94b4d03092d00930ccc9e8f409271e809", + "id": "17113393708669530064", + "senderId": "14608684293975358257L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "317d6c8745b99e32e07fc0429450375804eae6ed652f0afd4ebfce6bc906ab1c", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "game" + } + }, + "signature": "c2ed111655bb4105827fba524656992550b21e3b2eb72016ff281ed400697af96b5862b5548df4b4f481ee65835efbe4239b2d4c2126ef7e9493413330b3630d", + "id": "14045024600154226859", + "senderId": "14608684293975358257L" + }, + { + "amount": "0", + "recipientId": "14608684293975358257L", + "senderPublicKey": "317d6c8745b99e32e07fc0429450375804eae6ed652f0afd4ebfce6bc906ab1c", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+317d6c8745b99e32e07fc0429450375804eae6ed652f0afd4ebfce6bc906ab1c" + ] + }, + "signature": "f506d9be1395c52a5e24136ba4f2de84c73003a1784db1cef22b74e5d3dfb94ec13edf09ae114b10bb11878fde759655f1950a40459e3795c8dd8aa208f65f0e", + "id": "16302763240759475126", + "senderId": "14608684293975358257L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "317d6c8745b99e32e07fc0429450375804eae6ed652f0afd4ebfce6bc906ab1c", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+317d6c8745b99e32e07fc0429450375804eae6ed652f0afd4ebfce6bc906ab1c", + "+35d000fd6da211623474009e5d3d80a06ca8b19e37148f58a489a8ca44e37298" + ] + } + }, + "signature": "8cd8706fa696ad065670d97dc028e74dbc546f40f9ec73ba94ce7441811c5193775368a2dc1caabb29c0cf5b2a107d8922dbc3c2891f535e26e0f1b8b346d100", + "id": "7140497252682468748", + "senderId": "14608684293975358257L" + }, + { + "amount": "1000000", + "recipientId": "399687885325683754L", + "senderPublicKey": "07a4a89c9d1f6b78f648a15668e141c43465f7f2104691934fcdb693635d786f", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "d434bef4db6330ee9498aaf6dce0a7827c2c1d1edf8a94d8e0c1535dd0e11267a4dab4bf308863d837f7c3d954bbfbef5b65778a18e250c184eed26b9518be04", + "id": "6117617999096235942", + "senderId": "399687885325683754L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07a4a89c9d1f6b78f648a15668e141c43465f7f2104691934fcdb693635d786f", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c7da7c4fd2f6ee72d40b1ae6b2338500de8a83c7b69cd846e56e19737e7ff2be" + } + }, + "signature": "5359e88621015290baa9e62c94ae4d89085b042e00d20ea276af2ff6d85b63b2c3f8ce3d4caddb3ec77fcb45e212c0bd7fd01f7b7c3137c531786baf8f349600", + "id": "17796254985846051923", + "senderId": "399687885325683754L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07a4a89c9d1f6b78f648a15668e141c43465f7f2104691934fcdb693635d786f", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "cup" + } + }, + "signature": "824211c01ae6fa35ce66cb1d2a47b9f35369f527e77d147eea8d109ad22ed180198a7440f154a0bb6833355a8f00d8adf03c3d4fe159bb874233fa0ea39e0809", + "id": "13960241645360285844", + "senderId": "399687885325683754L" + }, + { + "amount": "0", + "recipientId": "399687885325683754L", + "senderPublicKey": "07a4a89c9d1f6b78f648a15668e141c43465f7f2104691934fcdb693635d786f", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+07a4a89c9d1f6b78f648a15668e141c43465f7f2104691934fcdb693635d786f" + ] + }, + "signature": "02b287920df54d7b5fc08edc0ea0cd1d8bed631e188920c410b3f79fb25e034ee3138123665731d494d33d193ff3a560c3933b56f48aafe2ec1ce4dddf301801", + "id": "7103420441501272516", + "senderId": "399687885325683754L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "07a4a89c9d1f6b78f648a15668e141c43465f7f2104691934fcdb693635d786f", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+07a4a89c9d1f6b78f648a15668e141c43465f7f2104691934fcdb693635d786f", + "+c7da7c4fd2f6ee72d40b1ae6b2338500de8a83c7b69cd846e56e19737e7ff2be" + ] + } + }, + "signature": "33769b061a1001c4aba37d5c9d8acbd9737a23b40572f3019de5a0f7191fdd6ac20768a9a3a9a6891cc7842776e3a1f52f9a4b43cdb936114e7490743a3a0d06", + "id": "1681829216927162735", + "senderId": "399687885325683754L" + }, + { + "amount": "1000000", + "recipientId": "8169435304351891655L", + "senderPublicKey": "49332227fc350f1d7957d558d9715b407e7077777e7b9caa1b95174bebc2162c", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "78bbb73a0285d9b20b6422b2486f1776cff4ff4dc68508bbbb524fdb3828c4b44ea81b5f6248c3952db2a03779ab5b587a1b7c89adaa370c9e911b3d8d79a604", + "id": "12360190015677956269", + "senderId": "8169435304351891655L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49332227fc350f1d7957d558d9715b407e7077777e7b9caa1b95174bebc2162c", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c254b37843f9afa0a7cac2236012d0d6b6b0abc31c885f7686562876ecc7fb55" + } + }, + "signature": "881643f9f932c3f82bfb618d20ce5f6ba2a4ee678d7f11a4de78e6fb6c66d024ac48e009b5989fb998542f46ef03f0a337e534457213b6d19ca14a62df3a2406", + "id": "5742018287025682959", + "senderId": "8169435304351891655L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49332227fc350f1d7957d558d9715b407e7077777e7b9caa1b95174bebc2162c", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "trouble" + } + }, + "signature": "03be043f3c76568192c106f42e4f7f73a4871e1af543e097a0aabb37012576e0ac65e2459401f54eea4a3e4a21e89c5ce57dddd5fb8325859500e0a9be9a3704", + "id": "3950419801161593746", + "senderId": "8169435304351891655L" + }, + { + "amount": "0", + "recipientId": "8169435304351891655L", + "senderPublicKey": "49332227fc350f1d7957d558d9715b407e7077777e7b9caa1b95174bebc2162c", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+49332227fc350f1d7957d558d9715b407e7077777e7b9caa1b95174bebc2162c" + ] + }, + "signature": "5d8ad77931fc8c1b9a6ebd46ab0e3c6844b0cef15ba050078c28aa79b95824a5f3f441ead4922fecca285127f4c3ef5727f176fd31437a8db906807a2a32b80e", + "id": "1165359969779300345", + "senderId": "8169435304351891655L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "49332227fc350f1d7957d558d9715b407e7077777e7b9caa1b95174bebc2162c", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+49332227fc350f1d7957d558d9715b407e7077777e7b9caa1b95174bebc2162c", + "+c254b37843f9afa0a7cac2236012d0d6b6b0abc31c885f7686562876ecc7fb55" + ] + } + }, + "signature": "1954b4d19bd751de3b1b975178e7f9cf9ac0e4ab6297383e9ca276d4aeca9bcb7ffc2c007052cc5072e1eb58f6b8a2a6faaba3bce27d5cb0c356e4b33877030d", + "id": "2715775931612148345", + "senderId": "8169435304351891655L" + }, + { + "amount": "1000000", + "recipientId": "6718335082194300758L", + "senderPublicKey": "612161b73cb67acfdfec56cd50975182ec747ed45ee1b829a0b20b11614de4e1", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "9f575bd3118987cef9b305c0dc657ad66ff41a20fb87f79043042c9bebdc31c1e0af8fac7045d0fef358b1cf9bedf3d5595fbbe1493165d88cd34873bef9290b", + "id": "11868005983103224854", + "senderId": "6718335082194300758L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "612161b73cb67acfdfec56cd50975182ec747ed45ee1b829a0b20b11614de4e1", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f144c93e0191b9a2c8f46e48744c85885250553ee24d57d312bd41ae4f524712" + } + }, + "signature": "de3dc54467cfc4608d067735ea9d71c26ff993764611094c57ffd1235cf3022535fe6411dc3632c7285f303f5c5e818eb06527cd7b0aebdaceeda315c5b47b09", + "id": "17533187887091487179", + "senderId": "6718335082194300758L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "612161b73cb67acfdfec56cd50975182ec747ed45ee1b829a0b20b11614de4e1", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "only" + } + }, + "signature": "20bd2ed8dcb19de0c07c5fc3359a806db1f8f15d32daad7b80d7081a181ef82fdbe58af88a4bb03ed2809e8f04f2330742b558235c38f08164507227f0876800", + "id": "16793463323442207957", + "senderId": "6718335082194300758L" + }, + { + "amount": "0", + "recipientId": "6718335082194300758L", + "senderPublicKey": "612161b73cb67acfdfec56cd50975182ec747ed45ee1b829a0b20b11614de4e1", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+612161b73cb67acfdfec56cd50975182ec747ed45ee1b829a0b20b11614de4e1" + ] + }, + "signature": "fc17c8a42cbca38d95bfd231a4ac21687a03d05e07334f07b92b7822a35a74afd2b57a189ef9cf6b306451b1f594ff9241d4d66082c29412baa5510029d35107", + "id": "7017727983034072470", + "senderId": "6718335082194300758L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "612161b73cb67acfdfec56cd50975182ec747ed45ee1b829a0b20b11614de4e1", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+612161b73cb67acfdfec56cd50975182ec747ed45ee1b829a0b20b11614de4e1", + "+f144c93e0191b9a2c8f46e48744c85885250553ee24d57d312bd41ae4f524712" + ] + } + }, + "signature": "71a015ac55cd51f5a7b15d5f5f74289e2af30b0184244ea438491a7d29e282bd75bda99a8c5f989c23fd45ec1930e591e1dfde017837791b6a227418e258e404", + "id": "10711672819085474965", + "senderId": "6718335082194300758L" + }, + { + "amount": "1000000", + "recipientId": "1312749963746460682L", + "senderPublicKey": "5238c57931fab65bb9a6e6d105be2ce71b0b67db2258c1b1e10ea26aec312d4f", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "cfb84995fc2166d839a2491f6500f54035cf8d929f4c93a825dda59c2e31a8b6e5842d2664eff4a6f611b7c707afe6d604e878ba88fbd9cebb5148882d83a70a", + "id": "17737242754574432235", + "senderId": "1312749963746460682L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5238c57931fab65bb9a6e6d105be2ce71b0b67db2258c1b1e10ea26aec312d4f", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "bc09ebfc0502691e45d5fb23a5e3dbf609d2e1ef63d0d71469431df1a2e4666b" + } + }, + "signature": "2279f74c4fbadf376d3d1b43694ea19f621589a85917bfc21b14ea50b51381306e337cef0d4356d435944735ca7a7cf19bf57adfe548a0ff076aea545b7e970d", + "id": "6291487177481739250", + "senderId": "1312749963746460682L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5238c57931fab65bb9a6e6d105be2ce71b0b67db2258c1b1e10ea26aec312d4f", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "frown" + } + }, + "signature": "e5cb7c928e10cce7d657c1ae32f5327dbfe8960daf66687a78d7ad66194adf1bd0bfaff0cdee39f63d35ffb2f5fb626eaec67450fd1c411cc1d5012d13ff6e05", + "id": "1517010100387471850", + "senderId": "1312749963746460682L" + }, + { + "amount": "0", + "recipientId": "1312749963746460682L", + "senderPublicKey": "5238c57931fab65bb9a6e6d105be2ce71b0b67db2258c1b1e10ea26aec312d4f", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5238c57931fab65bb9a6e6d105be2ce71b0b67db2258c1b1e10ea26aec312d4f" + ] + }, + "signature": "a3bf7bd1c672adf05a588bca2c5d84137b2c52c8ab24d7b8b860e4f9389d904fc6790ffad7f6ffde083007b31e19d80306cf0069f27e0618c21cefc064043f05", + "id": "1122321459121649947", + "senderId": "1312749963746460682L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5238c57931fab65bb9a6e6d105be2ce71b0b67db2258c1b1e10ea26aec312d4f", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5238c57931fab65bb9a6e6d105be2ce71b0b67db2258c1b1e10ea26aec312d4f", + "+bc09ebfc0502691e45d5fb23a5e3dbf609d2e1ef63d0d71469431df1a2e4666b" + ] + } + }, + "signature": "fac6e5579d5c41ae76d344c2c8a8d53f67018831f96a6f9d51c7642213b4af78e569b54272c9a07c2050aee30d3178ac09531c815a3b0d9d81d862108d85db07", + "id": "10343341922335200537", + "senderId": "1312749963746460682L" + }, + { + "amount": "1000000", + "recipientId": "1357930661074762850L", + "senderPublicKey": "651410e5145768b973ada60fd6de5d1973aadc0743a05b2cb0c4844322502b47", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "29d6bb60f3442b8a2a269cb7085ab39d6ab8cdfd84a64f8c2705e198cf28ebaa5a8160854e297ced76cb589d1df33bd8c32d85c81eb0feab0c2cffe0c0e89e0d", + "id": "7743526005978015808", + "senderId": "1357930661074762850L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "651410e5145768b973ada60fd6de5d1973aadc0743a05b2cb0c4844322502b47", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f0c73edf5b803c8b7b847984758e0c69ab74c1a339f7e813e1622876cb2c2efb" + } + }, + "signature": "1a5488c34ebae96321dd7634649d5d3a6cff16820677606484538c2be33d9907dd296c26ea5624ace92af86480798e5ad94b715f2a979e8a3c3c61f749eaea04", + "id": "1391266916448962522", + "senderId": "1357930661074762850L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "651410e5145768b973ada60fd6de5d1973aadc0743a05b2cb0c4844322502b47", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "avoid" + } + }, + "signature": "e278ebadc85d2909e58a67712eefb03ce01edbd6c40f309b6d3d21680efc75fa595bfbef9fa6c349e1031df2859c79613c0c09191e4087791036a989b547570b", + "id": "9354138924300719580", + "senderId": "1357930661074762850L" + }, + { + "amount": "0", + "recipientId": "1357930661074762850L", + "senderPublicKey": "651410e5145768b973ada60fd6de5d1973aadc0743a05b2cb0c4844322502b47", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+651410e5145768b973ada60fd6de5d1973aadc0743a05b2cb0c4844322502b47" + ] + }, + "signature": "7ab8db96735998eed92284ea1ec992c4d9295d060c4d4bad43e881900d3844fb7a6c3ea5ea6413f12ec755193e1399a2828a9d3a08fa542d540615d8b021cd0c", + "id": "15693453534072732395", + "senderId": "1357930661074762850L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "651410e5145768b973ada60fd6de5d1973aadc0743a05b2cb0c4844322502b47", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+651410e5145768b973ada60fd6de5d1973aadc0743a05b2cb0c4844322502b47", + "+f0c73edf5b803c8b7b847984758e0c69ab74c1a339f7e813e1622876cb2c2efb" + ] + } + }, + "signature": "72a32874a2d3a8107e01abb086ca83c9c4f4a97c0b6ea4024199b15c90cbb86adb5c080f7095acb2309a358f2306a9b9cbef3498340dbab3384f10e62c6e170a", + "id": "8094832489620015256", + "senderId": "1357930661074762850L" + }, + { + "amount": "1000000", + "recipientId": "7987928967922230013L", + "senderPublicKey": "5ca9c2d799b878d2627f0952fa0852380e4c5f089a10ef3b7a26bb9b8f22ec66", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "8db214e8a1513ee5e2fb7bf7a2cf2ed263c22b750c458dce463f80152573c257cd5e4d5a302f129f366547aedb784d975f343f8243197b0dc46806dd4904f70e", + "id": "7738854305725043349", + "senderId": "7987928967922230013L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5ca9c2d799b878d2627f0952fa0852380e4c5f089a10ef3b7a26bb9b8f22ec66", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "80737727bc946cbaa0dc36b01602ff15a100f4895f819a6b21a8cfcb4f1b53bc" + } + }, + "signature": "ce48c95d08e0c5dba185704e9e2a7fc42a812945e6421c46e8b46fe9f2bcc70006c8e87466424964113dc82cbb8a9fb7c58a3efb084682ee1e158cc05dd83d0f", + "id": "17800288639373468946", + "senderId": "7987928967922230013L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5ca9c2d799b878d2627f0952fa0852380e4c5f089a10ef3b7a26bb9b8f22ec66", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "service" + } + }, + "signature": "cab9672d67d8f3145294622868a475f134b7e639722ef8d712dd0dc31e1448114c23dd98da9ddabdabc0b421dd85f01287d8c187752673872d0387450f2dc504", + "id": "6820445755651812469", + "senderId": "7987928967922230013L" + }, + { + "amount": "0", + "recipientId": "7987928967922230013L", + "senderPublicKey": "5ca9c2d799b878d2627f0952fa0852380e4c5f089a10ef3b7a26bb9b8f22ec66", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+5ca9c2d799b878d2627f0952fa0852380e4c5f089a10ef3b7a26bb9b8f22ec66" + ] + }, + "signature": "2bddbc9bde4b0fc688ab637959f5cb27ccd1bad987104a4fbc52308e5aed62cbbe899fe5cdefcc3a268778dd3bee1237188dc3b5f20f2636d0c81e26e27d9009", + "id": "374794703364224288", + "senderId": "7987928967922230013L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "5ca9c2d799b878d2627f0952fa0852380e4c5f089a10ef3b7a26bb9b8f22ec66", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+5ca9c2d799b878d2627f0952fa0852380e4c5f089a10ef3b7a26bb9b8f22ec66", + "+80737727bc946cbaa0dc36b01602ff15a100f4895f819a6b21a8cfcb4f1b53bc" + ] + } + }, + "signature": "8026e554c5ff4358b60c187eec63ae35c40a7088b7eb82975bb199b901ee577aff8ad59809d888e54da97c7fb0e323783ea933de3d561c6f91a1bc3833f8d806", + "id": "57836718244391581", + "senderId": "7987928967922230013L" + }, + { + "amount": "1000000", + "recipientId": "3190776667541768693L", + "senderPublicKey": "2b50c09051a480454a6153377b857206d626da3b2b1a78e3cda54cd666a8e676", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "1141a57c7c4bc48b346de3e3b81ff770a5eb1c6ee8e19fffe7d48f3e3a392251aa10396dbed8314a687299349fa6873c1a31bc81afbcee48045711dd2cc24007", + "id": "333057501671259425", + "senderId": "3190776667541768693L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2b50c09051a480454a6153377b857206d626da3b2b1a78e3cda54cd666a8e676", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "153d67e3f004e49aa57039beac1d70d866ce4ad9009ff683848800f594f461c4" + } + }, + "signature": "b268234c5295f3153e6ebd4ca77c44a4397bb366a1ebe692f66f6fcc57a8a2d0bbed262bc3e570c4363e4a5e7a93d762209737f73337bedade45e74d70b22303", + "id": "5379174066193648776", + "senderId": "3190776667541768693L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2b50c09051a480454a6153377b857206d626da3b2b1a78e3cda54cd666a8e676", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "input" + } + }, + "signature": "ffd8b5058eff9f047a6e5fec05a030dd8db1de9bd77330810832fe0e138f5bbaeed43fbcd537cc359ff1993978da90f4b55adfab96970e746bd64545a7ec5900", + "id": "12361676144486438396", + "senderId": "3190776667541768693L" + }, + { + "amount": "0", + "recipientId": "3190776667541768693L", + "senderPublicKey": "2b50c09051a480454a6153377b857206d626da3b2b1a78e3cda54cd666a8e676", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+2b50c09051a480454a6153377b857206d626da3b2b1a78e3cda54cd666a8e676" + ] + }, + "signature": "8abd635791a1f9591ec25e6c56383c3dcb47c94f85c1b5deb1d2a96ca37cb0ddbbea47e31a77b7fa45c39e7ee25185d187ad51ae0504b4be7095f4e19c898f04", + "id": "5942269453552064825", + "senderId": "3190776667541768693L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2b50c09051a480454a6153377b857206d626da3b2b1a78e3cda54cd666a8e676", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+2b50c09051a480454a6153377b857206d626da3b2b1a78e3cda54cd666a8e676", + "+153d67e3f004e49aa57039beac1d70d866ce4ad9009ff683848800f594f461c4" + ] + } + }, + "signature": "0bb83d1968e021a75d5e00cb6f3be6877e5c303766eb1b1b87c74b8c14459bec3a4c61054ef016b203952ed33379229acdb3b51c9d092ba0859b8731407a4c06", + "id": "8198347201395581866", + "senderId": "3190776667541768693L" + }, + { + "amount": "1000000", + "recipientId": "12313615574089710672L", + "senderPublicKey": "bc1b7f26fe27aff384d7538a54856f89a43fd2e120dbbab8060586303577079f", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a23aae3769d210652e221863c843e503540a8f2dec96f8774e80ea9c4b15b3f40489dcceb75615bc6e788e3225c71f388c68f75d3e8a4c3bc8078a87c0defb06", + "id": "15691402691248606904", + "senderId": "12313615574089710672L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bc1b7f26fe27aff384d7538a54856f89a43fd2e120dbbab8060586303577079f", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3caa052021c78772ea136cdf99d75ad40d18ab42b552dbd6c42f70c67093bb41" + } + }, + "signature": "27816cd66c271e3294e27cbbe743185081714e0ff7352a70b6542f90cc5da21f7d1727659b4c9798261015ab970f0043b7f7edefad304e57ee58d4aa8f362807", + "id": "15977799356028283096", + "senderId": "12313615574089710672L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bc1b7f26fe27aff384d7538a54856f89a43fd2e120dbbab8060586303577079f", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "erase" + } + }, + "signature": "e45831882b68bbdf6f9927813749cfdcecb813476c6695c4c38c4e775c4dd0862a60e505977d23acff790b042c5e50665278954bd8e809e14e47c4e672cce902", + "id": "11147244354312492153", + "senderId": "12313615574089710672L" + }, + { + "amount": "0", + "recipientId": "12313615574089710672L", + "senderPublicKey": "bc1b7f26fe27aff384d7538a54856f89a43fd2e120dbbab8060586303577079f", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+bc1b7f26fe27aff384d7538a54856f89a43fd2e120dbbab8060586303577079f" + ] + }, + "signature": "54901b7099c656d8a691d162173a7d62a06d907696355b6a27d045926b28228d008992a64d0951ef8a9d41887e71ca07dfc5f84c73d1ac0a1f98198feee86e06", + "id": "12719957768197538000", + "senderId": "12313615574089710672L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bc1b7f26fe27aff384d7538a54856f89a43fd2e120dbbab8060586303577079f", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+bc1b7f26fe27aff384d7538a54856f89a43fd2e120dbbab8060586303577079f", + "+3caa052021c78772ea136cdf99d75ad40d18ab42b552dbd6c42f70c67093bb41" + ] + } + }, + "signature": "868fafe1276c263df3f35ccc515da565c6a3f31135b13e21e731d9a58fdc1b2026d1165f380d3a3d3ca587e3a1f5e5ebb596e5d8f744e485f4c288af26590202", + "id": "9803525398930418271", + "senderId": "12313615574089710672L" + }, + { + "amount": "1000000", + "recipientId": "10069992613393200607L", + "senderPublicKey": "55248d11da7d0cb7688147da8a2b21e63550e54e4eca07708d58d1fd8d5a01a8", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "10878bf0f5b5936006c8ad390cf0f110ed2de36bad565553934a09bf4c25161329a8458f1c9cbc1ad0ee1a7b256275981523393fe32678d22146d59bf297710a", + "id": "14620919230910118800", + "senderId": "10069992613393200607L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "55248d11da7d0cb7688147da8a2b21e63550e54e4eca07708d58d1fd8d5a01a8", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "a8d6637957dca16f7062253b2958d0f6518bb4acb0cace3d2f6300d4cfba2d34" + } + }, + "signature": "f6fed5a4dc52dc0276bd0cc67008caf9f0071589bc731b42041631094e9f60f39db5155c856bd8fbc9ef6276c6408e052589166228d6444c7ca40d0a0d697803", + "id": "730627130878670700", + "senderId": "10069992613393200607L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "55248d11da7d0cb7688147da8a2b21e63550e54e4eca07708d58d1fd8d5a01a8", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "state" + } + }, + "signature": "3a00f93382c50059b88fb058ecfe78810429ae2484e355d8d7284fe8bb8cb0a14c4a2fae5b227c56de52834205edfacdb54c998904cd9af53c7bb17bc39efc01", + "id": "4857967237451417997", + "senderId": "10069992613393200607L" + }, + { + "amount": "0", + "recipientId": "10069992613393200607L", + "senderPublicKey": "55248d11da7d0cb7688147da8a2b21e63550e54e4eca07708d58d1fd8d5a01a8", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+55248d11da7d0cb7688147da8a2b21e63550e54e4eca07708d58d1fd8d5a01a8" + ] + }, + "signature": "875d0b01e344ed5c3bb404a364c1bd23fceaaabff632db9c05dc1a30516b92fd63da761034418b9def139117f356ec636fdf5b24b9b7bc9e7933d5675ea95300", + "id": "15364747604573296044", + "senderId": "10069992613393200607L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "55248d11da7d0cb7688147da8a2b21e63550e54e4eca07708d58d1fd8d5a01a8", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+55248d11da7d0cb7688147da8a2b21e63550e54e4eca07708d58d1fd8d5a01a8", + "+a8d6637957dca16f7062253b2958d0f6518bb4acb0cace3d2f6300d4cfba2d34" + ] + } + }, + "signature": "7c3b1984cd67435eabdec5e4e17313f7c675cb55e633106def9aea4b6f3d9ef97480e1121c53085df4905b2e8bf4a0367d21d2f7a1a7c4846b67eccfc2f4f205", + "id": "5928654219712612628", + "senderId": "10069992613393200607L" + }, + { + "amount": "1000000", + "recipientId": "14192654215365553854L", + "senderPublicKey": "2d6f1cdb4dc10c7cdcc401ccdf983d0f07f62422b07184735f8530cf15ecdc96", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "78325355d32770ac0e64143710aa73b00615f67a548f0d558966c70f28b9deff59b150052018fdc64fe9d9b105f7338e3665807d1c3f5439f090bc74b7433109", + "id": "9395960987494730126", + "senderId": "14192654215365553854L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2d6f1cdb4dc10c7cdcc401ccdf983d0f07f62422b07184735f8530cf15ecdc96", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "fc105eb3550d6d4ec0df3907a4025502e65eaa05e240a957d60ac0e5c777683e" + } + }, + "signature": "cd30d1cdf3cdf671f09de19e9ba4ac138512860994afaa2972086504081e4d192c8edb4759c19fa9f25bcb65fce0588013ae050b8ec7a7dc1ce76cc6366f4a08", + "id": "839428045619408552", + "senderId": "14192654215365553854L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2d6f1cdb4dc10c7cdcc401ccdf983d0f07f62422b07184735f8530cf15ecdc96", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "hood" + } + }, + "signature": "6290c5ed478b096570a09adbe387e956a40d4a67c9b68939907fc4bb63176068f61e0ec0e3141ba14d5aa08c36cbf2a668890afccd8f550a2c5c282888523103", + "id": "536380699113352435", + "senderId": "14192654215365553854L" + }, + { + "amount": "0", + "recipientId": "14192654215365553854L", + "senderPublicKey": "2d6f1cdb4dc10c7cdcc401ccdf983d0f07f62422b07184735f8530cf15ecdc96", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+2d6f1cdb4dc10c7cdcc401ccdf983d0f07f62422b07184735f8530cf15ecdc96" + ] + }, + "signature": "de2bef75e41a597416ceeaba96b9b2957f1f9f73f1668bee356cf1c11dc72ba57c8acf8cc6cbe47ce0202ac48231fa804bfad4581d427a25e6a92994c226fd07", + "id": "7591193596090707691", + "senderId": "14192654215365553854L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "2d6f1cdb4dc10c7cdcc401ccdf983d0f07f62422b07184735f8530cf15ecdc96", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+2d6f1cdb4dc10c7cdcc401ccdf983d0f07f62422b07184735f8530cf15ecdc96", + "+fc105eb3550d6d4ec0df3907a4025502e65eaa05e240a957d60ac0e5c777683e" + ] + } + }, + "signature": "2f87fc9fc8278e429d96829d76066624db0e42341f03002bccabce57ad48adee1a9ab960b5677e4c41398ca682ecff5b659bdbeb93bde51e9191df37cefd5e02", + "id": "9473337978703227369", + "senderId": "14192654215365553854L" + }, + { + "amount": "1000000", + "recipientId": "13716803199232586937L", + "senderPublicKey": "a570482d4f729aebd1cbc51033676bb0ef7618d9bd88248ec45c8499b9ddd85a", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "70da3882375c7284ca6163d539ae35af4c5737bda3f8c96ed312e07386e7478bae18fc026630b3572c29db3f50cb3f8ae5a107af054541ad1bfe75f89057c600", + "id": "1283430892840655280", + "senderId": "13716803199232586937L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a570482d4f729aebd1cbc51033676bb0ef7618d9bd88248ec45c8499b9ddd85a", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3ff9cc20d685e6f1d13b09b648ee77160c5f3e5699f08503bc1e425302fd9aca" + } + }, + "signature": "d168a29568ed4b55feb2b94a49c652a2f6734f4781265a13f73cb2880cd6b683e4ee0c81fd32d979e9506d4fb43eebf5d8f562640c34ff01092526fcb2783d0b", + "id": "14370342193918341421", + "senderId": "13716803199232586937L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a570482d4f729aebd1cbc51033676bb0ef7618d9bd88248ec45c8499b9ddd85a", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "detail" + } + }, + "signature": "28eaa0b3e94997e5af8570d99fb809ae992b2ab4260b1026f8fad6529eae4cc9ef19c7d0bf3e36914d19bdb6856580eeb3b8da89ad13a4a8c50840fc18bb2d0a", + "id": "9784949255684090617", + "senderId": "13716803199232586937L" + }, + { + "amount": "0", + "recipientId": "13716803199232586937L", + "senderPublicKey": "a570482d4f729aebd1cbc51033676bb0ef7618d9bd88248ec45c8499b9ddd85a", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a570482d4f729aebd1cbc51033676bb0ef7618d9bd88248ec45c8499b9ddd85a" + ] + }, + "signature": "5f0dc0892f9cf5fb3323b559e7fa05c22f6197f57b6626da7484cfd00d6e5bfbe3c269e6ffdbe7bf2f06a1e148ffd46ed6cb047bdba724c2c57bd742ebe7620c", + "id": "12147212382789638609", + "senderId": "13716803199232586937L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a570482d4f729aebd1cbc51033676bb0ef7618d9bd88248ec45c8499b9ddd85a", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a570482d4f729aebd1cbc51033676bb0ef7618d9bd88248ec45c8499b9ddd85a", + "+3ff9cc20d685e6f1d13b09b648ee77160c5f3e5699f08503bc1e425302fd9aca" + ] + } + }, + "signature": "2cc999ef488bd9a321054935c2b595101c886dcfe13ce90e84dcf160b7359ee550932fc6a1b71a0d548bca58c00375136459e1fced27abfd68ce3358c17bb106", + "id": "17455128922377172391", + "senderId": "13716803199232586937L" + }, + { + "amount": "1000000", + "recipientId": "8762913442176959474L", + "senderPublicKey": "511a9f7835dfa0508e879feb4aec6907c6dfcff440ec985a9ba304b0ba2a4d84", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "dd16f4aba3afef558a7a09c42458a63ce6b5ebad6b5c1c2c44f566a132a87f65238b1fa6b9053495f72c94c1e368495417bfe3b7ce9507404681783bded9fb09", + "id": "10064141765018623047", + "senderId": "8762913442176959474L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "511a9f7835dfa0508e879feb4aec6907c6dfcff440ec985a9ba304b0ba2a4d84", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "8bd67dbf2bcd3da3b0f952623e1d180797cfb135f59f6f6b6c5bd498718c76a0" + } + }, + "signature": "f2443322b9e0e64ec464e64a55cf48c27bc4f4a6ef25d4e6aaf36bf07dcdcedb7b0323d8a239352f5258191266f9950dec4ee7d8389ce838043c3899ba4fdb05", + "id": "9982318714388412132", + "senderId": "8762913442176959474L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "511a9f7835dfa0508e879feb4aec6907c6dfcff440ec985a9ba304b0ba2a4d84", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "obscure" + } + }, + "signature": "0db4ec8dfea72d0d4b6aefdef59dc27142657429ba24e82da0cbd17675e98494c7e71f975624bfb7f368ba676e7ca71b59c7c35e5254343052e656666947f505", + "id": "3117767178459570232", + "senderId": "8762913442176959474L" + }, + { + "amount": "0", + "recipientId": "8762913442176959474L", + "senderPublicKey": "511a9f7835dfa0508e879feb4aec6907c6dfcff440ec985a9ba304b0ba2a4d84", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+511a9f7835dfa0508e879feb4aec6907c6dfcff440ec985a9ba304b0ba2a4d84" + ] + }, + "signature": "2978e3739edb516088a0b7ede3f5ee0e469002c9743a08e02afca49c5db86e32c712bd22230318b9a189a56dafe113cfebef651afd92bc0de6c76f0106b75602", + "id": "10914421651831679730", + "senderId": "8762913442176959474L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "511a9f7835dfa0508e879feb4aec6907c6dfcff440ec985a9ba304b0ba2a4d84", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+511a9f7835dfa0508e879feb4aec6907c6dfcff440ec985a9ba304b0ba2a4d84", + "+8bd67dbf2bcd3da3b0f952623e1d180797cfb135f59f6f6b6c5bd498718c76a0" + ] + } + }, + "signature": "eeca87a29d60c80c93b1edd7858a31322cd7f3b055ddb44599667044e37dfbfefdf3df23a3dfe7e8cb4a01609fdd8fff03432d468440f3c83e8c404f9ce0de0b", + "id": "6328874300264011642", + "senderId": "8762913442176959474L" + }, + { + "amount": "1000000", + "recipientId": "1719243736806599794L", + "senderPublicKey": "c7df03d4ce0a3c30115b55dc04110527eaba83b4ee8487f6f7f811e81cc116dc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "85c6cf5f813a5451b594483098e601db21a0450071b0f85b4d538e7bbf0032edac28617d2628f05ba7a689aa7403834b837f3a06713498fbb11457bdc1410405", + "id": "106723231045020233", + "senderId": "1719243736806599794L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c7df03d4ce0a3c30115b55dc04110527eaba83b4ee8487f6f7f811e81cc116dc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "2a2954546bf1e3c48c8454e4c46d83be85c6bff3577948f204ca398a9cc6d992" + } + }, + "signature": "938d4331f11d7dae253d540a79c3c4e52270c5979f880bbca7f44f69fdd3c23a0a988d3f8607cfc09f04a37ca86d14b7ea408d030c2d04dd05575a38dedd5405", + "id": "6388026818731725178", + "senderId": "1719243736806599794L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c7df03d4ce0a3c30115b55dc04110527eaba83b4ee8487f6f7f811e81cc116dc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "lab" + } + }, + "signature": "bd8fbf6120e21b354b2e357392f8857eec9026e619061692fdf236fad51fe1400586440ef3ac42f88da67894afdf5cea7fdb72c84636bdac01ee828526b8c40a", + "id": "4894915771299456541", + "senderId": "1719243736806599794L" + }, + { + "amount": "0", + "recipientId": "1719243736806599794L", + "senderPublicKey": "c7df03d4ce0a3c30115b55dc04110527eaba83b4ee8487f6f7f811e81cc116dc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c7df03d4ce0a3c30115b55dc04110527eaba83b4ee8487f6f7f811e81cc116dc" + ] + }, + "signature": "92038ba03dd3b6a14700ef953f2c5be088693337a6c61a9a94714c885bf5a7614d0a70cd6417de2682ec15f6718ee2b3d9777ff7b6fa9847efee71a269a1da0f", + "id": "9869416356799131040", + "senderId": "1719243736806599794L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c7df03d4ce0a3c30115b55dc04110527eaba83b4ee8487f6f7f811e81cc116dc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c7df03d4ce0a3c30115b55dc04110527eaba83b4ee8487f6f7f811e81cc116dc", + "+2a2954546bf1e3c48c8454e4c46d83be85c6bff3577948f204ca398a9cc6d992" + ] + } + }, + "signature": "fe7438b67ee46ffe6cd000f30c1ee53b9fc91aa425ce3b8d84a781a701df5fb90e94c499b10ba2288fa0dd91cb9f2a465abcb378cb4576776eb99d5cab99c808", + "id": "16974426274386244162", + "senderId": "1719243736806599794L" + }, + { + "amount": "1000000", + "recipientId": "13961530197827907819L", + "senderPublicKey": "346ed673e114c6f2a92cfb548767221ef415d631b9edafbe8db4c98033de7168", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f50bcfa5da2e79b8b84b4b3f58346aabc7acb67c74ad31c4eee2c9171cca6c1691c421fddbc1fb980e955e5daca0e6eb1d3407bea132b7857f44d3f6870a680b", + "id": "15332066560115690007", + "senderId": "13961530197827907819L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "346ed673e114c6f2a92cfb548767221ef415d631b9edafbe8db4c98033de7168", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "a20c32c9472d62a62315d79d91ab2571603e0f3f90f07d74f2087fdea23c505d" + } + }, + "signature": "a49e0759b520aa451f3bfac8990c6316abf815a1ccf2b1d0cdda80d519257abfd9307e6a3e220632b1547742be363357b4f417a24b8c3eadad301dc4b82f3400", + "id": "6600143091848461511", + "senderId": "13961530197827907819L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "346ed673e114c6f2a92cfb548767221ef415d631b9edafbe8db4c98033de7168", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "artefact" + } + }, + "signature": "df05bb7467ddbf554bd4bd252cae4ab7866104290a8ae44dfe5cda5a8c36a344f9cbdd7dfe9fb418ad56a8b44699e1e11a2d9aa298f8b6b3d102d7e53a29bc04", + "id": "5165351896410360804", + "senderId": "13961530197827907819L" + }, + { + "amount": "0", + "recipientId": "13961530197827907819L", + "senderPublicKey": "346ed673e114c6f2a92cfb548767221ef415d631b9edafbe8db4c98033de7168", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+346ed673e114c6f2a92cfb548767221ef415d631b9edafbe8db4c98033de7168" + ] + }, + "signature": "e728389b8109d493fd9cbad9f608a85306d7aa3e05c3c94f78c2724387855f27e94c26214cd47d9c359c57e6a7e525db987f959f32e2f9f98d340e77f681900b", + "id": "6445588771190460346", + "senderId": "13961530197827907819L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "346ed673e114c6f2a92cfb548767221ef415d631b9edafbe8db4c98033de7168", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+346ed673e114c6f2a92cfb548767221ef415d631b9edafbe8db4c98033de7168", + "+a20c32c9472d62a62315d79d91ab2571603e0f3f90f07d74f2087fdea23c505d" + ] + } + }, + "signature": "b36d17ea09d3a29d7f5295af3b1ffccec5830918559486f1b566777efdd6a89af65cf53dc96157b4b1f2b34c9e77ed2fdabdf63457d12b8e369c966b7f330d0a", + "id": "1853563834289898024", + "senderId": "13961530197827907819L" + }, + { + "amount": "1000000", + "recipientId": "1454506391342021962L", + "senderPublicKey": "e0849976e21ae3b49a0cf6ac479389e9c4e30c692d94e36d3b46b1152709488c", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "70dd5119366abb6a1e27c7d10c154466d77c843b13ee51a37fb9970c708eb8c484fccd34a9d53f2c21641b1097ae59d37014828b13a35a8c83b09d14a3e2240a", + "id": "11310274752276704078", + "senderId": "1454506391342021962L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e0849976e21ae3b49a0cf6ac479389e9c4e30c692d94e36d3b46b1152709488c", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "53f81c89915a8db0bbdd91fcd7f1fc51c90f57735be07fcdfa01e80ed211e693" + } + }, + "signature": "982fe3cf30ac256710f11f73b39f415b0cd1d328b4cf4ee1aa8fa74ecd45f280a28140bacd70cd645c05788a1501a2310aae6d21141eba9f6f655ffbb3bc2907", + "id": "6934646040997468174", + "senderId": "1454506391342021962L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e0849976e21ae3b49a0cf6ac479389e9c4e30c692d94e36d3b46b1152709488c", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "sustain" + } + }, + "signature": "cc523449caa69bcafb7511e5ef9d5977da5499ac9043f3a4aa7f8554240bb00b227a9fa247a2dd3c0381c1cbb6d85cbbefccca2d3617fbcd359cce2c9c5ba509", + "id": "5632749781122035939", + "senderId": "1454506391342021962L" + }, + { + "amount": "0", + "recipientId": "1454506391342021962L", + "senderPublicKey": "e0849976e21ae3b49a0cf6ac479389e9c4e30c692d94e36d3b46b1152709488c", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+e0849976e21ae3b49a0cf6ac479389e9c4e30c692d94e36d3b46b1152709488c" + ] + }, + "signature": "280dbd54a987809d281e5c2ade20f0dca24a238211c3a690535d9a02479ad00ce558c13cf98987a3325f966d504ec381cb8c274f6568bdb04af1db7d73d2d603", + "id": "5222705171823748069", + "senderId": "1454506391342021962L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e0849976e21ae3b49a0cf6ac479389e9c4e30c692d94e36d3b46b1152709488c", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e0849976e21ae3b49a0cf6ac479389e9c4e30c692d94e36d3b46b1152709488c", + "+53f81c89915a8db0bbdd91fcd7f1fc51c90f57735be07fcdfa01e80ed211e693" + ] + } + }, + "signature": "a096008b5588c01e161d0c8468c55cb24edb85bd9aae5c3117ecfddcab795d059fc99cd03fdb95619b277a59df38f7936c79119b71421f663d9b486541cef60b", + "id": "15028753377173108764", + "senderId": "1454506391342021962L" + }, + { + "amount": "1000000", + "recipientId": "1663443299711429869L", + "senderPublicKey": "c586c24877d8d14f89d46dca72197b07cc928d2d810a8f1c8d1c0ec051104e15", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "af41b0cffd08383fa94fefd4bac8fd1c48e34d905dbfcc9a29bdca04181830c47f5c145b66a6a9277a38538a66326fc694c1c3e25eb14c51345d16a0bc26d90b", + "id": "8194850612193218847", + "senderId": "1663443299711429869L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c586c24877d8d14f89d46dca72197b07cc928d2d810a8f1c8d1c0ec051104e15", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "060361f46759f35243fc2cccdf9316486459f8831e1231562b73fe766fd80202" + } + }, + "signature": "8eeddc8036c6e5b36947e90d29855b0c516e5fd0449b0526ab2d6361f04c87352f07f3873a4242568851b4528c24f55fbfa8686458d8d5fcaf51a0165568900a", + "id": "12072798750342889803", + "senderId": "1663443299711429869L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c586c24877d8d14f89d46dca72197b07cc928d2d810a8f1c8d1c0ec051104e15", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "comic" + } + }, + "signature": "75fd675d35f20f3171ec8a8c2cc9df8fe18061ae5dcafc766aab3c2dd2eb0f55a6c9181efbe68e0d580579186f2374835568f5b94a7782370c33815f87acef0b", + "id": "17069907720595367746", + "senderId": "1663443299711429869L" + }, + { + "amount": "0", + "recipientId": "1663443299711429869L", + "senderPublicKey": "c586c24877d8d14f89d46dca72197b07cc928d2d810a8f1c8d1c0ec051104e15", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c586c24877d8d14f89d46dca72197b07cc928d2d810a8f1c8d1c0ec051104e15" + ] + }, + "signature": "98667c5bab090564c2d883b6d636076b00695d173e61c8f8019fce194e460ca243456a4bde878b95242a802768d7741b59b286147ac0a5e0847bddc1cca4b904", + "id": "553752509895013391", + "senderId": "1663443299711429869L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c586c24877d8d14f89d46dca72197b07cc928d2d810a8f1c8d1c0ec051104e15", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c586c24877d8d14f89d46dca72197b07cc928d2d810a8f1c8d1c0ec051104e15", + "+060361f46759f35243fc2cccdf9316486459f8831e1231562b73fe766fd80202" + ] + } + }, + "signature": "c310a8b301ed140f75e0cfae5ea6c00d2194ada1c98144d19b918be9fee0385a6efd9175e25f6bb07b2afe7e8b2279a1186f302f8873b1da6f7efa7c61842402", + "id": "17291451787224626150", + "senderId": "1663443299711429869L" + }, + { + "amount": "1000000", + "recipientId": "10516970142268947805L", + "senderPublicKey": "eebfc8f36e3503dd5a591214cc5624ebb61d66cbd41ecac02d75578676f7f8cc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ff09f1c58333a8a1f7dc0af78ba570b0f6ccace80403d077715e66220fff939c70bef0416621dfd6c6c6ca101c8aad34d1b946617150f929c9750882d966d606", + "id": "888758149612657631", + "senderId": "10516970142268947805L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eebfc8f36e3503dd5a591214cc5624ebb61d66cbd41ecac02d75578676f7f8cc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e436fbefad4af11d5532aa675d3450152d4507c17efb3e3c0d18066721180cef" + } + }, + "signature": "968d4c2eb217ad2f5b080172037ecf6712b74548fa8462bcadd7dbdf69b6f4a9f9c349e7cba7deaeb0c5e3401fe7b3346b606588d01b42a0e7f6865d00770407", + "id": "16886705382043024394", + "senderId": "10516970142268947805L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eebfc8f36e3503dd5a591214cc5624ebb61d66cbd41ecac02d75578676f7f8cc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "stage" + } + }, + "signature": "c8134358dd1d5a2e23f3cebe24b80eb75b94afaff6a5401c57570d9c7ca90fe2599d4f7eec31a50c200741302e1dfb0b49ef334fef4e47bb725cf476754ff207", + "id": "14448805337777107355", + "senderId": "10516970142268947805L" + }, + { + "amount": "0", + "recipientId": "10516970142268947805L", + "senderPublicKey": "eebfc8f36e3503dd5a591214cc5624ebb61d66cbd41ecac02d75578676f7f8cc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+eebfc8f36e3503dd5a591214cc5624ebb61d66cbd41ecac02d75578676f7f8cc" + ] + }, + "signature": "ab13dee8e9e3bd8f68cad990835e09aa06853ddf633fb9bf077b758f33678733bf71d27e7083486da011a75737771ae0cf9570b09b207d6c6e58b983c6f0cb0c", + "id": "14074385413130396644", + "senderId": "10516970142268947805L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "eebfc8f36e3503dd5a591214cc5624ebb61d66cbd41ecac02d75578676f7f8cc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+eebfc8f36e3503dd5a591214cc5624ebb61d66cbd41ecac02d75578676f7f8cc", + "+e436fbefad4af11d5532aa675d3450152d4507c17efb3e3c0d18066721180cef" + ] + } + }, + "signature": "a275db8d9f6057d19296543f3c02907f8884702b9a780d8c4d665e69622f767ab72030df9261cd7ef2c751ebeb97394c3d0c426dfbd1b26ce6d635b61fb64a03", + "id": "16558910615375642573", + "senderId": "10516970142268947805L" + }, + { + "amount": "1000000", + "recipientId": "5922956840970443338L", + "senderPublicKey": "a0620e87822c59f872637c73f0fcf15e8a1425137c2f0c6a175e33596c1cef85", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "d315f4d93eae3b977f01f592ca1effc5a16444ab5e4580d290abfad1531a4d2048e22fb78c512e7b7264b95c5d64368b4e09806c88a30c8b730190592e78320a", + "id": "12706199918607565347", + "senderId": "5922956840970443338L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a0620e87822c59f872637c73f0fcf15e8a1425137c2f0c6a175e33596c1cef85", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "da382f6f6dc84f2c1fa64d4b4b185810ec472413d5720862226715cc5d44dd6c" + } + }, + "signature": "c9cc721afec869bae91316f0f12957365e8d732c87e74efb4846161584c33c540974c077958d10d9fcdbcc3da98bce563c09d09e9dd5c30ecb54b53e7bf2fe07", + "id": "2381538663046394272", + "senderId": "5922956840970443338L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a0620e87822c59f872637c73f0fcf15e8a1425137c2f0c6a175e33596c1cef85", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "demise" + } + }, + "signature": "10e196d92ddaabbf09847270aaad003368560130075dd71ef44c3ac669ff45758abbb6f446663412bef9d60b669cf3a918056870e5a16833b92ffbba3b113d00", + "id": "1757878831477183693", + "senderId": "5922956840970443338L" + }, + { + "amount": "0", + "recipientId": "5922956840970443338L", + "senderPublicKey": "a0620e87822c59f872637c73f0fcf15e8a1425137c2f0c6a175e33596c1cef85", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a0620e87822c59f872637c73f0fcf15e8a1425137c2f0c6a175e33596c1cef85" + ] + }, + "signature": "9cf09b76c177d8eb85e1bdd6c39096eda5d29401eb3912c891692f78635b6ffae7bd687fb23ef8c8820a2ed980397d018e109030fd14d041da0e9914ffcaf708", + "id": "4987845981997202885", + "senderId": "5922956840970443338L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a0620e87822c59f872637c73f0fcf15e8a1425137c2f0c6a175e33596c1cef85", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a0620e87822c59f872637c73f0fcf15e8a1425137c2f0c6a175e33596c1cef85", + "+da382f6f6dc84f2c1fa64d4b4b185810ec472413d5720862226715cc5d44dd6c" + ] + } + }, + "signature": "f329eedad666ab11991876cb81464c18c77b87626e4948eaa70fb39f093238a8c83655314e8d631bee9f6e4962b74a3207d8e6ab4af0fb269fa32516cd1c7705", + "id": "5839615485355390444", + "senderId": "5922956840970443338L" + }, + { + "amount": "1000000", + "recipientId": "16157148956722722703L", + "senderPublicKey": "822a4dd2eba7a84f4f9341840ba7a778e04d1ebedc1842470f313c4e6cdcb8f1", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "2196d2473448e3ef4dda1ee1313a33ffafe3c9405dde83920fababa926ee0d649be420fc3c7b701019989b2d1fa4efa54408c3968ce2b4020fc525596469dd0f", + "id": "6379218954140987217", + "senderId": "16157148956722722703L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "822a4dd2eba7a84f4f9341840ba7a778e04d1ebedc1842470f313c4e6cdcb8f1", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "5421f575bc7fa4fcde68fd0105d65f14920acf60b161caaf2c62bf916e10512b" + } + }, + "signature": "fa635b52c2f728f752bf22071ee88af8494193cbb57ad08ed4db7d35437942a6c93031ddcbdd13e9fc04a96b71efcd87fa06e9e50b997fe017d2a8d85bca4c0d", + "id": "9167792514065006276", + "senderId": "16157148956722722703L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "822a4dd2eba7a84f4f9341840ba7a778e04d1ebedc1842470f313c4e6cdcb8f1", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "space" + } + }, + "signature": "bd7679d1a845cc2dd49c1fbc3674bdb4aa72d9024ca681c1e9667239882f3ae5bf8e3ead4eb503c245b762304e839020a8372c8a07dcab0526eb785c93731f06", + "id": "14697663517961243974", + "senderId": "16157148956722722703L" + }, + { + "amount": "0", + "recipientId": "16157148956722722703L", + "senderPublicKey": "822a4dd2eba7a84f4f9341840ba7a778e04d1ebedc1842470f313c4e6cdcb8f1", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+822a4dd2eba7a84f4f9341840ba7a778e04d1ebedc1842470f313c4e6cdcb8f1" + ] + }, + "signature": "01484fe53eb416629bc7fd935274e6d630e31b52ea49c7d2c6715ac83f9317512129e0e555572e526f02d7e13e62a703cdf0b6a7001551bec9f03d1f624a160d", + "id": "7958313276385630392", + "senderId": "16157148956722722703L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "822a4dd2eba7a84f4f9341840ba7a778e04d1ebedc1842470f313c4e6cdcb8f1", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+822a4dd2eba7a84f4f9341840ba7a778e04d1ebedc1842470f313c4e6cdcb8f1", + "+5421f575bc7fa4fcde68fd0105d65f14920acf60b161caaf2c62bf916e10512b" + ] + } + }, + "signature": "d3cf2d7f2a80a4a9d14a39bbbac8ab03fa42a95de73a1a52964b8c36400d802049eeafc20e8f8a65a5f5b1acbc8512095b13e5534c5979675736c736588f4604", + "id": "6576794964208506478", + "senderId": "16157148956722722703L" + }, + { + "amount": "1000000", + "recipientId": "6138436421552052381L", + "senderPublicKey": "bef618e5514578332e9b1c8351e0ad5f855aae27b2cb27564d3d1cb3dbc18ee9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "009b7d064b1bf3d2e2b5ae13c131ec385720f8ef5d082f4b1985d3089f87d1ecf7626ff1e3da2f252caa863a4b7ae72bdccec66e2660b8ff3adb382cadc58106", + "id": "7888461680272951056", + "senderId": "6138436421552052381L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bef618e5514578332e9b1c8351e0ad5f855aae27b2cb27564d3d1cb3dbc18ee9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "a813af5d809a38e4753d7e345858df1336307345662cb8b2a2e0a4fd4aef46ae" + } + }, + "signature": "96019ddfff39acc2d7e7ef1556fda4e5f2eae8fd015f4ce443b2e20b8de865ccb333ad8072f7495cc9c85f442c11f1c7d83525bd8f392c5951795a2a32c8cf08", + "id": "991337236904346104", + "senderId": "6138436421552052381L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bef618e5514578332e9b1c8351e0ad5f855aae27b2cb27564d3d1cb3dbc18ee9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "toward" + } + }, + "signature": "447c559315d69713e56cccc89bd16290b86c2735227926ba0137b8de6e7146a551ede820a3a0a663dfbd04edd1be6ea5d2aed40a70b39024f64a57645db6ae09", + "id": "15195318052576428262", + "senderId": "6138436421552052381L" + }, + { + "amount": "0", + "recipientId": "6138436421552052381L", + "senderPublicKey": "bef618e5514578332e9b1c8351e0ad5f855aae27b2cb27564d3d1cb3dbc18ee9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+bef618e5514578332e9b1c8351e0ad5f855aae27b2cb27564d3d1cb3dbc18ee9" + ] + }, + "signature": "7e21113b5b2848eb2d2960a2a7cbc93842eeef059c539ad044a34c7d0650341ac91434c0b00972b90dc1f39db5029b5007b86be03c59b81e931c73a4313ed006", + "id": "17133270043001720501", + "senderId": "6138436421552052381L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bef618e5514578332e9b1c8351e0ad5f855aae27b2cb27564d3d1cb3dbc18ee9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+bef618e5514578332e9b1c8351e0ad5f855aae27b2cb27564d3d1cb3dbc18ee9", + "+a813af5d809a38e4753d7e345858df1336307345662cb8b2a2e0a4fd4aef46ae" + ] + } + }, + "signature": "b708dae0f8a33d188bad5d3ea904611ffb183a44ee7345b56c169c0fe5d65372f69dfe74867df7047bb9599c15dedc6f9e25132229feece81742a449ae3acf0a", + "id": "3566172445713247816", + "senderId": "6138436421552052381L" + }, + { + "amount": "1000000", + "recipientId": "8690529447321685485L", + "senderPublicKey": "39d6225c1dd67df2de046175c97c4c26b43e4c4d44a3ff73dccafe0aad8515cb", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "757a1ec5c555e321837d70f731fded6780027caf616c6b25b0af75470f7e8156b8525a979bf9e1fb3913ba2ffc4329152056b4cd8283ac47a1121eae8467e703", + "id": "3012209269244208690", + "senderId": "8690529447321685485L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "39d6225c1dd67df2de046175c97c4c26b43e4c4d44a3ff73dccafe0aad8515cb", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "8c1e1d56b092909a0784e887a478b3d901e30091adfcfb3b0148a84b06deea33" + } + }, + "signature": "08f0e4886c6d5bef18493cf85fd154c46c5ede234fa64e32d02919d6ad68bb5862a644e42e9f4069bc149bd8baf72e9c2998b137b24f5806b92ee2d485f0a80f", + "id": "11909780856536762344", + "senderId": "8690529447321685485L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "39d6225c1dd67df2de046175c97c4c26b43e4c4d44a3ff73dccafe0aad8515cb", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "slot" + } + }, + "signature": "559e6ced14487936b065d01c0c61119754f81ce0af47b0c08562722f3e95b80ceabfdb12d9cd7ccf56b036f0a17a4a341f5ffbe798e1f60e046eae3ef9b3130e", + "id": "10614008455922789846", + "senderId": "8690529447321685485L" + }, + { + "amount": "0", + "recipientId": "8690529447321685485L", + "senderPublicKey": "39d6225c1dd67df2de046175c97c4c26b43e4c4d44a3ff73dccafe0aad8515cb", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+39d6225c1dd67df2de046175c97c4c26b43e4c4d44a3ff73dccafe0aad8515cb" + ] + }, + "signature": "92523f21bc462cdcaa8f2da943a729cce33f7106051702e3f37604ebe7f00ddf7c25f1463eac97ed00b687abe5e1ecae16b01b0d72fc3552cb72b62464806c0c", + "id": "5142156108502538642", + "senderId": "8690529447321685485L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "39d6225c1dd67df2de046175c97c4c26b43e4c4d44a3ff73dccafe0aad8515cb", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+39d6225c1dd67df2de046175c97c4c26b43e4c4d44a3ff73dccafe0aad8515cb", + "+8c1e1d56b092909a0784e887a478b3d901e30091adfcfb3b0148a84b06deea33" + ] + } + }, + "signature": "17ab318015e2eff4029f66f8afc3f113d7dd89dca3cc50c1280f711d2eb69c96d6b655ab456681dc97406ba7b90f76589f945db94f45c43edc7c35e8f0e2c007", + "id": "17720273743355285964", + "senderId": "8690529447321685485L" + }, + { + "amount": "1000000", + "recipientId": "16828600199059189083L", + "senderPublicKey": "36f7eed674944bad682c33b2d76d7cf069ef220c316d1d052fc56d4f01d90f7e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "07a6d49a45ae31c2be3c22855c0ad770e81c0cccf3efd2f514d66493b3be939ef5ef060fc30d67a778dcd60a47148a32c9e26f2893a147cdf43a3778c685fd0b", + "id": "17050255120397160151", + "senderId": "16828600199059189083L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "36f7eed674944bad682c33b2d76d7cf069ef220c316d1d052fc56d4f01d90f7e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "c1db8bee1926d509369e451f834a532fc56bc48146d6f3ae92eb11db0f5f2205" + } + }, + "signature": "7192c2109b66d5b36f2f522ba159c4e9d14780bfdd6cc05a402c7ebd473b1a755f019eb7600a294e6b332780e061f985382655bbd2c3ab506755042cb8cc7205", + "id": "9292805283734001151", + "senderId": "16828600199059189083L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "36f7eed674944bad682c33b2d76d7cf069ef220c316d1d052fc56d4f01d90f7e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "soda" + } + }, + "signature": "76bc9614f9f6ac3c6c442383ce83091019bd277e2a458df0a5b872978abd89670a0884abc041c6eaf4fb838ba13b9ff84683d4cae61eb3fa5d42c6425f357e0f", + "id": "7775090140837522047", + "senderId": "16828600199059189083L" + }, + { + "amount": "0", + "recipientId": "16828600199059189083L", + "senderPublicKey": "36f7eed674944bad682c33b2d76d7cf069ef220c316d1d052fc56d4f01d90f7e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+36f7eed674944bad682c33b2d76d7cf069ef220c316d1d052fc56d4f01d90f7e" + ] + }, + "signature": "84ee5330c41c30e324bbe5526e76b4b4aee104726c4c39bc29db8058fb54f98c179880e9cbeed7e45e2cfa365b683ed97198f4849b8c2bd331ccba3df863430d", + "id": "14400591134218989279", + "senderId": "16828600199059189083L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "36f7eed674944bad682c33b2d76d7cf069ef220c316d1d052fc56d4f01d90f7e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+36f7eed674944bad682c33b2d76d7cf069ef220c316d1d052fc56d4f01d90f7e", + "+c1db8bee1926d509369e451f834a532fc56bc48146d6f3ae92eb11db0f5f2205" + ] + } + }, + "signature": "dda58f026b6bfa7b67bb9b11121f5af3bfef0fad5414817029037415e565b6bfe87f67916df2279464e6135fdef3d06a81dcb9f677a9f0582f507e3f9c48b60d", + "id": "6412957042965894684", + "senderId": "16828600199059189083L" + }, + { + "amount": "1000000", + "recipientId": "3117234715182843213L", + "senderPublicKey": "c24212c825b4c65db50c95de2b9da5e09fb3802112097e0256e43bc54c1cafb9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "307e8ceb6faee3736f87d9b063ab8741e4dff99b1c56c39bf993264259ebeac78ce71f7a37ad8aacd1e44570b576c62849c1b4ad8dffaa05634d03870d19b608", + "id": "10486961954290378439", + "senderId": "3117234715182843213L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c24212c825b4c65db50c95de2b9da5e09fb3802112097e0256e43bc54c1cafb9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e47f2dddcbae7b3378bb8b03e3c3a2d9fc8acaad0d1e1eb181317e66498d125d" + } + }, + "signature": "6e27501a15ae94d914804981d9f220bdfa20371fcdf032abbd96dcf1e62b880d152b67cf2ec289d13caf3952729d5f684b8a1474bae6ab8318065dac47bf430f", + "id": "15973086846135356940", + "senderId": "3117234715182843213L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c24212c825b4c65db50c95de2b9da5e09fb3802112097e0256e43bc54c1cafb9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "urban" + } + }, + "signature": "85068c3563bfdd13a55719555b75ef70c604bf1c1137a1e997286455816ffbb8427c09e473c1a7a6349057f4e4047cef43c173d882d245722089b2d6879c6d09", + "id": "3378542881235011415", + "senderId": "3117234715182843213L" + }, + { + "amount": "0", + "recipientId": "3117234715182843213L", + "senderPublicKey": "c24212c825b4c65db50c95de2b9da5e09fb3802112097e0256e43bc54c1cafb9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c24212c825b4c65db50c95de2b9da5e09fb3802112097e0256e43bc54c1cafb9" + ] + }, + "signature": "67911ea9036e8d824387e92a98e1c7089c39201487cc036a49a5f19f916a92ba7c6c46b84ef06cac4aeab676d10a38aa3b82deab7a1b650f6ee831ec6deb2400", + "id": "6796593739624964764", + "senderId": "3117234715182843213L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c24212c825b4c65db50c95de2b9da5e09fb3802112097e0256e43bc54c1cafb9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c24212c825b4c65db50c95de2b9da5e09fb3802112097e0256e43bc54c1cafb9", + "+e47f2dddcbae7b3378bb8b03e3c3a2d9fc8acaad0d1e1eb181317e66498d125d" + ] + } + }, + "signature": "5ec0453b15c36702a6407bb2ca59220eaa24ee87ff18f77d03f67e69e2fd66f4cf993f487c9cac3e8cdb806879b924351ee2239cff1794f65e143b7e3579ca0e", + "id": "17632507349126466035", + "senderId": "3117234715182843213L" + }, + { + "amount": "1000000", + "recipientId": "18008258998173769426L", + "senderPublicKey": "05b236537af28e1ee0d89e84710b9ce94744330977fa63dc2b8c116adeb11885", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a61180fc9d5656da7f4cec3a94a126c71563c0a64b19222a0266c4ab97d8841d5a68679b04858eb1e3865c3cedf8cc1493e97a440cef21c7b91de7b9601b460a", + "id": "3928992064237485027", + "senderId": "18008258998173769426L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "05b236537af28e1ee0d89e84710b9ce94744330977fa63dc2b8c116adeb11885", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "d9db46709e68ae190b12ee204d8a13eb44fee2dbadf45d8831626cc089cf1d00" + } + }, + "signature": "90f9ab4de5f0226c5162e07d0a968d5b5a711a50bd8db96bd6c70f6ffd8385ffac105284b00af05f6ee8da6c9ac27ae63e5bab212152f9bf353902ae033dfb03", + "id": "1292456244936165212", + "senderId": "18008258998173769426L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "05b236537af28e1ee0d89e84710b9ce94744330977fa63dc2b8c116adeb11885", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "jump" + } + }, + "signature": "42540e5b49b6d41c4a21007224cc0b78121e6a4eb7586acc3a0f80932e5ebddc07f7ce4f0f1402a5eb8c72c994330bd7c7de23f66f4915266746882210ce0d07", + "id": "4495520871444672123", + "senderId": "18008258998173769426L" + }, + { + "amount": "0", + "recipientId": "18008258998173769426L", + "senderPublicKey": "05b236537af28e1ee0d89e84710b9ce94744330977fa63dc2b8c116adeb11885", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+05b236537af28e1ee0d89e84710b9ce94744330977fa63dc2b8c116adeb11885" + ] + }, + "signature": "da5290ae26bf53fed6d6f9cb582399f828fc32c6fd6c4f88710e09d8c9cc7d04c20ed4523b082d349aa45af035c98b6f68a389f7260631a0e32af4279326e007", + "id": "18252616701304255923", + "senderId": "18008258998173769426L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "05b236537af28e1ee0d89e84710b9ce94744330977fa63dc2b8c116adeb11885", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+05b236537af28e1ee0d89e84710b9ce94744330977fa63dc2b8c116adeb11885", + "+d9db46709e68ae190b12ee204d8a13eb44fee2dbadf45d8831626cc089cf1d00" + ] + } + }, + "signature": "f379670faf88941f455fd5bde82f8748bcd29b5ada6cc99da178e27d556489d2b0fe283fd80b1f459f9554cff856c731e262f940911a209a490ae873fad0b605", + "id": "1623971003539621764", + "senderId": "18008258998173769426L" + }, + { + "amount": "1000000", + "recipientId": "18327507212732860521L", + "senderPublicKey": "700268733539d66fab4de74c38f42549415b1b8337222488d10918bf95599250", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "efc0f93a8b349d86088bd0d52891fb76a144e86b00d6031a5ce05bee5e5bd29e166ed9d720b224b5ee02db0c99c6425627ce815a550e984c8f8f05314109b102", + "id": "5924258582219097012", + "senderId": "18327507212732860521L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "700268733539d66fab4de74c38f42549415b1b8337222488d10918bf95599250", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "25de617ccd285ec6c9afc71cd08e6187e241fc9f0cbadfe44c86449cddd86ad2" + } + }, + "signature": "b40ec32432b95d87e7ca11debbd5b4132b23afcf9e4491ac747a276268865aeceb359030010e094468efb9957a2f2bdb6c6936d5fa9a90de0b69979a7edf4f0f", + "id": "7267508144057632311", + "senderId": "18327507212732860521L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "700268733539d66fab4de74c38f42549415b1b8337222488d10918bf95599250", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "bus" + } + }, + "signature": "e71c72cb4ef096377497c2c790aff7c1a6e721f2bf99149886b3d6b93b96f85b4cf8d496400a14b18b667d906b3ae78737544642645be4bdcab7ecca934d1a09", + "id": "354076192313096449", + "senderId": "18327507212732860521L" + }, + { + "amount": "0", + "recipientId": "18327507212732860521L", + "senderPublicKey": "700268733539d66fab4de74c38f42549415b1b8337222488d10918bf95599250", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+700268733539d66fab4de74c38f42549415b1b8337222488d10918bf95599250" + ] + }, + "signature": "c2e6354827d3b56beac9cd883b7b8884d3c3d7c8c316fd837d46b567644328dc2f422beca2f5d29449e830db22dd5867f07333fa13adcfd3fb9798715e4c0805", + "id": "9621685182091752527", + "senderId": "18327507212732860521L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "700268733539d66fab4de74c38f42549415b1b8337222488d10918bf95599250", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+700268733539d66fab4de74c38f42549415b1b8337222488d10918bf95599250", + "+25de617ccd285ec6c9afc71cd08e6187e241fc9f0cbadfe44c86449cddd86ad2" + ] + } + }, + "signature": "d0579ae91137cf1324f39118c33ddfa78a4c54f57f6e041234d0a45cf6028bd413d9f4d5c29fb6dff4cf7021b5ecad8b9f708c9a26c5f2b9b3f077f1247f0c03", + "id": "13165341021783134524", + "senderId": "18327507212732860521L" + }, + { + "amount": "1000000", + "recipientId": "10642381638630676703L", + "senderPublicKey": "bce384981dbebb2a41925fcd34e5ea69402e097de22b7e9c6a9d1dfcd7aca7a9", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "76e341126b584e3c711848d054baee3275dde0e7a934b0cca804b6efae546a208388d60989b22d5b9701e82431c981b2a1f69a0065cd06a3cad1e6447245790f", + "id": "491971838661859238", + "senderId": "10642381638630676703L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bce384981dbebb2a41925fcd34e5ea69402e097de22b7e9c6a9d1dfcd7aca7a9", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "32a8b4dbfa433525527cd41d19bc644955c5b237c0f83d101526912cd6fc4237" + } + }, + "signature": "830d49229df2eafd098b6292670a06e3d9de99eeb26510a5f2a49e58250d4614aa6f1d50b9348f51fd1e9059ad8cc16adee875493afa4fa73c9b44fb8ce34c0b", + "id": "17570680712444909474", + "senderId": "10642381638630676703L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bce384981dbebb2a41925fcd34e5ea69402e097de22b7e9c6a9d1dfcd7aca7a9", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "chuckle" + } + }, + "signature": "740876619564eea0082cf4c97c22f3210458a68f2349f5a495d05b3961ffd51124542c76a837889359906902ceba166b2c9c6949bee6164d6014291494a09e02", + "id": "10910467416546841292", + "senderId": "10642381638630676703L" + }, + { + "amount": "0", + "recipientId": "10642381638630676703L", + "senderPublicKey": "bce384981dbebb2a41925fcd34e5ea69402e097de22b7e9c6a9d1dfcd7aca7a9", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+bce384981dbebb2a41925fcd34e5ea69402e097de22b7e9c6a9d1dfcd7aca7a9" + ] + }, + "signature": "0df1de3e141ed9062234ef0607f2ce689a8de080be112231d8bf31392471f47611a7f7924164109b25817a066486c31ba282ddd43e6732f94eeb7e7b952e9c0f", + "id": "1487221016973802231", + "senderId": "10642381638630676703L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "bce384981dbebb2a41925fcd34e5ea69402e097de22b7e9c6a9d1dfcd7aca7a9", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+bce384981dbebb2a41925fcd34e5ea69402e097de22b7e9c6a9d1dfcd7aca7a9", + "+32a8b4dbfa433525527cd41d19bc644955c5b237c0f83d101526912cd6fc4237" + ] + } + }, + "signature": "18269dc0b121cea2fda1de13cfd9e4fdea821bb49121a3a3ebef30a25c2e57128cc25021e652c879a526cc7c925fd4e5bb056772ab0f785c32da65745f3aba0b", + "id": "8165726537587262139", + "senderId": "10642381638630676703L" + }, + { + "amount": "1000000", + "recipientId": "1832701800952916406L", + "senderPublicKey": "d011d67c9018ea9282532d9cc3de82533e9a19f7038add13fd54dcbcb038465c", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a28ed12354494462148807027bbc756f691b2f933832a22424d3725a888b96ba6fe8aa5bd0d73865412a39226d6ddfc54b207885f38263c9447cfe9f72277007", + "id": "12457787533034144722", + "senderId": "1832701800952916406L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d011d67c9018ea9282532d9cc3de82533e9a19f7038add13fd54dcbcb038465c", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4be939a544f33483b580fdc78d68b7de2a8abd1fdf93dbd3def8383afca9cb02" + } + }, + "signature": "ec4e070ef66aefc9554bb7521f306a9c6de049590c4d7ca12bac93ed146a05e30ec079478b884ee1d885f492e3bdbc3e815b3e46572a93d7f6bf012f02c7970a", + "id": "15705040774329190060", + "senderId": "1832701800952916406L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d011d67c9018ea9282532d9cc3de82533e9a19f7038add13fd54dcbcb038465c", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "tip" + } + }, + "signature": "7549af25929ba2c73e334df3527ec334993260fea66c2fa644d1c7e26b67a711de2c09cf82c2cddff1929ab09c3c9520d034ecc0d2dcf3ca4bb9ac46fcf0b50e", + "id": "5757225790046616722", + "senderId": "1832701800952916406L" + }, + { + "amount": "0", + "recipientId": "1832701800952916406L", + "senderPublicKey": "d011d67c9018ea9282532d9cc3de82533e9a19f7038add13fd54dcbcb038465c", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+d011d67c9018ea9282532d9cc3de82533e9a19f7038add13fd54dcbcb038465c" + ] + }, + "signature": "5d09ade8f05ebd05cf1531f96f605a81f3f38ad56b06ed63c771fbcf2d2ef227f8ede7f1f0bf1960555e8ead6c9bd22e677a7eb2ae92f1d721dd58eab5cd8708", + "id": "15811441328737543076", + "senderId": "1832701800952916406L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "d011d67c9018ea9282532d9cc3de82533e9a19f7038add13fd54dcbcb038465c", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+d011d67c9018ea9282532d9cc3de82533e9a19f7038add13fd54dcbcb038465c", + "+4be939a544f33483b580fdc78d68b7de2a8abd1fdf93dbd3def8383afca9cb02" + ] + } + }, + "signature": "388eecec10aaafd75d437ebae3b08499729ed24d62087adc3dd0ace43b11a142b8e23e65ebb1b7f111c46fa8e8751d4734a9133273013bbf1d024215e3b1c70b", + "id": "8336748969808659246", + "senderId": "1832701800952916406L" + }, + { + "amount": "1000000", + "recipientId": "3272065180880293808L", + "senderPublicKey": "6075ef9752cd466712c73a7f506788f67ffe121921ba01c2aab956d32e708363", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "8810263638fd39cb8794427d10293544de1ff093f4d981f9a84fa69582ecd095d67e10641f34f12b9b0c5cef00904d8feac02bf18016b2491cb0b519e9902805", + "id": "17014304882423612974", + "senderId": "3272065180880293808L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "6075ef9752cd466712c73a7f506788f67ffe121921ba01c2aab956d32e708363", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "4ead41d0b0322d03c5a230f0688e53a91444a3bdf616f41fa14785f6ab9d237d" + } + }, + "signature": "6cf96fc17a19060df2cfab4a8c9426c2d3d66e220be329aba379248bc041010afd0edd26795039f6f65b9e85249acc9fd87a1334c3549e5f45e14fb74f28c30b", + "id": "1461758195417699360", + "senderId": "3272065180880293808L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "6075ef9752cd466712c73a7f506788f67ffe121921ba01c2aab956d32e708363", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "summer" + } + }, + "signature": "b4f4ec046c52f4c1e785e0e2a5421b06ccb6832b08a10b04ae765c563a734e93d8b0cb737fff374b5000709bd62167cd50527bed72a944306a229f40968f5f0f", + "id": "11397918933160682071", + "senderId": "3272065180880293808L" + }, + { + "amount": "0", + "recipientId": "3272065180880293808L", + "senderPublicKey": "6075ef9752cd466712c73a7f506788f67ffe121921ba01c2aab956d32e708363", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+6075ef9752cd466712c73a7f506788f67ffe121921ba01c2aab956d32e708363" + ] + }, + "signature": "c2ce858ff46d8ac85360f27ade8b2721138b5d70ec8bfdfd30183bb2a357098be1d0bde0dad659765594d7b83930d9ec798d5e3f9b2d9f3f2e353dfe931ff900", + "id": "3028858852546700494", + "senderId": "3272065180880293808L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "6075ef9752cd466712c73a7f506788f67ffe121921ba01c2aab956d32e708363", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+6075ef9752cd466712c73a7f506788f67ffe121921ba01c2aab956d32e708363", + "+4ead41d0b0322d03c5a230f0688e53a91444a3bdf616f41fa14785f6ab9d237d" + ] + } + }, + "signature": "51938e5af10d16226ae203839bbd5adbf37d4d165183026b13a85acaa12d76f21c4fda41744561612743498598cb4b7866c643f10532fcb88444db08cc0bb80d", + "id": "971089570827899220", + "senderId": "3272065180880293808L" + }, + { + "amount": "1000000", + "recipientId": "6885133969991843253L", + "senderPublicKey": "7033a174c11f5545c698494039ab0ed2bdb3f76c59e2f341cdc18415023f2b35", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "79a108329717f349e2de959c3e6e33115ba3aa202911ee06f40ee7c713ccde7fd42c3d5d9c3e71f857d1fcb5da6270c49214f7cdc154cdec83974e5d2d04ff04", + "id": "8894840063834430358", + "senderId": "6885133969991843253L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7033a174c11f5545c698494039ab0ed2bdb3f76c59e2f341cdc18415023f2b35", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "b8dc1286429b54ed85859380c457b38108d078f3ef0178cd9fcff3ad992beb0e" + } + }, + "signature": "1df7b4ed6e3d503f0773e295b498706d3c0d55d35cef45390de3fc9041f608fa1f7752858f5dea48e8bdd9415baec6b2686810fd09eea249f5d084754de12102", + "id": "475853404418287223", + "senderId": "6885133969991843253L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7033a174c11f5545c698494039ab0ed2bdb3f76c59e2f341cdc18415023f2b35", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "together" + } + }, + "signature": "7cb7eea0bdec9053fa1b7f0059c46216b9d5dae76cb343c0ce88b2b160150d0b874e462011a6b4f51326fefe40b7bbaa42c52f5cef67af69b739139ca999e00d", + "id": "10981812982267958155", + "senderId": "6885133969991843253L" + }, + { + "amount": "0", + "recipientId": "6885133969991843253L", + "senderPublicKey": "7033a174c11f5545c698494039ab0ed2bdb3f76c59e2f341cdc18415023f2b35", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+7033a174c11f5545c698494039ab0ed2bdb3f76c59e2f341cdc18415023f2b35" + ] + }, + "signature": "fdd0a2fd7c20def99e149e9090bf568c20ce8bb5e7b28ca4b82dddc7f3031d1df97f7f282207fa8e14fecece738f2999bd0cd61ad3ad300837e37927dce99c00", + "id": "7761018479940167452", + "senderId": "6885133969991843253L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7033a174c11f5545c698494039ab0ed2bdb3f76c59e2f341cdc18415023f2b35", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+7033a174c11f5545c698494039ab0ed2bdb3f76c59e2f341cdc18415023f2b35", + "+b8dc1286429b54ed85859380c457b38108d078f3ef0178cd9fcff3ad992beb0e" + ] + } + }, + "signature": "30969361d40d0240a43afda79b97863aa4fe1f5c138fa770e3df1c4c24064aff398a5c002fbe1c7d48711ee21282bf36ab379fccd5a97bee43f20a2607b86608", + "id": "12524898016147040", + "senderId": "6885133969991843253L" + }, + { + "amount": "1000000", + "recipientId": "4869975650883480574L", + "senderPublicKey": "183899c3460f11352dee7071e421aca95ce7ec3a1416c665797a5db61b6e51f7", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "331a464a7123fa216913d5dce9dbc7ce95b2ab4171bb6c8295fc29f1612d4e3796c36a8990f26687f7ad1b859bb640dc3c3fc628f6bd37916cc6873177f2a406", + "id": "17391929534275735009", + "senderId": "4869975650883480574L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "183899c3460f11352dee7071e421aca95ce7ec3a1416c665797a5db61b6e51f7", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "32c70579c5e2963f2987cd7fc96dfc055d001c435b0476dd3711a1a968b7c70c" + } + }, + "signature": "834f36c233efa8af9ffbe1c8b88bc2bf13bfb3d599f5aa24063b9e64a3ea5c2f80fc040c064064c936a092bebfbbd7b4b45a5577d278bb459f795bff98be7908", + "id": "7351465186264064764", + "senderId": "4869975650883480574L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "183899c3460f11352dee7071e421aca95ce7ec3a1416c665797a5db61b6e51f7", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "patrol" + } + }, + "signature": "687b484889eda64e005df2bc15983d670f9e71b842a96716e94405254dda867c506c32fe75a2eb263b67641b0f87d981da997aab0e790510456d431b8856330c", + "id": "7228965334061013223", + "senderId": "4869975650883480574L" + }, + { + "amount": "0", + "recipientId": "4869975650883480574L", + "senderPublicKey": "183899c3460f11352dee7071e421aca95ce7ec3a1416c665797a5db61b6e51f7", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+183899c3460f11352dee7071e421aca95ce7ec3a1416c665797a5db61b6e51f7" + ] + }, + "signature": "07f9b4b39770c5cac147f925ca84b7317d98ae6229dbbe350b4b17e84776e9be643087b9800b1faecd3a904e4662e80c59fab228205aad9e3923773f382e9107", + "id": "7281221201899125500", + "senderId": "4869975650883480574L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "183899c3460f11352dee7071e421aca95ce7ec3a1416c665797a5db61b6e51f7", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+183899c3460f11352dee7071e421aca95ce7ec3a1416c665797a5db61b6e51f7", + "+32c70579c5e2963f2987cd7fc96dfc055d001c435b0476dd3711a1a968b7c70c" + ] + } + }, + "signature": "7575155bab0c175b1a31695cef13eb549ff314e82616deed1d2e4c8607bccf0175ca136a94b1db5250ae916c6c656f622d20fb1b08b58ff815289b913cf4330f", + "id": "14925052045578783357", + "senderId": "4869975650883480574L" + }, + { + "amount": "1000000", + "recipientId": "17382513943689513695L", + "senderPublicKey": "0024b96aa7172fc5d8e69b120cffc41ae5c817e2f8cc3ec0caaacfedef9c656d", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "9014e602e17b8dc0c0907e6849550e08715361514c991628d4378bcf135146b148c04c27ca4c16a94ad63fd08ca10dd7aa3ab5c20664f7951e260271c0631203", + "id": "9995054676557126854", + "senderId": "17382513943689513695L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0024b96aa7172fc5d8e69b120cffc41ae5c817e2f8cc3ec0caaacfedef9c656d", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e3628d9562b09139437f69f2013e8e1353e3ce7fe831ccc00471e09c6610e111" + } + }, + "signature": "0bfd999e4b182e071e89e9a50dddb33126f3fb4e2cc0f380554eaa4b58702cfb1ffefaefd5a38e1c833f61cdde048cd0cb33b630c5e5f82bd3ae865a41b4d107", + "id": "12757282079107432153", + "senderId": "17382513943689513695L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0024b96aa7172fc5d8e69b120cffc41ae5c817e2f8cc3ec0caaacfedef9c656d", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "record" + } + }, + "signature": "b5013d6c6004c36564925ae1c9c5cf4e2b4747ed1202d8fd96f7bcda5e213f268bba189664495e2b3f9ba6580e1481f703867a2c3956409f6ba9a74ceef07a06", + "id": "14258544998115852393", + "senderId": "17382513943689513695L" + }, + { + "amount": "0", + "recipientId": "17382513943689513695L", + "senderPublicKey": "0024b96aa7172fc5d8e69b120cffc41ae5c817e2f8cc3ec0caaacfedef9c656d", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+0024b96aa7172fc5d8e69b120cffc41ae5c817e2f8cc3ec0caaacfedef9c656d" + ] + }, + "signature": "3295e47b62388eb3395d2ada0a2e833686f4017ea64da5827609adf05ca970cc848ff446e7dbb8e24f127eb7d3e525fc3217d1c6d62f78142848b65d2e69ad0e", + "id": "9175962348795595662", + "senderId": "17382513943689513695L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "0024b96aa7172fc5d8e69b120cffc41ae5c817e2f8cc3ec0caaacfedef9c656d", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+0024b96aa7172fc5d8e69b120cffc41ae5c817e2f8cc3ec0caaacfedef9c656d", + "+e3628d9562b09139437f69f2013e8e1353e3ce7fe831ccc00471e09c6610e111" + ] + } + }, + "signature": "c46b4e431c5d7d7d718c03bc203c274c4039b5111b58b53a726d42240f094f555e8763bcb0172b2ce41a76a0cb962ba2d794a296e867b0defd2c01ff002db00b", + "id": "9041524685790727443", + "senderId": "17382513943689513695L" + }, + { + "amount": "1000000", + "recipientId": "8929885107192285804L", + "senderPublicKey": "de08d06bbc23118ad68b35d0e13013904cb0cd4f31672799507fd7584bda3623", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "029ab2c137e3dbaf6b67a5790692271577010bad0ab1032d1d3332f9933c1372ea518dc39aeca48df5795551a49bf0bf08631e736bdbae30aafbe12a136dea00", + "id": "11035175351134328686", + "senderId": "8929885107192285804L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "de08d06bbc23118ad68b35d0e13013904cb0cd4f31672799507fd7584bda3623", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "fce731c18ad4954344131edfa7c76277114305a376edadae9a779588b508db17" + } + }, + "signature": "f2460741a71eb744b93aab101619b485bd08d224a191f0be2d51079beb92594e64d3e57b069b3ddcd0f9365b49d3f503e23788214ac5499f154687b7c115ca05", + "id": "13036479657170914921", + "senderId": "8929885107192285804L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "de08d06bbc23118ad68b35d0e13013904cb0cd4f31672799507fd7584bda3623", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "black" + } + }, + "signature": "7dbe709da2218e6d3d5cc0c7305554cf718e10ec86260a8a946d9b92edf8c54b0cb7ae22bfdec74dc2a17df8d2973f70a6ae3ffc5a8cb477507c28efd1f03900", + "id": "3303394436166344575", + "senderId": "8929885107192285804L" + }, + { + "amount": "0", + "recipientId": "8929885107192285804L", + "senderPublicKey": "de08d06bbc23118ad68b35d0e13013904cb0cd4f31672799507fd7584bda3623", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+de08d06bbc23118ad68b35d0e13013904cb0cd4f31672799507fd7584bda3623" + ] + }, + "signature": "7e1caefca73d600acd3863253597ca0dbb6784824498c9fe22292d55e0b9f50ebe41701227ece016f269fdb786b1ff46334b416555919a67ba67c0765094e008", + "id": "14521495793047814734", + "senderId": "8929885107192285804L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "de08d06bbc23118ad68b35d0e13013904cb0cd4f31672799507fd7584bda3623", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+de08d06bbc23118ad68b35d0e13013904cb0cd4f31672799507fd7584bda3623", + "+fce731c18ad4954344131edfa7c76277114305a376edadae9a779588b508db17" + ] + } + }, + "signature": "c46913b8d601d4301b4a56485687d10deb10a832d89f4ba89c96ba85efc00b827d4d94e123f50c068b4ca35290ca09a0da6c1bc826eb21fb9723d999beffa107", + "id": "17990652371322251754", + "senderId": "8929885107192285804L" + }, + { + "amount": "1000000", + "recipientId": "12364889234919827602L", + "senderPublicKey": "1dc2e6bdefac86fc99098e43b627fccd0c45d246227b7533452251a5445c8fbc", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e284d5267d47308abaaeece62004702b3a0c8301d179d3a23094c9ad19d18acdcd3ab5a258670ee594bb21cecf571dec202bc1b4016ee0fa74321a06ba3fe704", + "id": "13215580320270670093", + "senderId": "12364889234919827602L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1dc2e6bdefac86fc99098e43b627fccd0c45d246227b7533452251a5445c8fbc", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9c5a5aed2b4553b3ef18f85481636613d5178c491ac4c0e8a4c21dc9cc55efcc" + } + }, + "signature": "f22bcf193108085b9a4359776eb469566648a9d2fa05f36ff93ae45375171a79c797f769b7b2fc397f54151c8dbe143b2031522635c7ba07adfdb4c48327c50f", + "id": "993761011459801939", + "senderId": "12364889234919827602L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1dc2e6bdefac86fc99098e43b627fccd0c45d246227b7533452251a5445c8fbc", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "add" + } + }, + "signature": "83990adb5c49bbda3fad4248865e961be2fd5bce73f9afa4972da16085972f366659b7e0eea77999e5ed7afa08925bb89d3f49a8c387c1204bf521eda4e5bf0e", + "id": "3609833885171214026", + "senderId": "12364889234919827602L" + }, + { + "amount": "0", + "recipientId": "12364889234919827602L", + "senderPublicKey": "1dc2e6bdefac86fc99098e43b627fccd0c45d246227b7533452251a5445c8fbc", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+1dc2e6bdefac86fc99098e43b627fccd0c45d246227b7533452251a5445c8fbc" + ] + }, + "signature": "fd2d892293d2c355c741092c7d476e46f677f42abd12e080c15015ebd6760a1acac6f002eaf77b14ad452c0b6fb2f627645f707f3a243a0a3e1516691421aa0c", + "id": "2146683489294336302", + "senderId": "12364889234919827602L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "1dc2e6bdefac86fc99098e43b627fccd0c45d246227b7533452251a5445c8fbc", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+1dc2e6bdefac86fc99098e43b627fccd0c45d246227b7533452251a5445c8fbc", + "+9c5a5aed2b4553b3ef18f85481636613d5178c491ac4c0e8a4c21dc9cc55efcc" + ] + } + }, + "signature": "181f25d3ab922fb9d51ae1c3c1625ae25eb464ab2196816af7fe85fd4eb9039e47b180b2d4c13240d687eb872111a78ea5053beb98484c3646d81f0594f7bb06", + "id": "6481310682950617299", + "senderId": "12364889234919827602L" + }, + { + "amount": "1000000", + "recipientId": "5057331965422499891L", + "senderPublicKey": "b2e6515135c4b88eb22ac948939debf9d0556623fdb418de1a9ae6db84ab978e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "bcc25200c7021b59d0677d15a38ca01b98d1d72dfbd3051aee1d29e8eb1bc5472062b7ed4f04d31b05d7490155bc9353aba9d27444fe6518f551a9830adede05", + "id": "4419921256735389386", + "senderId": "5057331965422499891L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b2e6515135c4b88eb22ac948939debf9d0556623fdb418de1a9ae6db84ab978e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "3961b7f72b9e942ab9f83e232c4a9cf76d8862048c826aefbb938e887b881704" + } + }, + "signature": "8c6a18b94b8c047986f99f66c115b7f9820aac71d58f57720c3f713ad494f1179e0df3e44d5eadbf4c4815384b469942f6913646c1d7ad5b9780ba6579c03b00", + "id": "6513979935341206216", + "senderId": "5057331965422499891L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b2e6515135c4b88eb22ac948939debf9d0556623fdb418de1a9ae6db84ab978e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "price" + } + }, + "signature": "5d098d7dde90b8d78d4451bf28d7025673e6a7c36443aa25c211873432e89458b857cde1bca21dc5ee88d390923538bebaea68133f4fdf3f74bdd03254a9d50f", + "id": "15610457050735846297", + "senderId": "5057331965422499891L" + }, + { + "amount": "0", + "recipientId": "5057331965422499891L", + "senderPublicKey": "b2e6515135c4b88eb22ac948939debf9d0556623fdb418de1a9ae6db84ab978e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+b2e6515135c4b88eb22ac948939debf9d0556623fdb418de1a9ae6db84ab978e" + ] + }, + "signature": "e59f6642027d1651318352d77c4942598f11452c4e1303cdb017ade4f1e0f17f682cfbfdd3496c36586ee7d0edff2dbf995b3d7787a260be878e67b6ffbd330c", + "id": "9039344760753503367", + "senderId": "5057331965422499891L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "b2e6515135c4b88eb22ac948939debf9d0556623fdb418de1a9ae6db84ab978e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+b2e6515135c4b88eb22ac948939debf9d0556623fdb418de1a9ae6db84ab978e", + "+3961b7f72b9e942ab9f83e232c4a9cf76d8862048c826aefbb938e887b881704" + ] + } + }, + "signature": "3a92a57cd9c5d5372e9b735628accf0b1908dddc4ea49cfa4bb43a982f88cd332fcfc635aacc49dfeeec9e5def8fa1b2141d7c22651e016b2544c2ab2696f706", + "id": "5018658948740898716", + "senderId": "5057331965422499891L" + }, + { + "amount": "1000000", + "recipientId": "2941105044814971087L", + "senderPublicKey": "40fa2c635eb91e0c857115a215822ae80c6129976705d5009298f8f5bfa7f90f", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "89bddbda79535873e4fb83125f24cbe5193059d4f0086845e99fa9096d981567884507d6c019a54ac98de3d89f96b8e0beea38bb15322b9b92a38dcfaebb580b", + "id": "6264558216743546070", + "senderId": "2941105044814971087L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "40fa2c635eb91e0c857115a215822ae80c6129976705d5009298f8f5bfa7f90f", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "83ae1ff680599034c99c85e57ae4f8645245164d5b759e3f1e0704e91e911e2a" + } + }, + "signature": "1f7a1bee804110e1c8f43d32afcda07eb0995e0da02372f7bad6d9701b849a2e77a09717cb7cf2c88807a0a63b5a4eb130e6c091998fe0848345a5ddfccd290f", + "id": "12210194352535017333", + "senderId": "2941105044814971087L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "40fa2c635eb91e0c857115a215822ae80c6129976705d5009298f8f5bfa7f90f", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "vanish" + } + }, + "signature": "9204b77a3d9e33c6e7e390d483f5ebc0031afba8e4d6df5a93a64461a24604e51c16fd7ccd5a10d8b6bc627be5a158ef816e2c2c1b5e6945ed068482a7f27500", + "id": "1951452286703327623", + "senderId": "2941105044814971087L" + }, + { + "amount": "0", + "recipientId": "2941105044814971087L", + "senderPublicKey": "40fa2c635eb91e0c857115a215822ae80c6129976705d5009298f8f5bfa7f90f", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+40fa2c635eb91e0c857115a215822ae80c6129976705d5009298f8f5bfa7f90f" + ] + }, + "signature": "d1714ad2cd6091136525b7cd5b8a6c6ceda6d761d6356585365833ef2cf848506ba2ec0c2c3aad514cd2a93bc7174c02da79ba523ac2cb25cc33945db1807005", + "id": "6935768816123957116", + "senderId": "2941105044814971087L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "40fa2c635eb91e0c857115a215822ae80c6129976705d5009298f8f5bfa7f90f", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+40fa2c635eb91e0c857115a215822ae80c6129976705d5009298f8f5bfa7f90f", + "+83ae1ff680599034c99c85e57ae4f8645245164d5b759e3f1e0704e91e911e2a" + ] + } + }, + "signature": "ba8f4ef1e636ee84b313c4e27cf22910275292b474921682f7c76b708262a55ef348b2fccac733a8bc29ff8458616c413fb485f946a2a0bd4540a66eb737b801", + "id": "15630431487075725736", + "senderId": "2941105044814971087L" + }, + { + "amount": "1000000", + "recipientId": "4460841135260728414L", + "senderPublicKey": "43c1e6bae29b779e3b8d8e8ce285aaa605025d7ce8879dd6e0ff4fcafb18a927", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e368922501c142aea504f160071a784a80ace6dd61480eb37f82d97baa7148496281ccc813fccfa50931600bf5f4a0a20421d681728030edb0a19b4eb3042102", + "id": "2689660414827892079", + "senderId": "4460841135260728414L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "43c1e6bae29b779e3b8d8e8ce285aaa605025d7ce8879dd6e0ff4fcafb18a927", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "9dc8e7581aa8a0de35c2a89f7b194dcb568d14f31622ce8efefc497a40641be3" + } + }, + "signature": "60fb824f915d2db0f3a34ed4bf544e6b9af0e25acf863f604fb52d797280657b27b6f696399c227d68fc5aeb18e35a7147461f20a8ffca7ca304726a11fa2f01", + "id": "1773540571762545557", + "senderId": "4460841135260728414L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "43c1e6bae29b779e3b8d8e8ce285aaa605025d7ce8879dd6e0ff4fcafb18a927", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "coach" + } + }, + "signature": "7f23fa718fad3ad42bde83d372ce885960e438e6ed9ac06024eae0ed8ca94cd18a5500bf672e6b14bb22ab34935356b9bc4e4d937fcbe663c0c7442751054601", + "id": "17659393810543911366", + "senderId": "4460841135260728414L" + }, + { + "amount": "0", + "recipientId": "4460841135260728414L", + "senderPublicKey": "43c1e6bae29b779e3b8d8e8ce285aaa605025d7ce8879dd6e0ff4fcafb18a927", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+43c1e6bae29b779e3b8d8e8ce285aaa605025d7ce8879dd6e0ff4fcafb18a927" + ] + }, + "signature": "08c579f6cca82764a351520902e5f43366095bbad6c44c207c60294e1cf59047093e9074b8dd529bac76c46f1c82854051642439618399bee726598fb584400a", + "id": "14618766165520868487", + "senderId": "4460841135260728414L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "43c1e6bae29b779e3b8d8e8ce285aaa605025d7ce8879dd6e0ff4fcafb18a927", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+43c1e6bae29b779e3b8d8e8ce285aaa605025d7ce8879dd6e0ff4fcafb18a927", + "+9dc8e7581aa8a0de35c2a89f7b194dcb568d14f31622ce8efefc497a40641be3" + ] + } + }, + "signature": "65b3c0ca35b950851e9bff6ea77687975b0feed1c62289a154cc05b0e075f3eba4be7f71fe9e1be9b76cef265011a3af87b375b1a9419a5447ab1cb2748d7e04", + "id": "164483807945233706", + "senderId": "4460841135260728414L" + }, + { + "amount": "1000000", + "recipientId": "11188995612554378488L", + "senderPublicKey": "8f52257c70d236b7874b8513b5a91b95e56d13fd500edc7153a0df9de6084868", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "5a180e5b14c7593d357f2968cf3ac23e292dbf77c2306f8c8dfcacbc72efd984d91270978e608b2686c2723e875248146172f99bbb624a63df7c22dce316e102", + "id": "10818385686784449006", + "senderId": "11188995612554378488L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8f52257c70d236b7874b8513b5a91b95e56d13fd500edc7153a0df9de6084868", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "b6e89ad34b5567e84e31b9a9e96c5b34533ec0811081960be957b2de40a42bea" + } + }, + "signature": "74c172cae3fb9f446a733d7b6155fee0690ffeddbfd327c861b417f8ae067c53598783f4784a6fc13df09b271675237fc2a3a2edcd4f272f081b141aa4de6806", + "id": "12973224838727763442", + "senderId": "11188995612554378488L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8f52257c70d236b7874b8513b5a91b95e56d13fd500edc7153a0df9de6084868", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "organ" + } + }, + "signature": "6431dfa5c43a6bd2afe20651f8b04f3216d92d648602e32f2be180e9056baf12622fa38a6846cd65b93364ac0bf7de41b331a39b53fa8a59c2cb6a68e72aa101", + "id": "1927256767307739565", + "senderId": "11188995612554378488L" + }, + { + "amount": "0", + "recipientId": "11188995612554378488L", + "senderPublicKey": "8f52257c70d236b7874b8513b5a91b95e56d13fd500edc7153a0df9de6084868", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+8f52257c70d236b7874b8513b5a91b95e56d13fd500edc7153a0df9de6084868" + ] + }, + "signature": "d10cbe47af09914121e4f799c400b9864ccd2f60b3547722dbbb5f55cd2fa8113f5df7840abdb69656418c7ff3ca94f39799a4df0e85059c5ffbf66ed0685704", + "id": "15364733461196987420", + "senderId": "11188995612554378488L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8f52257c70d236b7874b8513b5a91b95e56d13fd500edc7153a0df9de6084868", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+8f52257c70d236b7874b8513b5a91b95e56d13fd500edc7153a0df9de6084868", + "+b6e89ad34b5567e84e31b9a9e96c5b34533ec0811081960be957b2de40a42bea" + ] + } + }, + "signature": "ce62bb76b60f17dcd8236590e7f4d6c553bb16af6c2f4f1104084b009d13904f8d0d7e7d1a14bd86e395e75e554e3bca35b71e4d86e31087e643d03a0ac52d0e", + "id": "17260549755964133524", + "senderId": "11188995612554378488L" + }, + { + "amount": "1000000", + "recipientId": "1826426256229028807L", + "senderPublicKey": "e2559085f4922f53dd81de705667b7f354712645f47c4e4cfcf3c72c548fb782", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "95c8e7bfa5cc176966a0ee65356e8ca01eff0fc1c9f08f8dc21dc933e1527cbabb56f2b1f36fc29a2438691a290556b9a24cad59446caa982912db743cb53102", + "id": "14635399642997074780", + "senderId": "1826426256229028807L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e2559085f4922f53dd81de705667b7f354712645f47c4e4cfcf3c72c548fb782", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "462bbb18e4c0a2b12037bf4079ea58794c6eb329eb74c9e6609b0b18b8fb0f4d" + } + }, + "signature": "e2ecc063e8ae8f0d1f02a1b780b7d72387c4b2a77a9d79dff87e2e3208598677ee5e91d81828d253d7e4651d86d17781c0b9f4e00376b5b1c134b640b7ce2b0b", + "id": "7223233387875945404", + "senderId": "1826426256229028807L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e2559085f4922f53dd81de705667b7f354712645f47c4e4cfcf3c72c548fb782", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "pulse" + } + }, + "signature": "0407b2bfde9617993039f6b760d595d406c07403e6e3b7a73b88c3dd21fb6c06ec5b88575423ac3aa5fa1f80463b6a144e06f9ecc9d58410d79b97cf5365a10d", + "id": "18115072423565152668", + "senderId": "1826426256229028807L" + }, + { + "amount": "0", + "recipientId": "1826426256229028807L", + "senderPublicKey": "e2559085f4922f53dd81de705667b7f354712645f47c4e4cfcf3c72c548fb782", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+e2559085f4922f53dd81de705667b7f354712645f47c4e4cfcf3c72c548fb782" + ] + }, + "signature": "e8eaa20f64f3042f3964b1c51bbe5aa7a2adde0cb6bd05578f6c2304121bab1a5652be8f4589f0b23164294f5b68877f0af99beb7db03267e96e2be6b9b42f0c", + "id": "4409655331460701467", + "senderId": "1826426256229028807L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e2559085f4922f53dd81de705667b7f354712645f47c4e4cfcf3c72c548fb782", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e2559085f4922f53dd81de705667b7f354712645f47c4e4cfcf3c72c548fb782", + "+462bbb18e4c0a2b12037bf4079ea58794c6eb329eb74c9e6609b0b18b8fb0f4d" + ] + } + }, + "signature": "ee2df6d0ef8ca884cbb8655c133f7ace11d7b390726b667a143cd4fd805c94cfc50c5456438dd4b546ce79ec683052204261418e3a0bfbb1cef30f14bad6e909", + "id": "10730493187112223086", + "senderId": "1826426256229028807L" + }, + { + "amount": "1000000", + "recipientId": "3072337877364613825L", + "senderPublicKey": "886b3aca526b343e4cd9d31769dee3b364b22c9c229452f536e07388e3f1c9f7", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "2a53e1525a2955411ad38486cdef67421ecd76cbebef8eefef6e05a8760c660baef8d79b4ab51008638e6d7381c21a02472af0c53bc655c5eca2f8d1527cb60a", + "id": "11624422082092564102", + "senderId": "3072337877364613825L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "886b3aca526b343e4cd9d31769dee3b364b22c9c229452f536e07388e3f1c9f7", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "b223eaec7fec40ce4cdc24defffc926bd08e206f7329c29cd4fa0047aad6f648" + } + }, + "signature": "df5edfdc2c22582c8895a69553d259e20f1eee823f5c84a3d9ed5b119b925e63ef0a6978f65254414a12161449f2dc2f4aacaf28bd3c0336536e0877a2ade803", + "id": "12359644192906328246", + "senderId": "3072337877364613825L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "886b3aca526b343e4cd9d31769dee3b364b22c9c229452f536e07388e3f1c9f7", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "siege" + } + }, + "signature": "8c632fb7647b25e4bb3203a8fa02767b4b7303684e6a562cc2f7d69fb98b4110e25e254b749956873ed584af9cfa63e5d6725a09b821e15caa59ef7855d5af09", + "id": "16640860821190277355", + "senderId": "3072337877364613825L" + }, + { + "amount": "0", + "recipientId": "3072337877364613825L", + "senderPublicKey": "886b3aca526b343e4cd9d31769dee3b364b22c9c229452f536e07388e3f1c9f7", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+886b3aca526b343e4cd9d31769dee3b364b22c9c229452f536e07388e3f1c9f7" + ] + }, + "signature": "d2c44047607042cdbc73b54cb60f5614090f7cb836eed842203df32afbddc05df2b84bd6e3551002bff38cfdcf768f8fd5ec0db92524d7409f3be21997c72400", + "id": "60740728564309054", + "senderId": "3072337877364613825L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "886b3aca526b343e4cd9d31769dee3b364b22c9c229452f536e07388e3f1c9f7", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+886b3aca526b343e4cd9d31769dee3b364b22c9c229452f536e07388e3f1c9f7", + "+b223eaec7fec40ce4cdc24defffc926bd08e206f7329c29cd4fa0047aad6f648" + ] + } + }, + "signature": "730f792d961ff73867677aadedcc2bdd2f69a25f944099a79608b21a7c3dc04c8d286fea590e5d4fa9e826a77e4513d97748c1e136c98f56bd6577331e2d4f0c", + "id": "15916648962346321543", + "senderId": "3072337877364613825L" + }, + { + "amount": "1000000", + "recipientId": "1002722795512430133L", + "senderPublicKey": "a1e8b8965a25a06e51c99be2f903f7ecb32d07780c921c4c9f5bf1cd0f234e08", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a180ed9f9108836f0dfab77fe151f52f8c7951faca2a3114a5b36d0a2d12e0f4c6bc26ab7e3ae4e81ccd44a7e3f92f37683b50fbb14d410c3b7aa4b3593eb903", + "id": "6669836998972882919", + "senderId": "1002722795512430133L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a1e8b8965a25a06e51c99be2f903f7ecb32d07780c921c4c9f5bf1cd0f234e08", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "835dbd142723fff4ac6a67c4f18afd52023029507f2bf6462698aa01540b3c43" + } + }, + "signature": "2dadb098c26390f039a8ceb410987dbb98aff3a36576c9818f9966cea696b0cb3c57ab10b5d7d0a17727746b7f2ed9a0050b3943c3704e5a7f868c8f8c245a03", + "id": "10256339623652779206", + "senderId": "1002722795512430133L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a1e8b8965a25a06e51c99be2f903f7ecb32d07780c921c4c9f5bf1cd0f234e08", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "police" + } + }, + "signature": "e2f73329fe6337a005c7cfcca404113101c41c9e032dde9989ca54aa3a2aea1c860babc290ded54c9e67dc2f0eb04c80a1305ca0745eb6daf9278ecbeb23bd01", + "id": "10896022186792689496", + "senderId": "1002722795512430133L" + }, + { + "amount": "0", + "recipientId": "1002722795512430133L", + "senderPublicKey": "a1e8b8965a25a06e51c99be2f903f7ecb32d07780c921c4c9f5bf1cd0f234e08", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+a1e8b8965a25a06e51c99be2f903f7ecb32d07780c921c4c9f5bf1cd0f234e08" + ] + }, + "signature": "7d0e84bf92f3083b8a05fa7696b86e31af714f20c2686610e345fe7751264a3604a44cc4f2a96d801a591ff89464ae312bdb1ef88228f5a2a95a010d7cf67806", + "id": "8251553768039089764", + "senderId": "1002722795512430133L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "a1e8b8965a25a06e51c99be2f903f7ecb32d07780c921c4c9f5bf1cd0f234e08", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+a1e8b8965a25a06e51c99be2f903f7ecb32d07780c921c4c9f5bf1cd0f234e08", + "+835dbd142723fff4ac6a67c4f18afd52023029507f2bf6462698aa01540b3c43" + ] + } + }, + "signature": "871dd30839186727a3263c0d803b04bd72f1f2180eb0ed46ab4fd2b6f1e75ddab13ff2ef0783dfd1aaa64a298d9af8cfda463f41fc2d88aab965138826e6330c", + "id": "6993452257378664810", + "senderId": "1002722795512430133L" + }, + { + "amount": "1000000", + "recipientId": "7564039508345962387L", + "senderPublicKey": "ed9511d396bf4297989dbee7a0317d7a074696588425f170b019430cae7b06a2", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "a9fd1d24189192368971afcb695c3767589ca71106a234b9d6fe8600b64866e95e778d3b59a90dcc134899754180100d710effeb351a7d82ba24707c29c44c03", + "id": "5985121209172421001", + "senderId": "7564039508345962387L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ed9511d396bf4297989dbee7a0317d7a074696588425f170b019430cae7b06a2", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "1c327d6297446f4628fab22fb83d95a564bebbd6a043e4d3878a3e3456cb56bf" + } + }, + "signature": "c84213c0ae092a09f5c9c2ec862691e2795543193e47ff0e95aa400cf2508575147bda5f67916e2ca741a2036f87be831cb6481a197832adf2abd73b61dcad0d", + "id": "685904244833244378", + "senderId": "7564039508345962387L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ed9511d396bf4297989dbee7a0317d7a074696588425f170b019430cae7b06a2", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "escape" + } + }, + "signature": "fcc9bcb981edfb802ab6d4cfd3be83cf7e960bad4b205faa8ee48838f681f0ac433fab52ed994ad461e127ce0c1e775318cdecc93784bbc47308bda1523a1504", + "id": "4544530557153709049", + "senderId": "7564039508345962387L" + }, + { + "amount": "0", + "recipientId": "7564039508345962387L", + "senderPublicKey": "ed9511d396bf4297989dbee7a0317d7a074696588425f170b019430cae7b06a2", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+ed9511d396bf4297989dbee7a0317d7a074696588425f170b019430cae7b06a2" + ] + }, + "signature": "19a449fcfc7bcbd9e528a334937970728eb536e29a8bd5964a07b189c1f44335f1f580180ad14f1a88b5ad38b71806fd6625e9d64c1b261488c16b8ca6d50b00", + "id": "12049466611839317417", + "senderId": "7564039508345962387L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "ed9511d396bf4297989dbee7a0317d7a074696588425f170b019430cae7b06a2", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+ed9511d396bf4297989dbee7a0317d7a074696588425f170b019430cae7b06a2", + "+1c327d6297446f4628fab22fb83d95a564bebbd6a043e4d3878a3e3456cb56bf" + ] + } + }, + "signature": "0d697803b4f3562f1c9f366e878bc1d2f9225e7c934b01e345abd78e88007b7ffc8e053823a38ee8ce1975e7a8be641c71119b9cb222b6f302be174deb615c04", + "id": "17536780705019511293", + "senderId": "7564039508345962387L" + }, + { + "amount": "1000000", + "recipientId": "8477594334433202442L", + "senderPublicKey": "282ea999ff65eb19b18217635a1e022ce5e7718b0ddce8286163eb7f4bcaea25", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "d6cd6960146d82509e6fa7218fa43246598d79a31f148facdea5032215d0ec8619f14850ca14bfb6e815b518b8a1dbf51482971ba1ec53af8e0fcd70cbd0e206", + "id": "6821676372184450631", + "senderId": "8477594334433202442L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "282ea999ff65eb19b18217635a1e022ce5e7718b0ddce8286163eb7f4bcaea25", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f30495ca295cce2fd383d64110c6fd6fb357c00b55c6740fc4f80ba0e47772ae" + } + }, + "signature": "ccd00b139e3516fcb3811efd862a3228210f57178d9f9d7f54af10611e70b2cd89fec64aea3fd55a986faa5ddba1b8bf265ae60f2eac544db2bd2d1fa6d6a204", + "id": "5042461983663400415", + "senderId": "8477594334433202442L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "282ea999ff65eb19b18217635a1e022ce5e7718b0ddce8286163eb7f4bcaea25", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "omit" + } + }, + "signature": "af44135580e5de070a5e2ab6aef5ca46cdbd0c0c612d3961465e8f3cf67ad127ca8be70351eb14f14f0da30403f97dbb50065406b9aee53c66036b49ec7b3107", + "id": "13148231087343703916", + "senderId": "8477594334433202442L" + }, + { + "amount": "0", + "recipientId": "8477594334433202442L", + "senderPublicKey": "282ea999ff65eb19b18217635a1e022ce5e7718b0ddce8286163eb7f4bcaea25", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+282ea999ff65eb19b18217635a1e022ce5e7718b0ddce8286163eb7f4bcaea25" + ] + }, + "signature": "6d78458bb2a8d53cc88d8c4ab9a8d28e950e3c299373907648be40c5f13d6aefe8a926840e47a95ca20e6fd5af2e97d8136da064fd9623d33bb1d174e0800701", + "id": "5136137954712412349", + "senderId": "8477594334433202442L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "282ea999ff65eb19b18217635a1e022ce5e7718b0ddce8286163eb7f4bcaea25", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+282ea999ff65eb19b18217635a1e022ce5e7718b0ddce8286163eb7f4bcaea25", + "+f30495ca295cce2fd383d64110c6fd6fb357c00b55c6740fc4f80ba0e47772ae" + ] + } + }, + "signature": "9084bf1ce2b1d8cbc20990cfe86fc1ddcbf0c483be52cac712620fab9b5535a2043a5dc9601e59228c2c1f7ac948d82faa19e7b47c5464b13b80719cd5d81a05", + "id": "14071316546059000581", + "senderId": "8477594334433202442L" + }, + { + "amount": "1000000", + "recipientId": "10061339281844477568L", + "senderPublicKey": "7e3a99b599d37024e47313a03b2522cdb238d5c82ca2895d65ccc9063138c643", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "e25d2a0eb68b603376adf1d2ce089b983626791c94797cfc667b52e1264d47697cabefaa1a015cb12777fc2849f92be39f3cdd428f31e1a0d581242d55b53c0f", + "id": "7094892622809447126", + "senderId": "10061339281844477568L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7e3a99b599d37024e47313a03b2522cdb238d5c82ca2895d65ccc9063138c643", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "cca5bfae773476fa06c356c6d4460033c9654cce44d622b69fca8d35ca857c77" + } + }, + "signature": "118cc02b0188f1a1071f23239eac96841ff1915e9981953acb0b671a806c949e5af84e34fb17c06c9661aaa8237cbeff070726801972f00b7147ded8b2de0204", + "id": "18387897363372932983", + "senderId": "10061339281844477568L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7e3a99b599d37024e47313a03b2522cdb238d5c82ca2895d65ccc9063138c643", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "tongue" + } + }, + "signature": "ae49cdd06dbd00e4e79261028598a6faf039eb145cb4934d694b31b287af03dd76428c780524eabab21b9ef7a3550b27f0a8aa9a4f64a94e43ba24c627e1d902", + "id": "14965463276208605711", + "senderId": "10061339281844477568L" + }, + { + "amount": "0", + "recipientId": "10061339281844477568L", + "senderPublicKey": "7e3a99b599d37024e47313a03b2522cdb238d5c82ca2895d65ccc9063138c643", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+7e3a99b599d37024e47313a03b2522cdb238d5c82ca2895d65ccc9063138c643" + ] + }, + "signature": "3dc767d7a8830f7f6dfb858ce75cea66f8968ba022e4dd394a174b338a6cb2cea1654d8337d3ea2e8d8d0f5a8eabe763bea37c29fff635a5931f115e5806f303", + "id": "9364691692314196451", + "senderId": "10061339281844477568L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "7e3a99b599d37024e47313a03b2522cdb238d5c82ca2895d65ccc9063138c643", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+7e3a99b599d37024e47313a03b2522cdb238d5c82ca2895d65ccc9063138c643", + "+cca5bfae773476fa06c356c6d4460033c9654cce44d622b69fca8d35ca857c77" + ] + } + }, + "signature": "2ba43996aaf83358819cf7cfca358da271bd0d5e2c0f809f5d17fe138b28d3d2e444a4dbd252bdfdfddef0ba2259a4fba677b2f79e1f2d76c1fe4d3048612402", + "id": "2230406522950956612", + "senderId": "10061339281844477568L" + }, + { + "amount": "1000000", + "recipientId": "10973533420696678447L", + "senderPublicKey": "96ded1032028cd008d35c7230a638bff13455b36781574a9f22bab09aad1717b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "22d881dd464909a4acc8d78db72a4d29e5f503dcdf0c41f2c3f9bdfad4ba008579f164e5cb66fd94ae21cf1533ac6cae4a6290cb96d4436dee6cec532098a906", + "id": "1542381059352559910", + "senderId": "10973533420696678447L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "96ded1032028cd008d35c7230a638bff13455b36781574a9f22bab09aad1717b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "f1d6e3462aad115e9ca1083a32f46e6a23d2b428352529df767417400cf4b1a0" + } + }, + "signature": "b7f832d62c162dcbaa4f1bbcb5f6d2e81cf451024e08501209260f55fdd0daec8a3e473ee1361aeb386807d0259fc5a8b24bb5396940564911a0c5ddc07a5f0c", + "id": "10943907311935841810", + "senderId": "10973533420696678447L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "96ded1032028cd008d35c7230a638bff13455b36781574a9f22bab09aad1717b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "math" + } + }, + "signature": "a5ea3d600bf43bc3feb7c315dfb894529896c6deec6b9b492240768c958f7ef0d693822a9a3df5f4c57fbf4b67c8d52c17b04b16c4d30ebf4613ad37f2980402", + "id": "15209885307031770825", + "senderId": "10973533420696678447L" + }, + { + "amount": "0", + "recipientId": "10973533420696678447L", + "senderPublicKey": "96ded1032028cd008d35c7230a638bff13455b36781574a9f22bab09aad1717b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+96ded1032028cd008d35c7230a638bff13455b36781574a9f22bab09aad1717b" + ] + }, + "signature": "a01033ec22ba500c3a1b284651bf9fc33fd11affafbfc1cdacb787bf4a8287ec340fcc3e632330192deeeae74778a534b71ffd78886ba24f16c2fae55b5de701", + "id": "6214456926504622282", + "senderId": "10973533420696678447L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "96ded1032028cd008d35c7230a638bff13455b36781574a9f22bab09aad1717b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+96ded1032028cd008d35c7230a638bff13455b36781574a9f22bab09aad1717b", + "+f1d6e3462aad115e9ca1083a32f46e6a23d2b428352529df767417400cf4b1a0" + ] + } + }, + "signature": "8b0196799625fb979da3369b8017a8dbd1504622d7afdb38300a8ce80e4d7b6b80369ee7dc446d325e53418c04b49e1e7a28e524f0c4b94c2e962aafd42cdf02", + "id": "16861268585493474617", + "senderId": "10973533420696678447L" + }, + { + "amount": "1000000", + "recipientId": "17205056432162668840L", + "senderPublicKey": "479b97219706ccf76d3516d4da104c9a4cfdb22a8b87bf3a3b1b09379e6a474d", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "c84e9b086c5d4f54ce228e57b783bac17fa3d5970933a31fcebf344eff7f3b43f289c82b7d07b1eb1bcee28c6ff2b939db764c28e7c5bc4918e5fda9e3ce6901", + "id": "15002185682441461561", + "senderId": "17205056432162668840L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "479b97219706ccf76d3516d4da104c9a4cfdb22a8b87bf3a3b1b09379e6a474d", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "51e180eb2b00f7c58ef1a6ecf4c98de33856b61def046a95480f75390c4d4f2a" + } + }, + "signature": "96b21d4f3360020533ff2d4a34ea36c4c5f6573ba2483287134d4c61409cf21012a9b08b72f2a4376340c7f55c3e271190b3b01eef887d951f80bfac3f87aa0e", + "id": "3989314527496592693", + "senderId": "17205056432162668840L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "479b97219706ccf76d3516d4da104c9a4cfdb22a8b87bf3a3b1b09379e6a474d", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "guard" + } + }, + "signature": "005f957ce8b20238078f184a16e6e03cecb66ff66e242e13284d939463a74c9da4a46cb595a674f4fb5696d085b33f24279141dd985107c0aa7dd02493bf7e0e", + "id": "8056681700380558415", + "senderId": "17205056432162668840L" + }, + { + "amount": "0", + "recipientId": "17205056432162668840L", + "senderPublicKey": "479b97219706ccf76d3516d4da104c9a4cfdb22a8b87bf3a3b1b09379e6a474d", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+479b97219706ccf76d3516d4da104c9a4cfdb22a8b87bf3a3b1b09379e6a474d" + ] + }, + "signature": "b204efc17c8e20adbc4745c29a66dbe2197bc03fbabf12460465a6e802104365758f00519333714122a9102f3dc613dab586cbdf37cce3c37de53321a557bf0c", + "id": "1885772857902900367", + "senderId": "17205056432162668840L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "479b97219706ccf76d3516d4da104c9a4cfdb22a8b87bf3a3b1b09379e6a474d", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+479b97219706ccf76d3516d4da104c9a4cfdb22a8b87bf3a3b1b09379e6a474d", + "+51e180eb2b00f7c58ef1a6ecf4c98de33856b61def046a95480f75390c4d4f2a" + ] + } + }, + "signature": "c0cdd4a3e7ac9240e7959824ed7c6e33c0f8a6436878b892528fc44984ce156710d7e03c863bd5702363d0466b9ab2de1d3e2002474ca4711be5869a54dabe07", + "id": "13691233082754294214", + "senderId": "17205056432162668840L" + }, + { + "amount": "1000000", + "recipientId": "1831426387655050045L", + "senderPublicKey": "8fd89d17ce266427ff7fb1b3a283ff913404f4f24d0ea5709815b31ce4602c08", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ae97ee02a59010b43d7b29e6bd67fe57c69f51c9a77dd230f596e9d1df57089904864705a0544dc966cbe5924f36069e03c8f868e391fbcb881fcca6905e3504", + "id": "15217784168167405701", + "senderId": "1831426387655050045L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8fd89d17ce266427ff7fb1b3a283ff913404f4f24d0ea5709815b31ce4602c08", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "2b15f099745376d65bce7088e77308b048ad646eeb6e7d31eb129944c74e0b8d" + } + }, + "signature": "8578c88d485ea0093aa3d7355261f6841e6825c24f8f08d8992a85310b063707832fc7462b37ce4832dc38477c992908d93db9cb9568d27b448fce2275b78202", + "id": "14319689311399312779", + "senderId": "1831426387655050045L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8fd89d17ce266427ff7fb1b3a283ff913404f4f24d0ea5709815b31ce4602c08", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "book" + } + }, + "signature": "bbc50c7ccadb0cc3ab16fac6e4b5e5f04fd846bea318a9afd253430b16e6d45ae2e1cb7d6b70d278e2cdd0933b517657da0189b4fc89d8b39a1eb3f1433f6e0a", + "id": "19864372871737934", + "senderId": "1831426387655050045L" + }, + { + "amount": "0", + "recipientId": "1831426387655050045L", + "senderPublicKey": "8fd89d17ce266427ff7fb1b3a283ff913404f4f24d0ea5709815b31ce4602c08", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+8fd89d17ce266427ff7fb1b3a283ff913404f4f24d0ea5709815b31ce4602c08" + ] + }, + "signature": "af3d285397a15c91b80f96e3215d2ccb67e188888eccc5882ae91461d125018649c874caac52c292575dcedb62bd60d4d34c22f68d26d4023f440e5d9771ed09", + "id": "10054009123920384402", + "senderId": "1831426387655050045L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "8fd89d17ce266427ff7fb1b3a283ff913404f4f24d0ea5709815b31ce4602c08", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+8fd89d17ce266427ff7fb1b3a283ff913404f4f24d0ea5709815b31ce4602c08", + "+2b15f099745376d65bce7088e77308b048ad646eeb6e7d31eb129944c74e0b8d" + ] + } + }, + "signature": "6fa1c7be30ecad19067a819af72768c258e8c5a66178e722e4720b5907a82fc308456786f9b265c8fd08da2e1bcfdf7a1939b7f266dfc035a975eba1058a0a00", + "id": "2857302507364614819", + "senderId": "1831426387655050045L" + }, + { + "amount": "1000000", + "recipientId": "2623645469004101929L", + "senderPublicKey": "f24ab602f4424a1fffc754e7492e174185a08c7b06a6b7ed4c8d1bbfcde00d50", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "d48019a788cffd8a72440ee019e601f5f40296666ad87c54552755df5966081651f363f5f6b943910ba60bca4093d2e61e9b0dc1720eaa049cc78cb19899420c", + "id": "7450126652623253184", + "senderId": "2623645469004101929L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f24ab602f4424a1fffc754e7492e174185a08c7b06a6b7ed4c8d1bbfcde00d50", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "eea2c261c17abc58f2d68407593fcd325e0778e6dde0cc2ec69aa539b3757b3d" + } + }, + "signature": "723e959646144f8663582051cb71d5959e25c73588ad7a27bbb8e8d620fee908a794da408ac357fa3e872d688e7bef85db3e626f5a7604942b6a02e54db9750e", + "id": "5674255741168586718", + "senderId": "2623645469004101929L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f24ab602f4424a1fffc754e7492e174185a08c7b06a6b7ed4c8d1bbfcde00d50", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "seven" + } + }, + "signature": "5bc365f78ab34c775a6a5e36c2ea170344391820388b1ac158bf671313eae0ea93e4cb8fba909fe7aa8e359ceac9b86b55ea5559efb24d7317288dfc8bf94300", + "id": "1020100825974838144", + "senderId": "2623645469004101929L" + }, + { + "amount": "0", + "recipientId": "2623645469004101929L", + "senderPublicKey": "f24ab602f4424a1fffc754e7492e174185a08c7b06a6b7ed4c8d1bbfcde00d50", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f24ab602f4424a1fffc754e7492e174185a08c7b06a6b7ed4c8d1bbfcde00d50" + ] + }, + "signature": "3500cda9d90d22ce244c8a8a1fea551156fd18825ec12e775c959c45bb65492f62191bccef68e49b57b88ac258cd44c3f97f95b2396f1127fa59bb5111324b00", + "id": "12837573413164615111", + "senderId": "2623645469004101929L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f24ab602f4424a1fffc754e7492e174185a08c7b06a6b7ed4c8d1bbfcde00d50", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f24ab602f4424a1fffc754e7492e174185a08c7b06a6b7ed4c8d1bbfcde00d50", + "+eea2c261c17abc58f2d68407593fcd325e0778e6dde0cc2ec69aa539b3757b3d" + ] + } + }, + "signature": "79f3e1d0f3d6517c5d4bdf83acc6fbfd150f6fef02a7555090841f3a809e2f11bc1a576f4116e4dbd7412b3f61a7132662634630c22834e72ac31918f1973d08", + "id": "2342055033643780753", + "senderId": "2623645469004101929L" + }, + { + "amount": "1000000", + "recipientId": "8813059541939740410L", + "senderPublicKey": "c8fa24fed9c52d2cd1db8518690d81710918f64165f8d6ed2d0577f829c4a89b", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "ac3741ffee8d31dd6d089e1ea22705e8010bb8c251b2c4e4d9e43578bc60b32c455579214da71320b651a983884754156ee6c8b56cbf3968d71d37f3d8904f07", + "id": "10274397593856828347", + "senderId": "8813059541939740410L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c8fa24fed9c52d2cd1db8518690d81710918f64165f8d6ed2d0577f829c4a89b", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "e319282bae075bbaeb299db07bd6dd64b2c1423684b9bcd615a3376f999a3cbd" + } + }, + "signature": "98f39aa8b680e4ef4e5ca2cc30fa57c797f6fc45232adc54af62cdb1e2e605d422196e369f44fd0248bd4ed7ed295224847e8e6f33fdacf36e8d4a73c776c00f", + "id": "7942740933250950449", + "senderId": "8813059541939740410L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c8fa24fed9c52d2cd1db8518690d81710918f64165f8d6ed2d0577f829c4a89b", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "oak" + } + }, + "signature": "d405a95c49b818fce13f55e56763a70fa15decf5d041bf37ce74cb106daed4248ea391c34d6769633f83de91dbdd5338df0b294fdae255615484cf84e4ee9f0b", + "id": "2454301977090527386", + "senderId": "8813059541939740410L" + }, + { + "amount": "0", + "recipientId": "8813059541939740410L", + "senderPublicKey": "c8fa24fed9c52d2cd1db8518690d81710918f64165f8d6ed2d0577f829c4a89b", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+c8fa24fed9c52d2cd1db8518690d81710918f64165f8d6ed2d0577f829c4a89b" + ] + }, + "signature": "45f3a27d201748fc7a4c7d520b90e3f00efda337640f8d6a4a14f906cc55995ada20bb6327ac7e64e1fc8a543aa9ab07a248d6cf547b6cf25f3b27b11c9aa80a", + "id": "14709800610476028207", + "senderId": "8813059541939740410L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "c8fa24fed9c52d2cd1db8518690d81710918f64165f8d6ed2d0577f829c4a89b", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+c8fa24fed9c52d2cd1db8518690d81710918f64165f8d6ed2d0577f829c4a89b", + "+e319282bae075bbaeb299db07bd6dd64b2c1423684b9bcd615a3376f999a3cbd" + ] + } + }, + "signature": "eee9e383313210c2b01a712d6307218f1135770fbadcee9806a187feb9e31a22ae23780d2b712bf6f4359f4fe3589384ca4d7bc6cc66cfb36a9ca8952c239106", + "id": "17188612320675359193", + "senderId": "8813059541939740410L" + }, + { + "amount": "1000000", + "recipientId": "13371311846687282017L", + "senderPublicKey": "e4a393e77e15b016036964854dbad19384296414ae015d0023e22dde2b20d2ac", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "68a5192a5f716bfd473e0b3a638ee75328b98c76bba6532c126842d40a4b75deba8f6cef27c9d4e501012ebd217965b401a23081d28bb34263724f7effa8430d", + "id": "7563357969678701789", + "senderId": "13371311846687282017L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e4a393e77e15b016036964854dbad19384296414ae015d0023e22dde2b20d2ac", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "901810e0f89136bb052177348b7a551f64335d593b53beceb0982f5731954c6e" + } + }, + "signature": "5f9ede72ef857efa1b318c7400a82079eb7453712d7747caa646bfddc9007752106fcb38837948cdc5fecb0062a96179dc579feb6f63786a2de5b635f470fe09", + "id": "3144844964732977830", + "senderId": "13371311846687282017L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e4a393e77e15b016036964854dbad19384296414ae015d0023e22dde2b20d2ac", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "laundry" + } + }, + "signature": "7212cf6374ebc4d85ef692cb9fcd76151db9dbb136b79bd677666558da1c4b3615a4e8a7329aa49b6b8d73be6a4f9699d6a775e4613c6ea0abd23c373f651c06", + "id": "1956639072773941812", + "senderId": "13371311846687282017L" + }, + { + "amount": "0", + "recipientId": "13371311846687282017L", + "senderPublicKey": "e4a393e77e15b016036964854dbad19384296414ae015d0023e22dde2b20d2ac", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+e4a393e77e15b016036964854dbad19384296414ae015d0023e22dde2b20d2ac" + ] + }, + "signature": "4f2343d5a6bdfb3a68354a6c3817ab45e7979c5757a5ef8dc1da599bba9733cd09cf1777074235eef7fb6563bc6843b910f93d10cfc36d3c7d987555a730060d", + "id": "5270076710138655963", + "senderId": "13371311846687282017L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "e4a393e77e15b016036964854dbad19384296414ae015d0023e22dde2b20d2ac", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e4a393e77e15b016036964854dbad19384296414ae015d0023e22dde2b20d2ac", + "+901810e0f89136bb052177348b7a551f64335d593b53beceb0982f5731954c6e" + ] + } + }, + "signature": "05884605267e6280491cb2655c6762684b031f5cd5a12bd8a2c800edff9c5b13ee7df7c0fddd8b60d9f5a816b36cace05fe2237010120b1476214e74cf611506", + "id": "2340951844234651976", + "senderId": "13371311846687282017L" + }, + { + "amount": "1000000", + "recipientId": "3539294500270642084L", + "senderPublicKey": "f6ff6be887b6f4cc07c6d71dc95aa7bfe9aa888a4c998ca04ef10ecbefd06e5e", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "f17aeb66404bbfbdc704477dfbee5036310258cd4eeff1d3b88df4d192891be736a58756095a6949bb514dcd38e71e77813522e32e6d16e320b89caf6467a104", + "id": "3331917776977206725", + "senderId": "3539294500270642084L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f6ff6be887b6f4cc07c6d71dc95aa7bfe9aa888a4c998ca04ef10ecbefd06e5e", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "768497bd9f8b073e377546e6d3b12bb4f394a443c7a234adb7ca667e42f2d969" + } + }, + "signature": "01cffc7d032a34477a6175bd82603cd3dfe4583939f0714d2721def3b0a7f24a19145c189509f66f6ce69e01103e280a0f2e5177ff200c4be34432077f2b330c", + "id": "9522663232524718794", + "senderId": "3539294500270642084L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f6ff6be887b6f4cc07c6d71dc95aa7bfe9aa888a4c998ca04ef10ecbefd06e5e", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "avocado" + } + }, + "signature": "d0789ab23ea4ea6df8b546ae0aa86282e475f559bd49a5ab6ecec8353e8d68da3f6a1949ad50026e23953190addb407799b6793e885dd616481265d7814ecf04", + "id": "5893583769888232787", + "senderId": "3539294500270642084L" + }, + { + "amount": "0", + "recipientId": "3539294500270642084L", + "senderPublicKey": "f6ff6be887b6f4cc07c6d71dc95aa7bfe9aa888a4c998ca04ef10ecbefd06e5e", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+f6ff6be887b6f4cc07c6d71dc95aa7bfe9aa888a4c998ca04ef10ecbefd06e5e" + ] + }, + "signature": "9a195fdfd38d49dda328285f1ffe072188ecc9538e6ea4c468b034915f0026c31ba244196e57d25046615bad1f3d84a8c44476034d616e0031a624ce249aa000", + "id": "13286881088863974765", + "senderId": "3539294500270642084L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "f6ff6be887b6f4cc07c6d71dc95aa7bfe9aa888a4c998ca04ef10ecbefd06e5e", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+f6ff6be887b6f4cc07c6d71dc95aa7bfe9aa888a4c998ca04ef10ecbefd06e5e", + "+768497bd9f8b073e377546e6d3b12bb4f394a443c7a234adb7ca667e42f2d969" + ] + } + }, + "signature": "ac0377a91f4242f52671a17e707198e23cf28b2a5099d7b2757d789414366b3e6aae0bb0fe8e6b489dd2298b171cf0d99a56aebf754a5b5bdb2b552649cc360c", + "id": "523307651810676467", + "senderId": "3539294500270642084L" + }, + { + "amount": "1000000", + "recipientId": "1059049099930719314L", + "senderPublicKey": "26fbfbf00c45e24e49bc9dd94c08b60a0e5330c3527753e5e56de2baf591f953", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "171203cb0dcccdf6508deb1069c01993c86f7ec6f87c1fa191426eee6e8d75a03fe065cef23a15b34e1cb47b2e0c8c0403ee3c5c21f6bc207834c5c4b1ca9008", + "id": "3654579887653884318", + "senderId": "1059049099930719314L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "26fbfbf00c45e24e49bc9dd94c08b60a0e5330c3527753e5e56de2baf591f953", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "30cb2537b27d9804bee84b50f7df92226223be76db85ab2b58085e6f63e42a3f" + } + }, + "signature": "24682644c5f0ce99e0f0da1982d218a4bce9af48277cb3ada6c6bf297ebbea2e4194657be89111f9442dab35052c3f62ea3cd06f3507321fbed4a811fcf4ce0e", + "id": "5176106613867311770", + "senderId": "1059049099930719314L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "26fbfbf00c45e24e49bc9dd94c08b60a0e5330c3527753e5e56de2baf591f953", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "desert" + } + }, + "signature": "6a0aca029675306dab898a2edf026b99900184b4f7a523b74800dc23dfe4009dde031b6c0e4bf14062882a5461497b4d590da137b3faadbcf6f232fcde68f40b", + "id": "12208618646357630434", + "senderId": "1059049099930719314L" + }, + { + "amount": "0", + "recipientId": "1059049099930719314L", + "senderPublicKey": "26fbfbf00c45e24e49bc9dd94c08b60a0e5330c3527753e5e56de2baf591f953", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+26fbfbf00c45e24e49bc9dd94c08b60a0e5330c3527753e5e56de2baf591f953" + ] + }, + "signature": "64de51b3f90b61cf93d860d374f2c98d3c9e4e278fff12b5e27e3175b3146b5c7af123d0a836ee94b3c854356ca44f7e92320de257279d9829f7787c8f7d6f08", + "id": "11807800525920249862", + "senderId": "1059049099930719314L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "26fbfbf00c45e24e49bc9dd94c08b60a0e5330c3527753e5e56de2baf591f953", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+26fbfbf00c45e24e49bc9dd94c08b60a0e5330c3527753e5e56de2baf591f953", + "+30cb2537b27d9804bee84b50f7df92226223be76db85ab2b58085e6f63e42a3f" + ] + } + }, + "signature": "d0f15926806e7854e6d23e9188a2b17bddf6916b55172339f78d96702f64c38d1a247caf82c6e5525a9daea04ffd5303b8cafbf43028f43ffb648cf9c5bac106", + "id": "15478541557031355573", + "senderId": "1059049099930719314L" + }, + { + "amount": "1000000", + "recipientId": "13626916270102280476L", + "senderPublicKey": "68c538b6b9ed2ec8b1938a3456a2d237629e991bdc9d9880fefbdc43e13c3607", + "timestamp": 83529114, + "type": 0, + "fee": "10000000", + "asset": {}, + "signature": "203cd934e8555f28696e7967d82ae0ed9972056891297f71b967a103bb896b3d122b6df260b33669524ea7886fab7367ea7b0a20e0d850a095a29debb5b04d06", + "id": "10131139122195844017", + "senderId": "13626916270102280476L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "68c538b6b9ed2ec8b1938a3456a2d237629e991bdc9d9880fefbdc43e13c3607", + "timestamp": 83529114, + "type": 1, + "fee": "500000000", + "asset": { + "signature": { + "publicKey": "b0b626b6cfcba98c2dcc3a55964302f1bbdee2bac6aa2c127fc394b16c6c800c" + } + }, + "signature": "2a87a94cd34d8e263d2513a04e76c6333a34dc7568e0b44ad6ad4d5a45cc15196e1d6751e36024cf466eeea74720c4469420f3da8f066864dde1308cfe356406", + "id": "3325067498077101482", + "senderId": "13626916270102280476L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "68c538b6b9ed2ec8b1938a3456a2d237629e991bdc9d9880fefbdc43e13c3607", + "timestamp": 83529114, + "type": 2, + "fee": "2500000000", + "asset": { + "delegate": { + "username": "march" + } + }, + "signature": "7a7a790a6feab476e81a76e5926dd82cf35b3d5d5285f3b4d75618571910e63607d481f29a7a738e0dae22eca82e6144fa56d46331945e589d02142dc19fe408", + "id": "16563950048443435633", + "senderId": "13626916270102280476L" + }, + { + "amount": "0", + "recipientId": "13626916270102280476L", + "senderPublicKey": "68c538b6b9ed2ec8b1938a3456a2d237629e991bdc9d9880fefbdc43e13c3607", + "timestamp": 83529114, + "type": 3, + "fee": "100000000", + "asset": { + "votes": [ + "+68c538b6b9ed2ec8b1938a3456a2d237629e991bdc9d9880fefbdc43e13c3607" + ] + }, + "signature": "5222468d06f2a8431039a513583abf5207a58ffc32eab21a05e1172bc92d00190cff04115ed9f5e7743f5abea808a3e1254f08657e629e6deb5db417e5cc130b", + "id": "175726299397961065", + "senderId": "13626916270102280476L" + }, + { + "amount": "0", + "recipientId": "", + "senderPublicKey": "68c538b6b9ed2ec8b1938a3456a2d237629e991bdc9d9880fefbdc43e13c3607", + "timestamp": 83529114, + "type": 4, + "fee": "1500000000", + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+68c538b6b9ed2ec8b1938a3456a2d237629e991bdc9d9880fefbdc43e13c3607", + "+b0b626b6cfcba98c2dcc3a55964302f1bbdee2bac6aa2c127fc394b16c6c800c" + ] + } + }, + "signature": "4926ac16a306cdc92d277011a66cdb834d9e4670490c5d78f45531c27755b269a1a8b177d1aaf71ec97fe32387e01bfa9aa09511b101381cd6efdc8488d83105", + "id": "560011825439026733", + "senderId": "13626916270102280476L" + } +] \ No newline at end of file diff --git a/elements/lisk-transaction-pool/package-lock.json b/elements/lisk-transaction-pool/package-lock.json new file mode 100644 index 00000000000..aba0f15dc4b --- /dev/null +++ b/elements/lisk-transaction-pool/package-lock.json @@ -0,0 +1,1971 @@ +{ + "name": "@liskhq/lisk-transaction-pool", + "version": "0.1.0-alpha.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.3.tgz", + "integrity": "sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A==", + "dev": true, + "requires": { + "@babel/types": "^7.3.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.3.tgz", + "integrity": "sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.3.tgz", + "integrity": "sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@sinonjs/commons": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.3.0.tgz", + "integrity": "sha512-j4ZwhaHmwsCb4DlDOIWnI5YyKDNMoNThsmwEpfHx6a1EpsGZ9qYLxP++LMlmBRjtGptGHFsGItJ768snllFWpA==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.1.0.tgz", + "integrity": "sha512-ZAR2bPHOl4Xg6eklUGpsdiIJ4+J1SNag1DHHrG/73Uz/nVwXqjgUtRPLoS+aVyieN9cSbc0E4LsU984tWcDyNg==", + "dev": true, + "requires": { + "@sinonjs/samsam": "^2 || ^3" + } + }, + "@sinonjs/samsam": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.2.0.tgz", + "integrity": "sha512-j5F1rScewLtx6pbTK0UAjA3jJj4RYiSKOix53YWv+Jzy/AZ69qHxUpU8fwVLjyKbEEud9QrLpv6Ggs7WqTimYw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash": "^4.17.11" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==", + "dev": true + }, + "@types/sinon": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.6.tgz", + "integrity": "sha512-ldQl2p7kyCXHhr//5sQCu9jWgSiDbYuCD5dUp53r/z8T8jmgKpANpy4vqjbdho9P2ldFaQC/gpW31hch+oQ0IQ==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "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": "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" + } + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "array-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "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" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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" + } + }, + "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 + }, + "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 + } + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "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" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "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 + }, + "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 + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "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 + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "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" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "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-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "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=", + "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 + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "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 + } + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lolex": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz", + "integrity": "sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw==", + "dev": true + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "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 + }, + "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" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nise": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz", + "integrity": "sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + } + } + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "sinon": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", + "integrity": "sha512-i6j7sqcLEqTYqUcMV327waI745VASvYuSuQMCjbAwlpAeuCgKZ3LtrjDxAbu+GjNQR0FEDpywtwGCIh8GicNyg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/samsam": "^3.0.2", + "diff": "^3.5.0", + "lolex": "^3.0.0", + "nise": "^1.4.8", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "sinon-chai": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.3.0.tgz", + "integrity": "sha512-r2JhDY7gbbmh5z3Q62pNbrjxZdOAjpsqW/8yxAZRSqLZqowmfGZPGUZPFf3UX36NLis0cv8VEM5IJh9HgkSOAA==", + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "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": "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" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-transaction-pool/package.json b/elements/lisk-transaction-pool/package.json new file mode 100644 index 00000000000..5b95cfe6f7f --- /dev/null +++ b/elements/lisk-transaction-pool/package.json @@ -0,0 +1,66 @@ +{ + "name": "@liskhq/lisk-transaction-pool", + "version": "0.1.0-alpha.1", + "description": "Transaction pool library for use with Lisk-related software", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-transaction-pool#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=3 <=6" + }, + "main": "dist-node/index.js", + "typings": "dist-node/index.d.ts", + "scripts": { + "transpile": "tsc", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/}/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild": "npm run prebuild:node", + "build": "npm run build:node", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/mocha": "5.2.5", + "@types/node": "10.12.21", + "@types/sinon-chai": "3.2.2", + "chai": "4.2.0", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "sinon": "7.2.3", + "sinon-chai": "3.3.0", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1" + } +} diff --git a/elements/lisk-transaction-pool/scripts/clean.sh b/elements/lisk-transaction-pool/scripts/clean.sh new file mode 100755 index 00000000000..d58d3b2fa21 --- /dev/null +++ b/elements/lisk-transaction-pool/scripts/clean.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# Unofficial strict mode +set -euo pipefail +IFS=$'\n\t' + +# Usage +# npm run clean + +rm -rf .nyc_output/ +rm -rf coverage/ +rm -rf dist-node/ +rm -rf lerna-debug.log +rm -rf npm-debug.log \ No newline at end of file diff --git a/elements/lisk-transaction-pool/src/check_transactions.ts b/elements/lisk-transaction-pool/src/check_transactions.ts new file mode 100644 index 00000000000..85af26d8340 --- /dev/null +++ b/elements/lisk-transaction-pool/src/check_transactions.ts @@ -0,0 +1,103 @@ +import { Transaction } from './transaction_pool'; + +export type CheckerFunction = ( + transactions: ReadonlyArray, +) => Promise; + +export interface CheckerFunctionResponse { + status: Status; + transactionsResponses: ReadonlyArray; +} + +export interface TransactionResponse { + readonly errors: ReadonlyArray; + readonly id: string; + readonly status: Status; +} + +export enum Status { + FAIL = 0, + OK = 1, + PENDING = 2, +} + +export interface CheckTransactionsResponseWithPassAndFail { + failedTransactions: ReadonlyArray; + passedTransactions: ReadonlyArray; +} + +export interface CheckTransactionsResponseWithPassFailAndPending { + failedTransactions: ReadonlyArray; + passedTransactions: ReadonlyArray; + pendingTransactions: ReadonlyArray; +} + +const getTransactionByStatus = ( + transactions: ReadonlyArray, + responses: ReadonlyArray, + status: Status, +): ReadonlyArray => { + const transactionIdsByStatus = responses + .filter(transactionResponse => transactionResponse.status === status) + .map(transactionStatus => transactionStatus.id); + + const transactionsByStatus = transactions.filter(transaction => + transactionIdsByStatus.includes(transaction.id), + ); + + return transactionsByStatus; +}; + +export const checkTransactionsWithPassAndFail = async ( + transactions: ReadonlyArray, + checkerFunction: CheckerFunction, +): Promise => { + // Process transactions and check their validity + const { transactionsResponses } = await checkerFunction(transactions); + + const failedTransactions = getTransactionByStatus( + transactions, + transactionsResponses, + Status.FAIL, + ); + const passedTransactions = getTransactionByStatus( + transactions, + transactionsResponses, + Status.OK, + ); + + return { + failedTransactions, + passedTransactions, + }; +}; + +export const checkTransactionsWithPassFailAndPending = async ( + transactions: ReadonlyArray, + checkerFunction: CheckerFunction, +): Promise => { + // Process transactions and check their validity + const { transactionsResponses } = await checkerFunction(transactions); + + const failedTransactions = getTransactionByStatus( + transactions, + transactionsResponses, + Status.FAIL, + ); + const passedTransactions = getTransactionByStatus( + transactions, + transactionsResponses, + Status.OK, + ); + const pendingTransactions = getTransactionByStatus( + transactions, + transactionsResponses, + Status.PENDING, + ); + + return { + failedTransactions, + passedTransactions, + pendingTransactions, + }; +}; diff --git a/elements/lisk-transaction-pool/src/index.ts b/elements/lisk-transaction-pool/src/index.ts new file mode 100644 index 00000000000..21468327a10 --- /dev/null +++ b/elements/lisk-transaction-pool/src/index.ts @@ -0,0 +1 @@ +export * from './transaction_pool'; diff --git a/elements/lisk-transaction-pool/src/job.ts b/elements/lisk-transaction-pool/src/job.ts new file mode 100644 index 00000000000..ed9e61d6a3e --- /dev/null +++ b/elements/lisk-transaction-pool/src/job.ts @@ -0,0 +1,45 @@ +export class Job { + private _active = false; + private _id: NodeJS.Timer | undefined; + private readonly _interval: number; + private readonly _job: () => Promise; + + public constructor(job: () => Promise, interval: number) { + this._interval = interval; + this._job = job; + } + + public async start(): Promise { + if (!this._active) { + this._active = true; + + return this.run(); + } + } + + public stop(): void { + if (this._active && this._id !== undefined) { + clearTimeout(this._id); + this._id = undefined; + this._active = false; + } + } + + private async callJobAfterTimeout(): Promise { + return new Promise(resolve => { + this._id = setTimeout(async () => { + await this._job(); + resolve(); + + return; + }, this._interval); + }); + } + + private async run(): Promise { + // tslint:disable-next-line:no-loop-statement + while (this._active) { + await this.callJobAfterTimeout(); + } + } +} diff --git a/elements/lisk-transaction-pool/src/queue.ts b/elements/lisk-transaction-pool/src/queue.ts new file mode 100644 index 00000000000..ca86f67a0fd --- /dev/null +++ b/elements/lisk-transaction-pool/src/queue.ts @@ -0,0 +1,159 @@ +import { Transaction } from './transaction_pool'; + +interface QueueIndex { + [index: string]: Transaction | undefined; +} + +interface RemoveForReduceObject { + readonly affected: Transaction[]; + readonly unaffected: Transaction[]; +} + +interface ReduceUntilObject { + readonly affected: Transaction[]; + readonly conditionFailedOnce: boolean; + readonly unaffected: Transaction[]; +} + +export class Queue { + private readonly _index: QueueIndex; + private _transactions: ReadonlyArray; + + public get transactions(): ReadonlyArray { + return this._transactions; + } + + public get index(): QueueIndex { + return this._index; + } + + public constructor() { + this._transactions = []; + this._index = {}; + } + + public dequeueUntil( + condition: (transaction: Transaction) => boolean, + ): ReadonlyArray { + const reduceResult: ReduceUntilObject = this._transactions.reduceRight( + ( + { affected, unaffected, conditionFailedOnce }: ReduceUntilObject, + transaction: Transaction, + ) => { + // Add transaction to the unaffected list if the condition failed for this transaction or any previous transaction + if (conditionFailedOnce || !condition(transaction)) { + return { + affected, + unaffected: [transaction, ...unaffected], + conditionFailedOnce: true, + }; + } + + // Delete the index of the transaction which passed the condition + // tslint:disable-next-line:no-dynamic-delete + delete this._index[transaction.id]; + + return { + affected: [...affected, transaction], + unaffected, + conditionFailedOnce: false, + }; + }, + { + affected: [], + unaffected: [], + conditionFailedOnce: false, + }, + ); + + this._transactions = reduceResult.unaffected; + + return reduceResult.affected; + } + + public enqueueMany(transactions: ReadonlyArray): void { + this._transactions = [...transactions, ...this._transactions]; + + transactions.forEach((transaction: Transaction) => { + this._index[transaction.id] = transaction; + }); + } + + public enqueueOne(transaction: Transaction): void { + this._transactions = [transaction, ...this._transactions]; + this._index[transaction.id] = transaction; + } + + public exists(id: string): boolean { + return !!this._index[id]; + } + + public filter( + condition: (transaction: Transaction) => boolean, + ): ReadonlyArray { + return this._transactions.filter(condition); + } + + public peekUntil( + condition: (transaction: Transaction) => boolean, + ): ReadonlyArray { + const reduceResult: ReduceUntilObject = this._transactions.reduceRight( + ( + { affected, unaffected, conditionFailedOnce }: ReduceUntilObject, + transaction: Transaction, + ) => { + // Add transaction to the unaffected list if the condition failed for this transaction or any previous transaction + if (conditionFailedOnce || !condition(transaction)) { + return { + affected, + unaffected, + conditionFailedOnce: true, + }; + } + + return { + affected: [...affected, transaction], + unaffected, + conditionFailedOnce: false, + }; + }, + { + affected: [], + unaffected: [], + conditionFailedOnce: false, + }, + ); + + return reduceResult.affected; + } + + public removeFor( + condition: (transaction: Transaction) => boolean, + ): ReadonlyArray { + const { unaffected, affected } = this._transactions.reduce( + (reduceObject: RemoveForReduceObject, transaction: Transaction) => { + if (condition(transaction)) { + reduceObject.affected.push(transaction); + // tslint:disable-next-line no-dynamic-delete + delete this._index[transaction.id]; + } else { + reduceObject.unaffected.push(transaction); + } + + return reduceObject; + }, + { unaffected: [], affected: [] }, + ); + this._transactions = unaffected; + + return affected; + } + + public size(): number { + return this._transactions.length; + } + + public sizeBy(condition: (transaction: Transaction) => boolean): number { + return this._transactions.filter(condition).length; + } +} diff --git a/elements/lisk-transaction-pool/src/queue_checkers.ts b/elements/lisk-transaction-pool/src/queue_checkers.ts new file mode 100644 index 00000000000..8824300bf07 --- /dev/null +++ b/elements/lisk-transaction-pool/src/queue_checkers.ts @@ -0,0 +1,75 @@ +import { Transaction } from './transaction_pool'; + +export type TransactionFilterableKeys = + | 'id' + | 'recipientId' + | 'senderPublicKey' + | 'senderId' + | 'type'; + +export const checkTransactionPropertyForValues = ( + values: ReadonlyArray, + propertyName: TransactionFilterableKeys, +): ((transaction: Transaction) => boolean) => (transaction: Transaction) => + values.includes(transaction[propertyName]); + +export const returnTrueUntilLimit = ( + limit: number, +): ((transaction: Transaction) => boolean) => { + // tslint:disable-next-line:no-let + let current = 0; + + // tslint:disable-next-line:increment-decrement + return _ => current++ < limit; +}; + +export const checkTransactionForExpiry = (): (( + transaction: Transaction, +) => boolean) => { + const timeNow = new Date(); + + return (transaction: Transaction) => transaction.isExpired(timeNow); +}; + +export const checkTransactionForSenderPublicKey = ( + transactions: ReadonlyArray, +): ((transaction: Transaction) => boolean) => { + const senderProperty: TransactionFilterableKeys = 'senderPublicKey'; + const senderPublicKeys = transactions.map( + transaction => transaction[senderProperty], + ); + + return checkTransactionPropertyForValues(senderPublicKeys, senderProperty); +}; + +export const checkTransactionForId = ( + transactions: ReadonlyArray, +): ((transaction: Transaction) => boolean) => { + const idProperty: TransactionFilterableKeys = 'id'; + const ids = transactions.map(transaction => transaction.id); + + return checkTransactionPropertyForValues(ids, idProperty); +}; + +export const checkTransactionForSenderIdWithRecipientIds = ( + transactions: ReadonlyArray, +): ((transaction: Transaction) => boolean) => { + const recipientProperty: TransactionFilterableKeys = 'recipientId'; + const senderId: TransactionFilterableKeys = 'senderId'; + const recipients = transactions.map( + transaction => transaction[recipientProperty], + ); + + return checkTransactionPropertyForValues(recipients, senderId); +}; + +export const checkTransactionForTypes = ( + transactions: ReadonlyArray, +): ((transaction: Transaction) => boolean) => { + const typeProperty: TransactionFilterableKeys = 'type'; + const types: ReadonlyArray = transactions.map( + (transaction: Transaction) => transaction[typeProperty], + ); + + return checkTransactionPropertyForValues(types, typeProperty); +}; diff --git a/elements/lisk-transaction-pool/src/transaction_pool.ts b/elements/lisk-transaction-pool/src/transaction_pool.ts new file mode 100644 index 00000000000..c4be8977752 --- /dev/null +++ b/elements/lisk-transaction-pool/src/transaction_pool.ts @@ -0,0 +1,702 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { EventEmitter } from 'events'; +import { + CheckerFunction, + CheckTransactionsResponseWithPassAndFail, + CheckTransactionsResponseWithPassFailAndPending, + checkTransactionsWithPassAndFail, + checkTransactionsWithPassFailAndPending, + Status, + TransactionResponse, +} from './check_transactions'; +import { Job } from './job'; +import { Queue } from './queue'; +import * as queueCheckers from './queue_checkers'; + +export interface TransactionObject { + readonly id: string; + receivedAt?: Date; + readonly recipientId: string; + readonly senderPublicKey: string; + signatures?: ReadonlyArray; + readonly type: number; + readonly senderId: string; + containsUniqueData?: boolean; +} + +export interface SignatureObject { + transactionId: string; + signature: string; + publicKey: string; +} + +export interface TransactionFunctions { + isExpired(date: Date): boolean; + verifyAgainstOtherTransactions( + otherTransactions: ReadonlyArray, + ): boolean; + addVerifiedSignature(signature: string): TransactionResponse; + isReady(): boolean; +} + +export interface TransactionPoolConfiguration { + readonly expireTransactionsInterval: number; + readonly maxTransactionsPerQueue: number; + readonly receivedTransactionsLimitPerProcessing: number; + readonly receivedTransactionsProcessingInterval: number; + readonly validatedTransactionsLimitPerProcessing: number; + readonly validatedTransactionsProcessingInterval: number; + readonly verifiedTransactionsLimitPerProcessing: number; + readonly verifiedTransactionsProcessingInterval: number; + readonly pendingTransactionsProcessingLimit: number; +} + +export interface AddTransactionResult { + readonly alreadyExists: boolean; + readonly isFull: boolean; + readonly queueName: QueueNames; +} + +interface TransactionPoolDependencies { + processTransactions: CheckerFunction; + validateTransactions: CheckerFunction; + verifyTransactions: CheckerFunction; +} + +type TransactionPoolOptions = TransactionPoolConfiguration & + TransactionPoolDependencies; + +export type Transaction = TransactionObject & TransactionFunctions; + +export type QueueNames = + | 'received' + | 'validated' + | 'verified' + | 'pending' + | 'ready'; + +interface Queues { + readonly [queue: string]: Queue; +} + +const DEFAULT_PENDING_TRANSACTIONS_PROCESSING_LIMIT = 5; +const DEFAULT_EXPIRE_TRANSACTION_INTERVAL = 30000; +const DEFAULT_MAX_TRANSACTIONS_PER_QUEUE = 1000; +const DEFAULT_RECEIVED_TRANSACTIONS_PROCESSING_INTERVAL = 30000; +const DEFAULT_RECEIVED_TRANSACTIONS_LIMIT_PER_PROCESSING = 100; +const DEFAULT_VALIDATED_TRANSACTIONS_PROCESSING_INTERVAL = 30000; +const DEFAULT_VALIDATED_TRANSACTIONS_LIMIT_PER_PROCESSING = 100; +const DEFAULT_VERIFIED_TRANSACTIONS_PROCESSING_INTERVAL = 30000; +const DEFAULT_VERIFIED_TRANSACTIONS_LIMIT_PER_PROCESSING = 100; + +export const EVENT_ADDED_TRANSACTIONS = 'transactionsAdded'; +export const EVENT_REMOVED_TRANSACTIONS = 'transactionsRemoved'; +export const ACTION_ADD_VERIFIED_REMOVED_TRANSACTIONS = + 'addVerifiedRemovedTransactions'; +export const ACTION_REMOVE_CONFIRMED_TRANSACTIONS = + 'removeConfirmedTransactions'; +export const ACTION_ADD_TRANSACTIONS = 'addTransactions'; +export const ACTION_EXPIRE_TRANSACTIONS = 'expireTransactions'; +export const ACTION_PROCESS_VERIFIED_TRANSACTIONS = + 'processVerifiedTransactions'; +export const ACTION_VALIDATE_RECEIVED_TRANSACTIONS = + 'validateReceivedTransactions'; +export const ACTION_VERIFY_VALIDATED_TRANSACTIONS = + 'verifyValidatedTransactions'; + +export class TransactionPool extends EventEmitter { + private readonly _pendingTransactionsProcessingLimit: number; + private readonly _expireTransactionsInterval: number; + private readonly _expireTransactionsJob: Job>; + private readonly _maxTransactionsPerQueue: number; + private readonly _queues: Queues; + private readonly _receivedTransactionsProcessingInterval: number; + private readonly _receivedTransactionsProcessingLimitPerInterval: number; + private readonly _validatedTransactionsProcessingInterval: number; + private readonly _validatedTransactionsProcessingLimitPerInterval: number; + private readonly _verifiedTransactionsProcessingInterval: number; + private readonly _verifiedTransactionsProcessingLimitPerInterval: number; + private readonly _validateTransactions: CheckerFunction; + private readonly _validateTransactionsJob: Job< + CheckTransactionsResponseWithPassAndFail + >; + private readonly _verifyTransactions: CheckerFunction; + private readonly _verifyTransactionsJob: Job< + CheckTransactionsResponseWithPassAndFail + >; + private readonly _processTransactions: CheckerFunction; + private readonly _processTransactionsJob: Job< + CheckTransactionsResponseWithPassAndFail + >; + + public constructor({ + expireTransactionsInterval = DEFAULT_EXPIRE_TRANSACTION_INTERVAL, + maxTransactionsPerQueue = DEFAULT_MAX_TRANSACTIONS_PER_QUEUE, + receivedTransactionsProcessingInterval = DEFAULT_RECEIVED_TRANSACTIONS_PROCESSING_INTERVAL, + receivedTransactionsLimitPerProcessing = DEFAULT_RECEIVED_TRANSACTIONS_LIMIT_PER_PROCESSING, + validatedTransactionsProcessingInterval = DEFAULT_VALIDATED_TRANSACTIONS_PROCESSING_INTERVAL, + validatedTransactionsLimitPerProcessing = DEFAULT_VALIDATED_TRANSACTIONS_LIMIT_PER_PROCESSING, + verifiedTransactionsProcessingInterval = DEFAULT_VERIFIED_TRANSACTIONS_PROCESSING_INTERVAL, + verifiedTransactionsLimitPerProcessing = DEFAULT_VERIFIED_TRANSACTIONS_LIMIT_PER_PROCESSING, + pendingTransactionsProcessingLimit = DEFAULT_PENDING_TRANSACTIONS_PROCESSING_LIMIT, + validateTransactions, + verifyTransactions, + processTransactions, + }: TransactionPoolOptions) { + super(); + this._maxTransactionsPerQueue = maxTransactionsPerQueue; + this._pendingTransactionsProcessingLimit = pendingTransactionsProcessingLimit; + + this._queues = { + received: new Queue(), + validated: new Queue(), + verified: new Queue(), + pending: new Queue(), + ready: new Queue(), + }; + this._expireTransactionsInterval = expireTransactionsInterval; + + this._expireTransactionsJob = new Job( + this.expireTransactions.bind(this), + this._expireTransactionsInterval, + ); + // tslint:disable-next-line:no-floating-promises + this._expireTransactionsJob.start(); + + this._receivedTransactionsProcessingInterval = receivedTransactionsProcessingInterval; + this._receivedTransactionsProcessingLimitPerInterval = receivedTransactionsLimitPerProcessing; + this._validateTransactions = validateTransactions; + + this._validateTransactionsJob = new Job( + this.validateReceivedTransactions.bind(this), + this._receivedTransactionsProcessingInterval, + ); + // tslint:disable-next-line:no-floating-promises + this._validateTransactionsJob.start(); + + this._validatedTransactionsProcessingInterval = validatedTransactionsProcessingInterval; + this._validatedTransactionsProcessingLimitPerInterval = validatedTransactionsLimitPerProcessing; + this._verifyTransactions = verifyTransactions; + + this._verifyTransactionsJob = new Job( + this.verifyValidatedTransactions.bind(this), + this._validatedTransactionsProcessingInterval, + ); + // tslint:disable-next-line:no-floating-promises + this._verifyTransactionsJob.start(); + + this._verifiedTransactionsProcessingInterval = verifiedTransactionsProcessingInterval; + this._verifiedTransactionsProcessingLimitPerInterval = verifiedTransactionsLimitPerProcessing; + this._processTransactions = processTransactions; + + this._processTransactionsJob = new Job( + this.processVerifiedTransactions.bind(this), + this._verifiedTransactionsProcessingInterval, + ); + // tslint:disable-next-line:no-floating-promises + this._processTransactionsJob.start(); + } + + public cleanup(): void { + this.removeTransactionsFromQueues( + Object.keys(this.queues), + queueCheckers.returnTrueUntilLimit(this._maxTransactionsPerQueue), + ); + this._expireTransactionsJob.stop(); + this._validateTransactionsJob.stop(); + this._verifyTransactionsJob.stop(); + this._processTransactionsJob.stop(); + } + + public addTransaction(transaction: Transaction): AddTransactionResult { + const receivedQueue: QueueNames = 'received'; + + return this.addTransactionToQueue(receivedQueue, transaction); + } + + public addPendingTransaction(transaction: Transaction): AddTransactionResult { + const pendingQueue: QueueNames = 'pending'; + + return this.addTransactionToQueue(pendingQueue, transaction); + } + + public addVerifiedTransaction( + transaction: Transaction, + ): AddTransactionResult { + const verifiedQueue: QueueNames = 'verified'; + + return this.addTransactionToQueue(verifiedQueue, transaction); + } + + public addVerifiedRemovedTransactions( + transactions: ReadonlyArray, + ): void { + const { received, validated, ...otherQueues } = this._queues; + + // Move transactions from the validated queue to the received queue where account was a receipient in the verified removed transactions + // Rationale is explained in issue #963 + const removedTransactionsByRecipientIdFromValidatedQueue = this._queues.validated.removeFor( + queueCheckers.checkTransactionForSenderIdWithRecipientIds(transactions), + ); + + this._queues.received.enqueueMany( + removedTransactionsByRecipientIdFromValidatedQueue, + ); + + // Move transactions from the verified, pending and ready queues to the validated queue where account was a receipient in the verified removed transactions + const removedTransactionsByRecipientIdFromOtherQueues = this.removeTransactionsFromQueues( + Object.keys(otherQueues), + queueCheckers.checkTransactionForSenderIdWithRecipientIds(transactions), + ); + + this._queues.validated.enqueueMany( + removedTransactionsByRecipientIdFromOtherQueues, + ); + + // Add transactions to the verified queue which were included in the verified removed transactions + this._queues.verified.enqueueMany(transactions); + + this.emit(EVENT_ADDED_TRANSACTIONS, { + action: ACTION_ADD_VERIFIED_REMOVED_TRANSACTIONS, + to: 'verified', + payload: transactions, + }); + } + + // It is assumed that signature is verified for this transaction before this function is called + public addVerifiedSignature( + signatureObject: SignatureObject, + ): TransactionResponse { + const transaction = this.findInTransactionPool( + signatureObject.transactionId, + ); + if (transaction) { + return transaction.addVerifiedSignature(signatureObject.signature); + } + + return { + id: signatureObject.transactionId, + status: Status.FAIL, + errors: [new Error('Could not find transaction in transaction pool')], + }; + } + + public existsInTransactionPool(id: string): boolean { + return Object.keys(this._queues).reduce( + (previousValue, queueName) => + previousValue || this._queues[queueName].exists(id), + false, + ); + } + + public findInTransactionPool(id: string): Transaction | undefined { + return Object.keys(this._queues).reduce( + (previousValue: Transaction | undefined, queueName) => + previousValue || this._queues[queueName].index[id], + undefined, + ); + } + + public get queues(): Queues { + return this._queues; + } + + public getProcessableTransactions(limit: number): ReadonlyArray { + return this._queues.ready.peekUntil( + queueCheckers.returnTrueUntilLimit(limit), + ); + } + + public removeConfirmedTransactions( + transactions: ReadonlyArray, + ): void { + // Remove transactions in the transaction pool which were included in the confirmed transactions + const removedTransactions = this.removeTransactionsFromQueues( + Object.keys(this._queues), + queueCheckers.checkTransactionForId(transactions), + ); + + const { received, validated, ...otherQueues } = this._queues; + + const confirmedTransactionsWithUniqueData = transactions.filter( + (transaction: Transaction) => transaction.containsUniqueData, + ); + + // Remove transactions from the validated queue which were sent from the accounts in the confirmed transactions + const removedTransactionsBySenderPublicKeysFromValidatedQueue = this._queues.validated.removeFor( + queueCheckers.checkTransactionForSenderPublicKey(transactions), + ); + + // Remove transactions from the validated queue if they are of a type which includes unique data and that type is included in the confirmed transactions + const removedTransactionsByTypesFromValidatedQueue = this._queues.validated.removeFor( + queueCheckers.checkTransactionForTypes( + confirmedTransactionsWithUniqueData, + ), + ); + + // Add removed transactions from the validated queue to the received queue + // Rationale is explained in issue #963 + this._queues.received.enqueueMany([ + ...removedTransactionsBySenderPublicKeysFromValidatedQueue, + ...removedTransactionsByTypesFromValidatedQueue, + ]); + + // Remove transactions from the verified, pending and ready queues which were sent from the accounts in the confirmed transactions + const removedTransactionsBySenderPublicKeysFromOtherQueues = this.removeTransactionsFromQueues( + Object.keys(otherQueues), + queueCheckers.checkTransactionForSenderPublicKey(transactions), + ); + + // Remove all transactions from the verified, pending and ready queues if they are of a type which includes unique data and that type is included in the confirmed transactions + const removedTransactionsByTypesFromOtherQueues = this.removeTransactionsFromQueues( + Object.keys(otherQueues), + queueCheckers.checkTransactionForTypes( + confirmedTransactionsWithUniqueData, + ), + ); + + this.emit(EVENT_REMOVED_TRANSACTIONS, { + action: ACTION_REMOVE_CONFIRMED_TRANSACTIONS, + payload: removedTransactions, + }); + + // Add transactions which need to be reverified to the validated queue + this._queues.validated.enqueueMany([ + ...removedTransactionsBySenderPublicKeysFromOtherQueues, + ...removedTransactionsByTypesFromOtherQueues, + ]); + } + + public reverifyTransactionsFromSenders( + senderPublicKeys: ReadonlyArray, + ): void { + const { received, validated, ...otherQueues } = this._queues; + const senderProperty: queueCheckers.TransactionFilterableKeys = + 'senderPublicKey'; + + // Move transactions from the validated queue to the received queue which were sent from sender accounts + // Rationale is explained in issue #963 + const removedTransactionsBySenderPublicKeysFromValidatedQueue = this._queues.validated.removeFor( + queueCheckers.checkTransactionPropertyForValues( + senderPublicKeys, + senderProperty, + ), + ); + + this._queues.received.enqueueMany( + removedTransactionsBySenderPublicKeysFromValidatedQueue, + ); + + // Move transactions from the verified, pending and ready queues to the validated queue which were sent from sender accounts + const removedTransactionsBySenderPublicKeysFromOtherQueues = this.removeTransactionsFromQueues( + Object.keys(otherQueues), + queueCheckers.checkTransactionPropertyForValues( + senderPublicKeys, + senderProperty, + ), + ); + + this._queues.validated.enqueueMany( + removedTransactionsBySenderPublicKeysFromOtherQueues, + ); + } + + // This function is currently unused, the usability of this function will be decided after performance tests + public validateTransactionAgainstTransactionsInPool( + transaction: Transaction, + ): boolean { + return transaction.verifyAgainstOtherTransactions([ + ...this.queues.ready.transactions, + ...this.queues.pending.transactions, + ...this.queues.verified.transactions, + ]); + } + + private addTransactionToQueue( + queueName: QueueNames, + transaction: Transaction, + ): AddTransactionResult { + if (this.existsInTransactionPool(transaction.id)) { + return { + isFull: false, + alreadyExists: true, + queueName, + }; + } + + if (this._queues[queueName].size() >= this._maxTransactionsPerQueue) { + return { + isFull: true, + alreadyExists: false, + queueName, + }; + } + // Add receivedAt property for the transaction + transaction.receivedAt = new Date(); + + this._queues[queueName].enqueueOne(transaction); + + this.emit(EVENT_ADDED_TRANSACTIONS, { + action: ACTION_ADD_TRANSACTIONS, + to: queueName, + payload: [transaction], + }); + + return { + isFull: false, + alreadyExists: false, + queueName, + }; + } + + private async expireTransactions(): Promise> { + const expiredTransactions = this.removeTransactionsFromQueues( + Object.keys(this._queues), + queueCheckers.checkTransactionForExpiry(), + ); + + this.emit(EVENT_REMOVED_TRANSACTIONS, { + action: ACTION_EXPIRE_TRANSACTIONS, + payload: expiredTransactions, + }); + + return expiredTransactions; + } + + private async processVerifiedTransactions(): Promise< + CheckTransactionsResponseWithPassAndFail + > { + const transactionsInReadyQueue = this._queues.ready.size(); + const transactionsInVerifiedQueue = this._queues.verified.size(); + const processableTransactionsInPendingQueue = this._queues.pending.sizeBy( + transaction => transaction.isReady(), + ); + + if ( + transactionsInReadyQueue >= + this._verifiedTransactionsProcessingLimitPerInterval || + (transactionsInVerifiedQueue === 0 && + processableTransactionsInPendingQueue === 0) + ) { + return { + passedTransactions: [], + failedTransactions: [], + }; + } + + const additionalTransactionsToProcessLimit = + this._verifiedTransactionsProcessingLimitPerInterval - + transactionsInReadyQueue; + const transactionsFromPendingQueueLimit = Math.min( + additionalTransactionsToProcessLimit, + this._pendingTransactionsProcessingLimit, + ); + // Filter at max transactionsFromPendingQueueLimit from the pending queue which are also ready + const transactionsFromPendingQueue = this._queues.pending + .filter(transaction => transaction.isReady()) + .slice(0, transactionsFromPendingQueueLimit); + + const additionalVerifiedTransactionsToProcessLimit = + additionalTransactionsToProcessLimit - + transactionsFromPendingQueue.length; + + const transactionsFromVerifiedQueue = this._queues.verified.peekUntil( + queueCheckers.returnTrueUntilLimit( + additionalVerifiedTransactionsToProcessLimit, + ), + ); + const transactionsFromReadyQueue = this._queues.ready.peekUntil( + queueCheckers.returnTrueUntilLimit(transactionsInReadyQueue), + ); + const toProcessTransactions = [ + ...transactionsFromReadyQueue, + ...transactionsFromPendingQueue, + ...transactionsFromVerifiedQueue, + ]; + const { + passedTransactions, + failedTransactions, + } = await checkTransactionsWithPassAndFail( + toProcessTransactions, + this._processTransactions, + ); + + const { received, validated, ...otherQueues } = this._queues; + + // Remove invalid transactions from verified, pending and ready queues + const removedTransactions = this.removeTransactionsFromQueues( + Object.keys(otherQueues), + queueCheckers.checkTransactionForId(failedTransactions), + ); + + // Keep transactions in the ready queue which still exist + this._queues.ready.enqueueMany( + this._queues.ready.removeFor( + queueCheckers.checkTransactionForId(passedTransactions), + ), + ); + + // Move processeable transactions from the verified queue to the ready queue + this._queues.ready.enqueueMany( + this._queues.verified.removeFor( + queueCheckers.checkTransactionForId(passedTransactions), + ), + ); + + // Move processable transactions from the pending queue to the ready queue + this._queues.ready.enqueueMany( + this._queues.pending.removeFor( + queueCheckers.checkTransactionForId(passedTransactions), + ), + ); + + this.emit(EVENT_REMOVED_TRANSACTIONS, { + action: ACTION_PROCESS_VERIFIED_TRANSACTIONS, + payload: removedTransactions, + }); + + return { + passedTransactions, + failedTransactions, + }; + } + + private removeTransactionsFromQueues( + queueNames: ReadonlyArray, + condition: (transaction: Transaction) => boolean, + ): ReadonlyArray { + return queueNames + .map(queueName => this._queues[queueName].removeFor(condition)) + .reduce( + ( + transactionsAccumulatedFromQueues: ReadonlyArray, + transactionsFromCurrentQueue: ReadonlyArray, + ) => + transactionsAccumulatedFromQueues.concat( + transactionsFromCurrentQueue, + ), + [], + ); + } + + private async validateReceivedTransactions(): Promise< + CheckTransactionsResponseWithPassAndFail + > { + if ( + this.queues.validated.size() >= this._maxTransactionsPerQueue || + this.queues.received.size() === 0 + ) { + return { + passedTransactions: [], + failedTransactions: [], + }; + } + + const toValidateTransactions = this._queues.received.peekUntil( + queueCheckers.returnTrueUntilLimit( + this._receivedTransactionsProcessingLimitPerInterval, + ), + ); + const { + passedTransactions, + failedTransactions, + } = await checkTransactionsWithPassAndFail( + toValidateTransactions, + this._validateTransactions, + ); + + // Remove invalid transactions + const removedTransactions = this._queues.received.removeFor( + queueCheckers.checkTransactionForId(failedTransactions), + ); + // Move valid transactions from the received queue to the validated queue + this._queues.validated.enqueueMany( + this._queues.received.removeFor( + queueCheckers.checkTransactionForId(passedTransactions), + ), + ); + + this.emit(EVENT_REMOVED_TRANSACTIONS, { + action: ACTION_VALIDATE_RECEIVED_TRANSACTIONS, + payload: removedTransactions, + }); + + return { + passedTransactions, + failedTransactions, + }; + } + + private async verifyValidatedTransactions(): Promise< + CheckTransactionsResponseWithPassFailAndPending + > { + if ( + this.queues.verified.size() >= this._maxTransactionsPerQueue || + this.queues.validated.size() === 0 + ) { + return { + passedTransactions: [], + failedTransactions: [], + pendingTransactions: [], + }; + } + + const toVerifyTransactions = this._queues.validated.peekUntil( + queueCheckers.returnTrueUntilLimit( + this._validatedTransactionsProcessingLimitPerInterval, + ), + ); + + const { + failedTransactions, + pendingTransactions, + passedTransactions, + } = await checkTransactionsWithPassFailAndPending( + toVerifyTransactions, + this._verifyTransactions, + ); + + // Remove invalid transactions + const removedTransactions = this._queues.validated.removeFor( + queueCheckers.checkTransactionForId(failedTransactions), + ); + + // Move verified transactions from the validated queue to the verified queue + this._queues.verified.enqueueMany( + this._queues.validated.removeFor( + queueCheckers.checkTransactionForId(passedTransactions), + ), + ); + + // Move verified pending transactions from the validated queue to the pending queue + this._queues.pending.enqueueMany( + this._queues.validated.removeFor( + queueCheckers.checkTransactionForId(pendingTransactions), + ), + ); + + this.emit(EVENT_REMOVED_TRANSACTIONS, { + action: ACTION_VERIFY_VALIDATED_TRANSACTIONS, + payload: removedTransactions, + }); + + return { + passedTransactions, + failedTransactions, + pendingTransactions, + }; + } +} diff --git a/elements/lisk-transaction-pool/test/_global_hooks.ts b/elements/lisk-transaction-pool/test/_global_hooks.ts new file mode 100644 index 00000000000..21464e90f21 --- /dev/null +++ b/elements/lisk-transaction-pool/test/_global_hooks.ts @@ -0,0 +1,3 @@ +afterEach(() => { + return sandbox.restore(); +}); diff --git a/elements/lisk-transaction-pool/test/_setup.ts b/elements/lisk-transaction-pool/test/_setup.ts new file mode 100644 index 00000000000..ee11b9f8b3d --- /dev/null +++ b/elements/lisk-transaction-pool/test/_setup.ts @@ -0,0 +1,25 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as chai from 'chai'; +import * as sinon from 'sinon'; +import * as sinonChai from 'sinon-chai'; + +process.env.NODE_ENV = 'test'; + +[sinonChai].forEach(plugin => chai.use(plugin)); + +global.sandbox = sinon.createSandbox({ + useFakeTimers: true, +}); diff --git a/elements/lisk-transaction-pool/test/integration/helpers/common.ts b/elements/lisk-transaction-pool/test/integration/helpers/common.ts new file mode 100644 index 00000000000..aaeee98f7ae --- /dev/null +++ b/elements/lisk-transaction-pool/test/integration/helpers/common.ts @@ -0,0 +1,90 @@ +import { + CheckerFunctionResponse, + CheckTransactionsResponseWithPassAndFail, + Status, +} from '../../../src/check_transactions'; +import { Transaction } from '../../../src/transaction_pool'; + +export const checkerFunctionResponseGenerator = async ( + passedTransactions: ReadonlyArray, + failedTransactions: ReadonlyArray, +): Promise => { + const passedTransactionsResponse = passedTransactions.map(transaction => { + return { + id: transaction.id, + status: Status.OK, + errors: [], + }; + }); + + const failedTransactionsResponse = failedTransactions.map(transaction => { + return { + id: transaction.id, + status: Status.FAIL, + errors: [new Error()], + }; + }); + + return { + status: failedTransactions.length === 0 ? Status.OK : Status.FAIL, + transactionsResponses: [ + ...passedTransactionsResponse, + ...failedTransactionsResponse, + ], + }; +}; + +export const fakeCheckFunctionGenerator = ( + firstCharacterOfFailedTransactionsId: ReadonlyArray, +) => { + return (transactions: ReadonlyArray) => { + return transactions.reduce( + ( + checkedTransactions: CheckTransactionsResponseWithPassAndFail, + transaction: Transaction, + ) => { + if (!firstCharacterOfFailedTransactionsId.includes(transaction.id[0])) { + checkedTransactions.passedTransactions = [ + ...checkedTransactions.passedTransactions, + transaction, + ]; + } else { + checkedTransactions.failedTransactions = [ + ...checkedTransactions.failedTransactions, + transaction, + ]; + } + return checkedTransactions; + }, + { + passedTransactions: [], + failedTransactions: [], + }, + ); + }; +}; + +export const fakeCheckerFunctionGenerator = ( + checkFunction: ( + transactions: ReadonlyArray, + ) => CheckTransactionsResponseWithPassAndFail, +) => { + return (transactions: ReadonlyArray) => { + const { passedTransactions, failedTransactions } = checkFunction( + transactions, + ); + return checkerFunctionResponseGenerator( + passedTransactions, + failedTransactions, + ); + }; +}; + +export const wrapExpectationInNextTick = (expectations: Function) => { + return new Promise(resolve => { + process.nextTick(() => { + expectations(); + resolve(); + }); + }); +}; diff --git a/elements/lisk-transaction-pool/test/integration/transaction_movement.ts b/elements/lisk-transaction-pool/test/integration/transaction_movement.ts new file mode 100644 index 00000000000..d2d0261b027 --- /dev/null +++ b/elements/lisk-transaction-pool/test/integration/transaction_movement.ts @@ -0,0 +1,228 @@ +import { + TransactionPool, + TransactionPoolConfiguration, + Transaction, +} from '../../src/transaction_pool'; +import { + fakeCheckFunctionGenerator, + fakeCheckerFunctionGenerator, + wrapExpectationInNextTick, +} from './helpers/common'; +import { returnTrueUntilLimit } from '../../src/queue_checkers'; +import * as transactionObjects from '../../fixtures/transactions.json'; +import { wrapTransaction } from '../utils/add_transaction_functions'; +import { SinonFakeTimers } from 'sinon'; +import { expect } from 'chai'; + +describe('transaction movement between queues', () => { + const transactions: ReadonlyArray = transactionObjects.map( + wrapTransaction, + ); + let transactionPool: TransactionPool; + let clock: SinonFakeTimers; + + const configuration: TransactionPoolConfiguration = { + expireTransactionsInterval: 100, + maxTransactionsPerQueue: 1000, + receivedTransactionsLimitPerProcessing: 25, + receivedTransactionsProcessingInterval: 100, + validatedTransactionsLimitPerProcessing: 25, + validatedTransactionsProcessingInterval: 100, + verifiedTransactionsLimitPerProcessing: 25, + verifiedTransactionsProcessingInterval: 100, + pendingTransactionsProcessingLimit: 5, + }; + + const validateTransactionFunction = fakeCheckFunctionGenerator(['1']); + const verifyTransactionFunction = fakeCheckFunctionGenerator(['2']); + const processTransactionsFunction = fakeCheckFunctionGenerator(['3']); + + const dependencies = { + processTransactions: fakeCheckerFunctionGenerator( + processTransactionsFunction, + ), + validateTransactions: fakeCheckerFunctionGenerator( + validateTransactionFunction, + ), + verifyTransactions: fakeCheckerFunctionGenerator(verifyTransactionFunction), + }; + + beforeEach(async () => { + clock = sandbox.useFakeTimers(); + transactionPool = new TransactionPool({ + ...configuration, + ...dependencies, + }); + }); + + afterEach(async () => { + transactionPool.cleanup(); + }); + + describe('validate received transactions', () => { + let transactionsToValidate: ReadonlyArray; + let validTransactions: ReadonlyArray; + let invalidTransactions: ReadonlyArray; + + beforeEach(async () => { + transactions.forEach(transaction => { + transactionPool.addTransaction(transaction); + }); + transactionsToValidate = transactionPool.queues.received.peekUntil( + returnTrueUntilLimit( + configuration.receivedTransactionsLimitPerProcessing, + ), + ); + const { + passedTransactions, + failedTransactions, + } = validateTransactionFunction(transactionsToValidate); + + validTransactions = passedTransactions; + invalidTransactions = failedTransactions; + clock.tick(configuration.receivedTransactionsProcessingInterval + 1); + }); + + it('should remove transactions from the received queue', async () => { + await wrapExpectationInNextTick(() => { + transactionsToValidate.forEach(transaction => { + expect(transactionPool.queues.received.exists(transaction.id)).to.be + .false; + }); + }); + }); + + it('should move valid transactions to the validated queue', async () => { + await wrapExpectationInNextTick(() => { + validTransactions.forEach(transaction => { + expect(transactionPool.queues.validated.exists(transaction.id)).to.be + .true; + }); + expect(transactionPool.queues.validated.size()).to.equal( + validTransactions.length, + ); + }); + }); + + it('should remove invalid transactions from the transaction pool', async () => { + await wrapExpectationInNextTick(() => { + invalidTransactions.forEach(transaction => { + expect(transactionPool.existsInTransactionPool(transaction.id)).to.be + .false; + }); + }); + }); + + describe('from validated to the verified and pending queues', () => { + let transactionsToVerify: ReadonlyArray; + let verifiableTransactions: ReadonlyArray; + let unverifiableTransactions: ReadonlyArray; + + beforeEach(async () => { + transactionsToVerify = validTransactions; + const { + passedTransactions, + failedTransactions, + } = verifyTransactionFunction(transactionsToVerify); + + verifiableTransactions = passedTransactions; + unverifiableTransactions = failedTransactions; + clock.tick(configuration.validatedTransactionsProcessingInterval + 1); + }); + + it('should remove transactions from the validated queue', async () => { + await wrapExpectationInNextTick(() => { + transactionsToVerify.forEach(transaction => { + expect(transactionPool.queues.validated.exists(transaction.id)).to + .be.false; + }); + }); + }); + + it('should move verified transactions to the verified queue', async () => { + await wrapExpectationInNextTick(() => { + verifiableTransactions.forEach(transaction => { + expect(transactionPool.queues.verified.exists(transaction.id)).to.be + .true; + }); + expect(transactionPool.queues.verified.size()).to.equal( + verifiableTransactions.length, + ); + }); + }); + + it('should remove verified transactions from the transaction pool', async () => { + await wrapExpectationInNextTick(() => { + unverifiableTransactions.forEach(transaction => { + expect(transactionPool.existsInTransactionPool(transaction.id)).to + .be.false; + }); + }); + }); + + describe('from pending and verified to the ready queue', () => { + let transactionsToProcess: ReadonlyArray; + let processableTransactions: ReadonlyArray; + let unprocessableTransactions: ReadonlyArray; + + beforeEach(async () => { + transactionsToProcess = verifiableTransactions; + const { + passedTransactions, + failedTransactions, + } = processTransactionsFunction(transactionsToProcess); + + processableTransactions = passedTransactions; + unprocessableTransactions = failedTransactions; + clock.tick(configuration.verifiedTransactionsProcessingInterval + 1); + }); + + it('should remove transactions from the verified queue', async () => { + await wrapExpectationInNextTick(() => { + transactionsToProcess.forEach(transaction => { + expect(transactionPool.queues.verified.exists(transaction.id)).to + .be.false; + }); + }); + }); + + it('should move processable transactions to the ready queue', async () => { + await wrapExpectationInNextTick(() => { + processableTransactions.forEach(transaction => { + expect(transactionPool.queues.ready.exists(transaction.id)).to.be + .true; + }); + expect(transactionPool.queues.ready.size()).to.equal( + processableTransactions.length, + ); + }); + }); + + it('should remove unverfied transactions from the transaction pool', async () => { + await wrapExpectationInNextTick(() => { + unprocessableTransactions.forEach(transaction => { + expect(transactionPool.existsInTransactionPool(transaction.id)).to + .be.false; + }); + }); + }); + + it('should keep the transactions after running the job twice', async () => { + let transactionsInReadyQueue: ReadonlyArray; + await wrapExpectationInNextTick(() => { + transactionsInReadyQueue = + transactionPool.queues.ready.transactions; + clock.tick(configuration.verifiedTransactionsProcessingInterval); + }); + + await wrapExpectationInNextTick(() => { + transactionsInReadyQueue.forEach(transaction => { + expect(transactionPool.queues.ready.exists(transaction.id)).to.be + .true; + }); + }); + }); + }); + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/integration/transaction_pool_events.ts b/elements/lisk-transaction-pool/test/integration/transaction_pool_events.ts new file mode 100644 index 00000000000..0b17f250edf --- /dev/null +++ b/elements/lisk-transaction-pool/test/integration/transaction_pool_events.ts @@ -0,0 +1,321 @@ +import { + TransactionPool, + TransactionPoolConfiguration, + Transaction, +} from '../../src/transaction_pool'; +import { + fakeCheckFunctionGenerator, + fakeCheckerFunctionGenerator, +} from './helpers/common'; +import * as transactionObjects from '../../fixtures/transactions.json'; +import { wrapTransaction } from '../utils/add_transaction_functions'; +import { expect } from 'chai'; + +describe('transaction pool events', () => { + const transactions: ReadonlyArray = transactionObjects.map( + wrapTransaction, + ); + let transactionPool: TransactionPool; + + const configuration: TransactionPoolConfiguration = { + expireTransactionsInterval: 100, + maxTransactionsPerQueue: 1000, + receivedTransactionsLimitPerProcessing: 25, + receivedTransactionsProcessingInterval: 10000, + validatedTransactionsLimitPerProcessing: 25, + validatedTransactionsProcessingInterval: 10000, + verifiedTransactionsLimitPerProcessing: 25, + verifiedTransactionsProcessingInterval: 10000, + pendingTransactionsProcessingLimit: 5, + }; + + const validateTransactionFunction = fakeCheckFunctionGenerator([]); + const verifyTransactionFunction = fakeCheckFunctionGenerator([]); + const processTransactionsFunction = fakeCheckFunctionGenerator([]); + + const dependencies = { + processTransactions: fakeCheckerFunctionGenerator( + processTransactionsFunction, + ), + validateTransactions: fakeCheckerFunctionGenerator( + validateTransactionFunction, + ), + verifyTransactions: fakeCheckerFunctionGenerator(verifyTransactionFunction), + }; + + // Filter all transfer transactions from accounts from fixture + const transferTransactions = transactions.filter( + transaction => transaction.type === 0, + ); + // Filter all the other transaction types from accounts from fixture + const otherTransactions = transactions.filter( + transaction => transaction.type !== 0, + ); + + // In otherTransactions array, each account has 4 transactions. All transactions from the same account should be put in the same queue to allow easier testing. + // In order to keep all transactions from a single account in one queue, each queue length is divisible by 4. + const transactionsInReceivedQueue = otherTransactions.slice(0, 200); + const transactionsInValidatedQueue = otherTransactions.slice(200, 400); + const transactionsInVerifiedQueue = otherTransactions.slice(400, 600); + const transactionsInPendingQueue = otherTransactions.slice(600, 776); + const transactionsInReadyQueue = otherTransactions.slice(776, 800); + + beforeEach(async () => { + transactionPool = new TransactionPool({ + ...configuration, + ...dependencies, + }); + }); + + afterEach(async () => { + transactionPool.cleanup(); + }); + + describe('put transactions in all the different queues', () => { + beforeEach(async () => { + transactionPool.queues.received.enqueueMany(transactionsInReceivedQueue); + transactionPool.queues.validated.enqueueMany( + transactionsInValidatedQueue, + ); + transactionPool.queues.verified.enqueueMany(transactionsInVerifiedQueue); + transactionPool.queues.pending.enqueueMany(transactionsInPendingQueue); + transactionPool.queues.ready.enqueueMany(transactionsInReadyQueue); + }); + + describe('on adding verified removed transactions', () => { + // 4 transactions from each account are affected + const affectedTransactionsInValidatedQueue = transactionsInValidatedQueue.slice( + 0, + 8, + ); + const unaffectedTransactionsInValidatedQueue = transactionsInValidatedQueue.slice( + 8, + ); + const affectedTransactionsInVerifiedQueue = transactionsInVerifiedQueue.slice( + 0, + 8, + ); + const unaffectedTransactionsInVerifiedQueue = transactionsInVerifiedQueue.slice( + 8, + ); + const affectedTransactionsInPendingQueue = transactionsInPendingQueue.slice( + 0, + 8, + ); + const unaffectedTransactionsInPendingQueue = transactionsInPendingQueue.slice( + 8, + ); + const affectedTransactionsInReadyQueue = transactionsInReadyQueue.slice( + 0, + 8, + ); + const unaffectedTransactionsInReadyQueue = transactionsInReadyQueue.slice( + 8, + ); + const transactionsToMoveToValidatedQueue = [ + ...affectedTransactionsInVerifiedQueue, + ...affectedTransactionsInPendingQueue, + ...affectedTransactionsInReadyQueue, + ]; + const transactionsToMoveToReceivedQueue = affectedTransactionsInValidatedQueue; + const transactionsToAffectedReceipients = transferTransactions.filter( + transferTransaction => + [ + ...transactionsToMoveToValidatedQueue, + ...transactionsToMoveToReceivedQueue, + ].find( + affectedTransaction => + affectedTransaction.senderId === transferTransaction.recipientId, + ), + ); + + beforeEach(async () => { + transactionPool.addVerifiedRemovedTransactions( + transactionsToAffectedReceipients, + ); + }); + + it('should move affected transactions in verified, pending and ready queue to the validated queue', async () => { + transactionsToMoveToValidatedQueue.forEach(affectedTransaction => { + expect( + transactionPool.queues.validated.exists(affectedTransaction.id), + ).to.be.true; + }); + }); + + it('should move affected transactions in the validated queue to the received queue', async () => { + transactionsToMoveToReceivedQueue.forEach(affectedTransaction => { + expect(transactionPool.queues.received.exists(affectedTransaction.id)) + .to.be.true; + }); + }); + + it('should keep the unaffected transactions in their queues', async () => { + unaffectedTransactionsInReadyQueue.forEach( + transaction => + expect(transactionPool.queues.ready.exists(transaction.id)).to.be + .true, + ); + unaffectedTransactionsInVerifiedQueue.forEach( + transaction => + expect(transactionPool.queues.verified.exists(transaction.id)).to.be + .true, + ); + unaffectedTransactionsInPendingQueue.forEach( + transaction => + expect(transactionPool.queues.pending.exists(transaction.id)).to.be + .true, + ); + unaffectedTransactionsInValidatedQueue.forEach( + transaction => + expect(transactionPool.queues.validated.exists(transaction.id)).to + .be.true, + ); + }); + + it('should add transactions to the verified queue', async () => { + transactionsToAffectedReceipients.forEach( + transaction => + expect(transactionPool.queues.verified.exists(transaction.id)).to.be + .true, + ); + }); + }); + + describe('on removing confirmed transactions', () => { + const affectedTypeWhichContainsUniqueData = 2; + const filterForAffectedType = (transaction: Transaction) => + transaction.type === affectedTypeWhichContainsUniqueData; + + // Filter transactions in queues by type, and use the first transaction as a confirmed transaction + const [ + confirmedTransactionInVerifiedQueue, + ...transactionsWithAffectedTypeInVerifiedQueue + ] = transactionsInVerifiedQueue.filter(filterForAffectedType); + const [ + confirmedTransactionInPendingQueue, + ...transactionsWithAffectedTypeInPendingQueue + ] = transactionsInPendingQueue.filter(filterForAffectedType); + const [ + confirmedTransactionInReadyQueue, + ...transactionsWithAffectedTypeInReadyQueue + ] = transactionsInReadyQueue.filter(filterForAffectedType); + const [ + confirmedTransactionInValidatedQueue, + ...transactionsWithAffectedTypeInValidatedQueue + ] = transactionsInValidatedQueue.filter(filterForAffectedType); + + const confirmedTransactions = [ + confirmedTransactionInVerifiedQueue, + confirmedTransactionInPendingQueue, + confirmedTransactionInReadyQueue, + confirmedTransactionInValidatedQueue, + ]; + + const filterForAffectedTransactionsBySenderId = ( + transaction: Transaction, + ) => { + confirmedTransactions.find( + confirmedTransaction => + confirmedTransaction.senderId === transaction.senderId, + ); + }; + + const transactionsWithAffectedSenderIdInVerifiedQueue = transactionsInVerifiedQueue.filter( + filterForAffectedTransactionsBySenderId, + ); + const transactionsWithAffectedSenderIdInPendingQueue = transactionsInPendingQueue.filter( + filterForAffectedTransactionsBySenderId, + ); + const transactionsWithAffectedSenderIdInReadyQueue = transactionsInReadyQueue.filter( + filterForAffectedTransactionsBySenderId, + ); + const transactionsWithAffectedSenderIdInValidatedQueue = transactionsInValidatedQueue.filter( + filterForAffectedTransactionsBySenderId, + ); + + const transactionsToMoveToValidatedQueue = [ + ...transactionsWithAffectedTypeInVerifiedQueue, + ...transactionsWithAffectedTypeInPendingQueue, + ...transactionsWithAffectedTypeInReadyQueue, + ...transactionsWithAffectedSenderIdInVerifiedQueue, + ...transactionsWithAffectedSenderIdInPendingQueue, + ...transactionsWithAffectedSenderIdInReadyQueue, + ]; + + const transactionsToMoveToReceivedQueue = [ + ...transactionsWithAffectedTypeInValidatedQueue, + ...transactionsWithAffectedSenderIdInValidatedQueue, + ]; + + beforeEach(async () => { + transactionPool.removeConfirmedTransactions(confirmedTransactions); + }); + + afterEach(async () => {}); + + it('should remove confirmed transactions from the transaction pool', async () => { + confirmedTransactions.forEach(transaction => { + expect(transactionPool.existsInTransactionPool(transaction.id)).to.be + .false; + }); + }); + + it('should move affected transactions in the verified, ready and pending queue to the validated queue', async () => { + transactionsToMoveToValidatedQueue.forEach(transaction => { + expect(transactionPool.queues.validated.exists(transaction.id)).to.be + .true; + }); + }); + + it('should move affected transactions in the validated queue to the received queue', async () => { + transactionsToMoveToReceivedQueue.forEach(transaction => { + expect(transactionPool.queues.received.exists(transaction.id)).to.be + .true; + }); + }); + }); + + describe('on verifying transactions from senders', () => { + const affectedSenderPublicKeys = [ + transactionsInVerifiedQueue[0], + transactionsInPendingQueue[0], + transactionsInReadyQueue[0], + transactionsInValidatedQueue[0], + ].map(transaction => transaction.senderPublicKey); + + const transactionsToMoveToValidatedQueue = [ + ...transactionsInVerifiedQueue, + ...transactionsInPendingQueue, + ...transactionsInReadyQueue, + ].filter(transaction => + affectedSenderPublicKeys.includes(transaction.senderPublicKey), + ); + + const transactionsToMoveToReceivedQueue = transactionsInValidatedQueue.filter( + transaction => + affectedSenderPublicKeys.includes(transaction.senderPublicKey), + ); + + beforeEach(async () => { + transactionPool.reverifyTransactionsFromSenders( + affectedSenderPublicKeys, + ); + }); + + it('should move affected transactions in the validated queue to the received queue', async () => { + transactionsToMoveToReceivedQueue.forEach(transaction => { + expect(transactionPool.queues.received.exists(transaction.id)).to.be + .true; + }); + }); + + it('should move affected transactions in the verified, ready and pending queue to the validated queue', async () => { + transactionsToMoveToValidatedQueue.forEach(transaction => { + expect(transactionPool.queues.validated.exists(transaction.id)).to.be + .true; + }); + }); + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/mocha.opts b/elements/lisk-transaction-pool/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-transaction-pool/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-transaction-pool/test/performance/queue.ts b/elements/lisk-transaction-pool/test/performance/queue.ts new file mode 100644 index 00000000000..2f9632eebd2 --- /dev/null +++ b/elements/lisk-transaction-pool/test/performance/queue.ts @@ -0,0 +1,65 @@ +import { Queue } from '../../src/queue'; +import * as transactionObjects from '../../fixtures/transactions.json'; +import { wrapTransaction } from '../utils/add_transaction_functions'; +import { expect } from 'chai'; +import { + returnTrueUntilLimit, + checkTransactionForId, +} from '../../src/queue_checkers'; + +describe('queue', () => { + const transactions = transactionObjects.map(wrapTransaction); + let queue: Queue; + + beforeEach(() => { + queue = new Queue(); + }); + + describe('#enqueueOne', () => { + it('should enqueue 1000 transactions in under 100 milliseconds', async () => { + const startTime = new Date().getTime(); + transactions.forEach(transaction => queue.enqueueOne(transaction)); + const endTime = new Date().getTime(); + expect(endTime - startTime).to.be.lessThan(100); + }); + }); + + describe('#dequeueUntil', () => { + beforeEach(async () => { + transactions.forEach(transaction => queue.enqueueOne(transaction)); + }); + + it('should dequeue 1000 transactions in under 100 milliseconds', async () => { + const startTime = new Date().getTime(); + queue.dequeueUntil(returnTrueUntilLimit(1000)); + const endTime = new Date().getTime(); + expect(endTime - startTime).to.be.lessThan(100); + }); + }); + + describe('#removeFor', () => { + beforeEach(async () => { + transactions.forEach(transaction => queue.enqueueOne(transaction)); + }); + + it('should remove 1000 transactions in under 100 milliseconds', async () => { + const startTime = new Date().getTime(); + queue.removeFor(checkTransactionForId(transactions)); + const endTime = new Date().getTime(); + expect(endTime - startTime).to.be.lessThan(100); + }); + }); + + describe('#peekUntil', () => { + beforeEach(async () => { + transactions.forEach(transaction => queue.enqueueOne(transaction)); + }); + + it('should peek 100 transactions in under 100 milliseconds', async () => { + const startTime = new Date().getTime(); + queue.peekUntil(returnTrueUntilLimit(100)); + const endTime = new Date().getTime(); + expect(endTime - startTime).to.be.lessThan(100); + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/tsconfig.json b/elements/lisk-transaction-pool/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-transaction-pool/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transaction-pool/test/tslint.json b/elements/lisk-transaction-pool/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-transaction-pool/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transaction-pool/test/unit/check_transactions.ts b/elements/lisk-transaction-pool/test/unit/check_transactions.ts new file mode 100644 index 00000000000..c92528d81d5 --- /dev/null +++ b/elements/lisk-transaction-pool/test/unit/check_transactions.ts @@ -0,0 +1,96 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +import { + CheckerFunctionResponse, + Status, + checkTransactionsWithPassAndFail, +} from '../../src/check_transactions'; +import { expect } from 'chai'; +import * as transactionObjects from '../../fixtures/transactions.json'; +import { wrapTransaction } from '../utils/add_transaction_functions'; + +describe('#checkTransactions', () => { + const transactions = transactionObjects.map(wrapTransaction); + const passedTransactions = transactions.slice(0, 2); + const failedTransactions = transactions.slice(2, 5); + const transactionsToCheck = [...passedTransactions, ...failedTransactions]; + const checkerFunctionResponse: CheckerFunctionResponse = { + status: Status.FAIL, + transactionsResponses: [ + { + id: failedTransactions[0].id, + status: Status.FAIL, + errors: [new Error(), new Error()], + }, + { + id: failedTransactions[1].id, + status: Status.FAIL, + errors: [new Error(), new Error()], + }, + { + id: passedTransactions[0].id, + status: Status.OK, + errors: [], + }, + { + id: passedTransactions[1].id, + status: Status.OK, + errors: [], + }, + { + id: failedTransactions[2].id, + status: Status.FAIL, + errors: [new Error()], + }, + ], + }; + + let checkerFunction: sinon.SinonStub; + + describe('#checkTransactionWithPassAndFail', () => { + beforeEach(async () => { + checkerFunction = sandbox.stub().resolves(checkerFunctionResponse); + }); + + it('should call checkerFunction with the transactions passed', async () => { + await checkTransactionsWithPassAndFail( + transactionsToCheck, + checkerFunction, + ); + expect(checkerFunction).to.be.calledOnceWithExactly(transactionsToCheck); + }); + + it('should return transactions which passed the checkerFunction', async () => { + const checkTransactionsResponse = await checkTransactionsWithPassAndFail( + transactionsToCheck, + checkerFunction, + ); + expect(checkTransactionsResponse.passedTransactions).to.be.deep.equal( + passedTransactions, + ); + }); + + it('should return transactions which failed the checkerFunction', async () => { + const checkTransactionsResponse = await checkTransactionsWithPassAndFail( + transactionsToCheck, + checkerFunction, + ); + expect(checkTransactionsResponse.failedTransactions).to.be.deep.equal( + failedTransactions, + ); + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/unit/job.ts b/elements/lisk-transaction-pool/test/unit/job.ts new file mode 100644 index 00000000000..fe1553f4c46 --- /dev/null +++ b/elements/lisk-transaction-pool/test/unit/job.ts @@ -0,0 +1,83 @@ +import { expect } from 'chai'; +import { Job } from '../../src/job'; +import { SinonFakeTimers } from 'sinon'; + +describe('job', () => { + let jobStub: sinon.SinonStub; + const interval = 100000; + + beforeEach(async () => { + jobStub = sandbox.stub().returns(1); + }); + + describe('#constructor', () => { + it('should return a job instance', async () => { + expect(new Job(jobStub, interval)).to.be.instanceof(Job); + }); + }); + + describe('#start', () => { + let job: Job; + let clock: SinonFakeTimers; + + beforeEach(async () => { + job = new Job(jobStub, interval); + clock = sandbox.useFakeTimers(); + }); + + it('should call the job stub', async () => { + job.start(); + clock.tick(interval + 1); + expect(jobStub).to.be.calledOnce; + }); + + it('should run twice when interval is passed two times', async () => { + job.start(); + clock.tick(interval + 1); + return new Promise(resolve => { + // need to use nextTick because clock.tick calls the callbacks in setTimeout but does not resolve the wrapping promises. + process.nextTick(() => { + clock.tick(interval + 1); + expect(jobStub).to.be.calledTwice; + resolve(); + }); + }); + }); + + it('should set the id of the job', async () => { + job.start(); + clock.tick(interval + 1); + expect((job as any)._id).to.exist; + }); + + it('should call this.run function only once on multiple start calls', () => { + const runStub = sandbox.stub(job as any, 'run'); + job.start(); + job.start(); + expect(runStub).to.be.calledOnce; + }); + }); + + describe('#end', () => { + let job: Job; + let clock: SinonFakeTimers; + + beforeEach(async () => { + job = new Job(jobStub, interval); + clock = sandbox.useFakeTimers(); + job.start(); + }); + + it('should not run the job after stop is called', async () => { + job.stop(); + clock.tick(220000); + expect(jobStub).to.not.be.called; + }); + + it('should set the id of the job to undefined', async () => { + job.stop(); + expect((job as any)._id).to.not.exist; + return; + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/unit/queue.ts b/elements/lisk-transaction-pool/test/unit/queue.ts new file mode 100644 index 00000000000..646a5962f9f --- /dev/null +++ b/elements/lisk-transaction-pool/test/unit/queue.ts @@ -0,0 +1,242 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +import { Queue } from '../../src/queue'; +import { Transaction } from '../../src/transaction_pool'; +import { expect } from 'chai'; +import * as transactionObjects from '../../fixtures/transactions.json'; +import { wrapTransaction } from '../utils/add_transaction_functions'; + +const transactions = transactionObjects.map(wrapTransaction); + +describe('Queue', () => { + let queue: Queue; + + beforeEach(async () => { + queue = new Queue(); + }); + + describe('#enqueueOne', () => { + it('should add transaction to the queue', async () => { + const transaction = transactions[0]; + queue.enqueueOne(transaction); + expect(queue.transactions).to.include(transaction); + }); + + it('should add transaction to the queue index', async () => { + const transaction = transactions[0]; + queue.enqueueOne(transaction); + expect(queue.index[transaction.id]).to.deep.equal(transaction); + }); + }); + + describe('#enqueueMany', () => { + it('should add transactions to the queue', async () => { + queue.enqueueMany(transactions); + transactions.forEach((transaction: Transaction) => + expect(queue.transactions).to.include(transaction), + ); + }); + + it('should add transactions to the queue index', async () => { + queue.enqueueMany(transactions); + transactions.forEach((transaction: Transaction) => + expect(queue.index[transaction.id]).to.eq(transaction), + ); + }); + }); + + describe('#exists', () => { + it('should return true if transaction exists in queue', async () => { + const transaction = transactions[0]; + queue.enqueueOne(transaction); + expect(queue.exists(transaction.id)).to.be.true; + }); + + it('should return false if transaction does not exist in queue', async () => { + const transaction = transactions[0]; + expect(queue.exists(transaction.id)).to.be.false; + }); + }); + + describe('#removeFor', () => { + const alwaysReturnFalse = () => () => false; + const checkIdsExists = ( + ids: ReadonlyArray, + ): ((transaction: Transaction) => boolean) => { + return (transaction: Transaction) => ids.includes(transaction.id); + }; + + beforeEach(async () => { + queue.enqueueMany(transactions); + }); + + it('should not remove any transactions if the condition fails for all transactions', async () => { + const deletedTransactions = queue.removeFor(alwaysReturnFalse()); + expect(deletedTransactions).to.have.length(0); + expect(queue.transactions).to.deep.equal(transactions); + }); + + it('should return removed transactions which pass condition', async () => { + const [ + toRemoveTransaction1, + toRemoveTransaction2, + ...tokeepTransactions + ] = transactions; + const condition = checkIdsExists([ + toRemoveTransaction1.id, + toRemoveTransaction2.id, + ]); + + const removedTransactions = queue.removeFor(condition); + expect(removedTransactions).to.deep.equal([ + toRemoveTransaction1, + toRemoveTransaction2, + ]); + expect(queue.transactions).to.deep.equal(tokeepTransactions); + }); + + it('should remove transactions which pass condition', async () => { + const [ + toRemoveTransaction1, + toRemoveTransaction2, + ...tokeepTransactions + ] = transactions; + const condition = checkIdsExists([ + toRemoveTransaction1.id, + toRemoveTransaction2.id, + ]); + + queue.removeFor(condition); + expect(queue.transactions).not.to.contain([ + toRemoveTransaction1, + toRemoveTransaction2, + ]); + expect(queue.transactions).to.deep.equal(tokeepTransactions); + }); + + it('should remove queue index for transactions which pass condition', async () => { + const [ + toRemoveTransaction1, + toRemoveTransaction2, + ...tokeepTransactions + ] = transactions; + const condition = checkIdsExists([ + toRemoveTransaction1.id, + toRemoveTransaction2.id, + ]); + + queue.removeFor(condition); + expect(queue.index[toRemoveTransaction1.id]).not.to.exist; + expect(queue.index[toRemoveTransaction2.id]).not.to.exist; + expect(queue.transactions).to.deep.equal(tokeepTransactions); + }); + }); + + describe('#peekUntil', () => { + const returnTrueUntilLimit = (limit: number) => { + let currentValue = 0; + + return () => currentValue++ < limit; + }; + + beforeEach(async () => { + queue.enqueueMany(transactions); + }); + + it('should not return any transactions if the condition fails for first transaction', async () => { + const peekedTransactions = queue.peekUntil(returnTrueUntilLimit(0)); + expect(peekedTransactions).to.have.length(0); + }); + + it('should return transactions which pass condition', async () => { + const [secondToLastTransaciton, lastTransaction] = transactions.slice( + transactions.length - 2, + transactions.length, + ); + const condition = returnTrueUntilLimit(2); + + const peekedTransactions = queue.peekUntil(condition); + expect(peekedTransactions).to.deep.equal([ + lastTransaction, + secondToLastTransaciton, + ]); + }); + }); + + describe('#dequeueUntil', () => { + const returnTrueUntilLimit = (limit: number) => { + let currentValue = 0; + + return () => currentValue++ < limit; + }; + + beforeEach(async () => { + queue.enqueueMany(transactions); + }); + + it('should not dequeue any transactions if the condition fails for first transaction', async () => { + const dequeuedTransactions = queue.dequeueUntil(returnTrueUntilLimit(0)); + expect(dequeuedTransactions).to.have.length(0); + expect(queue.transactions).to.deep.equal(transactions); + }); + + it('should return dequeued transactions which pass condition', async () => { + const [secondToLastTransaciton, lastTransaction] = transactions.slice( + transactions.length - 2, + transactions.length, + ); + const condition = returnTrueUntilLimit(2); + + const dequeuedTransactions = queue.dequeueUntil(condition); + expect(dequeuedTransactions).to.deep.equal([ + lastTransaction, + secondToLastTransaciton, + ]); + }); + + it('should dequeue 2 transactions', async () => { + const condition = returnTrueUntilLimit(2); + + queue.dequeueUntil(condition); + expect(queue.transactions).to.deep.equal( + transactions.slice(0, transactions.length - 2), + ); + }); + + it('should remove queue index for transactions which pass condition', async () => { + const [secondToLastTransaciton, lastTransaction] = transactions.slice( + transactions.length - 2, + transactions.length, + ); + const condition = returnTrueUntilLimit(2); + + queue.dequeueUntil(condition); + expect(queue.index[lastTransaction.id]).not.to.exist; + expect(queue.index[secondToLastTransaciton.id]).not.to.exist; + }); + }); + + describe('#size', () => { + it('should return 0 if the queue is empty', async () => { + expect(queue.size()).to.equal(0); + }); + + it('should return the number of elements in the queue', async () => { + queue.enqueueMany(transactions); + expect(queue.size()).to.equal(transactions.length); + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/unit/queue_checkers.ts b/elements/lisk-transaction-pool/test/unit/queue_checkers.ts new file mode 100644 index 00000000000..063ad75743a --- /dev/null +++ b/elements/lisk-transaction-pool/test/unit/queue_checkers.ts @@ -0,0 +1,186 @@ +import { expect } from 'chai'; +import { Transaction } from '../../src/transaction_pool'; +import { wrapTransaction } from '../utils/add_transaction_functions'; +import * as queueCheckers from '../../src/queue_checkers'; +import * as transactionObjects from '../../fixtures/transactions.json'; +import { SinonStub } from 'sinon'; + +describe('queueCheckers', () => { + const [unincludedTransaction, ...transactions] = transactionObjects.map( + wrapTransaction, + ); + + describe('#checkTransactionPropertyForValues', () => { + const propertyName: queueCheckers.TransactionFilterableKeys = 'id'; + const values = transactions.map( + (transaction: Transaction) => transaction[propertyName], + ); + + it('should return a function', () => { + return expect( + queueCheckers.checkTransactionPropertyForValues(values, propertyName), + ).to.be.a('function'); + }); + + it('should return function which returns true for transaction whose property is included in the values', () => { + const checkerFunction = queueCheckers.checkTransactionPropertyForValues( + values, + propertyName, + ); + return expect(checkerFunction(transactions[0])).to.equal(true); + }); + + it('should return function which returns false for transaction whose property is not included in the values', () => { + const checkerFunction = queueCheckers.checkTransactionPropertyForValues( + values, + propertyName, + ); + return expect(checkerFunction(unincludedTransaction)).to.equal(false); + }); + }); + + describe('#returnTrueUntilLimit', () => { + const limit = 2; + + it('should return a function', () => { + return expect(queueCheckers.returnTrueUntilLimit(limit)).to.be.a( + 'function', + ); + }); + + it(`should return function which returns true until function is called less than ${limit} times`, () => { + const checkerFunction = queueCheckers.returnTrueUntilLimit(limit); + expect(checkerFunction(transactions[0])).to.equal(true); + return expect(checkerFunction(transactions[0])).to.equal(true); + }); + + it(`should return function which returns false after function is called more than ${limit} times`, () => { + const checkerFunction = queueCheckers.returnTrueUntilLimit(limit); + checkerFunction(transactions[0]); + checkerFunction(transactions[0]); + return expect(checkerFunction(transactions[0])).to.equal(false); + }); + }); + + describe('#checkTransactionForExpiry', () => { + it('should return a function', () => { + return expect(queueCheckers.checkTransactionForExpiry()).to.be.a( + 'function', + ); + }); + + it('should call transaction.isExpired function', () => { + const transactionExpiryCheckFunction = queueCheckers.checkTransactionForExpiry(); + const transaction = { + ...transactions[0], + receivedAt: new Date(new Date().getTime() - 29000), + }; + + const isExpiredStub = sandbox.stub(transaction, 'isExpired'); + transactionExpiryCheckFunction(transaction); + + return expect(isExpiredStub).to.be.calledOnce; + }); + }); + + describe('#checkTransactionForSenderPublicKey', () => { + beforeEach(() => { + return sandbox + .stub(queueCheckers, 'checkTransactionPropertyForValues') + .returns(() => true); + }); + + it('should return a function', () => { + return expect( + queueCheckers.checkTransactionForSenderPublicKey(transactions), + ).to.be.a('function'); + }); + + it('should call checkTransactionPropertyForValues with transactions senderPublicKeys values and senderPublicKey property', () => { + queueCheckers.checkTransactionForSenderPublicKey(transactions); + const senderProperty: queueCheckers.TransactionFilterableKeys = + 'senderPublicKey'; + const transactionSenderPublicKeys = transactions.map( + (transaction: Transaction) => transaction.senderPublicKey, + ); + return expect( + queueCheckers.checkTransactionPropertyForValues as SinonStub, + ).to.be.calledWith(transactionSenderPublicKeys, senderProperty); + }); + }); + + describe('#checkTransactionForId', () => { + beforeEach(() => { + return sandbox + .stub(queueCheckers, 'checkTransactionPropertyForValues') + .returns(() => true); + }); + + it('should return a function', () => { + return expect(queueCheckers.checkTransactionForId(transactions)).to.be.a( + 'function', + ); + }); + + it('should call checkTransactionPropertyForValues with transactions id values and id property', () => { + queueCheckers.checkTransactionForId(transactions); + const idProperty: queueCheckers.TransactionFilterableKeys = 'id'; + const transactionIds = transactions.map( + (transaction: Transaction) => transaction.id, + ); + return expect( + queueCheckers.checkTransactionPropertyForValues as SinonStub, + ).to.be.calledWith(transactionIds, idProperty); + }); + }); + + describe('#checkTransactionForSenderIdWithRecipientIds', () => { + beforeEach(() => { + return sandbox + .stub(queueCheckers, 'checkTransactionPropertyForValues') + .returns(() => true); + }); + + it('should return a function', () => { + return expect( + queueCheckers.checkTransactionForSenderIdWithRecipientIds(transactions), + ).to.be.a('function'); + }); + + it('should call checkTransactionPropertyForValues with transacitons recipientId values and senderId property', () => { + queueCheckers.checkTransactionForSenderIdWithRecipientIds(transactions); + const senderId: queueCheckers.TransactionFilterableKeys = 'senderId'; + const transactionRecipientIds = transactions.map( + (transaction: Transaction) => transaction.recipientId, + ); + return expect( + queueCheckers.checkTransactionPropertyForValues as SinonStub, + ).to.be.calledWith(transactionRecipientIds, senderId); + }); + }); + + describe('#checkTransactionForTypes', () => { + beforeEach(() => { + return sandbox + .stub(queueCheckers, 'checkTransactionPropertyForValues') + .returns(() => true); + }); + + it('should return a function', () => { + return expect( + queueCheckers.checkTransactionForTypes(transactions), + ).to.be.a('function'); + }); + + it('should call checkTransactionPropertyForValues with transaction type values and type property', () => { + queueCheckers.checkTransactionForTypes(transactions); + const typeProperty: queueCheckers.TransactionFilterableKeys = 'type'; + const transactionTypes = transactions.map( + (transaction: Transaction) => transaction.type, + ); + return expect( + queueCheckers.checkTransactionPropertyForValues as SinonStub, + ).to.be.calledWith(transactionTypes, typeProperty); + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/unit/transaction_pool.ts b/elements/lisk-transaction-pool/test/unit/transaction_pool.ts new file mode 100644 index 00000000000..4e7864fa172 --- /dev/null +++ b/elements/lisk-transaction-pool/test/unit/transaction_pool.ts @@ -0,0 +1,697 @@ +import { expect } from 'chai'; +import * as transactionObjects from '../../fixtures/transactions.json'; +import { Job } from '../../src/job'; +import { + Transaction, + TransactionPool, + AddTransactionResult, +} from '../../src/transaction_pool'; +import * as checkTransactions from '../../src/check_transactions'; +import { wrapTransaction } from './../utils/add_transaction_functions'; +import * as sinon from 'sinon'; +import { Queue } from '../../src/queue'; +import * as queueCheckers from '../../src/queue_checkers'; + +describe('transaction pool', () => { + const expireTransactionsInterval = 1000; + const maxTransactionsPerQueue = 1000; + const receivedTransactionsProcessingInterval = 100; + const receivedTransactionsLimitPerProcessing = 100; + const validatedTransactionsProcessingInterval = 100; + const validatedTransactionsLimitPerProcessing = 100; + const transactions = transactionObjects.map(wrapTransaction); + const verifiedTransactionsProcessingInterval = 100; + const verifiedTransactionsLimitPerProcessing = 100; + const pendingTransactionsProcessingLimit = 5; + + let transactionPool: TransactionPool; + + let checkerStubs: { + [key: string]: sinon.SinonStub; + }; + + let checkTransactionsWithPassAndFailStub: sinon.SinonStub; + let checkTransactionsWithPassFailAndPendingStub: sinon.SinonStub; + let validateTransactionsStub: sinon.SinonStub; + let verifyTransactionsStub: sinon.SinonStub; + let processTransactionsStub: sinon.SinonStub; + + beforeEach(async () => { + // Stubbing start function so the jobs do not start in the background. + sandbox.stub(Job.prototype, 'start'); + checkerStubs = { + returnTrueUntilLimit: sandbox.stub(queueCheckers, 'returnTrueUntilLimit'), + checkTransactionPropertyForValues: sandbox.stub( + queueCheckers, + 'checkTransactionPropertyForValues', + ), + checkTransactionForSenderPublicKey: sandbox.stub( + queueCheckers, + 'checkTransactionForSenderPublicKey', + ), + checkTransactionForId: sandbox.stub( + queueCheckers, + 'checkTransactionForId', + ), + checkTransactionForRecipientId: sandbox.stub( + queueCheckers, + 'checkTransactionForSenderIdWithRecipientIds', + ), + checkTransactionForExpiry: sandbox.stub( + queueCheckers, + 'checkTransactionForExpiry', + ), + }; + + checkTransactionsWithPassAndFailStub = sandbox.stub( + checkTransactions, + 'checkTransactionsWithPassAndFail', + ); + checkTransactionsWithPassFailAndPendingStub = sandbox.stub( + checkTransactions, + 'checkTransactionsWithPassFailAndPending', + ); + validateTransactionsStub = sandbox.stub(); + verifyTransactionsStub = sandbox.stub(); + processTransactionsStub = sandbox.stub(); + + transactionPool = new TransactionPool({ + expireTransactionsInterval, + maxTransactionsPerQueue, + pendingTransactionsProcessingLimit, + receivedTransactionsProcessingInterval, + receivedTransactionsLimitPerProcessing, + validateTransactions: validateTransactionsStub, + validatedTransactionsProcessingInterval, + validatedTransactionsLimitPerProcessing, + verifyTransactions: verifyTransactionsStub, + verifiedTransactionsLimitPerProcessing, + verifiedTransactionsProcessingInterval, + processTransactions: processTransactionsStub, + }); + // Stub queues + Object.keys(transactionPool.queues).forEach(queueName => { + sandbox + .stub((transactionPool as any)._queues, queueName) + .value(sinon.createStubInstance(Queue)); + }); + }); + + describe('#addTransactionToQueue', () => { + const queueName = 'received'; + let existsInPoolStub: sinon.SinonStub; + let receviedQueueSizeStub: sinon.SinonStub; + let addTransactionToQueue: ( + queueName: string, + transaction: Transaction, + ) => AddTransactionResult; + + beforeEach(async () => { + existsInPoolStub = sandbox.stub( + transactionPool, + 'existsInTransactionPool', + ); + receviedQueueSizeStub = transactionPool.queues.received + .size as sinon.SinonStub; + // addTransactionToQueue is a private function, therefore removing typesafety and binding the context here. + addTransactionToQueue = (transactionPool as any).addTransactionToQueue.bind( + transactionPool, + ); + }); + + it('should return true for alreadyExists if transaction already exists in pool', async () => { + existsInPoolStub.returns(true); + expect(addTransactionToQueue(queueName, transactions[0]).alreadyExists).to + .be.true; + }); + + it('should return false for alreadyExists if transaction does not exist in pool', async () => { + existsInPoolStub.returns(false); + expect(addTransactionToQueue(queueName, transactions[0]).alreadyExists).to + .be.false; + }); + + it('should return false for isFull if queue.size is less than maxTransactionsPerQueue', async () => { + existsInPoolStub.returns(false); + receviedQueueSizeStub.returns(maxTransactionsPerQueue - 1); + expect(addTransactionToQueue(queueName, transactions[0]).isFull).to.be + .false; + }); + + it('should return true for isFull if queue.size is equal to or greater than maxTransactionsPerQueue', async () => { + existsInPoolStub.returns(false); + receviedQueueSizeStub.returns(maxTransactionsPerQueue); + expect(addTransactionToQueue(queueName, transactions[0]).isFull).to.be + .true; + }); + + it('should call enqueue for received queue if the transaction does not exist and queue is not full', async () => { + existsInPoolStub.returns(false); + receviedQueueSizeStub.returns(maxTransactionsPerQueue - 1); + addTransactionToQueue(queueName, transactions[0]); + expect(transactionPool.queues.received + .enqueueOne as sinon.SinonStub).to.be.calledWith(transactions[0]); + }); + + it('should return false for isFull and alreadyExists if the transaction does not exist and queue is not full', async () => { + existsInPoolStub.returns(false); + receviedQueueSizeStub.returns(maxTransactionsPerQueue - 1); + const addedTransactionStatus = addTransactionToQueue( + queueName, + transactions[0], + ); + expect(addedTransactionStatus.isFull).to.be.false; + expect(addedTransactionStatus.alreadyExists).to.be.false; + }); + }); + + describe('#addTransaction', () => { + let addTransactionToQueueStub: sinon.SinonStub; + + beforeEach(async () => { + addTransactionToQueueStub = sandbox.stub( + transactionPool as any, + 'addTransactionToQueue', + ); + }); + + it('should call addTransactionToQueue with with correct parameters', async () => { + transactionPool.addTransaction(transactions[0]); + const receivedQueueName = 'received'; + expect(addTransactionToQueueStub).to.be.calledWith( + receivedQueueName, + transactions[0], + ); + }); + }); + + describe('#addVerifiedTransaction', () => { + let addTransactionToQueueStub: sinon.SinonStub; + + beforeEach(async () => { + addTransactionToQueueStub = sandbox.stub( + transactionPool as any, + 'addTransactionToQueue', + ); + }); + + it('should call addTransactionToQueue with with correct parameters', async () => { + transactionPool.addVerifiedTransaction(transactions[0]); + const verifiedQueueName = 'verified'; + expect(addTransactionToQueueStub).to.be.calledWith( + verifiedQueueName, + transactions[0], + ); + }); + }); + + describe('getProcessableTransactions', () => { + const limit = 10; + let peekUntilCondition: sinon.SinonStub; + + beforeEach(async () => { + peekUntilCondition = sandbox.stub(); + checkerStubs.returnTrueUntilLimit.returns(peekUntilCondition); + }); + + it('should call returnTrueUntilLimit conditional function with limit parameter', () => { + transactionPool.getProcessableTransactions(limit); + expect(checkerStubs.returnTrueUntilLimit).to.be.calledWith(limit); + }); + + it('should call peekUntil for ready queue with correct parameter', () => { + transactionPool.getProcessableTransactions(limit); + expect(transactionPool.queues.ready.peekUntil).to.be.calledWith( + peekUntilCondition, + ); + }); + }); + + describe('#expireTransactions', () => { + let removeTransactionsFromQueuesStub: sinon.SinonStub; + let expireTransactions: () => Promise>; + + beforeEach(async () => { + removeTransactionsFromQueuesStub = sandbox.stub( + transactionPool as any, + 'removeTransactionsFromQueues', + ); + expireTransactions = (transactionPool as any)['expireTransactions'].bind( + transactionPool, + ); + }); + + it('should call removeTransactionsFromQueues once', async () => { + await expireTransactions(); + expect(removeTransactionsFromQueuesStub).to.be.calledOnce; + }); + }); + + describe('#processVerifiedTransactions', () => { + const processableTransactionsInVerifiedQueue = transactions.slice(0, 1); + const unprocesableTransactionsInVerifiedQueue = transactions.slice(1, 2); + const transactionsInVerifiedQueue = [ + ...processableTransactionsInVerifiedQueue, + ...unprocesableTransactionsInVerifiedQueue, + ]; + const processableTransactionsInPendingQueue = transactions.slice(2, 3); + const unprocessableTransactionsInPendingQueue = transactions.slice(3, 4); + const unprocessableUnsignedTransactionsInPendingQueue = transactions.slice( + 4, + 5, + ); + const transactionsInPendingQueue = [ + ...processableTransactionsInPendingQueue, + ...unprocessableTransactionsInPendingQueue, + ...unprocessableUnsignedTransactionsInPendingQueue, + ]; + const signedTransactionsInPendingQueue = [ + ...processableTransactionsInPendingQueue, + ...unprocessableTransactionsInPendingQueue, + ]; + const processableTransactionsInReadyQueue = transactions.slice(5, 6); + const unprocessableTransactionsInReadyQueue = transactions.slice(6, 7); + const transactionsInReadyQueue = [ + ...processableTransactionsInReadyQueue, + ...unprocessableTransactionsInReadyQueue, + ]; + const processableTransactions = [ + ...processableTransactionsInReadyQueue, + ...processableTransactionsInPendingQueue, + ...processableTransactionsInVerifiedQueue, + ]; + const unprocessableTransactions = [ + ...unprocessableTransactionsInReadyQueue, + ...unprocessableTransactionsInPendingQueue, + ...unprocesableTransactionsInVerifiedQueue, + ]; + const transactionsToProcess = [ + ...transactionsInReadyQueue, + ...signedTransactionsInPendingQueue, + ...transactionsInVerifiedQueue, + ]; + + let processVerifiedTransactions: () => Promise< + checkTransactions.CheckTransactionsResponseWithPassAndFail + >; + + // Dummy functions to check used for assertions in tests + const checkForTransactionUnprocessableTransactionId = sandbox.stub(); + const checkForTransactionProcessableTransactionId = sandbox.stub(); + + const checkTransactionsResponse: checkTransactions.CheckTransactionsResponseWithPassAndFail = { + passedTransactions: processableTransactions, + failedTransactions: unprocessableTransactions, + }; + + beforeEach(async () => { + (transactionPool.queues.ready.size as sinon.SinonStub).returns( + transactionsInReadyQueue.length, + ); + (transactionPool.queues.verified.size as sinon.SinonStub).returns( + transactionsInVerifiedQueue.length, + ); + (transactionPool.queues.pending.size as sinon.SinonStub).returns( + transactionsInPendingQueue.length, + ); + (transactionPool.queues.verified.peekUntil as sinon.SinonStub).returns( + transactionsInVerifiedQueue, + ); + (transactionPool.queues.pending.peekUntil as sinon.SinonStub).returns( + transactionsInPendingQueue, + ); + (transactionPool.queues.ready.peekUntil as sinon.SinonStub).returns( + transactionsInReadyQueue, + ); + + (transactionPool.queues.pending.filter as sinon.SinonStub).returns( + signedTransactionsInPendingQueue, + ); + processVerifiedTransactions = (transactionPool as any)[ + 'processVerifiedTransactions' + ].bind(transactionPool); + checkTransactionsWithPassAndFailStub.resolves(checkTransactionsResponse); + }); + + it('should not call checkTransactionsWithPassAndFail if the size of the ready queue is bigger than verifiedTransactionsLimitPerProcessing', async () => { + (transactionPool.queues.ready.size as sinon.SinonStub).returns( + verifiedTransactionsLimitPerProcessing + 1, + ); + await processVerifiedTransactions(); + expect(checkTransactionsWithPassAndFailStub).to.not.be.called; + }); + + it('should not call checkTransactionsWithPassAndFail if verified and pending queues are empty', async () => { + (transactionPool.queues.verified.size as sinon.SinonStub).returns(0); + (transactionPool.queues.pending.sizeBy as sinon.SinonStub).returns(0); + await processVerifiedTransactions(); + expect(checkTransactionsWithPassAndFailStub).to.not.be.called; + }); + + it('should return empty passedTransactions, failedTransactions arrays if checkTransactionsWithPassAndFail is not called', async () => { + (transactionPool.queues.ready.size as sinon.SinonStub).returns( + verifiedTransactionsLimitPerProcessing + 1, + ); + const { + passedTransactions, + failedTransactions, + } = await processVerifiedTransactions(); + expect(passedTransactions).to.deep.equal([]); + expect(failedTransactions).to.deep.equal([]); + }); + + it('should remove unprocessable transactions from the verified, pending and ready queues', async () => { + checkerStubs.checkTransactionForId + .onCall(0) + .returns(checkForTransactionUnprocessableTransactionId); + await processVerifiedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(0)).to.be.calledWith( + unprocessableTransactions, + ); + expect( + (transactionPool.queues.verified.removeFor as sinon.SinonStub).getCall( + 0, + ), + ).to.be.calledWith(checkForTransactionUnprocessableTransactionId); + + expect( + (transactionPool.queues.pending.removeFor as sinon.SinonStub).getCall( + 0, + ), + ).to.be.calledWith(checkForTransactionUnprocessableTransactionId); + + expect( + (transactionPool.queues.ready.removeFor as sinon.SinonStub).getCall(0), + ).to.be.calledWith(checkForTransactionUnprocessableTransactionId); + }); + + it('should call checkTransactionsWithPassAndFail with transactions and processTransactionsStub', async () => { + await processVerifiedTransactions(); + expect(checkTransactionsWithPassAndFailStub.getCall(0)).to.be.calledWith( + transactionsToProcess, + processTransactionsStub, + ); + }); + + it('should move processable transactions to the ready queue', async () => { + checkerStubs.checkTransactionForId + .onCall(1) + .returns(checkForTransactionProcessableTransactionId); + checkerStubs.checkTransactionForId + .onCall(2) + .returns(checkForTransactionProcessableTransactionId); + checkerStubs.checkTransactionForId + .onCall(3) + .returns(checkForTransactionProcessableTransactionId); + (transactionPool.queues.verified.removeFor as sinon.SinonStub) + .onCall(1) + .returns(processableTransactions); + (transactionPool.queues.pending.removeFor as sinon.SinonStub) + .onCall(1) + .returns(processableTransactions); + (transactionPool.queues.ready.removeFor as sinon.SinonStub) + .onCall(1) + .returns(processableTransactions); + await processVerifiedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(1)).to.be.calledWith( + processableTransactions, + ); + expect(checkerStubs.checkTransactionForId.getCall(2)).to.be.calledWith( + processableTransactions, + ); + expect(checkerStubs.checkTransactionForId.getCall(3)).to.be.calledWith( + processableTransactions, + ); + expect( + (transactionPool.queues.verified.removeFor as sinon.SinonStub).getCall( + 1, + ), + ).to.be.calledWith(checkForTransactionProcessableTransactionId); + expect( + (transactionPool.queues.pending.removeFor as sinon.SinonStub).getCall( + 1, + ), + ).to.be.calledWith(checkForTransactionProcessableTransactionId); + expect( + (transactionPool.queues.ready.removeFor as sinon.SinonStub).getCall(1), + ).to.be.calledWith(checkForTransactionProcessableTransactionId); + expect(transactionPool.queues.ready.enqueueMany).to.be.calledWith( + processableTransactions, + ); + }); + + it('should not move processable transactions to the ready queue which no longer exist in the ready or verified queue', async () => { + const processableTransactionsExistingInVerifiedQueue = processableTransactions.slice( + 1, + ); + (transactionPool.queues.verified.removeFor as sinon.SinonStub) + .onCall(1) + .returns(processableTransactionsExistingInVerifiedQueue); + await processVerifiedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(3)).to.be.calledWith( + processableTransactions, + ); + expect(transactionPool.queues.ready.enqueueMany).to.be.calledWith( + processableTransactionsExistingInVerifiedQueue, + ); + }); + + it('should return passed and failed transactions', async () => { + expect(await processVerifiedTransactions()).to.deep.equal( + checkTransactionsResponse, + ); + }); + }); + + describe('#validateReceivedTransactions', () => { + const validTransactions = transactions.slice(0, 2); + const invalidTransactions = transactions.slice(2, 5); + const transactionsToValidate = [ + ...validTransactions, + ...invalidTransactions, + ]; + // Dummy functions to check used for assertions in tests + const checkForTransactionInvalidTransactionId = sandbox.stub(); + const checkForTransactionValidTransactionId = sandbox.stub(); + + const checkTransactionsResponse: checkTransactions.CheckTransactionsResponseWithPassAndFail = { + passedTransactions: validTransactions, + failedTransactions: invalidTransactions, + }; + let validateReceivedTransactions: () => Promise< + checkTransactions.CheckTransactionsResponseWithPassAndFail + >; + + beforeEach(async () => { + (transactionPool.queues.received.peekUntil as sinon.SinonStub).returns( + transactionsToValidate, + ); + validateReceivedTransactions = (transactionPool as any)[ + 'validateReceivedTransactions' + ].bind(transactionPool); + checkTransactionsWithPassAndFailStub.resolves(checkTransactionsResponse); + }); + + it('should remove invalid transactions from the received queue', async () => { + checkerStubs.checkTransactionForId + .onCall(0) + .returns(checkForTransactionInvalidTransactionId); + await validateReceivedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(0)).to.be.calledWith( + invalidTransactions, + ); + expect( + (transactionPool.queues.received.removeFor as sinon.SinonStub).getCall( + 0, + ), + ).to.be.calledWith(checkForTransactionInvalidTransactionId); + }); + + it('should call checkTransactionsWithPassAndFail with transactions and validateTransactionsStub', async () => { + await validateReceivedTransactions(); + expect(checkTransactionsWithPassAndFailStub).to.be.calledOnceWith( + transactionsToValidate, + validateTransactionsStub, + ); + }); + + it('should move valid transactions to the validated queue', async () => { + checkerStubs.checkTransactionForId + .onCall(1) + .returns(checkForTransactionValidTransactionId); + (transactionPool.queues.received.removeFor as sinon.SinonStub) + .onCall(1) + .returns(validTransactions); + await validateReceivedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(1)).to.be.calledWith( + validTransactions, + ); + expect(transactionPool.queues.received + .removeFor as sinon.SinonStub).to.be.calledWith( + checkForTransactionValidTransactionId, + ); + expect(transactionPool.queues.validated.enqueueMany).to.be.calledWith( + validTransactions, + ); + }); + + it('should not move valid transactions to the validated queue which no longer exist in the received queue', async () => { + const validTransactionsExistingInReceivedQueue = validTransactions.slice( + 1, + ); + (transactionPool.queues.received.removeFor as sinon.SinonStub) + .onCall(1) + .returns(validTransactionsExistingInReceivedQueue); + await validateReceivedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(1)).to.be.calledWith( + validTransactions, + ); + expect(transactionPool.queues.validated.enqueueMany).to.be.calledWith( + validTransactionsExistingInReceivedQueue, + ); + }); + + it('should return passed and failed transactions', async () => { + expect(await validateReceivedTransactions()).to.deep.equal( + checkTransactionsResponse, + ); + }); + }); + + describe('#verifyValidatedTransactions', () => { + const verifiableTransactions = transactions.slice(0, 2); + const unverifiableTransactions = transactions.slice(2, 4); + const pendingTransactions = transactions.slice(4, 6); + const transactionsToVerify = [ + ...verifiableTransactions, + ...unverifiableTransactions, + ...pendingTransactions, + ]; + // Dummy functions to check used for assertions in tests + const checkForTransactionUnverifiableTransactionId = sandbox.stub(); + const checkForTransactionVerifiableTransactionId = sandbox.stub(); + const checkForTransactionPendingTransactionId = sandbox.stub(); + + const checkTransactionsResponse: checkTransactions.CheckTransactionsResponseWithPassFailAndPending = { + passedTransactions: verifiableTransactions, + failedTransactions: unverifiableTransactions, + pendingTransactions: pendingTransactions, + }; + let verifyValidatedTransactions: () => Promise< + checkTransactions.CheckTransactionsResponseWithPassFailAndPending + >; + + beforeEach(async () => { + (transactionPool.queues.validated.peekUntil as sinon.SinonStub).returns( + transactionsToVerify, + ); + verifyValidatedTransactions = (transactionPool as any)[ + 'verifyValidatedTransactions' + ].bind(transactionPool); + checkTransactionsWithPassFailAndPendingStub.resolves( + checkTransactionsResponse, + ); + }); + + it('should remove unverifiable transactions from the validated queue', async () => { + checkerStubs.checkTransactionForId + .onCall(0) + .returns(checkForTransactionUnverifiableTransactionId); + await verifyValidatedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(0)).to.be.calledWith( + unverifiableTransactions, + ); + expect( + (transactionPool.queues.validated.removeFor as sinon.SinonStub).getCall( + 0, + ), + ).to.be.calledWith(checkForTransactionUnverifiableTransactionId); + }); + + it('should call checkTransactionsWithPassFailAndPendingStub with transactions and verifyTransactionsStub', async () => { + await verifyValidatedTransactions(); + expect(checkTransactionsWithPassFailAndPendingStub).to.be.calledOnceWith( + transactionsToVerify, + verifyTransactionsStub, + ); + }); + + it('should move verified transactions to the verified queue', async () => { + checkerStubs.checkTransactionForId + .onCall(1) + .returns(checkForTransactionVerifiableTransactionId); + (transactionPool.queues.validated.removeFor as sinon.SinonStub) + .onCall(1) + .returns(verifiableTransactions); + await verifyValidatedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(1)).to.be.calledWith( + verifiableTransactions, + ); + expect(transactionPool.queues.validated + .removeFor as sinon.SinonStub).to.be.calledWith( + checkForTransactionVerifiableTransactionId, + ); + expect(transactionPool.queues.verified.enqueueMany).to.be.calledWith( + verifiableTransactions, + ); + }); + + it('should not move verified transactions to the verified queue which no longer exist in the validated queue', async () => { + const verifiableTransactionsExistingInValidatedQueue = verifiableTransactions.slice( + 1, + ); + (transactionPool.queues.validated.removeFor as sinon.SinonStub) + .onCall(1) + .returns(verifiableTransactionsExistingInValidatedQueue); + await verifyValidatedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(1)).to.be.calledWith( + verifiableTransactions, + ); + expect(transactionPool.queues.verified.enqueueMany).to.be.calledWith( + verifiableTransactionsExistingInValidatedQueue, + ); + }); + + it('should move pending transactions to the pending queue', async () => { + checkerStubs.checkTransactionForId + .onCall(2) + .returns(checkForTransactionPendingTransactionId); + (transactionPool.queues.validated.removeFor as sinon.SinonStub) + .onCall(2) + .returns(pendingTransactions); + await verifyValidatedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(2)).to.be.calledWith( + pendingTransactions, + ); + expect(transactionPool.queues.validated + .removeFor as sinon.SinonStub).to.be.calledWith( + checkForTransactionPendingTransactionId, + ); + expect(transactionPool.queues.pending.enqueueMany).to.be.calledWith( + pendingTransactions, + ); + }); + + it('should not move pending transactions to the pending queue which no longer exist in the validated queue', async () => { + const pendingTransactionsExistingInValidatedQueue = pendingTransactions.slice( + 1, + ); + (transactionPool.queues.validated.removeFor as sinon.SinonStub) + .onCall(2) + .returns(pendingTransactionsExistingInValidatedQueue); + await verifyValidatedTransactions(); + expect(checkerStubs.checkTransactionForId.getCall(2)).to.be.calledWith( + pendingTransactions, + ); + expect(transactionPool.queues.pending.enqueueMany).to.be.calledWith( + pendingTransactionsExistingInValidatedQueue, + ); + }); + + it('should return passed, failed and pending transactions', async () => { + expect(await verifyValidatedTransactions()).to.deep.equal( + checkTransactionsResponse, + ); + }); + }); +}); diff --git a/elements/lisk-transaction-pool/test/utils/add_transaction_functions.ts b/elements/lisk-transaction-pool/test/utils/add_transaction_functions.ts new file mode 100644 index 00000000000..a9a20d6f379 --- /dev/null +++ b/elements/lisk-transaction-pool/test/utils/add_transaction_functions.ts @@ -0,0 +1,48 @@ +import { TransactionObject, Transaction } from '../../src/transaction_pool'; +import { TransactionResponse, Status } from '../../src/check_transactions'; + +export const wrapTransactionWithoutUniqueData = ( + transaction: TransactionObject, +): Transaction => { + return { + ...transaction, + containsUniqueData: false, + verifyAgainstOtherTransactions: () => true, + isExpired: (time: Date) => time.getTime() < 0, + isReady: () => true, + addVerifiedSignature: (signature: string): TransactionResponse => { + return { + status: Status.OK, + errors: [], + id: signature, + }; + }, + }; +}; + +export const wrapTransactionWithUniqueData = ( + transaction: TransactionObject, +): Transaction => { + return { + ...transaction, + containsUniqueData: true, + verifyAgainstOtherTransactions: () => true, + isExpired: (time: Date) => time.getTime() < 0, + isReady: () => true, + addVerifiedSignature: (signature: string): TransactionResponse => { + return { + status: Status.OK, + errors: [], + id: signature, + }; + }, + }; +}; + +export const wrapTransaction = ( + transaction: TransactionObject, +): Transaction => { + return [0, 1].includes(transaction.type) + ? wrapTransactionWithoutUniqueData(transaction) + : wrapTransactionWithUniqueData(transaction); +}; diff --git a/elements/lisk-transaction-pool/tsconfig.json b/elements/lisk-transaction-pool/tsconfig.json new file mode 100644 index 00000000000..db550527a7a --- /dev/null +++ b/elements/lisk-transaction-pool/tsconfig.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "declaration": true, + "outDir": "dist-node", + "rootDir": "./src" + }, + "include": ["../../types/**/*", "types/**/*", "src/**/*"] +} diff --git a/elements/lisk-transaction-pool/tslint.json b/elements/lisk-transaction-pool/tslint.json new file mode 100644 index 00000000000..74c91a27b2a --- /dev/null +++ b/elements/lisk-transaction-pool/tslint.json @@ -0,0 +1,9 @@ +{ + "extends": "../../tslint.json", + "rules": { + "no-delete": false, + "readonly-array": false, + "readonly-keyword": false, + "variable-name": false + } +} diff --git a/elements/lisk-transactions/.npmignore b/elements/lisk-transactions/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-transactions/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/.npmrc b/elements/lisk-transactions/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-transactions/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/.nycrc b/elements/lisk-transactions/.nycrc new file mode 120000 index 00000000000..42043af1cf1 --- /dev/null +++ b/elements/lisk-transactions/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc-ts.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/.prettierignore b/elements/lisk-transactions/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-transactions/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/.prettierrc.json b/elements/lisk-transactions/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-transactions/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/LICENSE b/elements/lisk-transactions/LICENSE new file mode 100644 index 00000000000..9cecc1d4669 --- /dev/null +++ b/elements/lisk-transactions/LICENSE @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. diff --git a/elements/lisk-transactions/README.md b/elements/lisk-transactions/README.md new file mode 100644 index 00000000000..8c8648b99d4 --- /dev/null +++ b/elements/lisk-transactions/README.md @@ -0,0 +1,37 @@ +# @liskhq/lisk-transactions + +@liskhq/lisk-transactions is containing everything related to transactions according to the Lisk protocol + +## Installation + +```sh +$ npm install --save @liskhq/lisk-transactions +``` + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-transactions/browsertest b/elements/lisk-transactions/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-transactions/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/cypress b/elements/lisk-transactions/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-transactions/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/cypress.json b/elements/lisk-transactions/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-transactions/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/index.ts b/elements/lisk-transactions/fixtures/index.ts new file mode 100644 index 00000000000..4d84ddc0434 --- /dev/null +++ b/elements/lisk-transactions/fixtures/index.ts @@ -0,0 +1,51 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as validAccount from './valid_account.json'; +import * as validDappTransactions from './valid_dapp_transactions.json'; +import * as validDelegateAccount from './valid_delegate_account.json'; +import * as validDelegateTransaction from './valid_delegate_transaction.json'; +import * as validInTransferTransactions from './valid_in_transfer_transaction.json'; +import * as validMultisignatureAccount from './valid_multisignature_account.json'; +import * as validMultisignatureRegistrationTransaction from './valid_multisignature_transaction.json'; +import * as validMultisignatureRegistrationTransactionNoSigs from './valid_multisignature_transaction_no_signatures.json'; +import * as validOutTransferTransactions from './valid_out_transfer_transactions.json'; +import * as validRegisterSecondSignatureTransaction from './valid_register_second_signature_transaction.json'; +import * as validSecondSignatureAccount from './valid_second_signature_account.json'; +import * as validTransaction from './valid_transaction.json'; +import * as validMultisignatureTransaction from './valid_transaction_from_multisignature_account.json'; +import * as validSecondSignatureTransaction from './valid_transaction_from_second_signature_account.json'; +import * as validTransferAccount from './valid_transfer_account.json'; +import * as validTransferTransactions from './valid_transfer_transactions.json'; +import * as validVoteTransactions from './valid_vote_transaction.json'; + +export { + validAccount, + validDelegateAccount, + validDelegateTransaction, + validTransaction, + validTransferTransactions, + validTransferAccount, + validMultisignatureAccount, + validMultisignatureRegistrationTransaction, + validMultisignatureTransaction, + validMultisignatureRegistrationTransactionNoSigs, + validRegisterSecondSignatureTransaction, + validSecondSignatureAccount, + validSecondSignatureTransaction, + validVoteTransactions, + validInTransferTransactions, + validDappTransactions, + validOutTransferTransactions, +}; diff --git a/elements/lisk-transactions/fixtures/invalid_transactions.json b/elements/lisk-transactions/fixtures/invalid_transactions.json new file mode 100644 index 00000000000..5a7654ed154 --- /dev/null +++ b/elements/lisk-transactions/fixtures/invalid_transactions.json @@ -0,0 +1,333 @@ +[ + { + "type":4, + "amount": "0", + "fee": "3000000000", + "recipientId":null, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp":54196079, + "asset": { + "multisignature": { + "min": 0, + "lifetime": 35, + "keysgroup": [ + "+cac3545e2fa5b9fe4a41a66ce86adbb0322587137e5289b06ba4527673a85574", + "+09e85edafad8b6e6191e1d989c58c5825b0596d5d5f5598e854eeabdffd2a850", + "+29d8260d35f110f33d988f6a23d29153c1a344a339894774690fb9b6b6bb494e", + "+346719e114848b4fbf9839836ebeb066b2898d872aef0dd315594b83d2fca1a2", + "+01b014d50765d9f705b720d6376c792afca3da4ba2798bc65626a97494579790" + ] + } + }, + "signature": "5d2acb6cc15f8de7a2531ba6a1e7725d82d07789672605e286f4ff11a19e0fb69034411f99c66267ead9245ceee54977d46a5427bdf651f8277d6908d2fd5e03", + "id": "14026504139568973606" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "multisignature": { + "min": 0, + "lifetime": 18, + "keysgroup": [ + "+740834a59435d283fd3fb30ad5d7cbde2550e82471b73abedcffb61eaa6298e4", + "+9bc8972fb01b70eb4624df5d4d4c7c00a51fd73958c50efaefe55260889aedd6", + "+66a68de8047bbe788f5ec5fbae6baf84c6438606f4e6fdf91b791113a0506ea6", + "+5f7c4b9b6f976a400dba8d0cc7f904603ea4ffe1d8702c80576a396037c49970", + "+4e4a6b5cf7b8840ba521dfae5914f55ec3805c7d5cf25dfbf44fac57f9c5f183" + ] + } + }, + "signature": + "57b54da646c7567df86fec60aa57a40bfadb6cdc65cccecfc442c822a7b0372f4958a280edd3fc2d83d38e2d3bf922a1da01249c500f0309a9638e941a21c501", + "id": "13916871066741078807" + }, + { + "type": 6, + "amount": "897386", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "81db12eccf99f92ffc5963383acb0b275777de860e7d2251d1432a1eeb46fb858d41737e68ac5cb61eab5adc7d8f6f6db8905767e997bb445babf6004ab1bb00", + "id": "14834734940279241743" + }, + { + "type": 7, + "amount": "761715", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "outTransfer": { "dappId": "720987408", "transactionId": "40486129" } + }, + "signature": + "69a84e9a883a8f624cb5dfc80f7d734f0eff9c2d2193f94238a0636b1a56afaeed8261b46de518f9ca7c9efe910628bdce9ff4a78fe86ef1a08a913486142e02" + }, + { + "type": 6, + "amount": "737434", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "7cb7d1c9f37aa5d753cd241d74b20fcd2a1540b27f7d5628b865b9b0e806eba23a0ca7ed043f73a5a881778c9cabd40ef836e0742226c60389075433b725860d", + "id": "10020668765583935219" + }, + { + "type": 7, + "amount": "646565", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "outTransfer": { "dappId": "336803878", "transactionId": "856503447" } + }, + "signature": + "caae702b9b12bd423cd2f3c742135b459149fb484f9479551bb0f1374c6f805cf881cb64f52b797770a512bdaaabf8404a22857af6713ac70035f5e9359fb60b" + }, + { + "type": 6, + "amount": "33067", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "33ce5ae051be0a10ad91ce33ee7636856e53eb0d6dfc3532333bbd11d832d7fa5a7f1cf3a3221625cd4c4c4a743587c5286a0e0166e7c2a4317bb4439f3ff008", + "id": "12483552871112483989" + }, + { + "type": 7, + "amount": "966482", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "outTransfer": { "dappId": "275792609", "transactionId": "421790462" } + }, + "signature": + "7d4cc20b24d9486a26bd74b14ba24ef1d12381f04434f125e8efaa322c1b3c1cb5c357a3b7c47fb4097fa88a0751360a37c28e6b03890f4955d51fff7948ff05" + }, + { + "type": 6, + "amount": "693810", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "1fdab67596b6201fc73d741c1d5e0c0b8fa8536ce19fc8625a0cd41db84e97575e862037db1377cdd4b7d2520b0541fe52800117ae5297a42bb10de13b451b02", + "signSignature": + "839c9397237065c0e676db1687ebf307c261382f34ac0c356d4a009d9f997c2bbeee0d48fa0ccd538543181efee63ce2810e9de144b13c1d5c78e95e8d097008", + "id": "9781155639793361245" + }, + { + "type": 7, + "amount": "476088", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "outTransfer": { "dappId": "102606108", "transactionId": "549685977" } + }, + "signature": + "01c46d39654e2b7708c998fe813e32f37fe1fe9a3f6547faefcec8743392909f119a8c76a63cce76d2bf9969b7adb80c75d31c72e2f9f98aa6d9ac9418e07e0c", + "signSignature": + "272815f308cabb04e4d8a817925758dc9d63e97425593c8e344089fead1936e6bcc51d3c49141fc97ea4eb7fbed67cd3f5bb89a979d121e174aaf526d23b210a" + }, + { + "type": 6, + "amount": "166413", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "f2b1a66d9bd8ae0c1b3404fe397a11bd696e5aea274e6a8d9fea2f976503d006b8ca65484daf2498f854a0c0109b924b653a8d6ba31a568cb70727b7d3472902", + "id": "9501694969515165251" + }, + { + "type": 7, + "amount": "835151", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "outTransfer": { "dappId": "614143983", "transactionId": "749591467" } + }, + "signature": + "646cd6cbe9f385bfa4f914b66a675a77080a3c1093278cfbca16d3d7fbf768350c9a7e270a8e5a72347e2792d3cfc770f3a3bb9ea542c300cba3976f34bd040e" + }, + { + "type": 6, + "amount": "270355", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "8a22d0b245bccd8f53ea7acd9b137bc3c7ed76a666318e7969aee45e67e75ab552dff73ec7c95c0653c2308691d068499be792d7229507c23ddd6d126a905d00", + "signSignature": + "a504c8a7ef794b6ec99aa9c914f9e562ce8e18a5797bdc92ff03a7cc479600e3f3d8cd2b3cf478b7006f996d174ceae94297568c27aab3c43c8925c1e760af08", + "id": "4482291724705265307" + }, + { + "type": 7, + "amount": "621696", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "outTransfer": { "dappId": "31057994", "transactionId": "377678276" } + }, + "signature": + "8c9abc118100d6aa016acae15ed4d10ce168b3aab9cc7d25f3bde38f2f198a3fcb729f670bdfeaba1b8e5a73192d3e115fa174e784e224a61439c00f1fef1304", + "signSignature": + "fdbab8d4029624fc82e372dae3ebc8636142b83e894c5c8c32f1b912a751b894640e0ed514b72ee1c67d8bcf6ee9ea140de7e45e58c849c16598ffe4dbb85b06" + }, + { + "type": 6, + "amount": "825188", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "ea3a2b7655d2be581f0c08af121ce114f5ffff7b3149727558f8c6775b266c738a7abc8f3fc2baa55d4f445f09ec206996f196a59c5f8502fc36121f9149ed0c", + "id": "6562982313425129534" + }, + { + "type": 7, + "amount": "628348", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "outTransfer": { "dappId": "49615750", "transactionId": "296407938" } + }, + "signature": + "67d0443b82b67d4fc2c287c3241fe44c40f68fc2df14e30d3746e463df2b7533f0cb4b4bca055a3f767d07f81a84c5843ad4b346554bfbe9cb1244a69b345e0d" + }, + { + "type": 6, + "amount": "369464", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "6042833a4578b512a0dc8451ad4a92aec63d684eb2ba4fd9602b4c7235ec72fac12bda1ff984132f7ec36c440a3f4b9f20c4634169309ed430f4434968fa8b03", + "id": "4907759462496699682" + }, + { + "type": 7, + "amount": "426107", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "outTransfer": { "dappId": "170489289", "transactionId": "11189562" } + }, + "signature": + "fc703ab98d6f25eb9617fab51a22cebdc8e340047c0b600bbf0fb216f9ac73520b10bbc6375ee3eafceb3c459f57dd0b661b4c19d114364cefec6e964bad5b08" + }, + { + "type": 6, + "amount": "405432", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "cac1442ade22a5ca056fcd157188a54f7f3648513ed1d8bbcd0656d7a0ae8aae1711b008623493f174d6318323e7e99ce7b9033a2f2b63d5fdb0406c598eec07", + "id": "11187309556374500080" + }, + { + "type": 7, + "amount": "728029", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "outTransfer": { "dappId": "433910011", "transactionId": "995526027" } + }, + "signature": + "e817a3bfe8570d13a7a728bcfd108168e47ab48e748424793dd866f61617f1786fc3908c8eaa20f470ae1e11363f8fdc55d64d8e08d0dbc399cccea38ecacc05" + }, + { + "type": 6, + "amount": "881374", + "fee": "10000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { "inTransfer": { "dappId": "1000000" } }, + "signature": + "f9facd4dd0b278e3fdca44e6b5527ff4d71f65fb05d1a993cc094f7a6e08118d96ad9103c7577c9efff41d3deec08ffb06346ab27aeff800d499785b53bea40d", + "signSignature": + "ddbe2671cb80cf478b581772242e20d49b8f88445928f8c685ea06a83733a7c7abec31c53f52f1962126abc6e1e03b2c8c7b881f6a3d6808496eb500498b730b", + "id": "10748675444711410396" + }, + { + "type": 7, + "amount": "370999", + "fee": "10000000", + "recipientId": "1859190791819301L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "outTransfer": { "dappId": "763580659", "transactionId": "89998498" } + }, + "signature": + "8041323c405e23fc8ebaaf7ded1a61e1922c29643d6ab5cf536655fb69380d7e64a158198a21cd34faa06ed1777321f403421fe59fc1b4c40087c19ab47eda0c", + "signSignature": + "177664c1e4afc88462f44f8af6192d36d435bf9457d2466e9ced8b52d44eb740be03232a6a9e0467762cf336bbd155fba04dd0a74cb7a6938ee976453bf6070b" + } +] diff --git a/elements/lisk-transactions/fixtures/transactions.json b/elements/lisk-transactions/fixtures/transactions.json new file mode 100644 index 00000000000..1efe2e012e7 --- /dev/null +++ b/elements/lisk-transactions/fixtures/transactions.json @@ -0,0 +1,1010 @@ +[ + { + "type": 1, + "amount": "0", + "fee": "500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54316324, + "asset": { + "signature": { + "publicKey": + "f9666bfed9ef2ff52a04408f22f2bfffaa81384c9433463697330224f10032a4" + } + }, + "signature": + "69d0c7bc50b82465e2b0885cebc422aa9cd575050dc89905e22a6e2cc88802935c6809a59a2daa04ca99623a6fef76b7d03215ed7f401b74ef5301b12bfe2002", + "id": "6998015087494860094" + }, + { + "type": 0, + "amount": "4008489300000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196076, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "1518a69983e348359f62a8e740f6f5f08c0c3cad651e5116bf991bc5a4b4cfb8bf8c033a86e30f596fac80142df5a4121400ac2e9307614a143ffd75cc07c20b", + "id": "7507990258936015021" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196076, + "asset": { + "votes": [ + "+0d720b72d179bdd07621cf0b6b68fd23a96777e0833f35b9d22b873c80f9b336", + "+44b58b4a9d8d0af057ada7c90bb90e30be47326c8a102c8bc6604e98ca93d1ef", + "+a8bde4a93381d7cb756611262af04844fb0a182fb9de515a3c4f068daa05c695", + "+7c5c08669e9d1366bfe6ae17ca6a054e92610358e2dc82865a826eac738fdb6a", + "-7742a72b4eb62bd994e2f1e4b44637fbce9fc1fa900080636b2f7eff40872fa6" + ] + }, + "signature": + "1d9b94e30ff2206b9de6406d9d221c751af00a300ea26fa479da3dd3bb1266d4461f8ae19a08b42ecf6648a86dc6969e965f8a617cd18c1d1ce6126d683e8605", + "id": "6128439024328469721" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196076, + "asset": { + "delegate": { + "username": "RLI0", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "3147b031c6fa71cbfc3f8a74b9cd5ed85b56b01f00e9df13244c354d43bfa90ec89dd2fe66d8e5107233073b5aac387cb54d1454ac68e73d43203d1f14ec0900", + "id": "5337978774712629501" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "multisignature": { + "min": 5, + "lifetime": 1, + "keysgroup": [ + "+6638548d991d49e2b41bf15b595fa19749b25c58483e7e8fc926038074571ebf", + "+a0ed6137800e9a65f796e423d9ebece0a7df53f0049e90eebc2e597452de69ed", + "+4bb9e15fa15cbe87d19b6854474d57c3aa515deb586548bb515630dc7121d021", + "+068bcac57c9d988f0a03bab381785c67ef4b63ca8047f41863fb2a0202aa88a5", + "+261fb86d60785e208ba7541db9ab56d3e02fcf9357a25bf859f826e87cadb816" + ] + } + }, + "signature": + "46f6ce8da1b5948aaa63a51cf28913210d356cc27a2cc952a2bf1b88f47d6cd6f250f8d907b9a4e0c531a66c601b50aa483a461e803412f2ae9543d99155970f", + "id": "15911083597203956215" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "dapp": { + "category": 0, + "name": "jSFFSiM4HZ91x7DXnOu", + "description": "HQWQewqxZ0AA330r", + "tags": "HReDOT69QpOGfR1ELav", + "type": 0, + "link": "qEXks", + "icon": "mJM14TJiZSe3OmvYXpkaSqk6pr" + } + }, + "signature": + "d4888d8e916127358c5f6417ae4cc110e5509f32ef35589401e1a147e6b20a32fd280567d10f2d11224a94a32db0088a834138408d3a6d490f6be34a57e36207", + "id": "6368378298793859048" + }, + { + "type": 0, + "amount": "8969127700000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196078, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "335033784ce58916373bfdec8c6b0a279155d3bf1f418e42e8a0804fa45906e5f71e8d0a34cb1bcd38397788efaf231e56d6d3527c3a08625ca46c1512d51c0b", + "id": "4937270977123783749" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "votes": [ + "+900fcb60a949a9269af36f0da4a7da6e5b9a81bafb1929b2882f8aeda5960ff0", + "+083d534a51c358e6dce6d43f4f0de8abf5bb1d8b8ee7fe817c5b225bb4c46fd8", + "+2027d6af78cc6b10d1fa9712dbb6241b67531552c2d3a688d8565c37b8a307ff", + "+9e3f52823ebdb0e07649b1d260f864691b81a4f7e18fdf8935bbb1bcfe454663", + "-18982fb4caf0cae685a3ca44fe91445c26bef542f09fc8ea0e25fd33fd948fd7" + ] + }, + "signature": + "45010721b4ed0424a003da5e82f5917a8895d99adb0bf9509b65cd7dbd14653efd9ed0b4f52a4d1ab7da89e3b8ef33337a67737af451df06bee51b124f741c0b", + "id": "9048233810524582722" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "delegate": { + "username": "TYX", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "660ba7172a25a19819344c1ac99f0b2532915ede18405563fcf454ff22278f1c8f33bf6fe44a29ac2a4daabf3edd1551809bb081766ef1a5b8a0251c5a656103", + "id": "17457098940654976683" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "multisignature": { + "min": 3, + "lifetime": 34, + "keysgroup": [ + "+ed2f2b9e8f377f77ad721ad572de0575796789b7a5b29cbafdc294a1f86f8a72", + "+d2e3dfb830bbbd6dd10ec6022dffac9d189343e7255f89346ede6ffbd66327fd", + "+e77283fe326d473aff78c74dac627538b7e761a7efd65edbc425c14916657b7a", + "+5124a5c4f48714c52e5242a124545fe7bf47e4bcdc03f80c485d55c886a98013", + "+ced89d652d99de651d8d1e5f30661c9a5780bb9b2955d11bf84ed1ed08abe60f" + ] + } + }, + "signature": + "97f663b356609227009f664e6072f58b43dbd5dc17f7586e9dad9511fe3272c813f81353135b5831e3c930c5669f0223402047694bc31f61276254c0ec5b170d", + "id": "16196080519305519880" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "dapp": { + "category": 0, + "name": "", + "description": "wE3f2s3OYt7eY7WjbFy", + "tags": "BcnXy7fBVgp", + "type": 0, + "link": "4", + "icon": "IBaIGbiH" + } + }, + "signature": + "8ad74d9fe9db6e9750986bce3890821e8611fa840f86019b891a9d30d5d53371372f0ebc79dab2854e5c0bb62cab3e3a49d76ae05f1f424a1112df0fda771b03", + "id": "4804584599866287174" + }, + { + "type": 0, + "amount": "4054494300000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196078, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "7b3f813eb3b130e9d31b74371b2a221fa2915fed0fc4fd435d42ea89c7cb76d7eafb105a973080e00bf54e62f48eb969cb88a4371ffec3c225c2821f9619af08", + "id": "11811758250853952228" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "votes": [ + "+3b458651eb45887a10a95489dad3f14a708c8eb2c50af6abfcfb753d4b01dcb3", + "+0a8e2446495959401daa8adcf7646276eaf49e1cf10993e36ac5a21a39945a7d", + "+765a399060d14680c7a12246e642b7cb46fede3dfc8f43c6cb57dfefbc1a4533", + "+586e1f97641d9c736737e9755f658461ed961aa475be28361b8331468a2b8fa0", + "-332438da41f1c8019098b148482d51fa58dc026cd3fb49d77d4f7356ff0c063d" + ] + }, + "signature": + "15cbfa6843efa6c6574c986d371ab689cfdddc958ad6ec7b7a8024f98559478cbfae09c7cf4e62e30ffd1331e24951c534db96d3349f828ae9514578f98b120e", + "id": "11944214126253524732" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "delegate": { + "username": "g0chqJUQp", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "0271091d6055e831ad6c14b6a9fecd77dbf44c4a20285e4df51302134f8ffccc3dcc73ba2a8a5ea1fcebeafd65943f503ffee41a4283f798e7a9996b5eb5a807", + "id": "10417213059747712454" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "multisignature": { + "min": 3, + "lifetime": 13, + "keysgroup": [ + "+9f207919be15e45a5fd89ec5d699d72390a2ccc6eaaf587d88eefa46a7f7c01c", + "+f209131118dd05585d3131b5250caf8737b712c63dfc56dcf7d9678e0551b4a8", + "+9d2a2afd25ee6c48b4aef7f673bffde98c6bf278997a917cce739568eefd99e3", + "+163cb0f7d9da97611350f72741fececd41d066e45dc8370076b0fabc951232a7", + "+66c085d46ec6c3b7c9270f9e62b113ce4248c7bd0e5924355307c57fb8ef93ae" + ] + } + }, + "signature": + "76a4b1df52bb97bedeaeff199a8ee7408d1bdab3ba735ff70b7e0a362d891d622726814b12499ef2b01b825717f92ba6d3c4ffc5c6fb0a22035b63a140ad4407", + "id": "8904533490777066124" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "dapp": { + "category": 0, + "name": "lF7s", + "description": "BZqgVHKUZjsyr5", + "tags": "AYV", + "type": 0, + "link": "dzQ3leCut", + "icon": "sJoKLJOdAvtdktEl5hzaIttiN" + } + }, + "signature": + "99c6e43a6a06caab60b6147dd0eba6c7afbdc4b4f6b82e6911100a454ca1252dfca560a5ec65f01bb03f71fb5e37d8f3ad0255f77b809991acfcf42504eb0e01", + "id": "16584586901330410057" + }, + { + "type": 0, + "amount": "8184360100000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196078, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "53c1cb90f379c1afa1b7fb7b7c79689d02ed96da32cc337b511d48573da35fdf261f2f85f744a01a62866c2d672ad1a73286f94ef6af494eb4890f0b6a4a0c02", + "id": "8699527477254187757" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "votes": [ + "+dd8fb02b092402d4bb4114cc7b79b83fe7b30a18fceaa62d8a47f737604a34ff", + "+82e42e6f8f9f4d910d8a883e9163fa46190064c3d112b05f4802fd92fa55b431", + "+ffcf0152971388d89b007ab293349e55979bf3c81dfb2a41bc5304d3b4140503", + "+2771daeae7b042c8927c7cf86821bee85f27914c8be3b185a9ff2d749852f923", + "-64b517fc24df9e1cbc2797b6bdb0747912f3efa5c2b863d53fba95788ef6d099" + ] + }, + "signature": + "e1ea529a6c252e4a50408693378a38aec68bbd474ee8562b33a3572d5ce38a69a515f7448de5185be0fb2dfc23652c43ea0cc3490683df185b052952f9ec610e", + "id": "1804328474810539521" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "delegate": { + "username": "mUUn", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "f5a2c0946bcae73ce24a29dbbdc16c1f3fd897ece7de5ae6d2a891f98673b54106f0d516398960f545b00cc0cdbd131a14590b796185e7e72d66fecdb9eab206", + "id": "13111698433238994230" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "multisignature": { + "min": 5, + "lifetime": 14, + "keysgroup": [ + "+465f0eed0a5614af4c282b35e4f8cc7b8010783aaf848a8c073386f619208864", + "+a5df78890691147c6b13c9330e2e5fabebfa52ef1eb5d79dfeb3d9892d4c8f8b", + "+ad8a0767c7cc1e566888902c5588c35c6f75ba985777f6d2f23e428a9c7c470d", + "+f7b14239c88d7c1e6931532c1a248080bf24591b2b4226748fa0b4b0b060808d", + "+744d25d065b806d6a4028a8f9de7a4342b8cc8b647e04e7ff66f7ea53df9f8c4" + ] + } + }, + "signature": + "c0f3f4ec468b647823511b81e199af569211269f898cbd872291b0f609608815526f837ba18038cfca3b5002e01a0f7054cbc6b6f74de66a275eda4909124206", + "id": "8649508251318979973" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "dapp": { + "category": 0, + "name": "5pATdfOO", + "description": "MwNovspfAO0jTsY0o", + "tags": "HP2qmZaRajMVNaSxB9NypeS19HRfoknG1WlE4l", + "type": 0, + "link": "EblohNQI", + "icon": "D" + } + }, + "signature": + "f56cca3239759dca1db8be70124e8a3ba1a64e4d1d8e7299e27d82d96fa386cc84bed703897bd60f3b862dc1d201c1688af75dcb572f048ccfc3e69a38c24d0e", + "id": "6415932520816963164" + }, + { + "type": 0, + "amount": "3649003300000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196078, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "8953d989a4be6d2d0ab25dbb11b1268a21ce3681aba6c0fe391b2b7c18179f52af5440aca8b27794eb27d29b41a306f931882190a1ad922c274fb9bc5be63303", + "signSignature": + "0ccd222e27835d041622c469da6d69c1720202f6bb8258b7199a690b86d1671b45ef8ad03ff0b78a8dd91c38a9fad694d9186f414e83f9ad076e69b72ab02c0d", + "id": "10897127897715572989" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "votes": [ + "+791dbbf8e7f52eb253611c92758a25aed0b1ced2c1449272c251dde27a63e164", + "+2b0fa724137c99da93590c1fbe2f2a988cc28b1b7f66e17942d7c3026b19bd65", + "+bc97c09776318348138aaf7031b642a665bb3d2bd5e76ccc525dcf74fae960fe", + "+b3036b5bde0f106f86f72245ca238148e7871235c236fb41bb08d8d0960ca807", + "-e97c6e9027d940686a92cc56069822ef64e17926ff677f12c88196d0441b8a8a" + ] + }, + "signature": + "ebf2a10ef69c5282b554b9d23c21c9884e558376f42972515d4d4397b535bb2d521ccfe48f28468a0371e00f2af7550fec1e17d374d75c1abc15051341b4cc00", + "signSignature": + "640fd85321213dcfa16ce7fcad219aeeb284119016cab7650b83beca2634650e834308996b85861c8046997344d1ff64be7c56bb43f77cea26655d2c17b6b608", + "id": "17799333624445334933" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "delegate": { + "username": "r9bGwAqXG1pOnVL", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "5c0b596006acb565cee01d22b5de2e60dde69df3c5cbf2e96c4242cb80811f205ae05fcf1110810bd477ad3e67cf42e103c3160e63207bd7d78aa1dbe1496300", + "signSignature": + "5030bf9be108b4a4084a32a7f35d74b893bdf4c67678b7f94b923b3cf1048d890e94e816a210e4442fe8e7bdab3ab45c1959adae14d6200cf552d3413a10900d", + "id": "12155900509392441171" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "multisignature": { + "min": 2, + "lifetime": 9, + "keysgroup": [ + "+56364190bc7dd833b37450a45a4beddf1bd7408324b75bf52f85decb424a159b", + "+11364ec15a0060b0e07846a5dfa81d2f43351bf35b360dc9f780ececb6402ad4", + "+e29841ce6c5147027b52eb2551ece8c3aa62090f563093e243a978a0dccee692", + "+f079d3f68a1b0b03824b229efb0814df113f255f1cfb06f26bac205bcadb2840", + "+95c11960a7deacab27f59518f1b47b3a7f9c37819ca80e9c0fad8a39a2eb3917" + ] + } + }, + "signature": + "2afa46bb4563de7f56254b06c8752a4bdf76a798971b1c9644d7e74bac7e58c8d234b0650d49462b2ca9fa6cdf26c572da8cd680e8de62bd9cc14f65f97a180e", + "signSignature": + "b8d0ab01ca30cd06f792fcc3e82ad1df451f6239fb470444d026c9e5b32fc9ccee3ab9deb398119b9d23ff76c3a807d210f32310a3b4c43e7ec3d7e05e6b6203", + "id": "14759833290133825198" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "dapp": { + "category": 0, + "name": "nryO", + "description": "7qs1Iv", + "tags": "fZdhM1QGdTlJWjhSZzPsH", + "type": 0, + "link": "OzG0whsxmEda24cfdA", + "icon": "pMOY8WpXagaPdVptqR1prGPdM" + } + }, + "signature": + "bb5f425e4c7aeed0f4899b22692e240e22e41756cae85113c73a200cdc607005c28d218bd29de212d4b2c65919b174ea097719341f5f023ade9c26c90d75ea05", + "signSignature": + "2597f3aa8afea57a1b8ab2328db3ee5abf315f0b367b686e50677da0ffabceee6694d9bb1c6613b7b218ee6c68ca5457261255dba185709fc44956a4eb523707", + "id": "12078587542208625234" + }, + { + "type": 0, + "amount": "2312331300000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196078, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "1cc982da7c70f06b32debb6bd3032c469a3ad5444b0257745297dbccf71050f382191e797daeb707a0eaba9286917fab90c5a37c8f2f49301febecc777c1eb0c", + "id": "8974713600754318131" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "votes": [ + "+2af82af1fd00f4c0e36037e124309a083769e307025c10ff29c66cac577cafec", + "+186521db6b809b250113a5bba66a1a6507251b8abba1d24f047b0984c050a1b5", + "+28cf88ac965648c238a2fabb8ac7b8fe4aba6327bb32bcc6aa291a8ce59a4c78", + "+77731ea9884dd4c684b7571b7e78b998fabbda4a66715854c40b7ee368ae446b", + "-d6124c312884182d2fd4c51a829a480cb30d00052daf257d224e62ab1969d268" + ] + }, + "signature": + "d0d603149cdac8ebd24d2617daca259d7cb0d7e14429421468e1a93f8c118e78ba78e0080e4b9b0d57daeefa0b973afff8cf2e984db2878730b5d868b3eabc09", + "id": "5300315452366475326" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "delegate": { + "username": "BmgeSxNgl7gWN4", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "ebc920b067e78f2350b7baceae66f4a74397912beed8ac9a8d1656fc28187b8849bbb593762b62843e7009cb15a626a7157eb3a0e6c828f69364932e8c0a2204", + "id": "14549490938474611289" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+e64df51060a2ce43f91b24ae75cc83f1866f9fead2ca2420cf3df153e6368a97", + "+4ef26ed51f4b82134b16f25a2556bed98a0b3963a17c0d2f0fa87f67cc6f29fe", + "+818d34925549e0aea67f1b82190c3e288b1c66de95ce699c2f5c87f1e622012c", + "+a2eece2bf0ee74e492939ac84723646270bfefab84914a5cf68baffd9bb84858", + "+46f3ec44dbcffe28c6bcd4eb494ce24ceea51677eb67005bdd4dd3202db55251" + ] + } + }, + "signature": + "4c8a3bfaacfab18a7ef34ce8d7176ea2701dfd7221a1c95ecbc1cce778bbccdb7cbbe1a87b3e9e47330f1cae6665c4a44666e132aa324de9a5ab9b6a1e2b1d0c", + "id": "18066659039293493823" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196078, + "asset": { + "dapp": { + "category": 0, + "name": "y2OPqyGLuw3F5u2Sxd", + "description": "xBIt2niD", + "tags": "qQvydic4uuw61X7a7cZ6tjrUKK2C", + "type": 0, + "link": "MaRhi5E7G6EZu7dxaaE", + "icon": "To900QF" + } + }, + "signature": + "a2910f485580a903e125b02198b0d9d8f2a9509bcd4e491932b2c30c06fad3d81969547f84073516ee24ce3036dbf388e63eede7e80848b555669c6d2392040b", + "id": "13459454681692221740" + }, + { + "type": 0, + "amount": "2801887300000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196079, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "be08dc16b70c47f58520f93599e72ad087d323adc312fc5cf89d57938f7a098686686551a834e52180e5b07a2b7339982581871b2da69f38fdf72df93c022901", + "signSignature": + "f2367e1be7450922a72168390dc1e1dfa7e3a685bb4755938b7f0ff48c18bbda4a11ea3309aaeb2398a5b110ec341d7d0b30f0f9cf6337231936b444dd4bb502", + "id": "13907564008476426594" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "votes": [ + "+6af5a4fdf2fdd10e565cd22dbc0bf942fa8c59786a29a4b3706ffe559331d636", + "+5bc0c67294e9a5be07c00fe051a50409502a62aa87032b60e737a15d58449333", + "+79d64906a7a4cf89736ad1fb1819aeb69b07982718b45b590b1102d2ee99c1cf", + "+2b0acc7ba95b1971c60f9a6da39c947fb79a1c8b359b4f054c371d40541afaac", + "-9e117730c9a4adf1f031d122635db1f84214690cd0632302103c682c2115074e" + ] + }, + "signature": + "f47f4b4b5b58140281e5d61a279ff4d009004114261e3ff39a8aa6119e8de6e7975bd9b49eb10aef58edd81061f395141828e5c267131add7e50a02297e64207", + "signSignature": + "95528967d585ec9a71352ce753fb5475e54c272102d6808eee4b99e6a64561806767b5bb1e5dbd7500ca46cdddecd1bab03e5507f4d70b5132afa04c7df47b0d", + "id": "408170376416400414" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "delegate": { + "username": "h9iWcquSm9iKpFw", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "e051ee9441a04d046d390e70e15eac640dbd0289a27c2e82942be648194b9684e9eb86c9ac19f50293567ab8238047abf2d04c73f52ae7ff03230016c840440c", + "signSignature": + "25f2e872b5c20445e5c8551ae0488edf3773736f401052d3689b061c418a79f9563c0b388ba2432608a67ba57cc6e8d7292550a626ad3f1a7e29e4dab631890c", + "id": "8936243264570089909" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "multisignature": { + "min": 4, + "lifetime": 30, + "keysgroup": [ + "+5bf096b1964c2a8035a1836e20aa72e775d8ed2d15b13b50c170da8f49e1c13b", + "+7167b3f440be68d7811b054f90906c595ee127e26e146ca27ebf728449b9ba63", + "+c472e853cf1e706c4e3025ec0300ed1fb03df590a7bdda8a0badca6888476591", + "+7902cd178a000cb672530ff982276e1b2b94c845988ac773abd775e5fda04a4b", + "+93d29f8c7663e4aa273176bb74e35cd8bd5e09b9688b8e5f21cbac93761e4bab" + ] + } + }, + "signature": + "615bfc47244237b3bb6eff7f032a4ba0530cce9ce1627f488b9075672383fff45b96641daaa715da37bba6c4b09ee12d77070e8a5c1493acc833d1806946c802", + "signSignature": + "a29ce1c2f682f924a68f85083ea6934edab494a2a81ffc3aaf090ba3a9aefb692317c97a0ce7187b1bf9bbaedb71d5f440ccd986279bee280b16b2ff5efd1006", + "id": "718478589882001258" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "dapp": { + "category": 0, + "name": "0REwN", + "description": "J82zELUzEnV", + "tags": "e", + "type": 0, + "link": "kPfG6Bt", + "icon": "ium" + } + }, + "signature": + "c15cc992aa2f1ac6effc00c894e98fce68ecece7bd4ac00664437ed711b8e1bf066ea433a613476767d14c85e1cab66d548fdec9fd56f96d1b112bee224c090c", + "signSignature": + "01b142ee1ffe3dd466fe863557500296dfd8313d098ca4d1897167e3138556999f91f8f73d337b53371fc643f713fead0461a0d3b2416585d3ca236144d4f40b", + "id": "6479396717400039057" + }, + { + "type": 0, + "amount": "5061165300000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196079, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "b2cef4445fc63d3100bfe4b8c5a3988962378d5f05f3f31a874545341d1421f40f6bede8195fb41de4998454510a578490dcbc5a646bcea75fe459b8be1c6002", + "id": "17133129148236935159" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "votes": [ + "+be4bbac72323ecc09bfe619fa112c5dcd42191f28e1f60b6a51b84a95f248941", + "+3180e1f79f626a2ebf2fc9bb4282c931becbd8858e49b370d00055a2d6b4a062", + "+d47f95719687003314535dd710180f1ff0e152773a772c625212bb2f034b854a", + "+7a9147a984e3555fad99d774a90831baba8cc2b2f4a7e06eb3f2be2f0d3cdb5f", + "-cb201cd4887eb52834a1e1a7a59c9903393e1abe2b75d61db81ad4199bef49a0" + ] + }, + "signature": + "ce02d218620a527f05baf1b3f125f46a0d5faefafc3bc359f0fd65511d3b406843cbee3a4d156669267d6510f870b5d359a07402f6f1695e5de4354822a6470c", + "id": "5473217291152754023" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "delegate": { + "username": "6YGNabt2vP", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "219af05289f95a6c5c920760d77afa80c750f11f221d21b6ae47942391d83aace624edc3814655cebe77ae045613c8148cbda97b3cda95ea52e19349611e7103", + "id": "4535306837758230670" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196079, + "asset": { + "dapp": { + "category": 0, + "name": "mZDJS", + "description": "O1sUrkoqguTAET3O7B", + "tags": "r2r9zWXWF3faCg", + "type": 0, + "link": "FYZZq0oT9i4UtRb3o7rLLKxQQFavCkrdgQ", + "icon": "KgpJyKuT8AxYN9JQ" + } + }, + "signature": + "cb4bc3a6279b9b994ee182f3dd65628910b8e0570685797877bbb2ded9679b6b00c3a6113b034ac5bead165b78dfdc4bb71620e3f99daf871d9399758a9ba30b", + "id": "17759930910428062541" + }, + { + "type": 0, + "amount": "4876278400000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196080, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "832fa468ebdad7a5accb6b16b8c82222f0a97bc00233451a89e18100dc22d9df2fc722a09549d3ef832d483c8e8c18e9765e963b5203a147c0c4b9236021cd06", + "id": "11425498570993926585" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "votes": [ + "+bfabfacd8fbd8d8a8aa825c07344d627c8e5b548b3c8af0bf0c447aad509c1ca", + "+01da309703eb58d4e6fd1ba576ea37bf9b1d40eae756907c14434e3922900e13", + "+9f7744d69fad50a9f187a6bc7a2f9847aa70302cd11459a33d7278eb0cf14dea", + "+2d417477f8d4690188fa277eef6a49b0386a4c2a68643e61ed507fa14c1157d5", + "-d8e2228f3bf31ab2cd455b8d04df8f37139c725c5819b328492d6e6c7a3779fe" + ] + }, + "signature": + "26e5a15fc5fe2e17cee68c61c73e2ca2b8c616cfcd6ae4aa9137f32bab7617bf11ba1ca41826c45244a47a0ff273c1e1eadaf24c88aeda67ff9993597ed0800b", + "id": "912105933902813252" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "delegate": { + "username": "a4axYoN", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "aa609c506bf96cd4c179cff4dacae3574ee84a075adc8b626181d7a357fa30498ac04ee4a536848674131a7629871c7e89c3d7cf5b98fe8bb0c84e7144da890f", + "id": "13972423096514804371" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "dapp": { + "category": 0, + "name": "WRZhl8", + "description": "xpxq9w6h", + "tags": "bC1605OZ6RgRRj2", + "type": 0, + "link": "2RKLfLCm13xX2eZ4WMoWBAAig6QioF", + "icon": "Yht9kxY37iCys8FVaFgBqBlk8WG" + } + }, + "signature": + "6cf050d618b6dc8b5e993de10eeba304d6f77eaf62e7893d976bcbdacaa194b89bac3c5bddb6e81a5cface98dafdc9be5b971768acaf8e5a820d460933f49706", + "id": "13519964049473247354" + }, + { + "type": 0, + "amount": "7543868600000000", + "fee": "10000000", + "recipientId": "1859190791819301L", + "timestamp": 54196080, + "asset": {}, + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "signature": + "ce60ee3b844d3bbd8030b842ba9568c857e6de41aa2e19322ab6314b8e66afa419752816fd17ad88a75dc8ef763de782be68cc27d3d47e0b5cd63f38de6a2d0f", + "signSignature": + "2d572dcce12b1e8acf7e46b0a40576d3408045fd4f7e432e4a1853f8092e387e322ad390e14f091176f6fd84bcb72b7011aecd9390230ea4a21db74546abc507", + "id": "6263613751669009115" + }, + { + "type": 3, + "amount": "0", + "fee": "100000000", + "recipientId": "16313739661670634666L", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "votes": [ + "+0b8a49bb952e5ed645cddb5fb9393c2f8a1be4f261c7623ce0ddb2b6b2a1be3e", + "+9cc4e085fe359f20c110ce5cf2ff30ffb4d6d613922e31afd572693be8e3f8ba", + "+d2133bd20300544bc4e16ba828223dd3d58955425634a2e2cd6762821f6176a2", + "+f11575b059598ffb9f0505e72041d05c685f949c4cce46c4366f50177d97dfbf", + "-cdfda7456076b9025b2964ef0679e8e1a5c3b8cd0d63345d7a05ac6faeea5f8b" + ] + }, + "signature": + "88c499e3dd5e10fecb16a192df9f8c81c32e9a7d2ac1f473bb076c7598cb431b14eb17423bf9493d8b112ca74b7cf1c64caa4a044cbac35f895185906f1b6107", + "signSignature": + "30dec17a7d2d0b13df25e958e66481407b87da3f35a9b8c7e93044dcb4cf13970491cf2d9b0778258865b051f8eb3b53b8e15a52d2cbdd48ed67ff2d55edec07", + "id": "15014970331019583344" + }, + { + "type": 2, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "delegate": { + "username": "L4cPrZgeE", + "publicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f" + } + }, + "signature": + "9e3d66ed9ba75a26b7380e09c29c38670b09233b9ca01ba93233fb0ce38e1c1fc92d66577292d2d70738d756a544878e044c3f49eb0dce22ad3c85c6211b5f09", + "signSignature": + "6ca1fe51268a786412f8f757d5fc0243f8ae00fa88812ae8501d399ed7e68326403fe68a508df4ab8ba48a98ac08d0f061ee21f5001f29cbc2f5343b0a66660f", + "id": "9014172721793470554" + }, + { + "type": 4, + "amount": "0", + "fee": "3000000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "multisignature": { + "min": 5, + "lifetime": 38, + "keysgroup": [ + "+617286b8de6ef7a91c7a0915a3c45ca9676216cbc8dc14bffa5e9022ea3a5683", + "+8141def6de5e8c92843d2af9589cd2568f3bb5e475dae78d334abde60682695c", + "+925e387ca6c63427391adb697273a4da8852944066ab33d50cb8e6279248427e", + "+9645504d7e06135a7a5db072aef3a6d80bb7ec8ca8cb61bc8f369faaa05587a8", + "+e1808d0e57e47bc1ffb21683c0bf98bbabe1c7e43d6bc6c2890a16d03543c100" + ] + } + }, + "signature": + "4a058d11726300ef0dd62941ce8f2ee861383f9448f17580826dcbef9cb62b0d953004eef3659a8b6d16bfd25b0732f93877f9b29e8828946ca849d9bb7b2d02", + "signSignature": + "ac3a9eec518b8c725aa8f8620546001f72b3036078242ab0c7639b6d6891ba4330448cc3e4f5c31516e896af4c5fa998fc2ba2673655a4cfb76168c8785c9109", + "id": "2884334432991037421" + }, + { + "type": 5, + "amount": "0", + "fee": "2500000000", + "recipientId": "", + "senderPublicKey": + "c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f", + "timestamp": 54196080, + "asset": { + "dapp": { + "category": 0, + "name": "OpwYfwHdAfO4ncn7D", + "description": "Ds", + "tags": "1nkfYVcgsisKnXyn7k0", + "type": 0, + "link": "WQDusb0DgH", + "icon": "RPAFQsBIsE" + } + }, + "signature": + "524afb27d284e4e71ea44de9d23f9a1cd603f37f81a55187a61ca92391dce1994d2c4a5e3f0ae8490caac66da5125a0d03f30d0775592aa02d451a72e3ed9303", + "signSignature": + "7043b795dab467e3d3239e7c379ee1b07914a8ba04e639bda406f6ed8810d75a7b4066ad5e90ef3c2030927b917e8492db59ffad017ce51878b7217b27d3a506", + "id": "7976119586785833934" + } +] diff --git a/elements/lisk-transactions/fixtures/valid_account.json b/elements/lisk-transactions/fixtures/valid_account.json new file mode 100644 index 00000000000..92804c893a1 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_account.json @@ -0,0 +1,7 @@ + { + "address": "18278674964748191682L", + "balance": "10000000", + "publicKey": "0eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243", + "secondPublicKey": "" + } + diff --git a/elements/lisk-transactions/fixtures/valid_dapp_transactions.json b/elements/lisk-transactions/fixtures/valid_dapp_transactions.json new file mode 100644 index 00000000000..625d83fe3cc --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_dapp_transactions.json @@ -0,0 +1,95 @@ +[ + { + "id": "366869793417060333", + "type": 5, + "timestamp": 2061751, + "senderPublicKey": "f19d39b087a3174cbf113162f2dad498edbf84341ffbfeb650a365ac8a40ac04", + "senderId": "11262132350228604999L", + "recipientId": "", + "amount": "0", + "fee": "2500000000", + "signature": "c990799d81eb166ad39af87995a80665f98cfc479617106f4bdca2c9d3b01beb151cf39e089aac3c7400ad26b3befe5bf1c66179368656f8d3d5f34c150af503", + "signatures": [], + "asset": { + "dapp": { + "name": "mschmoock/sdk", + "description": "Test forked SDK example", + "tags": "test", + "type": 0, + "link": "https://github.com/m-schmoock/lisk-dapps-sdk/archive/development.zip", + "category": 8 + } + } + }, + { + "id": "14602496231523117483", + "type": 5, + "timestamp": 6030199, + "senderPublicKey": "421d376fe99f7e66bcc0bc2722da8e1322c738bb75caffb2dabea71107fa95e3", + "senderId": "14689731924039906747L", + "recipientId": "", + "amount": "0", + "fee": "2500000000", + "signature": "01f2387212c55849ad7f2fa0cf20da53177af4e69461b48b5a6b37a97b7baf5992f272c431bbeaaf8a353d1c01538ee37b1fefdb3dc2effae113a7249af83f01", + "signatures": [], + "asset": { + "dapp": { + "name": "bitbooks", + "description": "bitbooks", + "tags": "bitbooks", + "type": 0, + "link": "https://github.com/VivekAusekar/liskApp/archive/stage.zip", + "category": 0, + "icon": "https://iconverticons.com/img/logo.png" + } + } + }, + { + "id": "17251328029729996639", + "type": 5, + "timestamp": 6149924, + "senderPublicKey": "38fce1516c4dac04f8a947b3a8d8bfd3bf1082d564bf1f2b8b7ad89e827341c0", + "senderId": "9407081917699190773L", + "recipientId": "", + "amount": "0", + "fee": "2500000000", + "signature": "08bb7e5c418bef98366c56cb2e6f8122b3e1675995d7fe308598e10bd64dc8ad240689ee0679f924c42caaf3d2b67db84ff875e7194b886832a34af8bb1f7f00", + "signatures": [], + "asset": { + "dapp": { + "name": "d3", + "description": "test", + "type": 0, + "link": "https://github.com/d3/d3/releases/download/v4.2.1/d3.zip", + "category": 4, + "icon": "http://www.webopixel.net/blog/wp-content/uploads/2014/04/d3-icon.png" + } + } + }, + { + "id": "13227044664082109069", + "type": 5, + "timestamp": 59721988, + "senderPublicKey": + "305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad", + "senderId": "13155556493249255133L", + "recipientId": "", + "recipientPublicKey": "", + "amount": "0", + "fee": "2500000000", + "signature": + "09f5e6b20e4b6eea012d7d6da487cc0c72fc8dfd53806882a65a8ecdeaa3dd07ea36356e8075e5c6c7e8515f664d81d59fa6ebb9c622a730de39bdf7c5cb7903", + "signatures": [], + "asset": { + "dapp": { + "name": "abcdemo", + "description": "demo", + "tags": "demo", + "type": 1, + "link": "http://google.de/abc.zip", + "category": 1, + "icon": "http://google.de/test.png" + } + } + } +] \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/valid_delegate_account.json b/elements/lisk-transactions/fixtures/valid_delegate_account.json new file mode 100644 index 00000000000..6b05c8f0744 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_delegate_account.json @@ -0,0 +1,7 @@ +{ + "address": "17676438278047402502L", + "balance": "15412982278208", + "publicKey": "dd786687dd2399605ce8fe70212d078db1a2fc6effba127defb176a004cec6d4", + "secondPublicKey": "", + "username": "genesis_10" +} diff --git a/elements/lisk-transactions/fixtures/valid_delegate_transaction.json b/elements/lisk-transactions/fixtures/valid_delegate_transaction.json new file mode 100644 index 00000000000..20d7e09033c --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_delegate_transaction.json @@ -0,0 +1,17 @@ +{ + "id": "8371141882694519315", + "type": 2, + "timestamp": 85173795, + "senderPublicKey": "ce37dbaf8758001efaf229be3f18c88e28f13131c2b0ddef5e0980b3a401b1fa", + "senderId": "11160212819235534805L", + "recipientId": "", + "amount": "0", + "fee": "2500000000", + "signature": "5c86ce1ef12b6bf310d3206e90dfa289b7899c3cbbda48651e055d3768108f3bd61aeb1f20afcf0d6e3508c9413891fafbc1ce7937b718dfd7aa6be42a83c50a", + "signatures": [], + "asset": { + "delegate": { + "username": "0x0" + } + } +} \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/valid_in_transfer_transaction.json b/elements/lisk-transactions/fixtures/valid_in_transfer_transaction.json new file mode 100644 index 00000000000..80cfeaa1c28 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_in_transfer_transaction.json @@ -0,0 +1,56 @@ +[ + { + "id": "13847108354832975754", + "type": 6, + "timestamp": 60991500, + "senderPublicKey": "305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad", + "senderId": "13155556493249255133L", + "recipientId": "", + "recipientPublicKey": "", + "amount": "500000000", + "fee": "10000000", + "signature": "be015020b4a89a8cc36ab8ed0047a8138b115f5ce3b1cee35afa5af1e75307a77290bfd07ca7fcc8667cc0c22a83e48bf964d547b5decf662d2624642bd2320e", + "signatures": [], + "asset": { + "inTransfer": { + "dappId": "13227044664082109069" + } + } + }, + { + "id": "16982944615812757099", + "type": 6, + "timestamp": 63895588, + "senderPublicKey": "e65b98c217bfcab6d57293056cf4ad78bf45253ab56bc384aff1665cf3611fe9", + "senderId": "18237045742439723234L", + "recipientId": "", + "recipientPublicKey": "", + "amount": "1000000000", + "fee": "10000000", + "signature": "4d5436e731e0f957d6d7eaff2a7bfc13f7a12f963edf88de13419151b74b6664860ddc8ee41588b6200b1018b535f72d3b54e69ccfbf94b6ef1d9b8a8d275205", + "signatures": [], + "asset": { + "inTransfer": { + "dappId": "16337394785118081960" + } + } + }, + { + "id": "16286924837183274179", + "type": 6, + "timestamp": 63898440, + "senderPublicKey": "e65b98c217bfcab6d57293056cf4ad78bf45253ab56bc384aff1665cf3611fe9", + "senderId": "18237045742439723234L", + "recipientId": "", + "recipientPublicKey": "", + "amount": "1100000000", + "fee": "10000000", + "signature": "e814fd4924cb1ad94adc788965364ab1e1c9957b03fb177f18866db2ef2254af2b30bd7ffa1b794d239f8990c6d86003be8fb09d3cc4c018979a459e3f82490e", + "signatures": [], + "asset": { + "inTransfer": { + "dappId": "16337394785118081960" + } + } + } +] diff --git a/elements/lisk-transactions/fixtures/valid_multisignature_account.json b/elements/lisk-transactions/fixtures/valid_multisignature_account.json new file mode 100644 index 00000000000..15be41336b3 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_multisignature_account.json @@ -0,0 +1,13 @@ +{ + "address": "9999142599245349337L", + "publicKey": "500660b67a2ade1e2528b7f648feef8f3b46e2f4f90ca7f5439101b5119f309d", + "secondPublicKey": "", + "balance": "94378900000", + "multiMin": 2, + "multiLifetime": 1, + "membersPublicKeys": [ + "40af643265a718844f3dac56ce17ae1d7d47d0a24a35a277a0a6cb0baaa1939f", + "d042ad3f1a5b042ddc5aa80c4267b5bfd3b4dda3a682da0a3ef7269409347adb", + "542fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf" + ] +} diff --git a/elements/lisk-transactions/fixtures/valid_multisignature_transaction.json b/elements/lisk-transactions/fixtures/valid_multisignature_transaction.json new file mode 100644 index 00000000000..1eaca373699 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_multisignature_transaction.json @@ -0,0 +1,28 @@ +{ + "id": "16018411649867568064", + "type": 4, + "timestamp": 24659540, + "senderPublicKey": "500660b67a2ade1e2528b7f648feef8f3b46e2f4f90ca7f5439101b5119f309d", + "senderId": "9999142599245349337L", + "recipientId": "", + "recipientPublicKey": "", + "amount": "0", + "fee": "2000000000", + "signature": "0ad43fb934626bed36da6e145f27fa3d5d54d255d179503ca17b9ed009af1180c2595322361b1adda9e2afb29252ffbd3f36c19a56debce5e759df6826d0a609", + "signatures": [ + "e527764e5bb5a4867b3af114320a063f2ae1a69a89d4a83f23d2950d1779811ff6d4344edb1b95759a1a1a1b313cdd913f335f1fcfbeeb20f1e07f951f7fcb06", + "ed2ae7d77eb28219b124930471a6a0069ac0a2dcc7bf2d076f3111a1594df2434cf5739cf0a7a40b37e508632681baee2229e55d735f80ab632cdfcb5847c202", + "2c8d9beefd6a7dafa67bc601b2f49eea5f3c0ede5976f598abe32028b8e27d5f5cd6b7d87da71426f1f696f7cde7d704da07aa1b6a45708a4be3865066616d07" + ], + "asset": { + "multisignature": { + "min": 2, + "lifetime": 1, + "keysgroup": [ + "+40af643265a718844f3dac56ce17ae1d7d47d0a24a35a277a0a6cb0baaa1939f", + "+d042ad3f1a5b042ddc5aa80c4267b5bfd3b4dda3a682da0a3ef7269409347adb", + "+542fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf" + ] + } + } + } \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/valid_multisignature_transaction_no_signatures.json b/elements/lisk-transactions/fixtures/valid_multisignature_transaction_no_signatures.json new file mode 100644 index 00000000000..f78958df332 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_multisignature_transaction_no_signatures.json @@ -0,0 +1,20 @@ +{ + "amount":"0", + "recipientId":"", + "senderPublicKey":"8e01392645649dcea5cc7317bfeae3e011c4e9dbf1489de3795ea6f2b929e893", + "timestamp":88355975, + "type":4, + "fee":"1500000000", + "asset":{ + "multisignature":{ + "min":2, + "lifetime":2, + "keysgroup":[ + "+142d1f24e17d3c90b0f2abdf49c2b14b02782e49b2ecfe85462ed12f654d60df", + "+bb7ef62be03d5c195a132efe82796420abae04638cd3f6321532a5d33031b30c" + ] + } + }, + "signature":"f26a5bd51a937db37d2832a60cedd17758b7a89aaea31d610e60f096839a1de9d450a2f147e2cdcef28ecea98319250d00a89826f9630cb623215ab513334004", + "id":"14644504552633286790" +} \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/valid_out_transfer_transactions.json b/elements/lisk-transactions/fixtures/valid_out_transfer_transactions.json new file mode 100644 index 00000000000..6753ce2023e --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_out_transfer_transactions.json @@ -0,0 +1,78 @@ +[ + { + "id": "2897056580360618798", + "type": 7, + "timestamp": 63897154, + "senderPublicKey": "e65b98c217bfcab6d57293056cf4ad78bf45253ab56bc384aff1665cf3611fe9", + "senderId": "18237045742439723234L", + "recipientId": "18237045742439723234L", + "recipientPublicKey": "e65b98c217bfcab6d57293056cf4ad78bf45253ab56bc384aff1665cf3611fe9", + "amount": "100000000", + "fee": "10000000", + "signature": "286934295859e8f196f00e216f5763cfa3313cc3023e4a34e9da559a96cfb7d7f1e950513b77ace49f56cab1b56b21b05e3183f04d4f389b0355e5b8e9072c08", + "signatures": [], + "asset": { + "outTransfer": { + "dappId": "16337394785118081960", + "transactionId": "12345678909876543213" + } + } + }, + { + "id": "7297225435992500205", + "type": 7, + "timestamp": 59722128, + "senderPublicKey": "305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad", + "senderId": "13155556493249255133L", + "recipientId": "13155556493249255133L", + "recipientPublicKey": "305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad", + "amount": "500", + "fee": "10000000", + "signature": "a85f18853aa209da756f82799b072530b0028db48619141025df0ede96fd0e172b1625650a12fb872a1f13070ce5bf4494fdca3c7cb2ad36a779fc0dacdcdb09", + "signatures": [], + "asset": { + "outTransfer": { + "dappId": "13227044664082109069", + "transactionId": "13227044664082109069" + } + } + }, + { + "id": "954328122073089358", + "type": 7, + "timestamp": 59722412, + "senderPublicKey": "305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad", + "senderId": "13155556493249255133L", + "recipientId": "13155556493249255134L", + "recipientPublicKey": "", + "amount": "500000000000", + "fee": "10000000", + "signature": "d097cb3a2b4b235214d8ae7d99059a62899fd4f974c1963f8fe700f69785228b5264062740809a7c5a356018c41cfd4128e1a66396a7bae47c47f507e39c580d", + "signatures": [], + "asset": { + "outTransfer": { + "dappId": "13227044664082109069", + "transactionId": "13227044664082109072" + } + } + }, + { + "id": "7297225435992500205", + "type": 7, + "timestamp": 59722128, + "senderPublicKey": "305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad", + "senderId": "13155556493249255133L", + "recipientId": "13155556493249255133L", + "recipientPublicKey": "305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad", + "amount": "500", + "fee": "10000000", + "signature": "a85f18853aa209da756f82799b072530b0028db48619141025df0ede96fd0e172b1625650a12fb872a1f13070ce5bf4494fdca3c7cb2ad36a779fc0dacdcdb09", + "signatures": [], + "asset": { + "outTransfer": { + "dappId": "13227044664082109069", + "transactionId": "13227044664082109069" + } + } + } +] \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/valid_register_second_signature_transaction.json b/elements/lisk-transactions/fixtures/valid_register_second_signature_transaction.json new file mode 100644 index 00000000000..034ec33691b --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_register_second_signature_transaction.json @@ -0,0 +1,18 @@ +{ + "id": "11661477170553280937", + "type": 1, + "timestamp": 1653152, + "senderPublicKey": "8aceda0f39b35d778f55593227f97152f0b5a78b80b5c4ae88979909095d6204", + "senderId": "10020978176543317477L", + "recipientId": "", + "recipientPublicKey": "", + "amount": "0", + "fee": "500000000", + "signature": "06041001f829ef0bcf0986bda00afdb2b1b58b604d0636325562146d13018cd02917c39ec4e98a89401554b08441b6685079013cc6951666a87a31997ee07909", + "signatures": [], + "asset": { + "signature": { + "publicKey": "ea8ff0123782a82268ddd69dbbd1b91ffaf2243a3415fc8d3ee8c5f0a5a48e6c" + } + } +} diff --git a/elements/lisk-transactions/fixtures/valid_second_signature_account.json b/elements/lisk-transactions/fixtures/valid_second_signature_account.json new file mode 100644 index 00000000000..937aac0f21b --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_second_signature_account.json @@ -0,0 +1,7 @@ +{ + "address": "10582186986223407633L", + "balance": "9500000000", + "publicKey": "bc10685b802c8dd127e5d78faadc9fad1903f09d562fdcf632462408d4ba52e8", + "secondPublicKey": + "bc10685b802c8dd127e5d78faadc9fad1903f09d562fdcf632462408d4ba52e8" +} diff --git a/elements/lisk-transactions/fixtures/valid_transaction.json b/elements/lisk-transactions/fixtures/valid_transaction.json new file mode 100644 index 00000000000..e2810cd29f6 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_transaction.json @@ -0,0 +1,17 @@ +{ + "id": "15822870279184933850", + "type": 0, + "confirmations": 123, + "height": 2, + "blockId": "13115894772963772254", + "timestamp": 79289378, + "senderPublicKey": "0eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243", + "senderId": "18278674964748191682L", + "recipientId": "17243547555692708431L", + "recipientPublicKey": "3f82af600f7507a5c95e8a1c2b69aa353b59f26906298dce1d8009a2a52c6f59", + "amount": "9312934243", + "fee": "10000000", + "signature": "2092abc5dd72d42b289f69ddfa85d0145d0bfc19a0415be4496c189e5fdd5eff02f57849f484192b7d34b1671c17e5c22ce76479b411cad83681132f53d7b309", + "signatures": [], + "asset": {} +} \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/valid_transaction_from_multisignature_account.json b/elements/lisk-transactions/fixtures/valid_transaction_from_multisignature_account.json new file mode 100644 index 00000000000..b9184123e75 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_transaction_from_multisignature_account.json @@ -0,0 +1,17 @@ +{ + "id": "17286708138898213252", + "type": 0, + "timestamp": 24660268, + "senderPublicKey": "500660b67a2ade1e2528b7f648feef8f3b46e2f4f90ca7f5439101b5119f309d", + "senderId": "9999142599245349337L", + "recipientId": "6281405850162033335L", + "recipientPublicKey": "93ec60444c28e8b8c0f1a613ed41f518b637280c454188e5500ea4e54e1a2f12", + "amount": "1111100000", + "fee": "10000000", + "signature": "89a447cc5382f3ca07bc937067a88814de0c01d2240d814edcdc815bfc0c24f1dfbca364768c84bec738735aadbf53abf86371e924d842d737660611a0dff10c", + "signatures": [ + "f223799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c", + "36a9b1f69af334a85c1ec6be23076071c76986b60583d1a9367f21ec0d26c76c11a9f106ab2712ffc47627a6bc63e0292af998f64103d586ddce12dfc1caf405" + ], + "asset": {} +} diff --git a/elements/lisk-transactions/fixtures/valid_transaction_from_second_signature_account.json b/elements/lisk-transactions/fixtures/valid_transaction_from_second_signature_account.json new file mode 100644 index 00000000000..6960046cb5a --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_transaction_from_second_signature_account.json @@ -0,0 +1,18 @@ +{ + "amount": "10000000000", + "recipientId": "13356260975429434553L", + "senderId": "10582186986223407633L", + "senderPublicKey": + "bc10685b802c8dd127e5d78faadc9fad1903f09d562fdcf632462408d4ba52e8", + "timestamp": 80685381, + "type": 0, + "fee": "10000000", + "recipientPublicKey": "", + "asset": {}, + "signature": + "3357658f70b9bece24bd42769b984b3e7b9be0b2982f82e6eef7ffbd841598d5868acd45f8b1e2f8ab5ccc8c47a245fe9d8e3dc32fc311a13cc95cc851337e01", + "signatures": [], + "signSignature": + "11f77b8596df14400f5dd5cf9ef9bd2a20f66a48863455a163cabc0c220ea235d8b98dec684bd86f62b312615e7f64b23d7b8699775e7c15dad0aef0abd4f503", + "id": "11638517642515821734" +} diff --git a/elements/lisk-transactions/fixtures/valid_transfer_account.json b/elements/lisk-transactions/fixtures/valid_transfer_account.json new file mode 100644 index 00000000000..5e97839a48b --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_transfer_account.json @@ -0,0 +1,20 @@ +[ + { + "address": "1977368676922172803L", + "balance": "1612516352", + "publicKey": "b3eae984ec05ea3b4d4564fa1f195d67d14fe56a1a0d038c2c34780e0c0f9a09", + "secondPublicKey": "" + }, + { + "address": "7675634738153324567L", + "balance": "2347483648", + "publicKey": "", + "secondPublicKey": "" + }, + { + "address": "7329472648011827824L", + "balance": "154610001743", + "publicKey": "9becd3e545be91f85270d8a796ae3b9e8ec01a8cb479fef46a298b4efd943a0f", + "secondPublicKey": "" + } +] diff --git a/elements/lisk-transactions/fixtures/valid_transfer_transaction_with_asset.json b/elements/lisk-transactions/fixtures/valid_transfer_transaction_with_asset.json new file mode 100644 index 00000000000..4eda07d6fc7 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_transfer_transaction_with_asset.json @@ -0,0 +1,16 @@ +{ + "id": "16446567313153430688", + "type": 0, + "timestamp": 73924804, + "senderPublicKey": "9becd3e545be91f85270d8a796ae3b9e8ec01a8cb479fef46a298b4efd943a0f", + "senderId": "7329472648011827824L", + "recipientId": "7329472648011827824L", + "recipientPublicKey": "9becd3e545be91f85270d8a796ae3b9e8ec01a8cb479fef46a298b4efd943a0f", + "amount": "1", + "fee": "10000000", + "signature": "5e47a52c998ef3c1868301a1fa716c92a6f56ae74e95df6b1241bca1e72eab0472465f0a1e1870f9b5ad31adfe49ac78f43b9a9eca15eba75a65e4e5e584220c", + "signatures": [], + "asset": { + "data": "a" + } + } \ No newline at end of file diff --git a/elements/lisk-transactions/fixtures/valid_transfer_transactions.json b/elements/lisk-transactions/fixtures/valid_transfer_transactions.json new file mode 100644 index 00000000000..ff4ba041716 --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_transfer_transactions.json @@ -0,0 +1,32 @@ +[ + { + "id": "5374209778555788325", + "type": 0, + "timestamp": 2346273, + "senderPublicKey": "b3eae984ec05ea3b4d4564fa1f195d67d14fe56a1a0d038c2c34780e0c0f9a09", + "senderId": "1977368676922172803L", + "recipientId": "7675634738153324567L", + "recipientPublicKey": "", + "amount": "10000001", + "fee": "10000000", + "signature": "bc42403a1a29bcd786839c13d8f84e39d30ff486e032b755bcd1cf9a74c9ef1817ab94f5eccbc61959daf2b2f23721edc1848ee707f9d74dbf2f6f38fe1ada0a", + "signatures": [], + "asset": {} + }, + { + "id": "16446567313153430688", + "type": 0, + "timestamp": 73924804, + "senderPublicKey": "9becd3e545be91f85270d8a796ae3b9e8ec01a8cb479fef46a298b4efd943a0f", + "senderId": "7329472648011827824L", + "recipientId": "7329472648011827824L", + "recipientPublicKey": "9becd3e545be91f85270d8a796ae3b9e8ec01a8cb479fef46a298b4efd943a0f", + "amount": "1", + "fee": "10000000", + "signature": "5e47a52c998ef3c1868301a1fa716c92a6f56ae74e95df6b1241bca1e72eab0472465f0a1e1870f9b5ad31adfe49ac78f43b9a9eca15eba75a65e4e5e584220c", + "signatures": [], + "asset": { + "data": "a" + } + } +] diff --git a/elements/lisk-transactions/fixtures/valid_vote_transaction.json b/elements/lisk-transactions/fixtures/valid_vote_transaction.json new file mode 100644 index 00000000000..e1c9ba52c8a --- /dev/null +++ b/elements/lisk-transactions/fixtures/valid_vote_transaction.json @@ -0,0 +1,120 @@ +[ + { + "id": "3729501093004464059", + "type": 3, + "timestamp": 1657012, + "senderPublicKey": "961d1a1057a09f865291873e9ba3d0af7b2a3a1e971bb7576a2aab1c526acbcd", + "senderId": "10773624498522558426L", + "recipientId": "10773624498522558426L", + "recipientPublicKey": "961d1a1057a09f865291873e9ba3d0af7b2a3a1e971bb7576a2aab1c526acbcd", + "amount": "0", + "fee": "100000000", + "signature": "8ac892e223db5cc6695563ffbbb13e86d099d62d41f86e8131f8a03082c51a3b868830a5ca4a60cdb10a63dc0605bf217798dfb00f599e37491b5e701f856704", + "signatures": [], + "asset": { + "votes": [ + "+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b", + "+633698916662935403780f04fd01119f32f9cd180a3b104b67c5ae5ebb6d5593", + "+278a9aecf13e324c42d73cae7e21e5efc1520afb1abcda084d086d24441ed2b4", + "+890e4c93d26f29c356516f3c333430968726a41a972467652ace2352319b1f7e", + "+cbf4ed7dbc6054b70e3744ce0150be4151e2cd99955cbffa19e3158b91739652", + "+18371bb39d3ab7540899ed9f5b806d17ea1cbf604564ce5e1f16d33c1a0d3c5a", + "+18d1b236b98b02c464bbe057077c7dea32b4f519f573b4b2de57ea0634e64a7c", + "+3193057832bb1c9782a8e4a32e543b535ed9d750b1b10383f8b6f50853569609", + "+38fce1516c4dac04f8a947b3a8d8bfd3bf1082d564bf1f2b8b7ad89e827341c0", + "+471bad28073057099b9cd5a111c1bfab4e5355cfa86d2ae7261f4ee1040a00bc", + "+60909cce4a4fd03286d8871e3df8ae7bb9f8756f27be452dd716802afe739c27", + "+a92605074d3249cea963a85fc03dff54f478550009d3dbd97df0234c95360fb0", + "+042322f765dc0139e6ffd21816c31a9ad13daa97753d050b4ae8e88088868255", + "+8aceda0f39b35d778f55593227f97152f0b5a78b80b5c4ae88979909095d6204", + "+4986dd3fb2385603de874763f8f87f56e0af369292734a96ab4fb9de0de20c06", + "+848b16a387bc6e20fea768d3c3c0cda643f4b113a6d2bf70a53e19120c93fa64", + "+e82b9ab22f2b60674fdb35dec867d83ccee65bd1694c7ff9859519da3766a337", + "+31d29205583befdf88e614ca875ab35a4a9e012bac6404e848ce146986afa7b0", + "+b59c6580a05ae00896f03dd66205ac141a22599674cbf0db6654a0908b73e5e5", + "+eb8b446163ba8bbdeb3039dd856a49b41a336e077c8f76049ed494384a5c2ff5", + "+1839e43774bc13e6cae6e36280f3d092be3ae9106c16e55ff718eb406fbace6c", + "+2f58f5b6b1e2e91a9634dfadd1d6726a5aed2875f33260b6753cb9ec7da72917", + "+9ebf21423d104929c857118aa16fa96165ed39a16ce61497c673ee42ad9e2235", + "+9ebf74d64dcecd6eb0005967d8888e66d3e2901c8d0c72c7396f021d93a130fc", + "+71e1e34dd0529d920ee6c38497b028352c57b7130d55737c8a778ff3974ec29f", + "+473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c", + "+6089206bdd49e8e6c824b4896f5b3c2d71207c30c6bf056d430ba0d8838e7c51", + "+410ebf1736f1e7f8c5a3ce5364626e62731b105943ed94d2294d33304a496fd3", + "+7beb5f1e8592022fe5272b45eeeda6a1b6923a801af6e1790933cc6a78ed95a1", + "+961d1a1057a09f865291873e9ba3d0af7b2a3a1e971bb7576a2aab1c526acbcd", + "+a6b504812068c9a1186034966868118e1d98e88bc60835a81252f51136c3cddd", + "+dc979116a6513fd00a0569d9f2f7f4776432328584494100998e594c2bbea79a", + "+cdcba9e30dfd559bdc217fbc5674007927ef68d443650ba804a67d41bf05a1b7" + ] + } + }, + { + "id": "13274099120884476109", + "type": 3, + "timestamp": 47247576, + "senderPublicKey": "30c07dbb72b41e3fda9f29e1a4fc0fce893bb00788515a5e6f50b80312e2f483", + "senderId": "8004805717140184627L", + "recipientId": "8004805717140184627L", + "recipientPublicKey": "30c07dbb72b41e3fda9f29e1a4fc0fce893bb00788515a5e6f50b80312e2f483", + "amount": "0", + "fee": "100000000", + "signature": "1728b2c6c86309f81354d131bfd980494ae3a80568958b234ef4701e28de46bed7a6f40aecec0abcc3d094eb2e1d72185329a357297ab77a126983a570d4570a", + "signatures": [], + "asset": { + "votes": [ + "+633698916662935403780f04fd01119f32f9cd180a3b104b67c5ae5ebb6d5593", + "+b59c6580a05ae00896f03dd66205ac141a22599674cbf0db6654a0908b73e5e5", + "+faf9f863e704f9cf560bc7a5718a25d851666d38195cba3cacd360cd5fa96fd3", + "+cda0220f413c7f62cfe46e9544519cced3277d0931d0342270e6b47b4b346e0b", + "+791576c970ff6bd58cb0be049618d031e31095d272496ebc54f221d1b2635295", + "+712add287f4979ff0c236265dfe437998c2d3b9f4b396e319e7d581e048fbeda", + "+19bdab59b24f7ef2a9d0b1b0942cff450875302e0c59c437a372eb6bb27a0b43", + "+8f2ae5a4fa63ecdd53aa85711ac0a14f2d9a42451838ebfcf5999c5cf5eded06", + "+ea613be11a264b5775e985b9d7d40f836a74bd181a1855de218ee849efa3b1fe", + "+6ee309d4190de0e9adea6b06f83582e61bc7556022e7d3e29a886e35ab80d6a4", + "+279320364fc3edd39b77f1fa29594d442e39220b165956fa729f741150b0dc4d", + "+6a8d02899c66dfa2423b125f44d360be6da0669cedadde32e63e629cb2e3195c", + "+db2627fbee9cf5351fe5b87e35ba981f3e29da085f0a45a1f9851c9e04db910e", + "+a725db7ae839028867f55feb5f332ae09e0ac0b6e9060f045a9ff4f8f2520aa8", + "+ad6fbbe0f62bfb934f4a510c24f59baf600dd8b8bfaa4b59944037c50873a481", + "+4d6e32111dc36f8074bda232f07119394180b11ac8e9f3698537c909ef24637e", + "+2521c1136f095d4031af08d9c5aaf5bbf2589e620c7fc79dfdcdcc6f05d00d72", + "+5a82f58bf35ef4bdfac9a371a64e91914519af31a5cf64a5b8b03ca7d32c15dc", + "-8aceda0f39b35d778f55593227f97152f0b5a78b80b5c4ae88979909095d6204", + "-71e1e34dd0529d920ee6c38497b028352c57b7130d55737c8a778ff3974ec29f", + "-e82b9ab22f2b60674fdb35dec867d83ccee65bd1694c7ff9859519da3766a337", + "-7beb5f1e8592022fe5272b45eeeda6a1b6923a801af6e1790933cc6a78ed95a1", + "-3697a4f8c74cb21949eec31fddde190c16ab2497709fb503c567d3a9e6a6e989", + "-abf9787621f8f43ec4e4a645b515094f42fc5615f2e231eca24eaf6e69dc6a65", + "-4c6a450cc6769efa4ba0f9a23318af0cb9def2402f0a51c5e7215856c08df7af", + "-fa7bfd3a2dc0ca55b700247aae4694709d6cdfa34c6bfb0237e032d7aae404f0", + "-9ebf74d64dcecd6eb0005967d8888e66d3e2901c8d0c72c7396f021d93a130fc", + "-71d74ec6d8d53244fde9cededae7c9c9f1d5dba5c7ddfe63d2e766cb874169b0", + "-fc4f231b00f72ba93a4778890c5d2b89d3f570e606c04619a0343a3cdddf73c7", + "-2493d52fc34ecaaa4a7d0d76e6de9bda24f1b5e11e3363c30a13d59e9c345f82", + "-e683da7b4fe46164b9db3fd599481ad0630d2d892546c1ac63e59a5acb903140", + "-b7633636a88ba1ce8acd98aa58b4a9618650c8ab860c167be6f8d78404265bae", + "-cdcba9e30dfd559bdc217fbc5674007927ef68d443650ba804a67d41bf05a1b7" + ] + } + }, + { + "id": "10029503120604691158", + "type": 3, + "timestamp": 60639370, + "senderPublicKey": "30c07dbb72b41e3fda9f29e1a4fc0fce893bb00788515a5e6f50b80312e2f483", + "senderId": "8004805717140184627L", + "recipientId": "8004805717140184627L", + "recipientPublicKey": "30c07dbb72b41e3fda9f29e1a4fc0fce893bb00788515a5e6f50b80312e2f483", + "amount": "0", + "fee": "100000000", + "signature": "1238a258f019b74f6fd86c489d26f1898ccf6ffb0445586108aa60f6a9f8e07818b261e7471b829986b836b17608be051cbc1eac46305856e61045c5fb76c303", + "signatures": [], + "asset": { + "votes": [ + "+473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c" + ] + } + } +] diff --git a/elements/lisk-transactions/package-lock.json b/elements/lisk-transactions/package-lock.json new file mode 100644 index 00000000000..7d553a6cc66 --- /dev/null +++ b/elements/lisk-transactions/package-lock.json @@ -0,0 +1,4913 @@ +{ + "name": "@liskhq/lisk-transactions", + "version": "2.1.0-alpha.4", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.3.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "@liskhq/bignum": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@liskhq/bignum/-/bignum-1.3.1.tgz", + "integrity": "sha512-q9+NvqbpmXOqpPmV8Y+XSEIUJFMZDGyfW6rkN9Ej3nzPb/qurY/Ic2UPTeTTaj8+q/bcw5JUwTb86hi7PIziDg==", + "requires": { + "@types/node": "11.11.2" + }, + "dependencies": { + "@types/node": { + "version": "11.11.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.2.tgz", + "integrity": "sha512-iEaHiDNkHv4Jrm9O5T37OYEUwjJesiyt6ZlhLFK0sbo4CLD0jyCOB4Pc2F9iD3MbW2397SLNxZKdDGntGaBjQQ==" + } + } + }, + "@sinonjs/commons": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", + "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", + "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.0.tgz", + "integrity": "sha512-beHeJM/RRAaLLsMJhsCvHK31rIqZuobfPLa/80yGH5hnD8PV1hyh9xJBJNFfNmO7yWqm+zomijHsXpI6iTQJfQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash": "^4.17.11" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "@types/verror": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.3.tgz", + "integrity": "sha512-7Jz0MPsW2pWg5dJfEp9nJYI0RDCYfgjg2wIo5HfQ8vOJvUq0/BxT7Mv2wNQvkKBmV9uT++6KF3reMnLmh/0HrA==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "ajv": { + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.8.1.tgz", + "integrity": "sha512-eqxCp82P+JfqL683wwsL73XmFs1eG6qjw+RD3YHx+Jll1r0jNd4dh8QG9NYAeNGA/hnZjeEDgtTskgJULbxpWQ==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-merge-patch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ajv-merge-patch/-/ajv-merge-patch-4.1.0.tgz", + "integrity": "sha512-0mAYXMSauA8RZ7r+B4+EAOYcZEcO9OK5EiQCR7W7Cv4E44pJj56ZnkKLJ9/PAcOc0dT+LlV9fdDcq2TxVJfOYw==", + "requires": { + "fast-json-patch": "^2.0.6", + "json-merge-patch": "^0.2.3" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=" + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "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" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.1.tgz", + "integrity": "sha512-/rrctvxZ78HMI/tPIsqdvFKHHscxR3IJuKrZI2ZoUgkt2SiufyLFBmcco+aqQBIu6P1qBsUNG3drAAGLx80vTQ==", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "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" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "extsprintf": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.0.tgz", + "integrity": "sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=" + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-patch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.0.7.tgz", + "integrity": "sha512-DQeoEyPYxdTtfmB3yDlxkLyKTdbJ6ABfFGcMynDqjvGhPYLto/pZyb/dG2Nyd/n9CArjEWN9ZST++AFmgzgbGw==", + "requires": { + "deep-equal": "^1.0.1" + } + }, + "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=" + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", + "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "dev": true, + "requires": { + "debug": "^3.2.6" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha512-6JeGDGoujJLmhjiRGlt8yK8Z9Kl0vnl/dQoQZlc4oeqaUoAKQg94NILLfrY3oWzSyFaQCVNTcKE5PZ3cH8VP9w==", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.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-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-merge-patch": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-0.2.3.tgz", + "integrity": "sha1-+ixrWvh9p3uuKWalidUuI+2B/kA=", + "requires": { + "deep-equal": "^1.0.0" + } + }, + "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.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + }, + "dependencies": { + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + } + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "lolex": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz", + "integrity": "sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw==", + "dev": true + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "requires": { + "mime-db": "~1.38.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "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": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "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 + }, + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "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" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nise": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz", + "integrity": "sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + } + } + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "portfinder": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "sinon": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", + "integrity": "sha512-i6j7sqcLEqTYqUcMV327waI745VASvYuSuQMCjbAwlpAeuCgKZ3LtrjDxAbu+GjNQR0FEDpywtwGCIh8GicNyg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/samsam": "^3.0.2", + "diff": "^3.5.0", + "lolex": "^3.0.0", + "nise": "^1.4.8", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "sinon-chai": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.3.0.tgz", + "integrity": "sha512-r2JhDY7gbbmh5z3Q62pNbrjxZdOAjpsqW/8yxAZRSqLZqowmfGZPGUZPFf3UX36NLis0cv8VEM5IJh9HgkSOAA==", + "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 + }, + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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" + } + }, + "supports-color": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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 + } + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "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" + }, + "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 + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", + "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "dash-ast": "^1.0.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "verror": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", + "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=", + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-transactions/package.json b/elements/lisk-transactions/package.json new file mode 100644 index 00000000000..dc3d261f599 --- /dev/null +++ b/elements/lisk-transactions/package.json @@ -0,0 +1,93 @@ +{ + "name": "@liskhq/lisk-transactions", + "version": "2.1.0-alpha.4", + "description": "Everything related to transactions according to the Lisk protocol", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-transactions#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s liskTransactions", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s liskTransactions", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/,/**/**/}/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11545 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11545) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11545 && cypress run --config baseUrl=http://localhost:11545 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "NODE_ENV=test nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@liskhq/bignum": "1.3.1", + "@liskhq/lisk-cryptography": "2.1.0-alpha.0", + "@types/node": "10.12.21", + "ajv": "6.8.1", + "ajv-merge-patch": "4.1.0", + "verror": "1.10.0" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "@types/node": "10.10.1", + "@types/verror": "1.10.3", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "sinon": "7.2.3", + "sinon-chai": "3.3.0", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-transactions/scripts b/elements/lisk-transactions/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-transactions/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/src/0_transfer.ts b/elements/lisk-transactions/src/0_transfer.ts new file mode 100644 index 00000000000..d9056543175 --- /dev/null +++ b/elements/lisk-transactions/src/0_transfer.ts @@ -0,0 +1,124 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { getAddressFromPublicKey } from '@liskhq/lisk-cryptography'; +import { TransferTransaction } from './0_transfer_transaction'; +import { BYTESIZES, TRANSFER_FEE } from './constants'; +import { TransactionJSON } from './transaction_types'; +import { + createBaseTransaction, + validateAddress, + validatePublicKey, + validateTransferAmount, +} from './utils'; + +export interface TransferInputs { + readonly amount: string; + readonly data?: string; + readonly passphrase?: string; + readonly recipientId?: string; + readonly recipientPublicKey?: string; + readonly secondPassphrase?: string; + readonly timeOffset?: number; +} + +const validateInputs = ({ + amount, + recipientId, + recipientPublicKey, + data, +}: TransferInputs): void => { + if (!validateTransferAmount(amount)) { + throw new Error('Amount must be a valid number in string format.'); + } + + if (!recipientId && !recipientPublicKey) { + throw new Error( + 'Either recipientId or recipientPublicKey must be provided.', + ); + } + + if (typeof recipientId !== 'undefined') { + validateAddress(recipientId); + } + + if (typeof recipientPublicKey !== 'undefined') { + validatePublicKey(recipientPublicKey); + } + + if ( + recipientId && + recipientPublicKey && + recipientId !== getAddressFromPublicKey(recipientPublicKey) + ) { + throw new Error('recipientId does not match recipientPublicKey.'); + } + + if (data && data.length > 0) { + if (typeof data !== 'string') { + throw new Error( + 'Invalid encoding in transaction data. Data must be utf-8 encoded string.', + ); + } + if (data.length > BYTESIZES.DATA) { + throw new Error('Transaction data field cannot exceed 64 bytes.'); + } + } +}; + +export const transfer = (inputs: TransferInputs): Partial => { + validateInputs(inputs); + const { + data, + amount, + recipientPublicKey, + passphrase, + secondPassphrase, + } = inputs; + + const recipientIdFromPublicKey = recipientPublicKey + ? getAddressFromPublicKey(recipientPublicKey) + : undefined; + const recipientId = inputs.recipientId + ? inputs.recipientId + : recipientIdFromPublicKey; + + const transaction = { + ...createBaseTransaction(inputs), + asset: data ? { data } : {}, + amount, + fee: TRANSFER_FEE.toString(), + recipientId: recipientId as string, + recipientPublicKey, + type: 0, + }; + + if (!passphrase) { + return transaction; + } + + const transactionWithSenderInfo = { + ...transaction, + recipientId: recipientId as string, + senderId: transaction.senderId as string, + senderPublicKey: transaction.senderPublicKey as string, + }; + + const transferTransaction = new TransferTransaction( + transactionWithSenderInfo, + ); + transferTransaction.sign(passphrase, secondPassphrase); + + return transferTransaction.toJSON(); +}; diff --git a/elements/lisk-transactions/src/0_transfer_transaction.ts b/elements/lisk-transactions/src/0_transfer_transaction.ts new file mode 100644 index 00000000000..ce7889fd93e --- /dev/null +++ b/elements/lisk-transactions/src/0_transfer_transaction.ts @@ -0,0 +1,264 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { getAddressFromPublicKey } from '@liskhq/lisk-cryptography'; +import { + BaseTransaction, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { MAX_TRANSACTION_AMOUNT, TRANSFER_FEE } from './constants'; +import { convertToAssetError, TransactionError } from './errors'; +import { TransactionJSON } from './transaction_types'; +import { + validateAddress, + validateTransferAmount, + validator, + verifyAmountBalance, + verifyBalance, +} from './utils'; + +const TRANSACTION_TRANSFER_TYPE = 0; + +export interface TransferAsset { + readonly data: string; +} + +export const transferAssetFormatSchema = { + type: 'object', + properties: { + data: { + type: 'string', + format: 'noNullByte', + maxLength: 64, + }, + }, +}; + +export class TransferTransaction extends BaseTransaction { + public readonly asset: TransferAsset; + + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + // Initializes to empty object if it doesn't exist + this.asset = (tx.asset || {}) as TransferAsset; + } + + protected assetToBytes(): Buffer { + const { data } = this.asset; + + return data ? Buffer.from(data, 'utf8') : Buffer.alloc(0); + } + + public assetToJSON(): TransferAsset { + return this.asset; + } + + public async prepare(store: StateStorePrepare): Promise { + await store.account.cache([ + { + address: this.senderId, + }, + { + address: this.recipientId, + }, + ]); + } + + // tslint:disable-next-line prefer-function-over-method + protected verifyAgainstTransactions( + _: ReadonlyArray, + ): ReadonlyArray { + return []; + } + + protected validateAsset(): ReadonlyArray { + validator.validate(transferAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (this.type !== TRANSACTION_TRANSFER_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_TRANSFER_TYPE, + ), + ); + } + + if (!validateTransferAmount(this.amount.toString())) { + errors.push( + new TransactionError( + 'Amount must be a valid number in string format.', + this.id, + '.amount', + this.amount.toString(), + ), + ); + } + + if (!this.fee.eq(TRANSFER_FEE)) { + errors.push( + new TransactionError( + `Fee must be equal to ${TRANSFER_FEE}`, + this.id, + '.fee', + this.fee.toString(), + TRANSFER_FEE, + ), + ); + } + + if (!this.recipientId) { + errors.push( + new TransactionError( + '`recipientId` must be provided.', + this.id, + '.recipientId', + ), + ); + } + + try { + validateAddress(this.recipientId); + } catch (error) { + errors.push( + new TransactionError( + error.message, + this.id, + '.recipientId', + this.recipientId, + ), + ); + } + + if (this.recipientPublicKey) { + const calculatedAddress = getAddressFromPublicKey( + this.recipientPublicKey, + ); + if (this.recipientId !== calculatedAddress) { + errors.push( + new TransactionError( + 'recipientId does not match recipientPublicKey.', + this.id, + '.recipientId', + this.recipientId, + calculatedAddress, + ), + ); + } + } + + return errors; + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const sender = store.account.get(this.senderId); + + const balanceError = verifyAmountBalance( + this.id, + sender, + this.amount, + this.fee, + ); + if (balanceError) { + errors.push(balanceError); + } + + const updatedSenderBalance = new BigNum(sender.balance).sub(this.amount); + + const updatedSender = { + ...sender, + balance: updatedSenderBalance.toString(), + }; + store.account.set(updatedSender.address, updatedSender); + const recipient = store.account.getOrDefault(this.recipientId); + + const updatedRecipientBalance = new BigNum(recipient.balance).add( + this.amount, + ); + + if (updatedRecipientBalance.gt(MAX_TRANSACTION_AMOUNT)) { + errors.push( + new TransactionError( + 'Invalid amount', + this.id, + '.amount', + this.amount.toString(), + ), + ); + } + + const updatedRecipient = { + ...recipient, + balance: updatedRecipientBalance.toString(), + }; + store.account.set(updatedRecipient.address, updatedRecipient); + + return errors; + } + + protected undoAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const sender = store.account.get(this.senderId); + const updatedSenderBalance = new BigNum(sender.balance).add(this.amount); + + if (updatedSenderBalance.gt(MAX_TRANSACTION_AMOUNT)) { + errors.push( + new TransactionError( + 'Invalid amount', + this.id, + '.amount', + this.amount.toString(), + ), + ); + } + + const updatedSender = { + ...sender, + balance: updatedSenderBalance.toString(), + }; + store.account.set(updatedSender.address, updatedSender); + const recipient = store.account.getOrDefault(this.recipientId); + + const balanceError = verifyBalance(this.id, recipient, this.amount); + + if (balanceError) { + errors.push(balanceError); + } + + const updatedRecipientBalance = new BigNum(recipient.balance).sub( + this.amount, + ); + + const updatedRecipient = { + ...recipient, + balance: updatedRecipientBalance.toString(), + }; + + store.account.set(updatedRecipient.address, updatedRecipient); + + return errors; + } +} diff --git a/elements/lisk-transactions/src/1_register_second_passphrase.ts b/elements/lisk-transactions/src/1_register_second_passphrase.ts new file mode 100644 index 00000000000..f8cc240cacc --- /dev/null +++ b/elements/lisk-transactions/src/1_register_second_passphrase.ts @@ -0,0 +1,61 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { getKeys } from '@liskhq/lisk-cryptography'; +import { SecondSignatureTransaction } from './1_second_signature_transaction'; +import { SIGNATURE_FEE } from './constants'; +import { TransactionJSON } from './transaction_types'; +import { createBaseTransaction } from './utils'; + +export interface SecondPassphraseInputs { + readonly passphrase?: string; + readonly secondPassphrase: string; + readonly timeOffset?: number; +} + +const validateInputs = ({ + secondPassphrase, +}: { + readonly secondPassphrase: string; +}): void => { + if (typeof secondPassphrase !== 'string') { + throw new Error('Please provide a secondPassphrase. Expected string.'); + } +}; + +export const registerSecondPassphrase = ( + inputs: SecondPassphraseInputs, +): Partial => { + validateInputs(inputs); + const { passphrase, secondPassphrase } = inputs; + const { publicKey } = getKeys(secondPassphrase); + + const transaction = { + ...createBaseTransaction(inputs), + type: 1, + fee: SIGNATURE_FEE.toString(), + asset: { signature: { publicKey } }, + }; + + if (!passphrase) { + return transaction; + } + + const secondSignatureTransaction = new SecondSignatureTransaction( + transaction as TransactionJSON, + ); + secondSignatureTransaction.sign(passphrase); + + return secondSignatureTransaction.toJSON(); +}; diff --git a/elements/lisk-transactions/src/1_second_signature_transaction.ts b/elements/lisk-transactions/src/1_second_signature_transaction.ts new file mode 100644 index 00000000000..600ad5e100a --- /dev/null +++ b/elements/lisk-transactions/src/1_second_signature_transaction.ts @@ -0,0 +1,213 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { hash, hexToBuffer, signData } from '@liskhq/lisk-cryptography'; +import { + BaseTransaction, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { SIGNATURE_FEE } from './constants'; +import { convertToAssetError, TransactionError } from './errors'; +import { TransactionJSON } from './transaction_types'; +import { getId, validator } from './utils'; + +const TRANSACTION_SIGNATURE_TYPE = 1; + +export interface SecondSignatureAsset { + readonly signature: { + readonly publicKey: string; + }; +} + +export const secondSignatureAssetFormatSchema = { + type: 'object', + required: ['signature'], + properties: { + signature: { + type: 'object', + required: ['publicKey'], + properties: { + publicKey: { + type: 'string', + format: 'publicKey', + }, + }, + }, + }, +}; + +export class SecondSignatureTransaction extends BaseTransaction { + public readonly asset: SecondSignatureAsset; + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + // tslint:disable-next-line no-object-literal-type-assertion + this.asset = (tx.asset || { signature: {} }) as SecondSignatureAsset; + } + + protected assetToBytes(): Buffer { + const { + signature: { publicKey }, + } = this.asset; + + return hexToBuffer(publicKey); + } + + public assetToJSON(): object { + return this.asset; + } + + public async prepare(store: StateStorePrepare): Promise { + await store.account.cache([ + { + address: this.senderId, + }, + ]); + } + + protected verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray { + return transactions + .filter( + tx => + tx.type === this.type && tx.senderPublicKey === this.senderPublicKey, + ) + .map( + tx => + new TransactionError( + 'Register second signature only allowed once per account.', + tx.id, + '.asset.signature', + ), + ); + } + + protected validateAsset(): ReadonlyArray { + validator.validate(secondSignatureAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (this.type !== TRANSACTION_SIGNATURE_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_SIGNATURE_TYPE, + ), + ); + } + + if (!this.amount.eq(0)) { + errors.push( + new TransactionError( + 'Amount must be zero for second signature registration transaction', + this.id, + '.amount', + this.amount.toString(), + '0', + ), + ); + } + + if (!this.fee.eq(SIGNATURE_FEE)) { + errors.push( + new TransactionError( + `Fee must be equal to ${SIGNATURE_FEE}`, + this.id, + '.fee', + this.fee.toString(), + SIGNATURE_FEE, + ), + ); + } + + if (this.recipientId) { + errors.push( + new TransactionError( + 'RecipientId is expected to be undefined.', + this.id, + '.recipientId', + this.recipientId, + '', + ), + ); + } + + if (this.recipientPublicKey) { + errors.push( + new TransactionError( + 'RecipientPublicKey is expected to be undefined.', + this.id, + '.recipientPublicKey', + this.recipientPublicKey, + '', + ), + ); + } + + return errors; + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const sender = store.account.get(this.senderId); + // Check if secondPublicKey already exists on account + if (sender.secondPublicKey) { + errors.push( + new TransactionError( + 'Register second signature only allowed once per account.', + this.id, + '.secondPublicKey', + ), + ); + } + const updatedSender = { + ...sender, + secondPublicKey: this.asset.signature.publicKey, + secondSignature: 1, + }; + store.account.set(updatedSender.address, updatedSender); + + return errors; + } + + protected undoAsset(store: StateStore): ReadonlyArray { + const sender = store.account.get(this.senderId); + const resetSender = { + ...sender, + // tslint:disable-next-line no-null-keyword - Exception for compatibility with Core 1.4 + secondPublicKey: null, + secondSignature: 0, + }; + + store.account.set(resetSender.address, resetSender); + + return []; + } + + public sign(passphrase: string): void { + this._signature = undefined; + this._signSignature = undefined; + this._signature = signData(hash(this.getBytes()), passphrase); + this._id = getId(this.getBytes()); + } +} diff --git a/elements/lisk-transactions/src/2_delegate_transaction.ts b/elements/lisk-transactions/src/2_delegate_transaction.ts new file mode 100644 index 00000000000..01e45bc79d9 --- /dev/null +++ b/elements/lisk-transactions/src/2_delegate_transaction.ts @@ -0,0 +1,223 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { + BaseTransaction, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { DELEGATE_FEE } from './constants'; +import { convertToAssetError, TransactionError } from './errors'; +import { Account, TransactionJSON } from './transaction_types'; +import { validator } from './utils'; + +const TRANSACTION_DELEGATE_TYPE = 2; + +export interface DelegateAsset { + readonly delegate: { + readonly username: string; + }; +} + +export const delegateAssetFormatSchema = { + type: 'object', + required: ['delegate'], + properties: { + delegate: { + type: 'object', + required: ['username'], + properties: { + username: { + type: 'string', + minLength: 1, + maxLength: 20, + format: 'username', + }, + }, + }, + }, +}; + +export class DelegateTransaction extends BaseTransaction { + public readonly asset: DelegateAsset; + public readonly containsUniqueData: boolean; + + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + this.asset = (tx.asset || { delegate: {} }) as DelegateAsset; + this.containsUniqueData = true; + } + + protected assetToBytes(): Buffer { + const { + delegate: { username }, + } = this.asset; + + return Buffer.from(username, 'utf8'); + } + + public assetToJSON(): DelegateAsset { + return this.asset; + } + + public async prepare(store: StateStorePrepare): Promise { + await store.account.cache([ + { + address: this.senderId, + }, + { + username: this.asset.delegate.username, + }, + ]); + } + + protected verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray { + return transactions + .filter( + tx => + tx.type === this.type && tx.senderPublicKey === this.senderPublicKey, + ) + .map( + tx => + new TransactionError( + 'Register delegate only allowed once per account.', + tx.id, + '.asset.delegate', + ), + ); + } + + protected validateAsset(): ReadonlyArray { + validator.validate(delegateAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (this.type !== TRANSACTION_DELEGATE_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_DELEGATE_TYPE, + ), + ); + } + + if (!this.amount.eq(0)) { + errors.push( + new TransactionError( + 'Amount must be zero for delegate registration transaction', + this.id, + '.amount', + this.amount.toString(), + '0', + ), + ); + } + + if (!this.fee.eq(DELEGATE_FEE)) { + errors.push( + new TransactionError( + `Fee must be equal to ${DELEGATE_FEE}`, + this.id, + '.fee', + this.fee.toString(), + DELEGATE_FEE, + ), + ); + } + + if (this.recipientId) { + errors.push( + new TransactionError( + 'RecipientId is expected to be undefined', + this.id, + '.recipientId', + this.recipientId, + ), + ); + } + + if (this.recipientPublicKey) { + errors.push( + new TransactionError( + 'Invalid recipientPublicKey', + this.id, + '.recipientPublicKey', + ), + ); + } + + return errors; + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const sender = store.account.get(this.senderId); + const usernameExists = store.account.find( + (account: Account) => account.username === this.asset.delegate.username, + ); + + if (usernameExists) { + errors.push( + new TransactionError( + `Username is not unique.`, + this.id, + '.asset.delegate.username', + ), + ); + } + if (sender.isDelegate || sender.username) { + errors.push( + new TransactionError( + 'Account is already a delegate', + this.id, + '.asset.delegate.username', + ), + ); + } + const updatedSender = { + ...sender, + username: this.asset.delegate.username, + vote: 0, + isDelegate: 1, + }; + store.account.set(updatedSender.address, updatedSender); + + return errors; + } + + protected undoAsset(store: StateStore): ReadonlyArray { + const sender = store.account.get(this.senderId); + const { username, ...strippedSender } = sender; + const resetSender = { + ...sender, + // tslint:disable-next-line no-null-keyword - Exception for compatibility with Core 1.4 + username: null, + vote: 0, + isDelegate: 0, + }; + store.account.set(strippedSender.address, resetSender); + + return []; + } +} diff --git a/elements/lisk-transactions/src/2_register_delegate.ts b/elements/lisk-transactions/src/2_register_delegate.ts new file mode 100644 index 00000000000..e317276d4a1 --- /dev/null +++ b/elements/lisk-transactions/src/2_register_delegate.ts @@ -0,0 +1,72 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { DelegateTransaction } from './2_delegate_transaction'; +import { DELEGATE_FEE, USERNAME_MAX_LENGTH } from './constants'; +import { TransactionJSON } from './transaction_types'; +import { createBaseTransaction } from './utils'; + +export interface RegisterDelegateInputs { + readonly passphrase?: string; + readonly secondPassphrase?: string; + readonly timeOffset?: number; + readonly username: string; +} + +const validateInputs = ({ username }: { readonly username: string }): void => { + if (!username || typeof username !== 'string') { + throw new Error('Please provide a username. Expected string.'); + } + + if (username.length > USERNAME_MAX_LENGTH) { + throw new Error( + `Username length does not match requirements. Expected to be no more than ${USERNAME_MAX_LENGTH} characters.`, + ); + } +}; + +export const registerDelegate = ( + inputs: RegisterDelegateInputs, +): Partial => { + validateInputs(inputs); + const { username, passphrase, secondPassphrase } = inputs; + + if (!username || typeof username !== 'string') { + throw new Error('Please provide a username. Expected string.'); + } + + if (username.length > USERNAME_MAX_LENGTH) { + throw new Error( + `Username length does not match requirements. Expected to be no more than ${USERNAME_MAX_LENGTH} characters.`, + ); + } + + const transaction = { + ...createBaseTransaction(inputs), + type: 2, + fee: DELEGATE_FEE.toString(), + asset: { delegate: { username } }, + }; + + if (!passphrase) { + return transaction; + } + + const delegateTransaction = new DelegateTransaction( + transaction as TransactionJSON, + ); + delegateTransaction.sign(passphrase, secondPassphrase); + + return delegateTransaction.toJSON(); +}; diff --git a/elements/lisk-transactions/src/3_cast_votes.ts b/elements/lisk-transactions/src/3_cast_votes.ts new file mode 100644 index 00000000000..9f86dd4d6a1 --- /dev/null +++ b/elements/lisk-transactions/src/3_cast_votes.ts @@ -0,0 +1,90 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { VoteTransaction } from './3_vote_transaction'; +import { VOTE_FEE } from './constants'; +import { TransactionJSON } from './transaction_types'; +import { + createBaseTransaction, + prependMinusToPublicKeys, + prependPlusToPublicKeys, + validatePublicKeys, +} from './utils'; + +export interface CastVoteInputs { + readonly passphrase?: string; + readonly secondPassphrase?: string; + readonly timeOffset?: number; + readonly unvotes?: ReadonlyArray; + readonly votes?: ReadonlyArray; +} + +interface VotesObject { + readonly unvotes?: ReadonlyArray; + readonly votes?: ReadonlyArray; +} + +const validateInputs = ({ votes = [], unvotes = [] }: VotesObject): void => { + if (!Array.isArray(votes)) { + throw new Error( + 'Please provide a valid votes value. Expected an array if present.', + ); + } + if (!Array.isArray(unvotes)) { + throw new Error( + 'Please provide a valid unvotes value. Expected an array if present.', + ); + } + + validatePublicKeys([...votes, ...unvotes]); +}; + +export const castVotes = (inputs: CastVoteInputs): Partial => { + validateInputs(inputs); + const { passphrase, secondPassphrase, votes = [], unvotes = [] } = inputs; + + const plusPrependedVotes = prependPlusToPublicKeys(votes); + const minusPrependedUnvotes = prependMinusToPublicKeys(unvotes); + const allVotes: ReadonlyArray = [ + ...plusPrependedVotes, + ...minusPrependedUnvotes, + ]; + + const transaction = { + ...createBaseTransaction(inputs), + type: 3, + fee: VOTE_FEE.toString(), + asset: { + votes: allVotes, + }, + }; + + if (!passphrase) { + return transaction; + } + + const transactionWithSenderInfo = { + ...transaction, + // SenderId and SenderPublicKey are expected to be exist from base transaction + senderId: transaction.senderId as string, + senderPublicKey: transaction.senderPublicKey as string, + recipientId: transaction.senderId as string, + recipientPublicKey: transaction.senderPublicKey, + }; + + const voteTransaction = new VoteTransaction(transactionWithSenderInfo); + voteTransaction.sign(passphrase, secondPassphrase); + + return voteTransaction.toJSON(); +}; diff --git a/elements/lisk-transactions/src/3_vote_transaction.ts b/elements/lisk-transactions/src/3_vote_transaction.ts new file mode 100644 index 00000000000..4fe700727ad --- /dev/null +++ b/elements/lisk-transactions/src/3_vote_transaction.ts @@ -0,0 +1,353 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { getAddressFromPublicKey } from '@liskhq/lisk-cryptography'; +import { + BaseTransaction, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { MAX_TRANSACTION_AMOUNT, VOTE_FEE } from './constants'; +import { convertToAssetError, TransactionError } from './errors'; +import { TransactionJSON } from './transaction_types'; +import { CreateBaseTransactionInput, verifyAmountBalance } from './utils'; +import { validateAddress, validator } from './utils/validation'; + +const PREFIX_UPVOTE = '+'; +const PREFIX_UNVOTE = '-'; +const MAX_VOTE_PER_ACCOUNT = 101; +const MIN_VOTE_PER_TX = 1; +const MAX_VOTE_PER_TX = 33; +const TRANSACTION_VOTE_TYPE = 3; + +export interface VoteAsset { + readonly votes: ReadonlyArray; +} + +export interface CreateVoteAssetInput { + readonly unvotes?: ReadonlyArray; + readonly votes?: ReadonlyArray; +} + +export type CastVoteInput = CreateBaseTransactionInput & CreateVoteAssetInput; + +export const voteAssetFormatSchema = { + type: 'object', + required: ['votes'], + properties: { + votes: { + type: 'array', + minItems: MIN_VOTE_PER_TX, + maxItems: MAX_VOTE_PER_TX, + items: { + type: 'string', + format: 'signedPublicKey', + }, + uniqueSignedPublicKeys: true, + }, + }, +}; + +export class VoteTransaction extends BaseTransaction { + public readonly containsUniqueData: boolean; + public readonly asset: VoteAsset; + + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + this.asset = (tx.asset || {}) as VoteAsset; + this.containsUniqueData = true; + } + + protected assetToBytes(): Buffer { + return Buffer.from(this.asset.votes.join(''), 'utf8'); + } + + public assetToJSON(): object { + return this.asset; + } + + public async prepare(store: StateStorePrepare): Promise { + const publicKeyObjectArray = this.asset.votes.map(pkWithAction => { + const publicKey = pkWithAction.slice(1); + + return { + publicKey, + }; + }); + + const filterArray = [ + { + address: this.senderId, + }, + ...publicKeyObjectArray, + ]; + + await store.account.cache(filterArray); + } + + protected verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray { + const sameTypeTransactions = transactions + .filter( + tx => + tx.senderPublicKey === this.senderPublicKey && tx.type === this.type, + ) + .map(tx => new VoteTransaction(tx)); + const publicKeys = this.asset.votes.map(vote => vote.substring(1)); + + return sameTypeTransactions.reduce( + (previous, tx) => { + const conflictingVotes = tx.asset.votes + .map(vote => vote.substring(1)) + .filter(publicKey => publicKeys.includes(publicKey)); + if (conflictingVotes.length > 0) { + return [ + ...previous, + new TransactionError( + `Transaction includes conflicting votes: ${conflictingVotes.toString()}`, + this.id, + '.asset.votes', + ), + ]; + } + + return previous; + }, + [] as ReadonlyArray, + ); + } + + protected validateAsset(): ReadonlyArray { + validator.validate(voteAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (!this.amount.eq(0)) { + errors.push( + new TransactionError( + 'Amount must be zero for vote transaction', + this.id, + '.amount', + this.amount.toString(), + '0', + ), + ); + } + + if (this.type !== TRANSACTION_VOTE_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_VOTE_TYPE, + ), + ); + } + + try { + validateAddress(this.recipientId); + } catch (err) { + errors.push( + new TransactionError( + 'RecipientId must be set for vote transaction', + this.id, + '.recipientId', + this.recipientId, + ), + ); + } + + if ( + this.recipientPublicKey && + this.recipientId !== getAddressFromPublicKey(this.recipientPublicKey) + ) { + errors.push( + new TransactionError( + 'recipientId does not match recipientPublicKey.', + this.id, + '.recipientId', + ), + ); + } + + if (!this.fee.eq(VOTE_FEE)) { + errors.push( + new TransactionError( + `Fee must be equal to ${VOTE_FEE}`, + this.id, + '.fee', + this.fee.toString(), + VOTE_FEE, + ), + ); + } + + return errors; + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const sender = store.account.get(this.senderId); + + // Deduct amount from sender in case of exceptions + // See issue: https://github.com/LiskHQ/lisk-elements/issues/1215 + const balanceError = verifyAmountBalance( + this.id, + sender, + this.amount, + this.fee, + ); + if (balanceError) { + errors.push(balanceError); + } + const updatedSenderBalance = new BigNum(sender.balance).sub(this.amount); + + this.asset.votes.forEach(actionVotes => { + const vote = actionVotes.substring(1); + const voteAccount = store.account.find( + account => account.publicKey === vote, + ); + if ( + !voteAccount || + (voteAccount && + (voteAccount.username === undefined || voteAccount.username === '')) + ) { + errors.push( + new TransactionError( + `${vote} is not a delegate.`, + this.id, + '.asset.votes', + ), + ); + } + }); + const senderVotes = sender.votedDelegatesPublicKeys || []; + this.asset.votes.forEach(vote => { + const action = vote.charAt(0); + const publicKey = vote.substring(1); + // Check duplicate votes + if (action === PREFIX_UPVOTE && senderVotes.includes(publicKey)) { + errors.push( + new TransactionError( + `${publicKey} is already voted.`, + this.id, + '.asset.votes', + ), + ); + // Check non-existing unvotes + } else if (action === PREFIX_UNVOTE && !senderVotes.includes(publicKey)) { + errors.push( + new TransactionError( + `${publicKey} is not voted.`, + this.id, + '.asset.votes', + ), + ); + } + }); + const upvotes = this.asset.votes + .filter(vote => vote.charAt(0) === PREFIX_UPVOTE) + .map(vote => vote.substring(1)); + const unvotes = this.asset.votes + .filter(vote => vote.charAt(0) === PREFIX_UNVOTE) + .map(vote => vote.substring(1)); + const originalVotes = sender.votedDelegatesPublicKeys || []; + const votedDelegatesPublicKeys: ReadonlyArray = [ + ...originalVotes, + ...upvotes, + ].filter(vote => !unvotes.includes(vote)); + if (votedDelegatesPublicKeys.length > MAX_VOTE_PER_ACCOUNT) { + errors.push( + new TransactionError( + `Vote cannot exceed ${MAX_VOTE_PER_ACCOUNT} but has ${ + votedDelegatesPublicKeys.length + }.`, + this.id, + '.asset.votes', + votedDelegatesPublicKeys.length.toString(), + MAX_VOTE_PER_ACCOUNT, + ), + ); + } + const updatedSender = { + ...sender, + balance: updatedSenderBalance.toString(), + votedDelegatesPublicKeys, + }; + store.account.set(updatedSender.address, updatedSender); + + return errors; + } + + protected undoAsset(store: StateStore): ReadonlyArray { + const errors = []; + const sender = store.account.get(this.senderId); + const updatedSenderBalance = new BigNum(sender.balance).add(this.amount); + + // Deduct amount from sender in case of exceptions + // See issue: https://github.com/LiskHQ/lisk-elements/issues/1215 + if (updatedSenderBalance.gt(MAX_TRANSACTION_AMOUNT)) { + errors.push( + new TransactionError( + 'Invalid amount', + this.id, + '.amount', + this.amount.toString(), + ), + ); + } + + const upvotes = this.asset.votes + .filter(vote => vote.charAt(0) === PREFIX_UPVOTE) + .map(vote => vote.substring(1)); + const unvotes = this.asset.votes + .filter(vote => vote.charAt(0) === PREFIX_UNVOTE) + .map(vote => vote.substring(1)); + const originalVotes = sender.votedDelegatesPublicKeys || []; + const votedDelegatesPublicKeys: ReadonlyArray = [ + ...originalVotes, + ...unvotes, + ].filter(vote => !upvotes.includes(vote)); + if (votedDelegatesPublicKeys.length > MAX_VOTE_PER_ACCOUNT) { + errors.push( + new TransactionError( + `Vote cannot exceed ${MAX_VOTE_PER_ACCOUNT} but has ${ + votedDelegatesPublicKeys.length + }.`, + this.id, + '.asset.votes', + votedDelegatesPublicKeys.length.toString(), + MAX_VOTE_PER_ACCOUNT, + ), + ); + } + const updatedSender = { + ...sender, + balance: updatedSenderBalance.toString(), + votedDelegatesPublicKeys, + }; + store.account.set(updatedSender.address, updatedSender); + + return errors; + } +} diff --git a/elements/lisk-transactions/src/4_multisignature_transaction.ts b/elements/lisk-transactions/src/4_multisignature_transaction.ts new file mode 100644 index 00000000000..85c24c53c0e --- /dev/null +++ b/elements/lisk-transactions/src/4_multisignature_transaction.ts @@ -0,0 +1,365 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { + BaseTransaction, + MultisignatureStatus, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { MULTISIGNATURE_FEE } from './constants'; +import { SignatureObject } from './create_signature_object'; +import { + convertToAssetError, + TransactionError, + TransactionPendingError, +} from './errors'; +import { createResponse, Status, TransactionResponse } from './response'; +import { TransactionJSON } from './transaction_types'; +import { validateMultisignatures, validateSignature, validator } from './utils'; + +const TRANSACTION_MULTISIGNATURE_TYPE = 4; + +export const multisignatureAssetFormatSchema = { + type: 'object', + required: ['multisignature'], + properties: { + multisignature: { + type: 'object', + required: ['min', 'lifetime', 'keysgroup'], + properties: { + min: { + type: 'integer', + minimum: 1, + maximum: 15, + }, + lifetime: { + type: 'integer', + minimum: 1, + maximum: 72, + }, + keysgroup: { + type: 'array', + uniqueItems: true, + minItems: 1, + maxItems: 15, + items: { + type: 'string', + format: 'additionPublicKey', + }, + }, + }, + }, + }, +}; + +export interface MultiSignatureAsset { + readonly multisignature: { + readonly keysgroup: ReadonlyArray; + readonly lifetime: number; + readonly min: number; + }; +} + +export class MultisignatureTransaction extends BaseTransaction { + public readonly asset: MultiSignatureAsset; + protected _multisignatureStatus: MultisignatureStatus = + MultisignatureStatus.PENDING; + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + this.asset = (tx.asset || { multisignature: {} }) as MultiSignatureAsset; + } + + protected assetToBytes(): Buffer { + const { + multisignature: { min, lifetime, keysgroup }, + } = this.asset; + const minBuffer = Buffer.alloc(1, min); + const lifetimeBuffer = Buffer.alloc(1, lifetime); + const keysgroupBuffer = Buffer.from(keysgroup.join(''), 'utf8'); + + return Buffer.concat([minBuffer, lifetimeBuffer, keysgroupBuffer]); + } + + public assetToJSON(): MultiSignatureAsset { + return this.asset; + } + + public async prepare(store: StateStorePrepare): Promise { + await store.account.cache([ + { + address: this.senderId, + }, + ]); + } + + protected verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray { + const errors = transactions + .filter( + tx => + tx.type === this.type && tx.senderPublicKey === this.senderPublicKey, + ) + .map( + tx => + new TransactionError( + 'Register multisignature only allowed once per account.', + tx.id, + '.asset.multisignature', + ), + ); + + return errors; + } + + protected validateAsset(): ReadonlyArray { + validator.validate(multisignatureAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (this.type !== TRANSACTION_MULTISIGNATURE_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_MULTISIGNATURE_TYPE, + ), + ); + } + + if (!this.amount.eq(0)) { + errors.push( + new TransactionError( + 'Amount must be zero for multisignature registration transaction', + this.id, + '.amount', + this.amount.toString(), + '0', + ), + ); + } + + if (errors.length > 0) { + return errors; + } + + const expectedFee = new BigNum(MULTISIGNATURE_FEE).mul( + this.asset.multisignature.keysgroup.length + 1, + ); + if (!this.fee.eq(expectedFee)) { + errors.push( + new TransactionError( + `Fee must be equal to ${expectedFee.toString()}`, + this.id, + '.fee', + this.fee.toString(), + expectedFee.toString(), + ), + ); + } + + if ( + this.asset.multisignature.min > this.asset.multisignature.keysgroup.length + ) { + errors.push( + new TransactionError( + 'Invalid multisignature min. Must be less than or equal to keysgroup size', + this.id, + '.asset.multisignature.min', + this.asset.multisignature.min, + ), + ); + } + + if (this.recipientId) { + errors.push( + new TransactionError( + 'RecipientId is expected to be undefined', + this.id, + '.recipientId', + this.recipientId, + ), + ); + } + + if (this.recipientPublicKey) { + errors.push( + new TransactionError( + 'RecipientPublicKey is expected to be undefined', + this.id, + '.recipientPublicKey', + this.recipientPublicKey, + ), + ); + } + + return errors; + } + + public processMultisignatures(_: StateStore): TransactionResponse { + const transactionBytes = this.getBasicBytes(); + + const { valid, errors } = validateMultisignatures( + this.asset.multisignature.keysgroup.map(signedPublicKey => + signedPublicKey.substring(1), + ), + this.signatures, + // Required to get signature from all of keysgroup + this.asset.multisignature.keysgroup.length, + transactionBytes, + this.id, + ); + if (valid) { + this._multisignatureStatus = MultisignatureStatus.READY; + + return createResponse(this.id, errors); + } + if ( + errors && + errors.length === 1 && + errors[0] instanceof TransactionPendingError + ) { + this._multisignatureStatus = MultisignatureStatus.PENDING; + + return { + id: this.id, + status: Status.PENDING, + errors, + }; + } + + this._multisignatureStatus = MultisignatureStatus.FAIL; + + return createResponse(this.id, errors); + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const sender = store.account.get(this.senderId); + + // Check if multisignatures already exists on account + if (sender.membersPublicKeys && sender.membersPublicKeys.length > 0) { + errors.push( + new TransactionError( + 'Register multisignature only allowed once per account.', + this.id, + '.signatures', + ), + ); + } + + // Check if multisignatures includes sender's own publicKey + if (this.asset.multisignature.keysgroup.includes(`+${sender.publicKey}`)) { + errors.push( + new TransactionError( + 'Invalid multisignature keysgroup. Can not contain sender', + this.id, + '.signatures', + ), + ); + } + + const updatedSender = { + ...sender, + membersPublicKeys: this.asset.multisignature.keysgroup.map(key => + key.substring(1), + ), + multiMin: this.asset.multisignature.min, + multiLifetime: this.asset.multisignature.lifetime, + }; + store.account.set(updatedSender.address, updatedSender); + + return errors; + } + + protected undoAsset(store: StateStore): ReadonlyArray { + const sender = store.account.get(this.senderId); + + const resetSender = { + ...sender, + membersPublicKeys: [], + multiMin: 0, + multiLifetime: 0, + }; + + store.account.set(resetSender.address, resetSender); + + return []; + } + + public addMultisignature( + store: StateStore, + signatureObject: SignatureObject, + ): TransactionResponse { + // Validate signature key belongs to pending multisig registration transaction + const keysgroup = this.asset.multisignature.keysgroup.map((aKey: string) => + aKey.slice(1), + ); + + if (!keysgroup.includes(signatureObject.publicKey)) { + return createResponse(this.id, [ + new TransactionError( + `Public Key '${signatureObject.publicKey}' is not a member.`, + this.id, + ), + ]); + } + + // Check if signature is already present + if (this.signatures.includes(signatureObject.signature)) { + return createResponse(this.id, [ + new TransactionError( + 'Encountered duplicate signature in transaction', + this.id, + ), + ]); + } + + // Check if signature is valid at all + const { valid } = validateSignature( + signatureObject.publicKey, + signatureObject.signature, + this.getBasicBytes(), + this.id, + ); + + if (valid) { + this.signatures.push(signatureObject.signature); + + return this.processMultisignatures(store); + } + + // Else populate errors + const errors = valid + ? [] + : [ + new TransactionError( + `Failed to add signature ${signatureObject.signature}.`, + this.id, + '.signatures', + ), + ]; + + return createResponse(this.id, errors); + } +} diff --git a/elements/lisk-transactions/src/4_register_multisignature_account.ts b/elements/lisk-transactions/src/4_register_multisignature_account.ts new file mode 100644 index 00000000000..bbea724a4ea --- /dev/null +++ b/elements/lisk-transactions/src/4_register_multisignature_account.ts @@ -0,0 +1,109 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { MultisignatureTransaction } from './4_multisignature_transaction'; +import { + MULTISIGNATURE_FEE, + MULTISIGNATURE_MAX_KEYSGROUP, + MULTISIGNATURE_MAX_LIFETIME, + MULTISIGNATURE_MIN_KEYSGROUP, + MULTISIGNATURE_MIN_LIFETIME, +} from './constants'; +import { TransactionJSON } from './transaction_types'; +import { + createBaseTransaction, + isValidInteger, + prependPlusToPublicKeys, + validateKeysgroup, +} from './utils'; + +export interface RegisterMultisignatureInputs { + readonly keysgroup: ReadonlyArray; + readonly lifetime: number; + readonly minimum: number; + readonly passphrase?: string; + readonly secondPassphrase?: string; + readonly timeOffset?: number; +} + +const validateInputs = ({ + keysgroup, + lifetime, + minimum, +}: { + readonly keysgroup: ReadonlyArray; + readonly lifetime: number; + readonly minimum: number; +}): void => { + if ( + !isValidInteger(lifetime) || + lifetime < MULTISIGNATURE_MIN_LIFETIME || + lifetime > MULTISIGNATURE_MAX_LIFETIME + ) { + throw new Error( + `Please provide a valid lifetime value. Expected integer between ${MULTISIGNATURE_MIN_LIFETIME} and ${MULTISIGNATURE_MAX_LIFETIME}.`, + ); + } + + if ( + !isValidInteger(minimum) || + minimum < MULTISIGNATURE_MIN_KEYSGROUP || + minimum > MULTISIGNATURE_MAX_KEYSGROUP + ) { + throw new Error( + `Please provide a valid minimum value. Expected integer between ${MULTISIGNATURE_MIN_KEYSGROUP} and ${MULTISIGNATURE_MAX_KEYSGROUP}.`, + ); + } + + if (keysgroup.length < minimum) { + throw new Error( + 'Minimum number of signatures is larger than the number of keys in the keysgroup.', + ); + } + validateKeysgroup(keysgroup); +}; + +export const registerMultisignature = ( + inputs: RegisterMultisignatureInputs, +): Partial => { + validateInputs(inputs); + const { keysgroup, lifetime, minimum, passphrase, secondPassphrase } = inputs; + + const plusPrependedKeysgroup = prependPlusToPublicKeys(keysgroup); + const keygroupFees = plusPrependedKeysgroup.length + 1; + + const transaction = { + ...createBaseTransaction(inputs), + type: 4, + fee: (MULTISIGNATURE_FEE * keygroupFees).toString(), + asset: { + multisignature: { + min: minimum, + lifetime, + keysgroup: plusPrependedKeysgroup, + }, + }, + }; + + if (!passphrase) { + return transaction; + } + + const multisignatureTransaction = new MultisignatureTransaction( + transaction as TransactionJSON, + ); + multisignatureTransaction.sign(passphrase, secondPassphrase); + + return multisignatureTransaction.toJSON(); +}; diff --git a/elements/lisk-transactions/src/5_create_dapp.ts b/elements/lisk-transactions/src/5_create_dapp.ts new file mode 100644 index 00000000000..db634dd778f --- /dev/null +++ b/elements/lisk-transactions/src/5_create_dapp.ts @@ -0,0 +1,96 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { DappTransaction } from './5_dapp_transaction'; +import { DAPP_FEE } from './constants'; +import { TransactionJSON } from './transaction_types'; +import { createBaseTransaction, isValidInteger } from './utils'; + +export interface DappOptions { + readonly category: number; + readonly description: string; + readonly icon: string; + readonly link: string; + readonly name: string; + readonly tags: string; + readonly type: number; +} + +export interface DappInputs { + readonly options: DappOptions; + readonly passphrase?: string; + readonly secondPassphrase?: string; + readonly timeOffset?: number; +} + +const validateInputs = ({ options }: DappInputs): void => { + if (typeof options !== 'object') { + throw new Error('Options must be an object.'); + } + const { category, name, type, link, description, tags, icon } = options; + + if (!isValidInteger(category)) { + throw new Error('Dapp category must be an integer.'); + } + if (typeof name !== 'string') { + throw new Error('Dapp name must be a string.'); + } + if (!isValidInteger(type)) { + throw new Error('Dapp type must be an integer.'); + } + if (typeof link !== 'string') { + throw new Error('Dapp link must be a string.'); + } + + if (typeof description !== 'undefined' && typeof description !== 'string') { + throw new Error('Dapp description must be a string if provided.'); + } + + if (typeof tags !== 'undefined' && typeof tags !== 'string') { + throw new Error('Dapp tags must be a string if provided.'); + } + + if (typeof icon !== 'undefined' && typeof icon !== 'string') { + throw new Error('Dapp icon must be a string if provided.'); + } +}; + +export const createDapp = (inputs: DappInputs): Partial => { + validateInputs(inputs); + const { passphrase, secondPassphrase, options } = inputs; + + const transaction = { + ...createBaseTransaction(inputs), + type: 5, + fee: DAPP_FEE.toString(), + asset: { + dapp: options, + }, + }; + + if (!passphrase) { + return transaction; + } + + const transactionWithSenderInfo = { + ...transaction, + senderId: transaction.senderId as string, + senderPublicKey: transaction.senderPublicKey as string, + }; + + const dappTransaction = new DappTransaction(transactionWithSenderInfo); + dappTransaction.sign(passphrase, secondPassphrase); + + return dappTransaction.toJSON(); +}; diff --git a/elements/lisk-transactions/src/5_dapp_transaction.ts b/elements/lisk-transactions/src/5_dapp_transaction.ts new file mode 100644 index 00000000000..722f9a015fd --- /dev/null +++ b/elements/lisk-transactions/src/5_dapp_transaction.ts @@ -0,0 +1,359 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { + BaseTransaction, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { DAPP_FEE } from './constants'; +import { convertToAssetError, TransactionError } from './errors'; +import { TransactionJSON } from './transaction_types'; +import { stringEndsWith, validator } from './utils/validation'; + +const TRANSACTION_DAPP_TYPE = 5; + +export interface DappAsset { + readonly dapp: { + readonly category: number; + readonly link: string; + readonly name: string; + readonly type: number; + // tslint:disable-next-line readonly-keyword + description?: string; + // tslint:disable-next-line readonly-keyword + icon?: string; + // tslint:disable-next-line readonly-keyword + tags?: string; + }; +} + +export const dappAssetFormatSchema = { + type: 'object', + required: ['dapp'], + properties: { + dapp: { + type: 'object', + required: ['name', 'type', 'category'], + properties: { + icon: { + type: 'string', + format: 'uri', + maxLength: 2000, + }, + category: { + type: 'integer', + minimum: 0, + maximum: 8, + }, + type: { + type: 'integer', + minimum: 0, + maximum: 1, + }, + link: { + type: 'string', + format: 'uri', + minLength: 0, + maxLength: 2000, + }, + tags: { + type: 'string', + format: 'noNullByte', + maxLength: 160, + }, + description: { + type: 'string', + format: 'noNullByte', + maxLength: 160, + }, + name: { + type: 'string', + format: 'noNullByte', + minLength: 1, + maxLength: 32, + }, + }, + }, + }, +}; + +export class DappTransaction extends BaseTransaction { + public readonly containsUniqueData: boolean; + public readonly asset: DappAsset; + + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + this.asset = (tx.asset || { dapp: {} }) as DappAsset; + this.containsUniqueData = true; + if (this.asset && this.asset.dapp && typeof this.asset.dapp === 'object') { + // If Optional field contains null, converts to undefined + this.asset.dapp.description = this.asset.dapp.description || undefined; + this.asset.dapp.icon = this.asset.dapp.icon || undefined; + this.asset.dapp.tags = this.asset.dapp.tags || undefined; + } + } + + protected assetToBytes(): Buffer { + const DAPP_TYPE_LENGTH = 4; + const DAPP_CATEGORY_LENGTH = 4; + const { + name, + description, + tags, + link, + icon, + type, + category, + } = this.asset.dapp; + const nameBuffer = Buffer.from(name, 'utf8'); + const linkBuffer = link ? Buffer.from(link, 'utf8') : Buffer.alloc(0); + const typeBuffer = Buffer.alloc(DAPP_TYPE_LENGTH); + typeBuffer.writeIntLE(type, 0, DAPP_TYPE_LENGTH); + const categoryBuffer = Buffer.alloc(DAPP_CATEGORY_LENGTH); + categoryBuffer.writeIntLE(category, 0, DAPP_CATEGORY_LENGTH); + + const descriptionBuffer = description + ? Buffer.from(description, 'utf8') + : Buffer.alloc(0); + const tagsBuffer = tags ? Buffer.from(tags, 'utf8') : Buffer.alloc(0); + const iconBuffer = icon ? Buffer.from(icon, 'utf8') : Buffer.alloc(0); + + return Buffer.concat([ + nameBuffer, + descriptionBuffer, + tagsBuffer, + linkBuffer, + iconBuffer, + typeBuffer, + categoryBuffer, + ]); + } + + public assetToJSON(): object { + return this.asset; + } + + public async prepare(store: StateStorePrepare): Promise { + await store.account.cache([ + { + address: this.senderId, + }, + ]); + + await store.transaction.cache([ + { + dapp_name: this.asset.dapp.name, + }, + { dapp_link: this.asset.dapp.link }, + ]); + } + + protected verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray { + const sameTypeTransactions = transactions.filter( + tx => tx.type === this.type, + ); + + const errors = + sameTypeTransactions.filter( + tx => + 'dapp' in tx.asset && + (tx.asset as DappAsset).dapp.name === this.asset.dapp.name, + ).length > 0 + ? [ + new TransactionError( + 'Dapp with the same name already exists.', + this.id, + '.asset.dapp.name', + this.asset.dapp.name, + ), + ] + : []; + if ( + sameTypeTransactions.filter( + tx => + 'dapp' in tx.asset && + this.asset.dapp.link && + this.asset.dapp.link === (tx.asset as DappAsset).dapp.link, + ).length > 0 + ) { + errors.push( + new TransactionError( + 'Dapp with the same link already exists.', + this.id, + '.asset.dapp.link', + this.asset.dapp.link, + ), + ); + } + + return errors; + } + + protected validateAsset(): ReadonlyArray { + validator.validate(dappAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (this.type !== TRANSACTION_DAPP_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_DAPP_TYPE, + ), + ); + } + + if (!this.amount.eq(0)) { + errors.push( + new TransactionError( + 'Amount must be zero for vote transaction', + this.id, + '.amount', + this.amount.toString(), + '0', + ), + ); + } + + if (this.recipientId) { + errors.push( + new TransactionError( + `RecipientId is expected to be undefined`, + this.id, + '.recipientId', + ), + ); + } + + if (!this.fee.eq(DAPP_FEE)) { + errors.push( + new TransactionError( + `Fee must be equal to ${DAPP_FEE}`, + this.id, + '.fee', + this.fee.toString(), + DAPP_FEE, + ), + ); + } + const validLinkSuffix = ['.zip']; + + if (errors.length > 0) { + return errors; + } + + if ( + this.asset.dapp.link && + !stringEndsWith(this.asset.dapp.link, validLinkSuffix) + ) { + errors.push( + new TransactionError( + `Dapp icon must have suffix ${validLinkSuffix.toString()}`, + this.id, + '.asset.dapp.link', + this.asset.dapp.link, + ), + ); + } + + const validIconSuffix = ['.png', '.jpeg', '.jpg']; + if ( + this.asset.dapp.icon && + !stringEndsWith(this.asset.dapp.icon, validIconSuffix) + ) { + errors.push( + new TransactionError( + `Dapp icon must have suffix of one of ${validIconSuffix.toString()}`, + this.id, + '.asset.dapp.icon', + this.asset.dapp.icon, + ), + ); + } + + if (this.asset.dapp.tags) { + const tags = this.asset.dapp.tags + .split(',') + .map(tag => tag.trim()) + .sort(); + if (tags.length !== new Set(tags).size) { + errors.push( + new TransactionError( + `Dapp tags must have unique set`, + this.id, + '.asset.dapp.tags', + this.asset.dapp.tags, + ), + ); + } + } + + return errors; + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const nameExists = store.transaction.find( + (transaction: TransactionJSON) => + transaction.type === TRANSACTION_DAPP_TYPE && + (transaction.asset as DappAsset).dapp && + (transaction.asset as DappAsset).dapp.name === this.asset.dapp.name, + ); + + if (nameExists) { + errors.push( + new TransactionError( + `Application name already exists: ${this.asset.dapp.name}`, + this.id, + this.asset.dapp.name, + ), + ); + } + + const linkExists = store.transaction.find( + (transaction: TransactionJSON) => + transaction.type === TRANSACTION_DAPP_TYPE && + (transaction.asset as DappAsset).dapp && + (transaction.asset as DappAsset).dapp.link === this.asset.dapp.link, + ); + + if (linkExists) { + errors.push( + new TransactionError( + `Application link already exists: ${this.asset.dapp.link}`, + this.id, + this.asset.dapp.link, + ), + ); + } + + return errors; + } + + // tslint:disable-next-line prefer-function-over-method + protected undoAsset(_: StateStore): ReadonlyArray { + return []; + } +} diff --git a/elements/lisk-transactions/src/6_in_transfer_transaction.ts b/elements/lisk-transactions/src/6_in_transfer_transaction.ts new file mode 100644 index 00000000000..674480086a0 --- /dev/null +++ b/elements/lisk-transactions/src/6_in_transfer_transaction.ts @@ -0,0 +1,261 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { + BaseTransaction, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { IN_TRANSFER_FEE } from './constants'; +import { convertToAssetError, TransactionError } from './errors'; +import { TransactionJSON } from './transaction_types'; +import { convertBeddowsToLSK, verifyAmountBalance } from './utils'; +import { validator } from './utils/validation'; + +const TRANSACTION_DAPP_TYPE = 5; +const TRANSACTION_INTRANSFER_TYPE = 6; + +export interface InTransferAsset { + readonly inTransfer: { + readonly dappId: string; + }; +} + +export const inTransferAssetFormatSchema = { + type: 'object', + required: ['inTransfer'], + properties: { + inTransfer: { + type: 'object', + required: ['dappId'], + properties: { + dappId: { + type: 'string', + format: 'id', + }, + }, + }, + }, +}; + +export class InTransferTransaction extends BaseTransaction { + public readonly asset: InTransferAsset; + + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + + this.asset = (tx.asset || { inTransfer: {} }) as InTransferAsset; + } + + protected assetToBytes(): Buffer { + return Buffer.from(this.asset.inTransfer.dappId, 'utf8'); + } + + public async prepare(store: StateStorePrepare): Promise { + await store.account.cache([{ address: this.senderId }]); + + const transactions = await store.transaction.cache([ + { + id: this.asset.inTransfer.dappId, + }, + ]); + + const dappTransaction = + transactions && transactions.length > 0 + ? transactions.find( + tx => + tx.type === TRANSACTION_DAPP_TYPE && + tx.id === this.asset.inTransfer.dappId, + ) + : undefined; + + if (dappTransaction) { + await store.account.cache([ + { address: dappTransaction.senderId as string }, + ]); + } + } + + public assetToJSON(): object { + return this.asset; + } + + // tslint:disable-next-line prefer-function-over-method + protected verifyAgainstTransactions( + _: ReadonlyArray, + ): ReadonlyArray { + return []; + } + + protected validateAsset(): ReadonlyArray { + validator.validate(inTransferAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (this.type !== TRANSACTION_INTRANSFER_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_INTRANSFER_TYPE, + ), + ); + } + + // Per current protocol, this recipientId and recipientPublicKey must be empty + if (this.recipientId) { + errors.push( + new TransactionError( + 'RecipientId is expected to be undefined.', + this.id, + '.recipientId', + this.recipientId, + ), + ); + } + + if (this.recipientPublicKey) { + errors.push( + new TransactionError( + 'RecipientPublicKey is expected to be undefined.', + this.id, + '.recipientPublicKey', + this.recipientPublicKey, + ), + ); + } + + if (this.amount.lte(0)) { + errors.push( + new TransactionError( + 'Amount must be greater than 0', + this.id, + '.amount', + this.amount.toString(), + '0', + ), + ); + } + + if (!this.fee.eq(IN_TRANSFER_FEE)) { + errors.push( + new TransactionError( + `Fee must be equal to ${IN_TRANSFER_FEE}`, + this.id, + '.fee', + this.fee.toString(), + IN_TRANSFER_FEE, + ), + ); + } + + return errors; + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const idExists = store.transaction.find( + (transaction: TransactionJSON) => + transaction.type === TRANSACTION_DAPP_TYPE && + transaction.id === this.asset.inTransfer.dappId, + ); + + if (!idExists) { + errors.push( + new TransactionError( + `Application not found: ${this.asset.inTransfer.dappId}`, + this.id, + this.asset.inTransfer.dappId, + ), + ); + } + const sender = store.account.get(this.senderId); + + const balanceError = verifyAmountBalance( + this.id, + sender, + this.amount, + this.fee, + ); + if (balanceError) { + errors.push(balanceError); + } + + const updatedBalance = new BigNum(sender.balance).sub(this.amount); + + const updatedSender = { ...sender, balance: updatedBalance.toString() }; + + store.account.set(updatedSender.address, updatedSender); + + const dappTransaction = store.transaction.get(this.asset.inTransfer.dappId); + + const recipient = store.account.get(dappTransaction.senderId as string); + + const updatedRecipientBalance = new BigNum(recipient.balance).add( + this.amount, + ); + const updatedRecipient = { + ...recipient, + balance: updatedRecipientBalance.toString(), + }; + + store.account.set(updatedRecipient.address, updatedRecipient); + + return errors; + } + + protected undoAsset(store: StateStore): ReadonlyArray { + const errors = []; + const sender = store.account.get(this.senderId); + const updatedBalance = new BigNum(sender.balance).add(this.amount); + const updatedSender = { ...sender, balance: updatedBalance.toString() }; + + store.account.set(updatedSender.address, updatedSender); + + const dappTransaction = store.transaction.get(this.asset.inTransfer.dappId); + + const recipient = store.account.get(dappTransaction.senderId as string); + + const updatedRecipientBalance = new BigNum(recipient.balance).sub( + this.amount, + ); + + if (updatedRecipientBalance.lt(0)) { + errors.push( + new TransactionError( + `Account does not have enough LSK: ${ + recipient.address + }, balance: ${convertBeddowsToLSK(recipient.balance)}.`, + this.id, + ), + ); + } + const updatedRecipient = { + ...recipient, + balance: updatedRecipientBalance.toString(), + }; + + store.account.set(updatedRecipient.address, updatedRecipient); + + return errors; + } +} diff --git a/elements/lisk-transactions/src/7_out_transfer_transaction.ts b/elements/lisk-transactions/src/7_out_transfer_transaction.ts new file mode 100644 index 00000000000..acdf3725201 --- /dev/null +++ b/elements/lisk-transactions/src/7_out_transfer_transaction.ts @@ -0,0 +1,281 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { + BaseTransaction, + StateStore, + StateStorePrepare, +} from './base_transaction'; +import { MAX_TRANSACTION_AMOUNT, OUT_TRANSFER_FEE } from './constants'; +import { convertToAssetError, TransactionError } from './errors'; +import { TransactionJSON } from './transaction_types'; +import { verifyAmountBalance } from './utils'; +import { validator } from './utils/validation'; + +const TRANSACTION_OUTTRANSFER_TYPE = 7; +const TRANSACTION_DAPP_REGISTERATION_TYPE = 5; + +export interface OutTransferAsset { + readonly outTransfer: { + readonly dappId: string; + readonly transactionId: string; + }; +} + +export const outTransferAssetFormatSchema = { + type: 'object', + required: ['outTransfer'], + properties: { + outTransfer: { + type: 'object', + required: ['dappId', 'transactionId'], + properties: { + dappId: { + type: 'string', + format: 'id', + }, + transactionId: { + type: 'string', + format: 'id', + }, + }, + }, + }, +}; + +export class OutTransferTransaction extends BaseTransaction { + public readonly asset: OutTransferAsset; + public readonly containsUniqueData: boolean; + + public constructor(rawTransaction: unknown) { + super(rawTransaction); + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + + this.asset = (tx.asset || { outTransfer: {} }) as OutTransferAsset; + this.containsUniqueData = true; + } + + public async prepare(store: StateStorePrepare): Promise { + await store.account.cache([ + { + address: this.senderId, + }, + { address: this.recipientId }, + ]); + + await store.transaction.cache([ + { + id: this.asset.outTransfer.dappId, + }, + { id: this.asset.outTransfer.transactionId }, + ]); + } + + protected assetToBytes(): Buffer { + const { dappId, transactionId } = this.asset.outTransfer; + const outAppIdBuffer = Buffer.from(dappId, 'utf8'); + const outTransactionIdBuffer = Buffer.from(transactionId, 'utf8'); + + return Buffer.concat([outAppIdBuffer, outTransactionIdBuffer]); + } + + public assetToJSON(): object { + return this.asset; + } + + protected verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray { + const sameTypeTransactions = transactions.filter( + tx => + tx.type === this.type && + 'outTransfer' in tx.asset && + this.asset.outTransfer.transactionId === + (tx.asset as OutTransferAsset).outTransfer.transactionId, + ); + + return sameTypeTransactions.length > 0 + ? [ + new TransactionError( + 'Out Transfer cannot refer to the same transactionId', + this.id, + '.asset.outTransfer.transactionId', + ), + ] + : []; + } + + protected validateAsset(): ReadonlyArray { + validator.validate(outTransferAssetFormatSchema, this.asset); + const errors = convertToAssetError( + this.id, + validator.errors, + ) as TransactionError[]; + + if (this.type !== TRANSACTION_OUTTRANSFER_TYPE) { + errors.push( + new TransactionError( + 'Invalid type', + this.id, + '.type', + this.type, + TRANSACTION_OUTTRANSFER_TYPE, + ), + ); + } + + // Amount has to be greater than 0 + if (this.amount.lte(0)) { + errors.push( + new TransactionError( + 'Amount must be greater than zero for outTransfer transaction', + this.id, + '.amount', + this.amount.toString(), + ), + ); + } + + if (!this.fee.eq(OUT_TRANSFER_FEE)) { + errors.push( + new TransactionError( + `Fee must be equal to ${OUT_TRANSFER_FEE}`, + this.id, + '.fee', + this.fee.toString(), + OUT_TRANSFER_FEE, + ), + ); + } + + if (this.recipientId === '') { + errors.push( + new TransactionError( + 'RecipientId must be set for outTransfer transaction', + this.id, + '.recipientId', + this.recipientId, + ), + ); + } + + return errors; + } + + protected applyAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const dappRegistrationTransaction = store.transaction.get( + this.asset.outTransfer.dappId, + ); + + if ( + !dappRegistrationTransaction || + dappRegistrationTransaction.type !== TRANSACTION_DAPP_REGISTERATION_TYPE + ) { + errors.push( + new TransactionError( + `Application not found: ${this.asset.outTransfer.dappId}`, + this.id, + '.asset.outTransfer.dappId', + ), + ); + } + + const sender = store.account.get(this.senderId); + + const balanceError = verifyAmountBalance( + this.id, + sender, + this.amount, + this.fee, + ); + if (balanceError) { + errors.push(balanceError); + } + + const updatedBalance = new BigNum(sender.balance).sub(this.amount); + + const updatedSender = { ...sender, balance: updatedBalance.toString() }; + store.account.set(updatedSender.address, updatedSender); + + const recipient = store.account.getOrDefault(this.recipientId); + + const updatedRecipientBalance = new BigNum(recipient.balance).add( + this.amount, + ); + + if (updatedRecipientBalance.gt(MAX_TRANSACTION_AMOUNT)) { + errors.push(new TransactionError('Invalid amount', this.id, '.amount')); + } + + const updatedRecipient = { + ...recipient, + balance: updatedRecipientBalance.toString(), + }; + + store.account.set(updatedRecipient.address, updatedRecipient); + + return errors; + } + + public undoAsset(store: StateStore): ReadonlyArray { + const errors: TransactionError[] = []; + const sender = store.account.get(this.senderId); + const updatedBalance = new BigNum(sender.balance).add(this.amount); + + if (updatedBalance.gt(MAX_TRANSACTION_AMOUNT)) { + errors.push( + new TransactionError( + 'Invalid amount', + this.id, + '.amount', + this.amount.toString(), + ), + ); + } + + const updatedSender = { ...sender, balance: updatedBalance.toString() }; + store.account.set(updatedSender.address, updatedSender); + + const recipient = store.account.getOrDefault(this.recipientId); + + const updatedRecipientBalance = new BigNum(recipient.balance).sub( + this.amount, + ); + + if (updatedRecipientBalance.lt(0)) { + errors.push( + new TransactionError( + `Account does not have enough LSK: ${recipient.address}, balance: ${ + recipient.balance + }`, + this.id, + updatedRecipientBalance.toString(), + ), + ); + } + + const updatedRecipient = { + ...recipient, + balance: updatedRecipientBalance.toString(), + }; + + store.account.set(updatedRecipient.address, updatedRecipient); + + return errors; + } +} diff --git a/elements/lisk-transactions/src/base_transaction.ts b/elements/lisk-transactions/src/base_transaction.ts new file mode 100644 index 00000000000..1171dd9a34c --- /dev/null +++ b/elements/lisk-transactions/src/base_transaction.ts @@ -0,0 +1,532 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { + bigNumberToBuffer, + getAddressFromPublicKey, + hash, + hexToBuffer, + signData, +} from '@liskhq/lisk-cryptography'; +import { + BYTESIZES, + MAX_TRANSACTION_AMOUNT, + UNCONFIRMED_MULTISIG_TRANSACTION_TIMEOUT, + UNCONFIRMED_TRANSACTION_TIMEOUT, +} from './constants'; +import { SignatureObject } from './create_signature_object'; +import { + convertToTransactionError, + TransactionError, + TransactionPendingError, +} from './errors'; +import { createResponse, Status } from './response'; +import { Account, TransactionJSON } from './transaction_types'; +import { + getId, + isValidNumber, + validateSenderIdAndPublicKey, + validateSignature, + validateTransactionId, + validator, + verifyBalance, + verifyMultiSignatures, + verifySecondSignature, + verifySenderId, + verifySenderPublicKey, +} from './utils'; +import * as schemas from './utils/validation/schema'; + +export interface TransactionResponse { + readonly id: string; + readonly status: Status; + readonly errors: ReadonlyArray; +} + +export interface StateStoreGetter { + get(key: string): T; + find(func: (item: T) => boolean): T | undefined; +} + +export interface StateStoreDefaultGetter { + getOrDefault(key: string): T; +} + +export interface StateStoreSetter { + set(key: string, value: T): void; +} + +export interface StateStore { + readonly account: StateStoreGetter & + StateStoreDefaultGetter & + StateStoreSetter; + readonly transaction: StateStoreGetter; +} + +export interface StateStoreCache { + cache( + filterArray: ReadonlyArray<{ readonly [key: string]: string }>, + ): Promise>; +} + +export interface StateStorePrepare { + readonly account: StateStoreCache; + readonly transaction: StateStoreCache; +} + +export enum MultisignatureStatus { + UNKNOWN = 0, + NONMULTISIGNATURE = 1, + PENDING = 2, + READY = 3, + FAIL = 4, +} + +export const ENTITY_ACCOUNT = 'account'; +export const ENTITY_TRANSACTION = 'transaction'; + +export abstract class BaseTransaction { + public readonly amount: BigNum; + public readonly recipientId: string; + public readonly blockId?: string; + public readonly height?: number; + public readonly confirmations?: number; + public readonly recipientPublicKey?: string; + public readonly senderId: string; + public readonly senderPublicKey: string; + public readonly signatures: string[]; + public readonly timestamp: number; + public readonly type: number; + public readonly containsUniqueData?: boolean; + public readonly fee: BigNum; + public receivedAt?: Date; + + protected _id?: string; + protected _signature?: string; + protected _signSignature?: string; + protected _multisignatureStatus: MultisignatureStatus = + MultisignatureStatus.UNKNOWN; + + public abstract assetToJSON(): object; + public abstract prepare(store: StateStorePrepare): Promise; + protected abstract assetToBytes(): Buffer; + protected abstract validateAsset(): ReadonlyArray; + protected abstract applyAsset( + store: StateStore, + ): ReadonlyArray; + protected abstract undoAsset( + store: StateStore, + ): ReadonlyArray; + protected abstract verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray; + + // tslint:disable-next-line cyclomatic-complexity + public constructor(rawTransaction: unknown) { + const tx = (typeof rawTransaction === 'object' && rawTransaction !== null + ? rawTransaction + : {}) as Partial; + this.amount = new BigNum( + isValidNumber(tx.amount) ? (tx.amount as string | number) : '0', + ); + this.fee = new BigNum( + isValidNumber(tx.fee) ? (tx.fee as string | number) : '0', + ); + + this._id = tx.id; + this.recipientId = tx.recipientId || ''; + this.recipientPublicKey = tx.recipientPublicKey || undefined; + this.senderPublicKey = tx.senderPublicKey || ''; + try { + this.senderId = tx.senderId + ? tx.senderId + : getAddressFromPublicKey(this.senderPublicKey); + } catch (error) { + this.senderId = ''; + } + + this._signature = tx.signature; + this.signatures = (tx.signatures as string[]) || []; + this._signSignature = tx.signSignature; + // Infinity is invalid for these types + this.timestamp = typeof tx.timestamp === 'number' ? tx.timestamp : Infinity; + this.type = typeof tx.type === 'number' ? tx.type : Infinity; + + // Additional data not related to the protocol + this.confirmations = tx.confirmations; + this.blockId = tx.blockId; + this.height = tx.height; + this.receivedAt = tx.receivedAt ? new Date(tx.receivedAt) : undefined; + } + + public get id(): string { + if (!this._id) { + throw new Error('id is required to be set before use'); + } + + return this._id; + } + + public get signature(): string { + if (!this._signature) { + throw new Error('signature is required to be set before use'); + } + + return this._signature; + } + + public get signSignature(): string | undefined { + return this._signSignature; + } + + public toJSON(): TransactionJSON { + const transaction = { + id: this.id, + blockId: this.blockId, + height: this.height, + confirmations: this.confirmations, + amount: this.amount.toString(), + type: this.type, + timestamp: this.timestamp, + senderPublicKey: this.senderPublicKey, + senderId: this.senderId, + recipientId: this.recipientId, + recipientPublicKey: this.recipientPublicKey, + fee: this.fee.toString(), + signature: this.signature, + signSignature: this.signSignature ? this.signSignature : undefined, + signatures: this.signatures, + asset: this.assetToJSON(), + receivedAt: this.receivedAt ? this.receivedAt.toISOString() : undefined, + }; + + return transaction; + } + + public isReady(): boolean { + return ( + this._multisignatureStatus === MultisignatureStatus.READY || + this._multisignatureStatus === MultisignatureStatus.NONMULTISIGNATURE + ); + } + + public getBytes(): Buffer { + const transactionBytes = Buffer.concat([ + this.getBasicBytes(), + this._signature ? hexToBuffer(this._signature) : Buffer.alloc(0), + this._signSignature ? hexToBuffer(this._signSignature) : Buffer.alloc(0), + ]); + + return transactionBytes; + } + + public validate(): TransactionResponse { + const errors = [...this._validateSchema(), ...this.validateAsset()]; + if (errors.length > 0) { + return createResponse(this.id, errors); + } + const transactionBytes = this.getBasicBytes(); + + const { + valid: signatureValid, + error: verificationError, + } = validateSignature( + this.senderPublicKey, + this.signature, + transactionBytes, + this.id, + ); + + if (!signatureValid && verificationError) { + errors.push(verificationError); + } + + const idError = validateTransactionId(this.id, this.getBytes()); + + if (idError) { + errors.push(idError); + } + + return createResponse(this.id, errors); + } + + public verifyAgainstOtherTransactions( + transactions: ReadonlyArray, + ): TransactionResponse { + const errors = this.verifyAgainstTransactions(transactions); + + return createResponse(this.id, errors); + } + + public apply(store: StateStore): TransactionResponse { + const sender = store.account.getOrDefault(this.senderId); + const errors = this._verify(sender) as TransactionError[]; + + // Verify MultiSignature + const { errors: multiSigError } = this.processMultisignatures(store); + if (multiSigError) { + errors.push(...multiSigError); + } + + const updatedBalance = new BigNum(sender.balance).sub(this.fee); + const updatedSender = { + ...sender, + balance: updatedBalance.toString(), + publicKey: sender.publicKey || this.senderPublicKey, + }; + store.account.set(updatedSender.address, updatedSender); + const assetErrors = this.applyAsset(store); + + errors.push(...assetErrors); + + if ( + this._multisignatureStatus === MultisignatureStatus.PENDING && + errors.length === 1 && + errors[0] instanceof TransactionPendingError + ) { + return { + id: this.id, + status: Status.PENDING, + errors, + }; + } + + return createResponse(this.id, errors); + } + + public undo(store: StateStore): TransactionResponse { + const sender = store.account.getOrDefault(this.senderId); + const updatedBalance = new BigNum(sender.balance).add(this.fee); + const updatedAccount = { + ...sender, + balance: updatedBalance.toString(), + publicKey: sender.publicKey || this.senderPublicKey, + }; + const errors = updatedBalance.lte(MAX_TRANSACTION_AMOUNT) + ? [] + : [ + new TransactionError( + 'Invalid balance amount', + this.id, + '.balance', + sender.balance, + updatedBalance.toString(), + ), + ]; + store.account.set(updatedAccount.address, updatedAccount); + const assetErrors = this.undoAsset(store); + errors.push(...assetErrors); + + return createResponse(this.id, errors); + } + + public addMultisignature( + store: StateStore, + signatureObject: SignatureObject, + ): TransactionResponse { + // Get the account + const account = store.account.get(this.senderId); + // Validate signature key belongs to account's multisignature group + if ( + account.membersPublicKeys && + !account.membersPublicKeys.includes(signatureObject.publicKey) + ) { + return createResponse(this.id, [ + new TransactionError( + `Public Key '${ + signatureObject.publicKey + }' is not a member for account '${account.address}'.`, + this.id, + ), + ]); + } + + // Check if signature is not already there + if (this.signatures.includes(signatureObject.signature)) { + return createResponse(this.id, [ + new TransactionError( + `Signature '${ + signatureObject.signature + }' already present in transaction.`, + this.id, + ), + ]); + } + + // Validate the signature using the signature sender and transaction details + const { valid } = validateSignature( + signatureObject.publicKey, + signatureObject.signature, + this.getBasicBytes(), + this.id, + ); + // If the signature is valid for the sender push it to the signatures array + if (valid) { + this.signatures.push(signatureObject.signature); + + return this.processMultisignatures(store); + } + // Else populate errors + const errors = valid + ? [] + : [ + new TransactionError( + `Failed to add signature '${signatureObject.signature}'.`, + this.id, + '.signatures', + ), + ]; + + return createResponse(this.id, errors); + } + + public addVerifiedMultisignature(signature: string): TransactionResponse { + if (!this.signatures.includes(signature)) { + this.signatures.push(signature); + + return createResponse(this.id, []); + } + + return createResponse(this.id, [ + new TransactionError('Failed to add signature.', this.id, '.signatures'), + ]); + } + + public processMultisignatures(store: StateStore): TransactionResponse { + const sender = store.account.get(this.senderId); + const transactionBytes = this.getBasicBytes(); + + const { status, errors } = verifyMultiSignatures( + this.id, + sender, + this.signatures, + transactionBytes, + ); + this._multisignatureStatus = status; + if (this._multisignatureStatus === MultisignatureStatus.PENDING) { + return { + id: this.id, + status: Status.PENDING, + errors, + }; + } + + return createResponse(this.id, errors); + } + + public isExpired(date: Date = new Date()): boolean { + if (!this.receivedAt) { + this.receivedAt = new Date(); + } + // tslint:disable-next-line no-magic-numbers + const timeNow = Math.floor(date.getTime() / 1000); + const timeOut = + this._multisignatureStatus === MultisignatureStatus.PENDING || + this._multisignatureStatus === MultisignatureStatus.READY + ? UNCONFIRMED_MULTISIG_TRANSACTION_TIMEOUT + : UNCONFIRMED_TRANSACTION_TIMEOUT; + const timeElapsed = + // tslint:disable-next-line no-magic-numbers + timeNow - Math.floor(this.receivedAt.getTime() / 1000); + + return timeElapsed > timeOut; + } + + public sign(passphrase: string, secondPassphrase?: string): void { + this._signature = undefined; + this._signSignature = undefined; + this._signature = signData(hash(this.getBytes()), passphrase); + if (secondPassphrase) { + this._signSignature = signData(hash(this.getBytes()), secondPassphrase); + } + this._id = getId(this.getBytes()); + } + + protected getBasicBytes(): Buffer { + const transactionType = Buffer.alloc(BYTESIZES.TYPE, this.type); + const transactionTimestamp = Buffer.alloc(BYTESIZES.TIMESTAMP); + transactionTimestamp.writeIntLE(this.timestamp, 0, BYTESIZES.TIMESTAMP); + + const transactionSenderPublicKey = hexToBuffer(this.senderPublicKey); + + const transactionRecipientID = this.recipientId + ? bigNumberToBuffer( + this.recipientId.slice(0, -1), + BYTESIZES.RECIPIENT_ID, + ).slice(0, BYTESIZES.RECIPIENT_ID) + : Buffer.alloc(BYTESIZES.RECIPIENT_ID); + + const transactionAmount = this.amount.toBuffer({ + endian: 'little', + size: BYTESIZES.AMOUNT, + }); + + return Buffer.concat([ + transactionType, + transactionTimestamp, + transactionSenderPublicKey, + transactionRecipientID, + transactionAmount, + this.assetToBytes(), + ]); + } + + private _verify(sender: Account): ReadonlyArray { + const secondSignatureTxBytes = Buffer.concat([ + this.getBasicBytes(), + hexToBuffer(this.signature), + ]); + + // Verify Basic state + return [ + verifySenderPublicKey(this.id, sender, this.senderPublicKey), + verifySenderId(this.id, sender, this.senderId), + verifyBalance(this.id, sender, this.fee), + verifySecondSignature( + this.id, + sender, + this.signSignature, + secondSignatureTxBytes, + ), + ].filter(Boolean) as ReadonlyArray; + } + + private _validateSchema(): ReadonlyArray { + const transaction = this.toJSON(); + validator.validate(schemas.baseTransaction, transaction); + const errors = convertToTransactionError( + this.id, + validator.errors, + ) as TransactionError[]; + + if ( + !errors.find( + (err: TransactionError) => err.dataPath === '.senderPublicKey', + ) + ) { + // `senderPublicKey` passed format check, safely check equality to senderId + const senderIdError = validateSenderIdAndPublicKey( + this.id, + this.senderId, + this.senderPublicKey, + ); + if (senderIdError) { + errors.push(senderIdError); + } + } + + return errors; + } +} diff --git a/elements/lisk-transactions/src/constants.ts b/elements/lisk-transactions/src/constants.ts new file mode 100644 index 00000000000..6305f59435b --- /dev/null +++ b/elements/lisk-transactions/src/constants.ts @@ -0,0 +1,59 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +/* tslint:disable:no-magic-numbers */ +export const FIXED_POINT = 10 ** 8; + +export const TRANSFER_FEE = FIXED_POINT * 0.1; +export const IN_TRANSFER_FEE = FIXED_POINT * 0.1; +export const OUT_TRANSFER_FEE = FIXED_POINT * 0.1; +export const SIGNATURE_FEE = FIXED_POINT * 5; +export const DELEGATE_FEE = FIXED_POINT * 25; +export const VOTE_FEE = FIXED_POINT * 1; +export const MULTISIGNATURE_FEE = FIXED_POINT * 5; +export const MULTISIGNATURE_MAX_LIFETIME = 72; +export const MULTISIGNATURE_MIN_LIFETIME = 1; +export const MULTISIGNATURE_MAX_KEYSGROUP = 15; +export const MULTISIGNATURE_MIN_KEYSGROUP = 1; +export const DAPP_FEE = FIXED_POINT * 25; +export const USERNAME_MAX_LENGTH = 20; + +export const BYTESIZES = { + TYPE: 1, + TIMESTAMP: 4, + MULTISIGNATURE_PUBLICKEY: 32, + RECIPIENT_ID: 8, + AMOUNT: 8, + SIGNATURE_TRANSACTION: 64, + SECOND_SIGNATURE_TRANSACTION: 64, + DATA: 64, +}; + +export const EPOCH_TIME = new Date(Date.UTC(2016, 4, 24, 17, 0, 0, 0)); +export const EPOCH_TIME_MILLISECONDS = EPOCH_TIME.getTime(); +const MS_FACTOR = 1000; +export const EPOCH_TIME_SECONDS = Math.floor(EPOCH_TIME.getTime() / MS_FACTOR); + +// Largest possible number which can be stored in eight bytes. +// Derived from bignum.fromBuffer(Buffer.from(new Array(8).fill(255))). +const MAX_EIGHT_BYTE_NUMBER = '18446744073709551615'; + +export const MAX_ADDRESS_NUMBER = MAX_EIGHT_BYTE_NUMBER; +export const MAX_TRANSACTION_ID = MAX_EIGHT_BYTE_NUMBER; +// Largest possible amount. Maximum value for PostgreSQL bigint. +export const MAX_TRANSACTION_AMOUNT = '9223372036854775807'; +export const UNCONFIRMED_TRANSACTION_TIMEOUT = 10800; +export const UNCONFIRMED_MULTISIG_TRANSACTION_TIMEOUT = 10800 * 8; +export const MAX_MULTISIG_SIGNATURES = 15; +export const MAX_PUBLIC_KEY_LENGTH = 32; diff --git a/elements/lisk-transactions/src/create_signature_object.ts b/elements/lisk-transactions/src/create_signature_object.ts new file mode 100644 index 00000000000..87ad5f3a9fc --- /dev/null +++ b/elements/lisk-transactions/src/create_signature_object.ts @@ -0,0 +1,46 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as cryptography from '@liskhq/lisk-cryptography'; +import { TransactionJSON } from './transaction_types'; +import { multiSignTransaction, verifyTransaction } from './utils'; + +export interface SignatureObject { + readonly publicKey: string; + readonly signature: string; + readonly transactionId: string; +} + +export const createSignatureObject = ( + transaction: TransactionJSON, + passphrase: string, +): SignatureObject => { + if (!verifyTransaction(transaction)) { + throw new Error('Invalid transaction.'); + } + + if (!transaction.id) { + throw new Error('Transaction ID is required to create a signature object.'); + } + + const { publicKey } = cryptography.getPrivateAndPublicKeyFromPassphrase( + passphrase, + ); + + return { + transactionId: transaction.id, + publicKey, + signature: multiSignTransaction(transaction, passphrase), + }; +}; diff --git a/elements/lisk-transactions/src/errors.ts b/elements/lisk-transactions/src/errors.ts new file mode 100644 index 00000000000..2a062b6bf0b --- /dev/null +++ b/elements/lisk-transactions/src/errors.ts @@ -0,0 +1,113 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +// tslint:disable max-classes-per-file +import { VError } from 'verror'; + +export class TransactionError extends VError { + public id: string; + public dataPath: string; + public actual?: string | number; + public expected?: string | number; + public constructor( + message: string = '', + id: string = '', + dataPath: string = '', + actual?: string | number, + expected?: string | number, + ) { + super(message); + this.name = 'TransactionError'; + this.id = id; + this.dataPath = dataPath; + this.actual = actual; + this.expected = expected; + } + + public toString(): string { + const defaultMessage = `Transaction: ${this.id} failed at ${ + this.dataPath + }: ${this.message}`; + const withActual = this.actual + ? `${defaultMessage}, actual: ${this.actual}` + : defaultMessage; + const withExpected = this.expected + ? `${withActual}, expected: ${this.expected}` + : withActual; + + return withExpected; + } +} + +export class TransactionPendingError extends TransactionError { + public id: string; + public dataPath: string; + public constructor( + message: string = '', + id: string = '', + dataPath: string = '', + ) { + super(message); + this.name = 'TransactionPendingError'; + this.id = id; + this.dataPath = dataPath; + } + + public toString(): string { + return `Transaction: ${this.id} failed at ${this.dataPath}: ${ + this.message + } `; + } +} + +interface ErrorObject { + readonly dataPath: string; + readonly message?: string; +} + +export const convertToTransactionError = ( + id: string, + errors: ReadonlyArray | null | undefined, +): ReadonlyArray => { + if (!errors) { + return []; + } + + return errors.map( + error => + new TransactionError( + `'${error.dataPath}' ${error.message}`, + id, + error.dataPath, + ), + ); +}; + +export const convertToAssetError = ( + id: string, + errors: ReadonlyArray | null | undefined, +): ReadonlyArray => { + if (!errors) { + return []; + } + + return errors.map( + error => + new TransactionError( + `'${error.dataPath || '.asset'}' ${error.message}`, + id, + error.dataPath || '.asset', + ), + ); +}; diff --git a/elements/lisk-transactions/src/index.ts b/elements/lisk-transactions/src/index.ts new file mode 100644 index 00000000000..fcbc92eaef4 --- /dev/null +++ b/elements/lisk-transactions/src/index.ts @@ -0,0 +1,106 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { transfer } from './0_transfer'; +import { TransferTransaction } from './0_transfer_transaction'; +import { registerSecondPassphrase } from './1_register_second_passphrase'; +import { SecondSignatureTransaction } from './1_second_signature_transaction'; +import { DelegateTransaction } from './2_delegate_transaction'; +import { registerDelegate } from './2_register_delegate'; +import { castVotes } from './3_cast_votes'; +import { VoteTransaction } from './3_vote_transaction'; +import { MultisignatureTransaction } from './4_multisignature_transaction'; +import { registerMultisignature } from './4_register_multisignature_account'; +import { createDapp } from './5_create_dapp'; +import { DappTransaction } from './5_dapp_transaction'; +import { InTransferTransaction } from './6_in_transfer_transaction'; +import { OutTransferTransaction } from './7_out_transfer_transaction'; +import { BaseTransaction } from './base_transaction'; +import * as constants from './constants'; +import { createSignatureObject } from './create_signature_object'; +import { TransactionError } from './errors'; +import { Status, TransactionResponse } from './response'; +import { TransactionJSON } from './transaction_types'; +import { + checkPublicKeysForDuplicates, + convertBeddowsToLSK, + convertLSKToBeddows, + getTransactionBytes, + getTransactionHash, + getTransactionId, + isValidInteger, + multiSignTransaction, + prepareTransaction, + prependMinusToPublicKeys, + prependPlusToPublicKeys, + signRawTransaction, + signTransaction, + validateAddress, + validateFee, + validateKeysgroup, + validatePublicKey, + validatePublicKeys, + validateTransaction, + verifyTransaction, +} from './utils'; + +const exposedUtils = { + convertBeddowsToLSK, + convertLSKToBeddows, + isValidInteger, + multiSignTransaction, + prependMinusToPublicKeys, + prependPlusToPublicKeys, + validateAddress, + validateKeysgroup, + validatePublicKey, + validatePublicKeys, + + // TODO: Deprecated + signTransaction, + getTransactionBytes, + getTransactionId, + verifyTransaction, + checkPublicKeysForDuplicates, + getTransactionHash, + prepareTransaction, + signRawTransaction, + validateFee, + validateTransaction, +}; + +export { + BaseTransaction, + TransferTransaction, + transfer, + SecondSignatureTransaction, + registerSecondPassphrase, + DelegateTransaction, + registerDelegate, + VoteTransaction, + castVotes, + MultisignatureTransaction, + registerMultisignature, + DappTransaction, + createDapp, + InTransferTransaction, + OutTransferTransaction, + createSignatureObject, + Status, + TransactionResponse, + TransactionJSON, + TransactionError, + constants, + exposedUtils as utils, +}; diff --git a/elements/lisk-transactions/src/response.ts b/elements/lisk-transactions/src/response.ts new file mode 100644 index 00000000000..0c69fbb881f --- /dev/null +++ b/elements/lisk-transactions/src/response.ts @@ -0,0 +1,36 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { TransactionError } from './errors'; + +export enum Status { + FAIL = 0, + OK = 1, + PENDING = 2, +} + +export interface TransactionResponse { + readonly id: string; + readonly status: Status; + readonly errors: ReadonlyArray; +} + +export const createResponse = ( + id: string, + errors?: ReadonlyArray, +) => ({ + id, + status: errors && errors.length > 0 ? Status.FAIL : Status.OK, + errors: errors ? errors : [], +}); diff --git a/elements/lisk-transactions/src/transaction_types.ts b/elements/lisk-transactions/src/transaction_types.ts new file mode 100644 index 00000000000..66d0bcd5423 --- /dev/null +++ b/elements/lisk-transactions/src/transaction_types.ts @@ -0,0 +1,70 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { TransactionError } from './errors'; + +export interface Account { + readonly address: string; + readonly balance: string; + readonly delegate?: Delegate; + readonly publicKey?: string; + readonly secondPublicKey?: string | null; + readonly secondSignature?: number; + readonly membersPublicKeys?: ReadonlyArray; + readonly multiMin?: number; + readonly multiLifetime?: number; + readonly username?: string | null; + readonly votedDelegatesPublicKeys?: ReadonlyArray; + readonly isDelegate?: number; + readonly vote?: number; +} + +export interface Delegate { + readonly username: string; +} + +export interface TransactionJSON { + readonly amount: string | number; + readonly asset: object; + readonly fee: string | number; + readonly id?: string; + readonly blockId?: string; + readonly height?: number; + readonly confirmations?: number; + readonly recipientId: string | null; + readonly recipientPublicKey?: string; + readonly senderId?: string; + readonly senderPublicKey: string; + readonly signature?: string; + readonly signatures?: ReadonlyArray; + readonly signSignature?: string; + readonly timestamp: number; + readonly type: number; + readonly receivedAt?: string; +} + +export interface IsValidResponse { + readonly valid: boolean; + readonly errors?: ReadonlyArray; +} + +export interface IsValidResponseWithError { + readonly valid: boolean; + readonly error?: TransactionError; +} + +export interface IsVerifiedResponse { + readonly verified: boolean; + readonly errors?: ReadonlyArray; +} diff --git a/elements/lisk-transactions/src/utils/address.ts b/elements/lisk-transactions/src/utils/address.ts new file mode 100644 index 00000000000..f4b1482356d --- /dev/null +++ b/elements/lisk-transactions/src/utils/address.ts @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { getAddressFromPublicKey } from '@liskhq/lisk-cryptography'; +import { TransactionError } from '../errors'; + +export const validateSenderIdAndPublicKey = ( + id: string, + senderId: string, + senderPublicKey: string, +): TransactionError | undefined => { + const actualAddress = getAddressFromPublicKey(senderPublicKey); + + return senderId.toUpperCase() !== actualAddress.toUpperCase() + ? new TransactionError( + '`senderId` does not match `senderPublicKey`', + id, + '.senderId', + actualAddress, + senderId, + ) + : undefined; +}; diff --git a/elements/lisk-transactions/src/utils/create_base_transaction.ts b/elements/lisk-transactions/src/utils/create_base_transaction.ts new file mode 100644 index 00000000000..213f089e3df --- /dev/null +++ b/elements/lisk-transactions/src/utils/create_base_transaction.ts @@ -0,0 +1,41 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +import { getAddressAndPublicKeyFromPassphrase } from '@liskhq/lisk-cryptography'; +import { getTimeWithOffset } from './time'; + +export interface CreateBaseTransactionInput { + readonly passphrase?: string; + readonly secondPassphrase?: string; + readonly timeOffset?: number; +} + +export const createBaseTransaction = ({ + passphrase, + timeOffset, +}: CreateBaseTransactionInput) => { + const { address: senderId, publicKey: senderPublicKey } = passphrase + ? getAddressAndPublicKeyFromPassphrase(passphrase) + : { address: undefined, publicKey: undefined }; + const timestamp = getTimeWithOffset(timeOffset); + + return { + amount: '0', + recipientId: '', + senderId, + senderPublicKey, + timestamp, + }; +}; diff --git a/elements/lisk-transactions/src/utils/format.ts b/elements/lisk-transactions/src/utils/format.ts new file mode 100644 index 00000000000..e8c34257476 --- /dev/null +++ b/elements/lisk-transactions/src/utils/format.ts @@ -0,0 +1,62 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { FIXED_POINT } from '../constants'; +import { isGreaterThanMaxTransactionAmount } from './validation'; + +const BASE_10 = 10; +const LISK_MAX_DECIMAL_POINTS = 8; +const getDecimalPlaces = (amount: string): number => + (amount.split('.')[1] || '').length; + +export const convertBeddowsToLSK = (beddowsAmount?: string): string => { + if (typeof beddowsAmount !== 'string') { + throw new Error('Cannot convert non-string amount'); + } + if (getDecimalPlaces(beddowsAmount)) { + throw new Error('Beddows amount should not have decimal points'); + } + const beddowsAmountBigNum = new BigNum(beddowsAmount); + if (isGreaterThanMaxTransactionAmount(beddowsAmountBigNum)) { + throw new Error('Beddows amount out of range'); + } + const lskAmountBigNum = beddowsAmountBigNum.div(FIXED_POINT); + + return lskAmountBigNum.toString(BASE_10); +}; + +export const convertLSKToBeddows = (lskAmount?: string): string => { + if (typeof lskAmount !== 'string') { + throw new Error('Cannot convert non-string amount'); + } + if (getDecimalPlaces(lskAmount) > LISK_MAX_DECIMAL_POINTS) { + throw new Error('LSK amount has too many decimal points'); + } + const lskAmountBigNum = new BigNum(lskAmount); + const beddowsAmountBigNum = lskAmountBigNum.mul(FIXED_POINT); + if (isGreaterThanMaxTransactionAmount(beddowsAmountBigNum)) { + throw new Error('LSK amount out of range'); + } + + return beddowsAmountBigNum.toString(); +}; + +export const prependPlusToPublicKeys = ( + publicKeys: ReadonlyArray, +): ReadonlyArray => publicKeys.map(publicKey => `+${publicKey}`); + +export const prependMinusToPublicKeys = ( + publicKeys: ReadonlyArray, +): ReadonlyArray => publicKeys.map(publicKey => `-${publicKey}`); diff --git a/elements/lisk-transactions/src/utils/get_transaction_bytes.ts b/elements/lisk-transactions/src/utils/get_transaction_bytes.ts new file mode 100644 index 00000000000..1f17670e153 --- /dev/null +++ b/elements/lisk-transactions/src/utils/get_transaction_bytes.ts @@ -0,0 +1,260 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { TransferAsset } from '../0_transfer_transaction'; +import { SecondSignatureAsset } from '../1_second_signature_transaction'; +import { DelegateAsset } from '../2_delegate_transaction'; +import { VoteAsset } from '../3_vote_transaction'; +import { MultiSignatureAsset } from '../4_multisignature_transaction'; +import { DappAsset } from '../5_dapp_transaction'; +import { InTransferAsset } from '../6_in_transfer_transaction'; +import { OutTransferAsset } from '../7_out_transfer_transaction'; +import { BYTESIZES, MAX_TRANSACTION_AMOUNT } from '../constants'; +import { TransactionJSON } from '../transaction_types'; + +// FIXME: Deprecated +export const isValidValue = (value: unknown): boolean => { + if (value === undefined) { + return false; + } + if (typeof value === 'number' && Number.isNaN(value)) { + return false; + } + if (value === false) { + return false; + } + + return true; +}; + +// FIXME: Deprecated +export const checkRequiredFields = ( + requiredFields: ReadonlyArray, + data: { readonly [key: string]: unknown }, +): boolean => { + const dataFields = Object.keys(data); + requiredFields.forEach(parameter => { + if (!dataFields.includes(parameter) || !isValidValue(data[parameter])) { + throw new Error(`${parameter} is a required parameter.`); + } + }); + + return true; +}; + +// FIXME: Deprecated +export const getAssetDataForTransferTransaction = ({ + data, +}: TransferAsset): Buffer => + data ? Buffer.from(data, 'utf8') : Buffer.alloc(0); + +// FIXME: Deprecated +export const getAssetDataForRegisterSecondSignatureTransaction = ({ + signature, +}: SecondSignatureAsset): Buffer => { + checkRequiredFields(['publicKey'], signature); + const { publicKey } = signature; + + return cryptography.hexToBuffer(publicKey); +}; + +// FIXME: Deprecated +export const getAssetDataForRegisterDelegateTransaction = ({ + delegate, +}: DelegateAsset): Buffer => { + checkRequiredFields(['username'], delegate); + const { username } = delegate; + + return Buffer.from(username, 'utf8'); +}; + +// FIXME: Deprecated +export const getAssetDataForCastVotesTransaction = ({ + votes, +}: VoteAsset): Buffer => { + if (!Array.isArray(votes)) { + throw new Error('votes parameter must be an Array.'); + } + + return Buffer.from(votes.join(''), 'utf8'); +}; + +// FIXME: Deprecated +export const getAssetDataForRegisterMultisignatureAccountTransaction = ({ + multisignature, +}: MultiSignatureAsset): Buffer => { + checkRequiredFields(['min', 'lifetime', 'keysgroup'], multisignature); + const { min, lifetime, keysgroup } = multisignature; + const minBuffer = Buffer.alloc(1, min); + const lifetimeBuffer = Buffer.alloc(1, lifetime); + const keysgroupBuffer = Buffer.from(keysgroup.join(''), 'utf8'); + + return Buffer.concat([minBuffer, lifetimeBuffer, keysgroupBuffer]); +}; + +const DAPP_TYPE_LENGTH = 4; +const DAPP_CATEGORY_LENGTH = 4; + +// FIXME: Deprecated +export const getAssetDataForCreateDappTransaction = ({ + dapp, +}: DappAsset): Buffer => { + checkRequiredFields(['name', 'link', 'type', 'category'], dapp); + const { name, description, tags, link, icon, type, category } = dapp; + const nameBuffer = Buffer.from(name, 'utf8'); + const linkBuffer = Buffer.from(link, 'utf8'); + const typeBuffer = Buffer.alloc(DAPP_TYPE_LENGTH); + typeBuffer.writeIntLE(type, 0, DAPP_TYPE_LENGTH); + const categoryBuffer = Buffer.alloc(DAPP_CATEGORY_LENGTH); + categoryBuffer.writeIntLE(category, 0, DAPP_CATEGORY_LENGTH); + + const descriptionBuffer = description + ? Buffer.from(description, 'utf8') + : Buffer.alloc(0); + const tagsBuffer = tags ? Buffer.from(tags, 'utf8') : Buffer.alloc(0); + const iconBuffer = icon ? Buffer.from(icon, 'utf8') : Buffer.alloc(0); + + return Buffer.concat([ + nameBuffer, + descriptionBuffer, + tagsBuffer, + linkBuffer, + iconBuffer, + typeBuffer, + categoryBuffer, + ]); +}; + +// FIXME: Deprecated +export const getAssetDataForTransferIntoDappTransaction = ({ + inTransfer, +}: InTransferAsset): Buffer => { + checkRequiredFields(['dappId'], inTransfer); + const { dappId } = inTransfer; + + return Buffer.from(dappId, 'utf8'); +}; + +// FIXME: Deprecated +export const getAssetDataForTransferOutOfDappTransaction = ({ + outTransfer, +}: OutTransferAsset): Buffer => { + checkRequiredFields(['dappId', 'transactionId'], outTransfer); + const { dappId, transactionId } = outTransfer; + const outAppIdBuffer = Buffer.from(dappId, 'utf8'); + const outTransactionIdBuffer = Buffer.from(transactionId, 'utf8'); + + return Buffer.concat([outAppIdBuffer, outTransactionIdBuffer]); +}; + +// FIXME: Deprecated +const transactionTypeAssetGetBytesMap: { + // tslint:disable-next-line no-any + readonly [type: number]: (asset: any) => Buffer; +} = { + 0: getAssetDataForTransferTransaction, + 1: getAssetDataForRegisterSecondSignatureTransaction, + 2: getAssetDataForRegisterDelegateTransaction, + 3: getAssetDataForCastVotesTransaction, + 4: getAssetDataForRegisterMultisignatureAccountTransaction, + 5: getAssetDataForCreateDappTransaction, + 6: getAssetDataForTransferIntoDappTransaction, + 7: getAssetDataForTransferOutOfDappTransaction, +}; + +// FIXME: Deprecated +export const getAssetBytes = (transaction: TransactionJSON): Buffer => + transactionTypeAssetGetBytesMap[transaction.type](transaction.asset); + +const REQUIRED_TRANSACTION_PARAMETERS: ReadonlyArray = [ + 'type', + 'timestamp', + 'senderPublicKey', + 'amount', +]; + +// FIXME: Deprecated +export const checkTransaction = (transaction: TransactionJSON): boolean => { + checkRequiredFields(REQUIRED_TRANSACTION_PARAMETERS, transaction); + const { data } = transaction.asset as TransferAsset; + if (data && data.length > BYTESIZES.DATA) { + throw new Error( + `Transaction asset data exceeds size of ${BYTESIZES.DATA}.`, + ); + } + + return true; +}; + +// FIXME: Deprecated +export const getTransactionBytes = (transaction: TransactionJSON): Buffer => { + checkTransaction(transaction); + const { + type, + timestamp, + senderPublicKey, + recipientId, + amount, + signature, + signSignature, + } = transaction; + + const transactionType = Buffer.alloc(BYTESIZES.TYPE, type); + const transactionTimestamp = Buffer.alloc(BYTESIZES.TIMESTAMP); + transactionTimestamp.writeIntLE(timestamp, 0, BYTESIZES.TIMESTAMP); + + const transactionSenderPublicKey = cryptography.hexToBuffer(senderPublicKey); + + const transactionRecipientID = recipientId + ? cryptography.bigNumberToBuffer( + recipientId.slice(0, -1), + BYTESIZES.RECIPIENT_ID, + ) + : Buffer.alloc(BYTESIZES.RECIPIENT_ID); + + const amountBigNum = new BigNum(amount); + if (amountBigNum.lt(0)) { + throw new Error('Transaction amount must not be negative.'); + } + if (amountBigNum.gt(new BigNum(MAX_TRANSACTION_AMOUNT))) { + throw new Error('Transaction amount is too large.'); + } + const transactionAmount = amountBigNum.toBuffer({ + endian: 'little', + size: BYTESIZES.AMOUNT, + }); + + const transactionAssetData = getAssetBytes(transaction); + + const transactionSignature = signature + ? cryptography.hexToBuffer(signature) + : Buffer.alloc(0); + + const transactionSecondSignature = signSignature + ? cryptography.hexToBuffer(signSignature) + : Buffer.alloc(0); + + return Buffer.concat([ + transactionType, + transactionTimestamp, + transactionSenderPublicKey, + transactionRecipientID, + transactionAmount, + transactionAssetData, + transactionSignature, + transactionSecondSignature, + ]); +}; diff --git a/elements/lisk-transactions/src/utils/get_transaction_hash.ts b/elements/lisk-transactions/src/utils/get_transaction_hash.ts new file mode 100644 index 00000000000..1ebcd9e5013 --- /dev/null +++ b/elements/lisk-transactions/src/utils/get_transaction_hash.ts @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as cryptography from '@liskhq/lisk-cryptography'; +import { TransactionJSON } from '../transaction_types'; +import { getTransactionBytes } from './get_transaction_bytes'; + +// FIXME: Deprecated +export const getTransactionHash = (transaction: TransactionJSON): Buffer => { + const bytes = getTransactionBytes(transaction); + + return cryptography.hash(bytes); +}; diff --git a/elements/lisk-transactions/src/utils/index.ts b/elements/lisk-transactions/src/utils/index.ts new file mode 100644 index 00000000000..2106fae2ecf --- /dev/null +++ b/elements/lisk-transactions/src/utils/index.ts @@ -0,0 +1,26 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export * from './address'; +export * from './create_base_transaction'; +export * from './get_transaction_bytes'; +export * from './get_transaction_hash'; +export * from './transaction_id'; +export * from './format'; +export * from './sign_and_validate'; +export * from './time'; +export * from './validation'; +export * from './verify'; +export * from './prepare_transaction'; +export * from './sign_raw_transaction'; diff --git a/elements/lisk-transactions/src/utils/prepare_transaction.ts b/elements/lisk-transactions/src/utils/prepare_transaction.ts new file mode 100644 index 00000000000..11b9330676e --- /dev/null +++ b/elements/lisk-transactions/src/utils/prepare_transaction.ts @@ -0,0 +1,70 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as cryptography from '@liskhq/lisk-cryptography'; +import { TransactionJSON } from '../transaction_types'; +import { secondSignTransaction, signTransaction } from './sign_and_validate'; +import { getTimeWithOffset } from './time'; +import { getTransactionId } from './transaction_id'; + +// FIXME: Deprecated +const validTransaction = ( + partial: Partial, +): partial is TransactionJSON => partial.type !== undefined; + +// FIXME: Deprecated +export const prepareTransaction = ( + partialTransaction: Partial, + passphrase?: string, + secondPassphrase?: string, + timeOffset?: number, +): TransactionJSON => { + const senderPublicKey = passphrase + ? cryptography.getKeys(passphrase).publicKey + : undefined; + const timestamp = getTimeWithOffset(timeOffset); + + const transaction = { + amount: '0', + recipientId: '', + senderPublicKey, + timestamp, + ...partialTransaction, + }; + + if (!validTransaction(transaction)) { + throw new Error('Invalid transaction to process'); + } + + if (!passphrase) { + return transaction; + } + + const singleSignedTransaction = { + ...transaction, + signature: signTransaction(transaction, passphrase), + }; + + const signedTransaction = + typeof secondPassphrase === 'string' && transaction.type !== 1 + ? secondSignTransaction(singleSignedTransaction, secondPassphrase) + : singleSignedTransaction; + + const transactionWithId = { + ...signedTransaction, + id: getTransactionId(signedTransaction), + }; + + return transactionWithId; +}; diff --git a/elements/lisk-transactions/src/utils/sign_and_validate.ts b/elements/lisk-transactions/src/utils/sign_and_validate.ts new file mode 100644 index 00000000000..52d2c9e4184 --- /dev/null +++ b/elements/lisk-transactions/src/utils/sign_and_validate.ts @@ -0,0 +1,224 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as cryptography from '@liskhq/lisk-cryptography'; +import { TransactionError, TransactionPendingError } from '../errors'; +import { + IsValidResponse, + IsValidResponseWithError, + TransactionJSON, +} from '../transaction_types'; +import { getTransactionHash } from './get_transaction_hash'; + +export const multiSignTransaction = ( + transaction: TransactionJSON, + passphrase: string, +): string => { + const { signature, signSignature, ...transactionToSign } = transaction; + + const transactionHash = getTransactionHash(transactionToSign); + + return cryptography.signData(transactionHash, passphrase); +}; + +export const validateSignature = ( + publicKey: string, + signature: string, + transactionBytes: Buffer, + id?: string, +): IsValidResponseWithError => { + const transactionHash = cryptography.hash(transactionBytes); + + const valid = cryptography.verifyData(transactionHash, signature, publicKey); + + return { + valid, + error: !valid + ? new TransactionError( + `Failed to validate signature ${signature}`, + id, + '.signature', + ) + : undefined, + }; +}; + +export const signaturesAreUnique = ( + signatures: ReadonlyArray, +): boolean => { + const uniqueSignatures: ReadonlyArray = [...new Set(signatures)]; + if (uniqueSignatures.length !== signatures.length) { + return false; + } + + return true; +}; + +export const checkPublicKeySignatureUniqueness = ( + publicKeys: ReadonlyArray, + signatures: ReadonlyArray, + transactionBytes: Buffer, + id?: string, +): Set => { + const checkedPublicKeys = new Set(); + const validSignatures = new Set(); + publicKeys.forEach(publicKey => { + signatures.forEach((signature: string) => { + // Avoid single key from verifying more than one signature. + // See issue: https://github.com/LiskHQ/lisk/issues/2540 + if (checkedPublicKeys.has(publicKey) || validSignatures.has(signature)) { + return; + } + + const { valid: signatureValid } = validateSignature( + publicKey, + signature, + transactionBytes, + id, + ); + + if (signatureValid) { + checkedPublicKeys.add(publicKey); + validSignatures.add(signature); + } + }); + }); + + return validSignatures; +}; + +export const validateMultisignatures = ( + publicKeys: ReadonlyArray, + signatures: ReadonlyArray, + minimumValidations: number, + transactionBytes: Buffer, + id?: string, +): IsValidResponse => { + // Check that signatures are unique + if (!signaturesAreUnique(signatures)) { + return { + valid: false, + errors: [ + new TransactionError( + 'Encountered duplicate signature in transaction', + id, + '.signatures', + ), + ], + }; + } + + // Check that each PK signed only once + const validSignatures = checkPublicKeySignatureUniqueness( + publicKeys, + signatures, + transactionBytes, + id, + ); + + const invalidTransactionSignatures = signatures.filter( + signature => !validSignatures.has(signature), + ); + + // Transaction is waiting for more signatures + if (signatures.length < minimumValidations) { + return { + valid: false, + errors: [ + new TransactionPendingError(`Missing signatures`, id, '.signatures'), + ], + }; + } + + return { + valid: + validSignatures.size >= minimumValidations && + invalidTransactionSignatures.length === 0, + errors: + invalidTransactionSignatures.length > 0 + ? invalidTransactionSignatures.map( + signature => + new TransactionError( + `Failed to validate signature ${signature}`, + id, + '.signatures', + ), + ) + : [], + }; +}; + +// FIXME: Deprecated +export const signTransaction = ( + transaction: TransactionJSON, + passphrase: string, +): string => { + const transactionHash = getTransactionHash(transaction); + + return cryptography.signData(transactionHash, passphrase); +}; + +// FIXME: Deprecated +export const secondSignTransaction = ( + transaction: TransactionJSON, + secondPassphrase: string, +): TransactionJSON => ({ + ...transaction, + signSignature: signTransaction(transaction, secondPassphrase), +}); + +// FIXME: Deprecated +export const verifyTransaction = ( + transaction: TransactionJSON, + secondPublicKey?: string, +): boolean => { + if (!transaction.signature) { + throw new Error('Cannot verify transaction without signature.'); + } + if (!!transaction.signSignature && !secondPublicKey) { + throw new Error('Cannot verify signSignature without secondPublicKey.'); + } + + const { + signature, + signSignature, + ...transactionWithoutSignatures + } = transaction; + const transactionWithoutSignature = !!transaction.signSignature + ? { + ...transactionWithoutSignatures, + signature, + } + : transactionWithoutSignatures; + + const transactionHash = getTransactionHash(transactionWithoutSignature); + + const publicKey = + !!transaction.signSignature && secondPublicKey + ? secondPublicKey + : transaction.senderPublicKey; + const lastSignature = transaction.signSignature + ? transaction.signSignature + : transaction.signature; + + const verified = cryptography.verifyData( + transactionHash, + lastSignature, + publicKey, + ); + + return !!transaction.signSignature + ? verified && verifyTransaction(transactionWithoutSignature) + : verified; +}; diff --git a/elements/lisk-transactions/src/utils/sign_raw_transaction.ts b/elements/lisk-transactions/src/utils/sign_raw_transaction.ts new file mode 100644 index 00000000000..2fddf2bf2c0 --- /dev/null +++ b/elements/lisk-transactions/src/utils/sign_raw_transaction.ts @@ -0,0 +1,60 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as cryptography from '@liskhq/lisk-cryptography'; +import { TransactionJSON } from '../transaction_types'; +import { prepareTransaction } from './prepare_transaction'; +import { getTimeWithOffset } from './time'; + +export interface SignRawTransactionInput { + readonly passphrase: string; + readonly secondPassphrase?: string; + readonly timeOffset?: number; + readonly transaction: TransactionJSON; +} + +// FIXME: Deprecated +export const signRawTransaction = ({ + transaction, + passphrase, + secondPassphrase, + timeOffset, +}: SignRawTransactionInput): TransactionJSON => { + const { + publicKey, + address, + } = cryptography.getAddressAndPublicKeyFromPassphrase(passphrase); + const senderSecondPublicKey = secondPassphrase + ? cryptography.getPrivateAndPublicKeyFromPassphrase(secondPassphrase) + .publicKey + : undefined; + + const propertiesToAdd = { + senderPublicKey: publicKey, + senderSecondPublicKey, + senderId: address, + timestamp: getTimeWithOffset(timeOffset), + }; + + const transactionWithProperties = { + ...transaction, + ...propertiesToAdd, + }; + + return prepareTransaction( + transactionWithProperties, + passphrase, + secondPassphrase, + ); +}; diff --git a/elements/lisk-transactions/src/utils/time.ts b/elements/lisk-transactions/src/utils/time.ts new file mode 100644 index 00000000000..9ace314ec87 --- /dev/null +++ b/elements/lisk-transactions/src/utils/time.ts @@ -0,0 +1,32 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +import { EPOCH_TIME_MILLISECONDS } from '../constants'; + +const MS_TIME = 1000; + +export const getTimeFromBlockchainEpoch = (givenTimestamp?: number): number => { + const startingPoint = givenTimestamp || new Date().getTime(); + const blockchainInitialTime = EPOCH_TIME_MILLISECONDS; + + return Math.floor((startingPoint - blockchainInitialTime) / MS_TIME); +}; + +export const getTimeWithOffset = (offset?: number): number => { + const now = new Date().getTime(); + const timeWithOffset = offset ? now + offset * MS_TIME : now; + + return getTimeFromBlockchainEpoch(timeWithOffset); +}; diff --git a/elements/lisk-transactions/src/utils/transaction_id.ts b/elements/lisk-transactions/src/utils/transaction_id.ts new file mode 100644 index 00000000000..9a70cbe330f --- /dev/null +++ b/elements/lisk-transactions/src/utils/transaction_id.ts @@ -0,0 +1,55 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as cryptography from '@liskhq/lisk-cryptography'; +import { TransactionError } from '../errors'; +import { TransactionJSON } from '../transaction_types'; +import { getTransactionBytes } from './get_transaction_bytes'; + +export const getId = (transactionBytes: Buffer): string => { + const transactionHash = cryptography.hash(transactionBytes); + const bufferFromFirstEntriesReversed = cryptography.getFirstEightBytesReversed( + transactionHash, + ); + const transactionId = cryptography.bufferToBigNumberString( + bufferFromFirstEntriesReversed, + ); + + return transactionId; +}; + +export const validateTransactionId = ( + id: string, + bytes: Buffer, +): TransactionError | undefined => { + const expectedId = getId(bytes); + + return id !== expectedId + ? new TransactionError(`Invalid transaction id`, id, '.id', id, expectedId) + : undefined; +}; + +// FIXME: Deprecated +export const getTransactionId = (transaction: TransactionJSON): string => { + const transactionBytes = getTransactionBytes(transaction); + const transactionHash = cryptography.hash(transactionBytes); + const bufferFromFirstEntriesReversed = cryptography.getFirstEightBytesReversed( + transactionHash, + ); + const firstEntriesToNumber = cryptography.bufferToBigNumberString( + bufferFromFirstEntriesReversed, + ); + + return firstEntriesToNumber; +}; diff --git a/elements/lisk-transactions/src/utils/validation/index.ts b/elements/lisk-transactions/src/utils/validation/index.ts new file mode 100644 index 00000000000..b450819c4d7 --- /dev/null +++ b/elements/lisk-transactions/src/utils/validation/index.ts @@ -0,0 +1,34 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export { + checkPublicKeysForDuplicates, + validatePublicKey, + validatePublicKeys, + validateKeysgroup, + validateAddress, + validateNonTransferAmount, + validateTransferAmount, + validateUsername, + validateFee, + isValidInteger, + isGreaterThanMaxTransactionAmount, + isGreaterThanZero, + isNumberString, + stringEndsWith, + isUnique, + isValidNumber, +} from './validation'; +export { validateTransaction } from './validate_transaction'; +export { validator } from './validator'; diff --git a/elements/lisk-transactions/src/utils/validation/schema.ts b/elements/lisk-transactions/src/utils/validation/schema.ts new file mode 100644 index 00000000000..9638373fb69 --- /dev/null +++ b/elements/lisk-transactions/src/utils/validation/schema.ts @@ -0,0 +1,366 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export const transaction = { + $id: 'lisk/transaction', + type: 'object', + required: ['type', 'amount', 'fee', 'senderPublicKey', 'timestamp'], + properties: { + id: { + type: 'string', + }, + blockId: { + type: 'string', + }, + amount: { + type: ['string', 'integer'], + }, + fee: { + type: ['string', 'integer'], + }, + type: { + type: 'integer', + }, + timestamp: { + type: 'integer', + }, + senderId: { + type: 'string', + }, + senderPublicKey: { + type: 'string', + }, + recipientId: { + type: ['string', 'null'], + }, + recipientPublicKey: { + type: ['string', 'null'], + }, + signature: { + type: 'string', + }, + signSignature: { + type: 'string', + }, + signatures: { + type: 'array', + }, + asset: { + type: 'object', + }, + receivedAt: { + type: 'string', + }, + }, +}; + +// TODO: Add senderId and recipientId to required once deprecated functions relying on this schema are removed +export const baseTransaction = { + $id: 'lisk/base-transaction', + type: 'object', + required: [ + 'id', + 'type', + 'amount', + 'fee', + 'senderPublicKey', + 'timestamp', + 'asset', + 'signature', + ], + properties: { + id: { + type: 'string', + format: 'id', + }, + blockId: { + type: 'string', + format: 'id', + }, + height: { + type: 'integer', + minimum: 0, + }, + confirmations: { + type: 'integer', + minimum: 0, + }, + + amount: { + type: 'string', + format: 'amount', + }, + fee: { + type: 'string', + format: 'fee', + }, + type: { + type: 'integer', + minimum: 0, + maximum: 7, + }, + timestamp: { + type: 'integer', + minimum: -2147483648, + maximum: 2147483647, + }, + senderId: { + type: 'string', + format: 'address', + }, + senderPublicKey: { + type: 'string', + format: 'publicKey', + }, + senderSecondPublicKey: { + type: 'string', + format: 'publicKey', + }, + recipientId: { + type: 'string', + }, + recipientPublicKey: { + type: 'string', + format: 'emptyOrPublicKey', + }, + signature: { + type: 'string', + format: 'signature', + }, + signSignature: { + type: 'string', + format: 'signature', + }, + signatures: { + type: 'array', + uniqueItems: true, + items: { + type: 'string', + format: 'signature', + }, + minItems: 0, + maxItems: 15, + }, + asset: { + type: 'object', + }, + receivedAt: { + type: 'string', + format: 'date-time', + }, + }, +}; + +export const transferTransaction = { + $merge: { + source: { $ref: 'lisk/base-transaction' }, + with: { + properties: { + recipientId: { + format: 'address', + }, + amount: { + format: 'transferAmount', + }, + asset: { + type: 'object', + properties: { + data: { + type: 'string', + maxLength: 64, + }, + }, + }, + }, + }, + }, +}; + +export const signatureTransaction = { + $merge: { + source: { $ref: 'lisk/base-transaction' }, + with: { + properties: { + amount: { + format: 'nonTransferAmount', + }, + asset: { + type: 'object', + required: ['signature'], + properties: { + signature: { + type: 'object', + required: ['publicKey'], + properties: { + publicKey: { + type: 'string', + format: 'publicKey', + }, + }, + }, + }, + }, + }, + }, + }, +}; + +export const delegateTransaction = { + $merge: { + source: { $ref: 'lisk/base-transaction' }, + with: { + properties: { + amount: { + format: 'nonTransferAmount', + }, + asset: { + type: 'object', + required: ['delegate'], + properties: { + delegate: { + type: 'object', + required: ['username'], + properties: { + username: { + type: 'string', + maxLength: 20, + }, + }, + }, + }, + }, + }, + }, + }, +}; + +export const voteTransaction = { + $merge: { + source: { $ref: 'lisk/base-transaction' }, + with: { + properties: { + amount: { + format: 'nonTransferAmount', + }, + asset: { + type: 'object', + required: ['votes'], + properties: { + votes: { + type: 'array', + uniqueSignedPublicKeys: true, + minItems: 1, + maxItems: 33, + items: { + type: 'string', + format: 'signedPublicKey', + }, + }, + }, + }, + }, + }, + }, +}; + +export const multiTransaction = { + $merge: { + source: { $ref: 'lisk/base-transaction' }, + with: { + properties: { + amount: { + format: 'nonTransferAmount', + }, + asset: { + type: 'object', + required: ['multisignature'], + properties: { + multisignature: { + type: 'object', + required: ['min', 'lifetime', 'keysgroup'], + properties: { + min: { + type: 'integer', + minimum: 1, + maximum: 15, + }, + lifetime: { + type: 'integer', + minimum: 1, + maximum: 72, + }, + keysgroup: { + type: 'array', + uniqueItems: true, + minItems: 1, + maxItems: 15, + items: { + type: 'string', + format: 'additionPublicKey', + }, + }, + }, + }, + }, + }, + }, + }, + }, +}; + +export const dappTransaction = { + $merge: { + source: { $ref: 'lisk/base-transaction' }, + with: { + properties: { + amount: { + format: 'nonTransferAmount', + }, + asset: { + type: 'object', + required: ['dapp'], + properties: { + dapp: { + type: 'object', + required: ['name', 'type', 'category', 'link'], + properties: { + icon: { + type: 'string', + }, + category: { + type: 'integer', + }, + type: { + type: 'integer', + }, + link: { + type: 'string', + }, + tags: { + type: 'string', + }, + description: { + type: 'string', + }, + name: { + type: 'string', + }, + }, + }, + }, + }, + }, + }, + }, +}; diff --git a/elements/lisk-transactions/src/utils/validation/validate_transaction.ts b/elements/lisk-transactions/src/utils/validation/validate_transaction.ts new file mode 100644 index 00000000000..80d2ed1a52f --- /dev/null +++ b/elements/lisk-transactions/src/utils/validation/validate_transaction.ts @@ -0,0 +1,92 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { ErrorObject, ValidateFunction } from 'ajv'; +import { MultiSignatureAsset } from '../../4_multisignature_transaction'; +import { TransactionJSON } from '../../transaction_types'; +import * as schemas from './schema'; +import { validator } from './validator'; + +const TRANSACTION_TYPE_MULTI_SIGNATURE = 4; + +const schemaMap: { readonly [key: number]: ValidateFunction } = { + 0: validator.compile(schemas.transferTransaction), + 1: validator.compile(schemas.signatureTransaction), + 2: validator.compile(schemas.delegateTransaction), + 3: validator.compile(schemas.voteTransaction), + 4: validator.compile(schemas.multiTransaction), + 5: validator.compile(schemas.dappTransaction), +}; + +const getTransactionSchemaValidator = (type: number): ValidateFunction => { + const schema = schemaMap[type]; + if (!schema) { + throw new Error('Unsupported transaction type.'); + } + + return schema; +}; + +export interface ValidationResult { + readonly errors?: ReadonlyArray; + readonly valid: boolean; +} + +const validateMultiTransaction = (tx: TransactionJSON): ValidationResult => { + if ( + (tx.asset as MultiSignatureAsset).multisignature.min > + (tx.asset as MultiSignatureAsset).multisignature.keysgroup.length + ) { + return { + valid: false, + errors: [ + { + dataPath: '.asset.multisignature.min', + keyword: 'multisignatures.keysgroup.min', + message: + '.asset.multisignature.min cannot be greater than .asset.multisignature.keysgroup.length', + params: {}, + schemaPath: 'lisk/base-transaction', + }, + ] as ReadonlyArray, + }; + } + + return { + valid: true, + }; +}; + +export const validateTransaction = (tx: TransactionJSON): ValidationResult => { + if (tx.type === undefined || tx.type === null) { + throw new Error('Transaction type is required.'); + } + + const validateSchema = getTransactionSchemaValidator(tx.type); + const valid = validateSchema(tx) as boolean; + // Ajv produces merge error when error happens within $merge + const errors = validateSchema.errors + ? validateSchema.errors.filter( + (e: { readonly keyword: string }) => e.keyword !== '$merge', + ) + : undefined; + if (valid && tx.type === TRANSACTION_TYPE_MULTI_SIGNATURE) { + return validateMultiTransaction(tx); + } + + return { + valid, + errors, + }; +}; diff --git a/elements/lisk-transactions/src/utils/validation/validation.ts b/elements/lisk-transactions/src/utils/validation/validation.ts new file mode 100644 index 00000000000..c0da4259b43 --- /dev/null +++ b/elements/lisk-transactions/src/utils/validation/validation.ts @@ -0,0 +1,186 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { + MAX_ADDRESS_NUMBER, + MAX_PUBLIC_KEY_LENGTH, + MAX_TRANSACTION_AMOUNT, + MAX_TRANSACTION_ID, + MULTISIGNATURE_MAX_KEYSGROUP, + MULTISIGNATURE_MIN_KEYSGROUP, +} from '../../constants'; + +export const validatePublicKey = (publicKey: string) => { + const publicKeyBuffer = cryptography.hexToBuffer(publicKey); + if (publicKeyBuffer.length !== MAX_PUBLIC_KEY_LENGTH) { + throw new Error( + `Public key ${publicKey} length differs from the expected 32 bytes for a public key.`, + ); + } + + return true; +}; + +export const isNullByteIncluded = (input: string) => + new RegExp('\\0|\\U00000000').test(input); + +export const validateUsername = (username: string) => { + if (isNullByteIncluded(username)) { + return false; + } + + if (username !== username.trim().toLowerCase()) { + return false; + } + + if (/^[0-9]{1,21}[L|l]$/g.test(username)) { + return false; + } + + if (!/^[a-z0-9!@$&_.]+$/g.test(username)) { + return false; + } + + return true; +}; + +export const validateSignature = (signature: string) => + /^[a-f0-9]{128}$/i.test(signature); + +export const checkPublicKeysForDuplicates = ( + publicKeys: ReadonlyArray, +) => + publicKeys.every((element, index) => { + if (publicKeys.slice(index + 1).includes(element)) { + throw new Error(`Duplicated public key: ${publicKeys[index]}.`); + } + + return true; + }); + +export const stringEndsWith = ( + target: string, + suffixes: ReadonlyArray, +): boolean => suffixes.some(suffix => target.endsWith(suffix)); + +export const validatePublicKeys = (publicKeys: ReadonlyArray) => + publicKeys.every(validatePublicKey) && + checkPublicKeysForDuplicates(publicKeys); + +export const validateKeysgroup = (keysgroup: ReadonlyArray) => { + if ( + keysgroup.length < MULTISIGNATURE_MIN_KEYSGROUP || + keysgroup.length > MULTISIGNATURE_MAX_KEYSGROUP + ) { + throw new Error( + `Expected between ${MULTISIGNATURE_MIN_KEYSGROUP} and ${MULTISIGNATURE_MAX_KEYSGROUP} public keys in the keysgroup.`, + ); + } + + return validatePublicKeys(keysgroup); +}; + +const MIN_ADDRESS_LENGTH = 2; +const MAX_ADDRESS_LENGTH = 22; +const BASE_TEN = 10; +export const validateAddress = (address: string): boolean => { + if ( + address.length < MIN_ADDRESS_LENGTH || + address.length > MAX_ADDRESS_LENGTH + ) { + throw new Error( + 'Address length does not match requirements. Expected between 2 and 22 characters.', + ); + } + + if (address[address.length - 1] !== 'L') { + throw new Error( + 'Address format does not match requirements. Expected "L" at the end.', + ); + } + + if (address.includes('.')) { + throw new Error( + 'Address format does not match requirements. Address includes invalid character: `.`.', + ); + } + + const addressString = address.slice(0, -1); + const addressNumber = new BigNum(addressString); + + if (addressNumber.cmp(new BigNum(MAX_ADDRESS_NUMBER)) > 0) { + throw new Error( + 'Address format does not match requirements. Address out of maximum range.', + ); + } + + if (addressString !== addressNumber.toString(BASE_TEN)) { + throw new Error( + "Address string format does not match it's number representation.", + ); + } + + return true; +}; + +export const isGreaterThanZero = (amount: BigNum) => amount.cmp(0) > 0; + +export const isGreaterThanMaxTransactionAmount = (amount: BigNum) => + amount.cmp(MAX_TRANSACTION_AMOUNT) > 0; + +export const isGreaterThanMaxTransactionId = (id: BigNum) => + id.cmp(MAX_TRANSACTION_ID) > 0; + +export const isNumberString = (str: string) => { + if (typeof str !== 'string') { + return false; + } + + return /^[0-9]+$/g.test(str); +}; + +export const validateNonTransferAmount = (data: string) => + isNumberString(data) && data === '0'; + +export const validateTransferAmount = (data: string) => + isNumberString(data) && + isGreaterThanZero(new BigNum(data)) && + !isGreaterThanMaxTransactionAmount(new BigNum(data)); + +export const validateFee = (data: string) => + isNumberString(data) && + isGreaterThanZero(new BigNum(data)) && + !isGreaterThanMaxTransactionAmount(new BigNum(data)); + +export const isValidInteger = (num: unknown) => + typeof num === 'number' ? Math.floor(num) === num : false; + +export const isUnique = (values: ReadonlyArray): boolean => { + const unique = [...new Set(values)]; + + return unique.length === values.length; +}; + +export const isValidNumber = (num: unknown): boolean => { + if (typeof num === 'number') { + return true; + } + if (typeof num === 'string') { + return isNumberString(num); + } + + return false; +}; diff --git a/elements/lisk-transactions/src/utils/validation/validator.ts b/elements/lisk-transactions/src/utils/validation/validator.ts new file mode 100644 index 00000000000..c320a1a5fab --- /dev/null +++ b/elements/lisk-transactions/src/utils/validation/validator.ts @@ -0,0 +1,130 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import * as Ajv from 'ajv'; +// tslint:disable-next-line no-require-imports +import addKeywords = require('ajv-merge-patch'); +import * as schemas from './schema'; +import { + isGreaterThanMaxTransactionId, + isNullByteIncluded, + isNumberString, + validateAddress, + validateFee, + validateNonTransferAmount, + validatePublicKey, + validateSignature, + validateTransferAmount, + validateUsername, +} from './validation'; + +export const validator = new Ajv({ allErrors: true, removeAdditional: 'all' }); +addKeywords(validator); + +validator.addFormat('signature', validateSignature); + +validator.addFormat( + 'id', + data => + isNumberString(data) && !isGreaterThanMaxTransactionId(new BigNum(data)), +); + +validator.addFormat('address', data => { + try { + validateAddress(data); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('amount', isNumberString); + +validator.addFormat('transferAmount', validateTransferAmount); + +validator.addFormat('nonTransferAmount', validateNonTransferAmount); + +validator.addFormat('fee', validateFee); + +validator.addFormat('emptyOrPublicKey', data => { + if (data === null || data === '') { + return true; + } + + try { + validatePublicKey(data); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('publicKey', data => { + try { + validatePublicKey(data); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('signedPublicKey', data => { + try { + const action = data[0]; + if (action !== '+' && action !== '-') { + return false; + } + const publicKey = data.slice(1); + validatePublicKey(publicKey); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('additionPublicKey', data => { + const action = data[0]; + if (action !== '+') { + return false; + } + try { + const publicKey = data.slice(1); + validatePublicKey(publicKey); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('username', validateUsername); + +validator.addFormat('noNullByte', data => !isNullByteIncluded(data)); + +validator.addKeyword('uniqueSignedPublicKeys', { + type: 'array', + compile: () => (data: ReadonlyArray) => + new Set( + data + .filter(datum => typeof datum === 'string') + .map((key: string) => key.slice(1)), + ).size === data.length, +}); + +validator.addSchema(schemas.baseTransaction); diff --git a/elements/lisk-transactions/src/utils/verify.ts b/elements/lisk-transactions/src/utils/verify.ts new file mode 100644 index 00000000000..01acee673e7 --- /dev/null +++ b/elements/lisk-transactions/src/utils/verify.ts @@ -0,0 +1,192 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { MultisignatureStatus } from '../base_transaction'; +import { TransactionError, TransactionPendingError } from '../errors'; +import { Account } from '../transaction_types'; +import { convertBeddowsToLSK } from '../utils/format'; +import { + validateMultisignatures, + validateSignature, +} from './sign_and_validate'; + +export const verifySenderPublicKey = ( + id: string, + sender: Account, + publicKey: string, +): TransactionError | undefined => + sender.publicKey && sender.publicKey !== publicKey + ? new TransactionError( + 'Invalid sender publicKey', + id, + '.senderPublicKey', + publicKey, + sender.publicKey, + ) + : undefined; + +export const verifySenderId = ( + id: string, + sender: Account, + address: string, +): TransactionError | undefined => + sender.address.toUpperCase() !== address.toUpperCase() + ? new TransactionError( + 'Invalid sender address', + id, + '.senderId', + address.toUpperCase(), + sender.address.toUpperCase(), + ) + : undefined; + +export const verifyBalance = ( + id: string, + account: Account, + amount: BigNum, +): TransactionError | undefined => + new BigNum(account.balance).lt(new BigNum(amount)) + ? new TransactionError( + `Account does not have enough LSK: ${ + account.address + }, balance: ${convertBeddowsToLSK(account.balance.toString())}`, + id, + '.balance', + account.balance, + convertBeddowsToLSK(account.balance.toString()), + ) + : undefined; + +export const verifyAmountBalance = ( + id: string, + account: Account, + amount: BigNum, + fee: BigNum, +): TransactionError | undefined => { + const balance = new BigNum(account.balance); + if (balance.gte(0) && balance.lt(new BigNum(amount))) { + return new TransactionError( + `Account does not have enough LSK: ${ + account.address + }, balance: ${convertBeddowsToLSK(balance.plus(fee).toString())}`, + id, + '.balance', + ); + } + + return undefined; +}; + +export const verifySecondSignature = ( + id: string, + sender: Account, + signSignature: string | undefined, + transactionBytes: Buffer, +): TransactionError | undefined => { + if (!sender.secondPublicKey && signSignature) { + return new TransactionError( + 'Sender does not have a secondPublicKey', + id, + '.signSignature', + ); + } + if (!sender.secondPublicKey) { + return undefined; + } + if (!signSignature) { + return new TransactionError('Missing signSignature', id, '.signSignature'); + } + const { valid, error } = validateSignature( + sender.secondPublicKey, + signSignature, + transactionBytes, + id, + ); + if (valid) { + return undefined; + } + + return error; +}; + +interface VerifyMultiSignatureResult { + readonly status: MultisignatureStatus; + readonly errors: ReadonlyArray; +} + +const isMultisignatureAccount = (account: Account): boolean => + !!( + account.membersPublicKeys && + account.membersPublicKeys.length > 0 && + account.multiMin + ); + +export const verifyMultiSignatures = ( + id: string, + sender: Account, + signatures: ReadonlyArray, + transactionBytes: Buffer, +): VerifyMultiSignatureResult => { + if (!isMultisignatureAccount(sender) && signatures.length > 0) { + return { + status: MultisignatureStatus.FAIL, + errors: [ + new TransactionError( + 'Sender is not a multisignature account', + id, + '.signatures', + ), + ], + }; + } + + if (!isMultisignatureAccount(sender)) { + return { + status: MultisignatureStatus.NONMULTISIGNATURE, + errors: [], + }; + } + + const { valid, errors } = validateMultisignatures( + sender.membersPublicKeys as ReadonlyArray, + signatures, + sender.multiMin as number, + transactionBytes, + id, + ); + + if (valid) { + return { + status: MultisignatureStatus.READY, + errors: [], + }; + } + + if ( + errors && + errors.length === 1 && + errors[0] instanceof TransactionPendingError + ) { + return { + status: MultisignatureStatus.PENDING, + errors, + }; + } + + return { + status: MultisignatureStatus.FAIL, + errors: errors || [], + }; +}; diff --git a/elements/lisk-transactions/test/0_transfer.ts b/elements/lisk-transactions/test/0_transfer.ts new file mode 100644 index 00000000000..d1c1b95c868 --- /dev/null +++ b/elements/lisk-transactions/test/0_transfer.ts @@ -0,0 +1,344 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { transfer } from '../src/0_transfer'; +import * as time from '../src/utils/time'; +import { TransactionJSON } from '../src/transaction_types'; + +describe('#transfer transaction', () => { + const fixedPoint = 10 ** 8; + const testData = 'data'; + const passphrase = 'secret'; + const secondPassphrase = 'second secret'; + const transactionType = 0; + const publicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const recipientId = '18160565574430594874L'; + const recipientPublicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const recipientPublicKeyThatDoesNotMatchRecipientId = + '12345a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const amount = '1000'; + const fee = (0.1 * fixedPoint).toString(); + const timeWithOffset = 38350076; + + let getTimeWithOffsetStub: sinon.SinonStub; + let transferTransaction: Partial; + + beforeEach(() => { + getTimeWithOffsetStub = sandbox + .stub(time, 'getTimeWithOffset') + .returns(timeWithOffset); + return Promise.resolve(); + }); + + describe('with first passphrase', () => { + describe('without data', () => { + beforeEach(() => { + transferTransaction = transfer({ + recipientId, + amount, + passphrase, + }); + return Promise.resolve(); + }); + + it('should create a transfer transaction', () => { + return expect(transferTransaction).to.be.ok; + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(undefined); + }); + + it('should use time.getTimeWithOffset with an offset of -10 seconds to calculate the timestamp', () => { + const offset = -10; + transfer({ + recipientId, + amount, + passphrase, + timeOffset: offset, + }); + + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(offset); + }); + + it('should be an object', () => { + return expect(transferTransaction).to.be.an('object'); + }); + + it('should have id string', () => { + return expect(transferTransaction) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have type number equal to 0', () => { + return expect(transferTransaction) + .to.have.property('type') + .and.be.a('number') + .and.equal(transactionType); + }); + + it('should have amount string equal to provided amount', () => { + return expect(transferTransaction) + .to.have.property('amount') + .and.be.a('string') + .and.equal(amount); + }); + + it('should have fee string equal to transfer fee', () => { + return expect(transferTransaction) + .to.have.property('fee') + .and.be.a('string') + .and.equal(fee); + }); + + it('should have recipientId string equal to provided recipient id', () => { + return expect(transferTransaction) + .to.have.property('recipientId') + .and.be.a('string') + .and.equal(recipientId); + }); + + it('should have senderPublicKey hex string equal to sender public key', () => { + return expect(transferTransaction) + .to.have.property('senderPublicKey') + .and.be.hexString.and.equal(publicKey); + }); + + it('should have timestamp number equal to result of time.getTimeWithOffset', () => { + return expect(transferTransaction) + .to.have.property('timestamp') + .and.be.a('number') + .and.equal(timeWithOffset); + }); + + it('should have signature hex string', () => { + return expect(transferTransaction).to.have.property('signature').and.be + .hexString; + }); + + it('should have an empty asset object', () => { + return expect(transferTransaction) + .to.have.property('asset') + .and.be.an('object').and.be.empty; + }); + + it('second signature property should be undefined', () => { + return expect(transferTransaction.signSignature).to.be.undefined; + }); + }); + + describe('with data', () => { + beforeEach(() => { + transferTransaction = transfer({ + recipientId, + amount, + passphrase, + data: testData, + }); + return Promise.resolve(); + }); + + it('should handle invalid (non-utf8 string) data', () => { + return expect( + transfer.bind(null, { + recipientId, + amount, + passphrase, + data: Buffer.from('hello') as any, + }), + ).to.throw( + 'Invalid encoding in transaction data. Data must be utf-8 encoded string.', + ); + }); + + it('should have fee string equal to transfer fee', () => { + return expect(transferTransaction) + .to.have.property('fee') + .and.be.a('string') + .and.equal(fee); + }); + + describe('data asset', () => { + it('should be a string equal to provided data', () => { + return expect(transferTransaction.asset) + .to.have.property('data') + .and.be.a('string') + .and.equal(testData); + }); + }); + }); + }); + + describe('with first and second passphrase', () => { + beforeEach(() => { + transferTransaction = transfer({ + recipientId, + amount, + passphrase, + secondPassphrase, + }); + return Promise.resolve(); + }); + + it('should create a transfer transaction with data property', () => { + transferTransaction = transfer({ + recipientId, + amount, + passphrase, + secondPassphrase, + data: testData, + }); + + return expect(transferTransaction.asset).to.have.property('data'); + }); + + it('should have the second signature property as hex string', () => { + return expect(transferTransaction).to.have.property('signSignature').and + .be.hexString; + }); + }); + + describe('unsigned transfer transaction', () => { + describe('when the transfer transaction is created without a passphrase', () => { + beforeEach(() => { + transferTransaction = transfer({ + recipientId, + amount, + }); + return Promise.resolve(); + }); + + it('should throw error when amount is 0', () => { + return expect( + transfer.bind(null, { + amount: '0', + }), + ).to.throw('Amount must be a valid number in string format.'); + }); + + it('should throw error when amount is greater than max transaction amount', () => { + return expect( + transfer.bind(null, { + amount: '18446744073709551616', + }), + ).to.throw('Amount must be a valid number in string format.'); + }); + + it('should throw error when recipientId & non-matching recipientPublicKey provided', () => { + return expect( + transfer.bind(null, { + amount, + recipientId, + recipientPublicKey: recipientPublicKeyThatDoesNotMatchRecipientId, + }), + ).to.throw('recipientId does not match recipientPublicKey.'); + }); + + it('should non throw error when recipientId & matching recipientPublicKey provided', () => { + return expect( + transfer.bind(null, { + amount, + recipientId, + recipientPublicKey, + }), + ).to.not.throw(); + }); + + it('should throw error when neither recipientId nor recipientPublicKey were provided', () => { + return expect( + transfer.bind(null, { + amount, + passphrase, + data: Buffer.from('hello') as any, + }), + ).to.throw( + 'Either recipientId or recipientPublicKey must be provided.', + ); + }); + + it('should set recipientId when recipientId was not provided but recipientPublicKey was provided', () => { + const tx = transfer({ + amount, + passphrase, + recipientPublicKey: publicKey, + }); + return expect(tx) + .to.have.property('recipientId') + .and.be.a('string') + .to.equal(cryptography.getAddressFromPublicKey(publicKey)); + }); + + it('should handle too much data', () => { + return expect( + transfer.bind(null, { + recipientId, + amount, + data: new Array(65).fill('0').join(''), + }), + ).to.throw('Transaction data field cannot exceed 64 bytes.'); + }); + + it('should have the type', () => { + return expect(transferTransaction) + .to.have.property('type') + .equal(transactionType); + }); + + it('should have the amount', () => { + return expect(transferTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the fee', () => { + return expect(transferTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the recipient', () => { + return expect(transferTransaction) + .to.have.property('recipientId') + .equal(recipientId); + }); + + it('should have the sender public key', () => { + return expect(transferTransaction) + .to.have.property('senderPublicKey') + .equal(undefined); + }); + + it('should have the timestamp', () => { + return expect(transferTransaction).to.have.property('timestamp'); + }); + + it('should have the asset', () => { + return expect(transferTransaction).to.have.property('asset'); + }); + + it('should not have the signature', () => { + return expect(transferTransaction).not.to.have.property('signature'); + }); + + it('should not have the id', () => { + return expect(transferTransaction).not.to.have.property('id'); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/0_transfer_transaction.ts b/elements/lisk-transactions/test/0_transfer_transaction.ts new file mode 100644 index 00000000000..f92c0a5f6e4 --- /dev/null +++ b/elements/lisk-transactions/test/0_transfer_transaction.ts @@ -0,0 +1,270 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { expect } from 'chai'; +import { MAX_TRANSACTION_AMOUNT, TRANSFER_FEE } from '../src/constants'; +import { TransferTransaction } from '../src/0_transfer_transaction'; +import { Account } from '../src/transaction_types'; +import { Status } from '../src/response'; +import { TransactionError } from '../src/errors'; +import { addTransactionFields, MockStateStore as store } from './helpers'; +import { validTransferAccount, validTransferTransactions } from '../fixtures'; + +describe('Transfer transaction class', () => { + const validTransferTransaction = addTransactionFields( + validTransferTransactions[0], + ); + const validSelfTransferTransaction = addTransactionFields( + validTransferTransactions[1], + ); + let validTransferTestTransaction: TransferTransaction; + let validSelfTransferTestTransaction: TransferTransaction; + let sender: Account; + let recipient: Account; + let storeAccountCacheStub: sinon.SinonStub; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountGetOrDefaultStub: sinon.SinonStub; + let storeAccountSetStub: sinon.SinonStub; + + beforeEach(async () => { + validTransferTestTransaction = new TransferTransaction( + validTransferTransaction, + ); + validSelfTransferTestTransaction = new TransferTransaction( + validSelfTransferTransaction, + ); + sender = validTransferAccount[0]; + recipient = validTransferAccount[1]; + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + storeAccountGetStub = sandbox.stub(store.account, 'get').returns(sender); + storeAccountGetOrDefaultStub = sandbox + .stub(store.account, 'getOrDefault') + .returns(recipient); + storeAccountSetStub = sandbox.stub(store.account, 'set'); + }); + + describe('#constructor', () => { + it('should create instance of TransferTransaction', async () => { + expect(validSelfTransferTestTransaction) + .to.be.an('object') + .and.be.instanceof(TransferTransaction); + }); + + it('should set transfer asset', async () => { + expect(validSelfTransferTestTransaction.asset).to.eql({ data: 'a' }); + }); + + it('should set fee to transfer transaction fee amount', async () => { + expect(validSelfTransferTestTransaction.fee.toString()).to.eql( + TRANSFER_FEE.toString(), + ); + }); + }); + + describe('#assetToBytes', () => { + it('should return a buffer', async () => { + const expectedBytes = '61'; + const assetBytes = (validSelfTransferTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql(Buffer.from(expectedBytes, 'hex')); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return a successful transaction response', async () => { + const { + id, + status, + errors, + } = validTransferTestTransaction.verifyAgainstOtherTransactions([]); + expect(id).to.be.eql(validTransferTransaction.id); + expect(errors).to.be.empty; + expect(status).to.eql(Status.OK); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validSelfTransferTestTransaction.assetToJSON()) + .to.be.an('object') + .and.to.have.property('data') + .that.is.a('string'); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + await validSelfTransferTestTransaction.prepare(store); + expect(storeAccountCacheStub).to.have.been.calledWithExactly([ + { address: validSelfTransferTestTransaction.senderId }, + { address: validSelfTransferTestTransaction.recipientId }, + ]); + }); + }); + + describe('#validateAsset', () => { + it('should return no errors with a valid transfer transaction', async () => { + const errors = (validTransferTestTransaction as any).validateAsset(); + + expect(errors).to.be.empty; + }); + + it('should return error with invalid recipientId', async () => { + const transferTransactionWithInvalidRecipientId = new TransferTransaction( + { + ...validTransferTransaction, + recipientId: '123456', + }, + ); + const errors = (transferTransactionWithInvalidRecipientId as any).validateAsset(); + + expect(errors[0]) + .to.be.instanceof(TransactionError) + .and.to.have.property( + 'message', + 'Address format does not match requirements. Expected "L" at the end.', + ); + }); + + it('should return error with invalid amount', async () => { + const transferTransactionWithInvalidAmount = new TransferTransaction({ + ...validTransferTransaction, + amount: '9223372036854775808', + }); + const errors = (transferTransactionWithInvalidAmount as any).validateAsset(); + + expect(errors[0]) + .to.be.instanceof(TransactionError) + .and.to.have.property( + 'message', + `Amount must be a valid number in string format.`, + ); + }); + + it('should return error with invalid asset', async () => { + const transferTransactionWithInvalidAsset = new TransferTransaction({ + ...validTransferTransaction, + asset: { + data: + 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', + }, + }); + const errors = (transferTransactionWithInvalidAsset as any).validateAsset(); + + expect(errors[0]).to.be.instanceof(TransactionError); + }); + }); + + describe('#applyAsset', () => { + it('should return no errors', async () => { + const errors = (validTransferTestTransaction as any).applyAsset(store); + expect(errors).to.be.empty; + }); + + it('should call state store', async () => { + (validTransferTestTransaction as any).applyAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTransferTestTransaction.senderId, + ); + expect( + storeAccountSetStub.getCall(0).calledWithExactly(sender.address, { + ...sender, + balance: new BigNum(sender.balance) + .sub(validTransferTestTransaction.amount) + .toString(), + }), + ); + expect(storeAccountGetOrDefaultStub).to.be.calledWithExactly( + validTransferTestTransaction.recipientId, + ); + expect( + storeAccountSetStub.getCall(1).calledWithExactly(recipient.address, { + ...recipient, + balance: new BigNum(recipient.balance) + .add(validTransferTestTransaction.amount) + .toString(), + }), + ); + }); + + it('should return error when sender balance is insufficient', async () => { + storeAccountGetStub.returns({ + ...sender, + balance: new BigNum(10000000), + }); + const errors = (validTransferTestTransaction as any).applyAsset(store); + expect(errors).to.have.length(1); + expect(errors[0].message).to.equal( + `Account does not have enough LSK: ${sender.address}, balance: 0.2`, + ); + }); + + it('should return error when recipient balance is over maximum amount', async () => { + storeAccountGetOrDefaultStub.returns({ + ...sender, + balance: new BigNum(MAX_TRANSACTION_AMOUNT), + }); + const errors = (validTransferTestTransaction as any).applyAsset(store); + expect(errors[0]).and.to.have.property('message', 'Invalid amount'); + }); + }); + + describe('#undoAsset', () => { + it('should call state store', async () => { + (validTransferTestTransaction as any).undoAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTransferTestTransaction.senderId, + ); + expect( + storeAccountSetStub.getCall(0).calledWithExactly(sender.address, { + ...sender, + balance: new BigNum(sender.balance) + .add(validTransferTestTransaction.amount) + .toString(), + }), + ); + expect(storeAccountGetOrDefaultStub).to.be.calledWithExactly( + validTransferTestTransaction.recipientId, + ); + expect( + storeAccountSetStub.getCall(1).calledWithExactly(recipient.address, { + ...recipient, + balance: new BigNum(recipient.balance) + .sub(validTransferTestTransaction.amount) + .toString(), + }), + ); + }); + + it('should return error when recipient balance is insufficient', async () => { + storeAccountGetOrDefaultStub.returns({ + ...recipient, + balance: new BigNum('0'), + }); + const errors = (validTransferTestTransaction as any).undoAsset(store); + expect(errors[0].message).to.equal( + `Account does not have enough LSK: ${recipient.address}, balance: 0`, + ); + }); + + it('should return error when sender balance is over maximum amount', async () => { + storeAccountGetStub.returns({ + ...recipient, + balance: new BigNum(MAX_TRANSACTION_AMOUNT), + }); + const errors = (validTransferTestTransaction as any).undoAsset(store); + expect(errors[0]).and.to.have.property('message', 'Invalid amount'); + }); + }); +}); diff --git a/elements/lisk-transactions/test/1_register_second_passphrase.ts b/elements/lisk-transactions/test/1_register_second_passphrase.ts new file mode 100644 index 00000000000..6abf01212b4 --- /dev/null +++ b/elements/lisk-transactions/test/1_register_second_passphrase.ts @@ -0,0 +1,255 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { registerSecondPassphrase } from '../src/1_register_second_passphrase'; +import { SecondSignatureAsset } from '../src/1_second_signature_transaction'; +import { TransactionJSON } from '../src/transaction_types'; +import * as time from '../src/utils/time'; + +describe('#registerSecondPassphrase transaction', () => { + const fixedPoint = 10 ** 8; + const passphrase = 'secret'; + const secondPassphrase = 'second secret'; + const transactionType = 1; + const publicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const secondPublicKey = + '0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f'; + const emptyStringPublicKey = + 'be907b4bac84fee5ce8811db2defc9bf0b2a2a2bbc3d54d8a2257ecd70441962'; + const secondPassphraseFee = (5 * fixedPoint).toString(); + const timeWithOffset = 38350076; + const fee = (5 * fixedPoint).toString(); + const amount = '0'; + + let getTimeWithOffsetStub: sinon.SinonStub; + let registerSecondPassphraseTransaction: Partial; + + beforeEach(() => { + getTimeWithOffsetStub = sandbox + .stub(time, 'getTimeWithOffset') + .returns(timeWithOffset); + registerSecondPassphraseTransaction = registerSecondPassphrase({ + passphrase, + secondPassphrase, + }); + return Promise.resolve(); + }); + + it('should create a register second passphrase transaction', () => { + return expect(registerSecondPassphraseTransaction).to.be.ok; + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(undefined); + }); + + it('should use time.getTimeWithOffset with an offset of -10 seconds to calculate the timestamp', () => { + const offset = -10; + registerSecondPassphrase({ + passphrase, + secondPassphrase, + timeOffset: offset, + }); + + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(offset); + }); + + describe('returned register second passphrase transaction', () => { + it('should be an object', () => { + return expect(registerSecondPassphraseTransaction).to.be.an('object'); + }); + + it('should have an id string', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have type number equal to 1', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('type') + .and.be.a('number') + .and.equal(transactionType); + }); + + it('should have amount string equal to 0', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('amount') + .and.be.a('string') + .and.equal(amount); + }); + + it('should have fee string equal to second passphrase fee', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('fee') + .and.be.a('string') + .and.equal(secondPassphraseFee); + }); + + it('should have recipientId equal to empty string', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('recipientId') + .and.equal(''); + }); + + it('should have senderPublicKey hex string equal to sender public key', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('senderPublicKey') + .and.be.hexString.and.equal(publicKey); + }); + + it('should have timestamp number equal to result of time.getTimeWithOffset', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('timestamp') + .and.be.a('number') + .and.equal(timeWithOffset); + }); + + it('should have signature hex string', () => { + return expect(registerSecondPassphraseTransaction).to.have.property( + 'signature', + ).and.be.hexString; + }); + + it('should have asset object', () => { + return expect(registerSecondPassphraseTransaction).to.have.property( + 'asset', + ).and.not.be.empty; + }); + + it('should have an undefined signSignature property', () => { + return expect(registerSecondPassphraseTransaction.signSignature).to.be + .undefined; + }); + + describe('signature asset', () => { + it('should be an object', () => { + return expect(registerSecondPassphraseTransaction.asset) + .to.have.property('signature') + .and.be.an('object').and.not.be.empty; + }); + + it('should have a 32-byte publicKey hex string', () => { + expect(registerSecondPassphraseTransaction.asset) + .to.have.property('signature') + .with.property('publicKey').and.be.hexString; + const { + signature, + } = registerSecondPassphraseTransaction.asset as SecondSignatureAsset; + return expect(Buffer.from(signature.publicKey, 'hex')).to.have.length( + 32, + ); + }); + + it('should have a publicKey equal to the public key for the provided second passphrase', () => { + return expect(registerSecondPassphraseTransaction.asset) + .to.have.property('signature') + .with.property('publicKey') + .and.equal(secondPublicKey); + }); + + it('should have the correct publicKey if the provided second passphrase is an empty string', () => { + registerSecondPassphraseTransaction = registerSecondPassphrase({ + passphrase, + secondPassphrase: '', + }); + const { + signature, + } = registerSecondPassphraseTransaction.asset as SecondSignatureAsset; + return expect(signature.publicKey).to.be.equal(emptyStringPublicKey); + }); + }); + }); + + describe('unsigned register second passphrase transaction', () => { + describe('when the register second passphrase transaction is created without a passphrase', () => { + beforeEach(() => { + registerSecondPassphraseTransaction = registerSecondPassphrase({ + secondPassphrase, + }); + return Promise.resolve(); + }); + + it('should throw error when secondPassphrase was not provided', () => { + return expect(registerSecondPassphrase.bind(null, {} as any)).to.throw( + 'Please provide a secondPassphrase. Expected string.', + ); + }); + + it('should not throw error when secondPassphrase is empty string', () => { + return expect( + registerSecondPassphrase.bind(null, { secondPassphrase: '' }), + ).to.not.throw(); + }); + + it('should have the type', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('type') + .equal(transactionType); + }); + + it('should have the amount', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the fee', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the recipient', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('recipientId') + .equal(''); + }); + + it('should have the sender public key', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('senderPublicKey') + .equal(undefined); + }); + + it('should have the timestamp', () => { + return expect(registerSecondPassphraseTransaction).to.have.property( + 'timestamp', + ); + }); + + it('should have the asset with the signature with the public key', () => { + return expect(registerSecondPassphraseTransaction) + .to.have.property('asset') + .with.property('signature') + .with.property('publicKey') + .of.a('string'); + }); + + it('should not have the signature', () => { + return expect(registerSecondPassphraseTransaction).not.to.have.property( + 'signature', + ); + }); + + it('should not have the id', () => { + return expect(registerSecondPassphraseTransaction).not.to.have.property( + 'id', + ); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/1_second_passphrase_transaction.ts b/elements/lisk-transactions/test/1_second_passphrase_transaction.ts new file mode 100644 index 00000000000..daf07dff79b --- /dev/null +++ b/elements/lisk-transactions/test/1_second_passphrase_transaction.ts @@ -0,0 +1,224 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { MockStateStore as store } from './helpers'; +import { SecondSignatureTransaction } from '../src/1_second_signature_transaction'; +import { + validRegisterSecondSignatureTransaction, + validTransaction, +} from '../fixtures'; +import { TransactionJSON } from '../src/transaction_types'; +import { Status } from '../src/response'; +import { hexToBuffer } from '@liskhq/lisk-cryptography'; + +describe('Second signature registration transaction class', () => { + let validTestTransaction: SecondSignatureTransaction; + let storeAccountCacheStub: sinon.SinonStub; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountSetStub: sinon.SinonStub; + + const sender = { + address: '10020978176543317477L', + balance: '32981247530771', + publicKey: + '8aceda0f39b35d778f55593227f97152f0b5a78b80b5c4ae88979909095d6204', + secondPublicKey: null, + secondSignature: 0, + }; + + beforeEach(async () => { + validTestTransaction = new SecondSignatureTransaction( + validRegisterSecondSignatureTransaction, + ); + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + storeAccountGetStub = sandbox.stub(store.account, 'get').returns(sender); + storeAccountSetStub = sandbox.stub(store.account, 'set'); + }); + + describe('#constructor', () => { + it('should create instance of SecondSignatureTransaction', async () => { + expect(validTestTransaction).to.be.instanceOf(SecondSignatureTransaction); + }); + + it('should set the second signature asset', async () => { + expect(validTestTransaction.asset.signature) + .to.be.an('object') + .and.to.have.property('publicKey'); + }); + + it('should not throw when asset signature publicKey is not string', async () => { + const invalidSecondSignatureTransaction = { + ...validRegisterSecondSignatureTransaction, + asset: { + signature: { publicKey: 123 }, + }, + }; + expect( + () => new SecondSignatureTransaction(invalidSecondSignatureTransaction), + ).not.to.throw(); + }); + }); + + describe('#assetToBytes', () => { + it('should return valid buffer', async () => { + const assetBytes = (validTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql( + hexToBuffer( + validRegisterSecondSignatureTransaction.asset.signature.publicKey, + ), + ); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return a successful transaction response', async () => { + const { + id, + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + { ...validRegisterSecondSignatureTransaction, type: 0 }, + ] as ReadonlyArray); + expect(id).to.be.eql(validTestTransaction.id); + expect(errors).to.be.eql([]); + expect(status).to.equal(Status.OK); + }); + + it('should return status true with non related transactions', async () => { + const { + id, + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validTransaction, + ] as ReadonlyArray); + expect(id).to.be.eql(validTestTransaction.id); + expect(errors).to.be.empty; + expect(status).to.equal(Status.OK); + }); + + it('should return TransactionResponse with error when other second signature registration transaction from the same account exists', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validRegisterSecondSignatureTransaction, + ] as ReadonlyArray); + expect(errors).to.not.be.empty; + expect(status).to.equal(Status.FAIL); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validTestTransaction.assetToJSON()) + .to.be.an('object') + .and.to.have.property('signature'); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + await validTestTransaction.prepare(store); + expect(storeAccountCacheStub).to.have.been.calledWithExactly([ + { address: validTestTransaction.senderId }, + ]); + }); + }); + + describe('#validateAsset', () => { + it('should return no errors', async () => { + const errors = (validTestTransaction as any).validateAsset(); + + expect(errors).to.be.empty; + }); + + it('should return error when amount is non-zero', async () => { + const invalidTransaction = { + ...validRegisterSecondSignatureTransaction, + amount: '100', + }; + const transaction = new SecondSignatureTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + + expect(errors).not.to.be.empty; + }); + + it('should return error when asset includes invalid publicKey', async () => { + const invalidTransaction = { + ...validRegisterSecondSignatureTransaction, + asset: { + signature: { + publicKey: '1234', + }, + }, + }; + const transaction = new SecondSignatureTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + + expect(errors).not.to.be.empty; + }); + }); + + describe('#applyAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).applyAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + expect(storeAccountSetStub).to.be.calledWithExactly(sender.address, { + ...sender, + secondPublicKey: validTestTransaction.asset.signature.publicKey, + secondSignature: 1, + }); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).to.be.empty; + }); + + it('should return error when secondPublicKey exists on account', async () => { + storeAccountGetStub.returns({ + ...sender, + secondPublicKey: '123', + }); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors[0].message).to.contains( + 'Register second signature only allowed once per account.', + ); + }); + }); + + describe('#undoAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).undoAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + + expect(storeAccountSetStub).to.be.calledWithExactly(sender.address, { + ...sender, + secondSignature: 0, + secondPublicKey: null, + }); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).undoAsset(store); + expect(errors).to.be.empty; + }); + }); +}); diff --git a/elements/lisk-transactions/test/2_delegate_transaction.ts b/elements/lisk-transactions/test/2_delegate_transaction.ts new file mode 100644 index 00000000000..0c938542677 --- /dev/null +++ b/elements/lisk-transactions/test/2_delegate_transaction.ts @@ -0,0 +1,248 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { MockStateStore as store } from './helpers'; +import { DelegateTransaction } from '../src/2_delegate_transaction'; +import { + validDelegateAccount, + validDelegateTransaction, + validTransaction, +} from '../fixtures'; +import { Account, TransactionJSON } from '../src/transaction_types'; + +describe('Delegate registration transaction class', () => { + let validTestTransaction: DelegateTransaction; + let sender: Account; + let storeAccountCacheStub: sinon.SinonStub; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountSetStub: sinon.SinonStub; + let storeAccountFindStub: sinon.SinonStub; + + beforeEach(async () => { + validTestTransaction = new DelegateTransaction(validDelegateTransaction); + sender = validDelegateAccount; + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + storeAccountGetStub = sandbox.stub(store.account, 'get').returns(sender); + storeAccountSetStub = sandbox.stub(store.account, 'set'); + storeAccountFindStub = sandbox.stub(store.account, 'find'); + }); + + describe('#constructor', () => { + it('should create instance of DelegateTransaction', async () => { + expect(validTestTransaction).to.be.instanceOf(DelegateTransaction); + }); + + it('should set the delegate asset', async () => { + expect(validTestTransaction.asset.delegate).to.be.an('object'); + expect(validTestTransaction.asset.delegate.username).to.eql('0x0'); + }); + + it('should not throw when asset is not valid string', async () => { + const invalidDelegateTransactionData = { + ...validDelegateTransaction, + asset: { + delegate: { + username: 123, + }, + }, + }; + expect( + () => new DelegateTransaction(invalidDelegateTransactionData), + ).not.to.throw(); + }); + }); + + describe('#assetToBytes', () => { + it('should return valid buffer', async () => { + const assetBytes = (validTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql( + Buffer.from(validDelegateTransaction.asset.delegate.username, 'utf8'), + ); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return no errors with non conflicting transactions', async () => { + const { errors } = validTestTransaction.verifyAgainstOtherTransactions([ + validTransaction, + ] as ReadonlyArray); + expect(errors).to.be.empty; + }); + + it('should return error when other transaction from same account has the same type', async () => { + const conflictTransaction = { + ...validTransaction, + senderPublicKey: validDelegateTransaction.senderPublicKey, + type: 2, + }; + const { errors } = validTestTransaction.verifyAgainstOtherTransactions([ + conflictTransaction, + ] as ReadonlyArray); + expect(errors).to.not.be.empty; + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validTestTransaction.assetToJSON()) + .to.be.an('object') + .and.to.have.property('delegate'); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + await validTestTransaction.prepare(store); + expect(storeAccountCacheStub).to.have.been.calledWithExactly([ + { address: validTestTransaction.senderId }, + { username: validTestTransaction.asset.delegate.username }, + ]); + }); + }); + + describe('#validateAsset', () => { + it('should no errors', async () => { + const errors = (validTestTransaction as any).validateAsset(); + expect(errors).to.be.empty; + }); + + it('should return error when asset includes invalid characters', async () => { + const invalidTransaction = { + ...validDelegateTransaction, + asset: { + delegate: { + username: '%invalid%username*', + }, + }, + }; + const transaction = new DelegateTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when asset includes uppercase', async () => { + const invalidTransaction = { + ...validDelegateTransaction, + asset: { + delegate: { + username: 'InValIdUsErNAmE', + }, + }, + }; + const transaction = new DelegateTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should error when asset is potential address', async () => { + const invalidTransaction = { + ...validDelegateTransaction, + asset: { + delegate: { + username: '1L', + }, + }, + }; + const transaction = new DelegateTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when recipientId is not empty', async () => { + const invalidTransaction = { + ...validDelegateTransaction, + recipientId: '1L', + id: '17277443568874824891', + }; + const transaction = new DelegateTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + + expect(errors).not.to.be.empty; + }); + + it('should return error when recipientPublicKey is not empty', async () => { + const invalidTransaction = { + ...validDelegateTransaction, + recipientPublicKey: '123', + }; + const transaction = new DelegateTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.be.equal('.recipientPublicKey'); + }); + }); + + describe('#applyAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).applyAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + expect(storeAccountFindStub).to.be.calledOnce; + expect(storeAccountSetStub).to.be.calledWithExactly(sender.address, { + ...sender, + isDelegate: 1, + vote: 0, + username: validTestTransaction.asset.delegate.username, + }); + }); + + it('should return no errors', async () => { + const { isDelegate, username, ...strippedSender } = sender; + storeAccountGetStub.returns(strippedSender); + storeAccountFindStub.returns(false); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).to.be.empty; + }); + + it('should return error when username is taken', async () => { + storeAccountFindStub.returns(true); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.be.equal('.asset.delegate.username'); + }); + + it('should return an error when account is already delegate', async () => { + const errors = (validTestTransaction as any).applyAsset(store); + + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.be.equal('.asset.delegate.username'); + }); + }); + + describe('#undoAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).undoAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + expect(storeAccountSetStub).to.be.calledWithExactly(sender.address, { + ...sender, + isDelegate: 0, + vote: 0, + username: null, + }); + }); + + it('should return no errors', async () => { + storeAccountGetStub.returns(sender); + const errors = (validTestTransaction as any).undoAsset(store); + expect(errors).to.be.empty; + }); + }); +}); diff --git a/elements/lisk-transactions/test/2_register_delegate.ts b/elements/lisk-transactions/test/2_register_delegate.ts new file mode 100644 index 00000000000..38394cd8025 --- /dev/null +++ b/elements/lisk-transactions/test/2_register_delegate.ts @@ -0,0 +1,250 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { registerDelegate } from '../src/2_register_delegate'; +import { DelegateAsset } from '../src/2_delegate_transaction'; +import { TransactionJSON } from '../src/transaction_types'; +import * as time from '../src/utils/time'; + +describe('#registerDelegate transaction', () => { + const fixedPoint = 10 ** 8; + const passphrase = 'secret'; + const secondPassphrase = 'second secret'; + const transactionType = 2; + const publicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const username = 'test_delegate_1@\\'; + const fee = (25 * fixedPoint).toString(); + const timeWithOffset = 38350076; + const amount = '0'; + + let getTimeWithOffsetStub: sinon.SinonStub; + let registerDelegateTransaction: Partial; + + beforeEach(() => { + getTimeWithOffsetStub = sandbox + .stub(time, 'getTimeWithOffset') + .returns(timeWithOffset); + return Promise.resolve(); + }); + + describe('with first passphrase', () => { + beforeEach(() => { + registerDelegateTransaction = registerDelegate({ + passphrase, + username, + }); + return Promise.resolve(); + }); + + it('should create a register delegate transaction', () => { + return expect(registerDelegateTransaction).to.be.ok; + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(undefined); + }); + + it('should use time.getTimeWithOffset with an offset of -10 seconds to calculate the timestamp', () => { + const offset = -10; + registerDelegate({ passphrase, username, timeOffset: offset }); + + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(offset); + }); + + it('should be an object', () => { + return expect(registerDelegateTransaction).to.be.an('object'); + }); + + it('should have an id string', () => { + return expect(registerDelegateTransaction) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have type number equal to 2', () => { + return expect(registerDelegateTransaction) + .to.have.property('type') + .and.be.a('number') + .and.equal(transactionType); + }); + + it('should have amount string equal to 0', () => { + return expect(registerDelegateTransaction) + .to.have.property('amount') + .and.be.a('string') + .and.equal(amount); + }); + + it('should have fee string equal to 25 LSK', () => { + return expect(registerDelegateTransaction) + .to.have.property('fee') + .and.be.a('string') + .and.equal(fee); + }); + + it('should have recipientId equal to empty string', () => { + return expect(registerDelegateTransaction) + .to.have.property('recipientId') + .and.equal(''); + }); + + it('should have senderPublicKey hex string equal to sender public key', () => { + return expect(registerDelegateTransaction) + .to.have.property('senderPublicKey') + .and.be.hexString.and.equal(publicKey); + }); + + it('should have timestamp number equal to result of time.getTimeWithOffset', () => { + return expect(registerDelegateTransaction) + .to.have.property('timestamp') + .and.be.a('number') + .and.equal(timeWithOffset); + }); + + it('should have signature hex string', () => { + return expect(registerDelegateTransaction).to.have.property('signature') + .and.be.hexString; + }); + + it('second signature property should be undefined', () => { + return expect(registerDelegateTransaction.signSignature).to.be.eql( + undefined, + ); + }); + + it('should have asset', () => { + return expect(registerDelegateTransaction).to.have.property('asset').and + .not.be.empty; + }); + + describe('delegate asset', () => { + it('should be an object', () => { + return expect(registerDelegateTransaction.asset) + .to.have.property('delegate') + .and.be.an('object'); + }); + + it('should have the provided username as a string', () => { + const { delegate } = registerDelegateTransaction.asset as DelegateAsset; + return expect(delegate) + .to.have.property('username') + .and.be.a('string') + .and.equal(username); + }); + }); + }); + + describe('with first and second passphrase', () => { + beforeEach(() => { + registerDelegateTransaction = registerDelegate({ + passphrase, + username, + secondPassphrase, + }); + return Promise.resolve(); + }); + + it('should have the second signature property as hex string', () => { + return expect(registerDelegateTransaction).to.have.property( + 'signSignature', + ).and.be.hexString; + }); + }); + + describe('unsigned register delegate transaction', () => { + describe('when the register delegate transaction is created without a passphrase', () => { + beforeEach(() => { + registerDelegateTransaction = registerDelegate({ + username, + }); + return Promise.resolve(); + }); + + it('should throw error when username was not provided', () => { + return expect(registerDelegate.bind(null, {} as any)).to.throw( + 'Please provide a username. Expected string.', + ); + }); + + it('should throw error when username is empty string', () => { + return expect(registerDelegate.bind(null, { username: '' })).to.throw( + 'Please provide a username. Expected string.', + ); + }); + + it('should throw error when invalid username was provided', () => { + return expect( + registerDelegate.bind(null, { username: '12345678901234567890a' }), + ).to.throw( + 'Username length does not match requirements. Expected to be no more than 20 characters.', + ); + }); + + it('should have the type', () => { + return expect(registerDelegateTransaction) + .to.have.property('type') + .equal(transactionType); + }); + + it('should have the amount', () => { + return expect(registerDelegateTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the fee', () => { + return expect(registerDelegateTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the recipient id', () => { + return expect(registerDelegateTransaction) + .to.have.property('recipientId') + .equal(''); + }); + + it('should have the sender public key', () => { + return expect(registerDelegateTransaction) + .to.have.property('senderPublicKey') + .equal(undefined); + }); + + it('should have the timestamp', () => { + return expect(registerDelegateTransaction).to.have.property( + 'timestamp', + ); + }); + + it('should have the asset with the delegate', () => { + return expect(registerDelegateTransaction) + .to.have.property('asset') + .with.property('delegate') + .with.property('username'); + }); + + it('should not have the signature', () => { + return expect(registerDelegateTransaction).not.to.have.property( + 'signature', + ); + }); + + it('should not have the id', () => { + return expect(registerDelegateTransaction).not.to.have.property('id'); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/3_cast_votes.ts b/elements/lisk-transactions/test/3_cast_votes.ts new file mode 100644 index 00000000000..6fd83260f86 --- /dev/null +++ b/elements/lisk-transactions/test/3_cast_votes.ts @@ -0,0 +1,409 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { castVotes } from '../src/3_cast_votes'; +import { VoteAsset } from '../src/3_vote_transaction'; +import { TransactionJSON } from '../src/transaction_types'; +import * as time from '../src/utils/time'; + +describe('#castVotes transaction', () => { + const fixedPoint = 10 ** 8; + const passphrase = 'secret'; + const secondPassphrase = 'second secret'; + const transactionType = 3; + const firstPublicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const secondPublicKey = + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa'; + const thirdPublicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca'; + const fourthPublicKey = + 'd019a4b6fa37e8ebeb64766c7b239d962fb3b3f265b8d3083206097b912cd914'; + const tooShortPublicKey = + 'd019a4b6fa37e8ebeb64766c7b239d962fb3b3f265b8d3083206097b912cd9'; + const plusPrependedPublicKey = + '+5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const votePublicKeys = [firstPublicKey, secondPublicKey]; + const unvotePublicKeys = [thirdPublicKey, fourthPublicKey]; + const address = '18160565574430594874L'; + const timeWithOffset = 38350076; + const amount = '0'; + const fee = (1 * fixedPoint).toString(); + + let getTimeWithOffsetStub: sinon.SinonStub; + let castVotesTransaction: Partial; + + beforeEach(() => { + getTimeWithOffsetStub = sandbox + .stub(time, 'getTimeWithOffset') + .returns(timeWithOffset); + return Promise.resolve(); + }); + + describe('when the transaction is created with one passphrase and the votes', () => { + beforeEach(() => { + castVotesTransaction = castVotes({ + passphrase, + votes: votePublicKeys, + }); + return Promise.resolve(); + }); + + it('should create a cast votes transaction', () => { + return expect(castVotesTransaction).to.be.ok; + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(undefined); + }); + + it('should use time.getTimeWithOffset with an offset of -10 seconds to calculate the timestamp', () => { + const offset = -10; + castVotes({ passphrase, votes: votePublicKeys, timeOffset: offset }); + + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(offset); + }); + + describe('the returned cast votes transaction', () => { + it('should be an object', () => { + return expect(castVotesTransaction).to.be.an('object'); + }); + + it('should have id string', () => { + return expect(castVotesTransaction) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have type number equal to 3', () => { + return expect(castVotesTransaction) + .to.have.property('type') + .and.be.a('number') + .and.equal(transactionType); + }); + + it('should have amount string equal to 0', () => { + return expect(castVotesTransaction) + .to.have.property('amount') + .and.be.a('string') + .and.equal(amount); + }); + + it('should have fee string equal to 100000000', () => { + return expect(castVotesTransaction) + .to.have.property('fee') + .and.be.a('string') + .and.equal(fee); + }); + + it('should have recipientId string equal to address', () => { + return expect(castVotesTransaction) + .to.have.property('recipientId') + .and.be.a('string') + .and.equal(address); + }); + + it('should have senderPublicKey hex string equal to sender public key', () => { + return expect(castVotesTransaction) + .to.have.property('senderPublicKey') + .and.be.hexString.and.equal(firstPublicKey); + }); + + it('should have timestamp number equal to result of time.getTimeWithOffset', () => { + return expect(castVotesTransaction) + .to.have.property('timestamp') + .and.be.a('number') + .and.equal(timeWithOffset); + }); + + it('should have signature hex string', () => { + return expect(castVotesTransaction).to.have.property('signature').and.be + .hexString; + }); + + it('second signature property should be undefined', () => { + return expect(castVotesTransaction.signSignature).to.be.undefined; + }); + + it('should have asset', () => { + return expect(castVotesTransaction).to.have.property('asset').and.not.be + .empty; + }); + + describe('votes asset', () => { + it('should be array', () => { + return expect(castVotesTransaction.asset) + .to.have.property('votes') + .and.be.an('array'); + }); + + it('should contain two elements', () => { + const { votes } = castVotesTransaction.asset as VoteAsset; + return expect(votes).to.have.length(2); + }); + + it('should have a vote for the delegate public key', () => { + const { votes } = castVotesTransaction.asset as VoteAsset; + const expectedArray = [`+${firstPublicKey}`, `+${secondPublicKey}`]; + return expect(votes).to.be.eql(expectedArray); + }); + }); + }); + }); + + describe('with first and second passphrase', () => { + beforeEach(() => { + castVotesTransaction = castVotes({ + passphrase, + votes: [firstPublicKey], + secondPassphrase, + }); + return Promise.resolve(); + }); + + it('should have the second signature property as hex string', () => { + return expect(castVotesTransaction).to.have.property('signSignature').and + .be.hexString; + }); + }); + + describe('when the cast vote transaction is created with the votes and unvotes', () => { + beforeEach(() => { + castVotesTransaction = castVotes({ + passphrase, + votes: votePublicKeys, + unvotes: unvotePublicKeys, + }); + return Promise.resolve(); + }); + + it('the transaction should have the votes as an array', () => { + return expect(castVotesTransaction.asset) + .to.have.property('votes') + .and.be.an('array'); + }); + + it('the transaction should have the votes and the unvotes', () => { + const expectedArray = [ + `+${firstPublicKey}`, + `+${secondPublicKey}`, + `-${thirdPublicKey}`, + `-${fourthPublicKey}`, + ]; + const { votes } = castVotesTransaction.asset as VoteAsset; + return expect(votes).to.be.eql(expectedArray); + }); + }); + + describe('when the cast vote transaction is created with the invalid votes and invalid unvotes', () => { + it('should throw error when null was provided for votes', () => { + return expect( + castVotes.bind(null, { + passphrase, + votes: null as any, + }), + ).to.throw( + 'Please provide a valid votes value. Expected an array if present.', + ); + }); + + it('should throw error when string was provided for votes', () => { + return expect( + castVotes.bind(null, { + passphrase, + votes: `+${firstPublicKey}` as any, + }), + ).to.throw( + 'Please provide a valid votes value. Expected an array if present.', + ); + }); + + it('should throw error when null was provided for unvotes', () => { + return expect( + castVotes.bind(null, { + passphrase, + unvotes: null as any, + }), + ).to.throw( + 'Please provide a valid unvotes value. Expected an array if present.', + ); + }); + + it('should throw error when string was provided for unvotes', () => { + return expect( + castVotes.bind(null, { + passphrase, + unvotes: `-${firstPublicKey}` as any, + }), + ).to.throw( + 'Please provide a valid unvotes value. Expected an array if present.', + ); + }); + }); + + describe('when the cast vote transaction is created with the unvotes', () => { + beforeEach(() => { + castVotesTransaction = castVotes({ + passphrase, + unvotes: unvotePublicKeys, + }); + return Promise.resolve(); + }); + + it('the transaction should have the votes array', () => { + return expect(castVotesTransaction.asset) + .to.have.property('votes') + .and.be.an('array'); + }); + + it('the transaction asset should have the unvotes', () => { + const expectedArray = [`-${thirdPublicKey}`, `-${fourthPublicKey}`]; + const { votes } = castVotesTransaction.asset as VoteAsset; + return expect(votes).to.be.eql(expectedArray); + }); + }); + + describe('when the cast vote transaction is created with one too short public key', () => { + it('should throw an error', () => { + return expect( + castVotes.bind(null, { + passphrase, + unvotes: unvotePublicKeys, + votes: [tooShortPublicKey], + }), + ).to.throw( + 'Public key d019a4b6fa37e8ebeb64766c7b239d962fb3b3f265b8d3083206097b912cd9 length differs from the expected 32 bytes for a public key.', + ); + }); + }); + + describe('when the cast vote transaction is created with one plus prepended public key', () => { + it('should throw an error', () => { + return expect( + castVotes.bind(null, { + passphrase, + unvotes: unvotePublicKeys, + votes: [plusPrependedPublicKey], + }), + ).to.throw('Argument must be a valid hex string.'); + }); + }); + + describe('when the cast vote transaction is created with duplicated public keys', () => { + describe('Given votes and unvotes with duplication', () => { + it('should throw a duplication error', () => { + const votes = [firstPublicKey, secondPublicKey]; + const unvotes = [firstPublicKey, thirdPublicKey]; + return expect( + castVotes.bind(null, { + passphrase, + unvotes, + votes, + }), + ).to.throw( + 'Duplicated public key: 5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09.', + ); + }); + }); + + describe('Given votes with duplication', () => { + it('should throw a duplication error for votes', () => { + const votes = [firstPublicKey, secondPublicKey, firstPublicKey]; + return expect( + castVotes.bind(null, { + passphrase, + votes, + }), + ).to.throw( + 'Duplicated public key: 5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09.', + ); + }); + }); + + describe('Given unvotes with duplication', () => { + it('should throw a duplication error for unvotes', () => { + const unvotes = [firstPublicKey, secondPublicKey, firstPublicKey]; + return expect( + castVotes.bind(null, { + passphrase, + unvotes, + }), + ).to.throw( + 'Duplicated public key: 5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09.', + ); + }); + }); + }); + + describe('unsigned cast votes transaction', () => { + describe('when the cast votes transaction is created without a passphrase', () => { + beforeEach(() => { + castVotesTransaction = castVotes({ + votes: votePublicKeys, + unvotes: unvotePublicKeys, + }); + return Promise.resolve(); + }); + + it('should have the type', () => { + return expect(castVotesTransaction) + .to.have.property('type') + .equal(transactionType); + }); + + it('should have the amount', () => { + return expect(castVotesTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the fee', () => { + return expect(castVotesTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the recipient id', () => { + return expect(castVotesTransaction) + .to.have.property('recipientId') + .equal(''); + }); + + it('should have the sender public key', () => { + return expect(castVotesTransaction) + .to.have.property('senderPublicKey') + .equal(undefined); + }); + + it('should have the timestamp', () => { + return expect(castVotesTransaction).to.have.property('timestamp'); + }); + + it('should have the asset with the votes', () => { + return expect(castVotesTransaction) + .to.have.property('asset') + .with.property('votes'); + }); + + it('should not have the signature', () => { + return expect(castVotesTransaction).not.to.have.property('signature'); + }); + + it('should not have the id', () => { + return expect(castVotesTransaction).not.to.have.property('id'); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/3_vote_transaction.ts b/elements/lisk-transactions/test/3_vote_transaction.ts new file mode 100644 index 00000000000..e1983ccdfa4 --- /dev/null +++ b/elements/lisk-transactions/test/3_vote_transaction.ts @@ -0,0 +1,383 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { MockStateStore as store } from './helpers'; +import { VoteTransaction } from '../src/3_vote_transaction'; +import { validVoteTransactions } from '../fixtures'; +import { TransactionJSON } from '../src/transaction_types'; +import { Status } from '../src/response'; +import { generateRandomPublicKeys } from './helpers/cryptography'; + +describe('Vote transaction class', () => { + let validTestTransaction: VoteTransaction; + let storeAccountCacheStub: sinon.SinonStub; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountSetStub: sinon.SinonStub; + let storeAccountFindStub: sinon.SinonStub; + + const defaultValidSender = { + address: '8004805717140184627L', + balance: '100000000', + publicKey: + '30c07dbb72b41e3fda9f29e1a4fc0fce893bb00788515a5e6f50b80312e2f483', + votedDelegatesPublicKeys: [ + '5a82f58bf35ef4bdfac9a371a64e91914519af31a5cf64a5b8b03ca7d32c15dc', + ], + }; + + const defaultValidDependentAccounts = [ + { + balance: '0', + address: '123L', + publicKey: + '473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c', + username: 'delegate_0', + }, + ]; + + beforeEach(async () => { + validTestTransaction = new VoteTransaction(validVoteTransactions[2]); + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + storeAccountGetStub = sandbox + .stub(store.account, 'get') + .returns(defaultValidSender); + storeAccountSetStub = sandbox.stub(store.account, 'set'); + storeAccountFindStub = sandbox + .stub(store.account, 'find') + .returns(defaultValidDependentAccounts[0]); + }); + + describe('#constructor', () => { + it('should create instance of VoteTransaction', async () => { + expect(validTestTransaction).to.be.instanceOf(VoteTransaction); + }); + + it('should set the vote asset', async () => { + expect(validTestTransaction.asset.votes).to.be.an('array'); + }); + + it('should not throw TransactionMultiError when asset is not string array', async () => { + const invalidVoteTransactionData = { + ...validVoteTransactions[1], + asset: { + votes: [1, 2, 3], + }, + }; + expect( + () => new VoteTransaction(invalidVoteTransactionData), + ).not.to.throw(); + }); + }); + + describe('#assetToBytes', () => { + it('should return valid buffer', async () => { + const assetBytes = (validTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql( + Buffer.from(validVoteTransactions[2].asset.votes.join(''), 'utf8'), + ); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return status true with non conflicting transactions', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validVoteTransactions[1], + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(0); + expect(status).to.equal(Status.OK); + }); + + it('should return status true with non related transactions', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validVoteTransactions[0], + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(0); + expect(status).to.equal(Status.OK); + }); + + it('should return TransactionResponse with error when other transaction has the same addition public key', async () => { + const conflictTransaction = { + ...validVoteTransactions[2], + asset: { votes: validVoteTransactions[2].asset.votes.slice() }, + }; + conflictTransaction.asset.votes.push( + validVoteTransactions[1].asset.votes.filter( + v => v.charAt(0) === '+', + )[0], + ); + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + conflictTransaction, + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(1); + expect(status).to.equal(Status.FAIL); + }); + + it('should return TransactionResponse with error when other transaction has the same deletion public key', async () => { + const conflictTransaction = { + ...validVoteTransactions[2], + asset: { votes: validVoteTransactions[2].asset.votes.slice() }, + }; + conflictTransaction.asset.votes.push( + validVoteTransactions[1].asset.votes.filter( + v => v.charAt(0) === '-', + )[0], + ); + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + conflictTransaction, + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(1); + expect(status).to.equal(Status.FAIL); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validTestTransaction.assetToJSON()) + .to.be.an('object') + .and.to.have.property('votes') + .that.is.a('array'); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + await validTestTransaction.prepare(store); + expect(storeAccountCacheStub).to.have.been.calledWithExactly([ + { address: validTestTransaction.senderId }, + { + publicKey: + '473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c', + }, + ]); + }); + }); + + describe('#validateAsset', () => { + it('should return no errors', async () => { + const errors = (validTestTransaction as any).validateAsset(); + + expect(errors).to.be.empty; + }); + + it('should return error when asset includes unsigned public key', async () => { + const invalidTransaction = { + ...validVoteTransactions[2], + asset: { + votes: [ + ...validVoteTransactions[2].asset.votes, + 'e683da7b4fe46164b9db3fd599481ad0630d2d892546c1ac63e59a5acb903140', + ], + }, + }; + const transaction = new VoteTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when asset includes more than 33 signed public key', async () => { + const invalidTransaction = { + ...validVoteTransactions[2], + asset: { + votes: [ + '+633698916662935403780f04fd01119f32f9cd180a3b104b67c5ae5ebb6d5593', + '+b59c6580a05ae00896f03dd66205ac141a22599674cbf0db6654a0908b73e5e5', + '+faf9f863e704f9cf560bc7a5718a25d851666d38195cba3cacd360cd5fa96fd3', + '+cda0220f413c7f62cfe46e9544519cced3277d0931d0342270e6b47b4b346e0b', + '+791576c970ff6bd58cb0be049618d031e31095d272496ebc54f221d1b2635295', + '+712add287f4979ff0c236265dfe437998c2d3b9f4b396e319e7d581e048fbeda', + '+19bdab59b24f7ef2a9d0b1b0942cff450875302e0c59c437a372eb6bb27a0b43', + '+8f2ae5a4fa63ecdd53aa85711ac0a14f2d9a42451838ebfcf5999c5cf5eded06', + '+ea613be11a264b5775e985b9d7d40f836a74bd181a1855de218ee849efa3b1fe', + '+6ee309d4190de0e9adea6b06f83582e61bc7556022e7d3e29a886e35ab80d6a4', + '+279320364fc3edd39b77f1fa29594d442e39220b165956fa729f741150b0dc4d', + '+6a8d02899c66dfa2423b125f44d360be6da0669cedadde32e63e629cb2e3195c', + '+db2627fbee9cf5351fe5b87e35ba981f3e29da085f0a45a1f9851c9e04db910e', + '+a725db7ae839028867f55feb5f332ae09e0ac0b6e9060f045a9ff4f8f2520aa8', + '+ad6fbbe0f62bfb934f4a510c24f59baf600dd8b8bfaa4b59944037c50873a481', + '+4d6e32111dc36f8074bda232f07119394180b11ac8e9f3698537c909ef24637e', + '+2521c1136f095d4031af08d9c5aaf5bbf2589e620c7fc79dfdcdcc6f05d00d72', + '+5a82f58bf35ef4bdfac9a371a64e91914519af31a5cf64a5b8b03ca7d32c15dc', + '+473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c', + '-8aceda0f39b35d778f55593227f97152f0b5a78b80b5c4ae88979909095d6204', + '-71e1e34dd0529d920ee6c38497b028352c57b7130d55737c8a778ff3974ec29f', + '-e82b9ab22f2b60674fdb35dec867d83ccee65bd1694c7ff9859519da3766a337', + '-7beb5f1e8592022fe5272b45eeeda6a1b6923a801af6e1790933cc6a78ed95a1', + '-3697a4f8c74cb21949eec31fddde190c16ab2497709fb503c567d3a9e6a6e989', + '-abf9787621f8f43ec4e4a645b515094f42fc5615f2e231eca24eaf6e69dc6a65', + '-4c6a450cc6769efa4ba0f9a23318af0cb9def2402f0a51c5e7215856c08df7af', + '-fa7bfd3a2dc0ca55b700247aae4694709d6cdfa34c6bfb0237e032d7aae404f0', + '-9ebf74d64dcecd6eb0005967d8888e66d3e2901c8d0c72c7396f021d93a130fc', + '-71d74ec6d8d53244fde9cededae7c9c9f1d5dba5c7ddfe63d2e766cb874169b0', + '-fc4f231b00f72ba93a4778890c5d2b89d3f570e606c04619a0343a3cdddf73c7', + '-2493d52fc34ecaaa4a7d0d76e6de9bda24f1b5e11e3363c30a13d59e9c345f82', + '-e683da7b4fe46164b9db3fd599481ad0630d2d892546c1ac63e59a5acb903140', + '-b7633636a88ba1ce8acd98aa58b4a9618650c8ab860c167be6f8d78404265bae', + '-cdcba9e30dfd559bdc217fbc5674007927ef68d443650ba804a67d41bf05a1b7', + ], + }, + }; + const transaction = new VoteTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when asset includes null', async () => { + const invalidTransaction = { + ...validVoteTransactions[2], + asset: { + votes: [null], + }, + }; + const transaction = new VoteTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when asset is an empty array', async () => { + const invalidTransaction = { + ...validVoteTransactions[2], + asset: { votes: [] }, + id: '12771680061315781764', + }; + const transaction = new VoteTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.be.equal('.votes'); + }); + + it('should return error when recipientId is empty', async () => { + const invalidTransaction = { + ...validVoteTransactions[2], + recipientId: '', + id: '17277443568874824891', + }; + const transaction = new VoteTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.be.equal('.recipientId'); + }); + }); + + describe('#applyAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).applyAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + expect(storeAccountFindStub).to.be.calledOnce; + expect(storeAccountSetStub).to.be.calledWithExactly( + defaultValidSender.address, + { + ...defaultValidSender, + votedDelegatesPublicKeys: [ + ...defaultValidSender.votedDelegatesPublicKeys, + '473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c', + ], + }, + ); + }); + + it('should return error when voted account is not a delegate', async () => { + const nonDelegateAccount = [ + { + balance: '0', + address: '123L', + publicKey: + '473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c', + }, + ]; + storeAccountFindStub.returns(nonDelegateAccount[0]); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + }); + + it('should return error when the delegate is already voted', async () => { + const invalidSender = { + address: '8004805717140184627L', + balance: '100000000', + publicKey: + '30c07dbb72b41e3fda9f29e1a4fc0fce893bb00788515a5e6f50b80312e2f483', + votedDelegatesPublicKeys: [ + '5a82f58bf35ef4bdfac9a371a64e91914519af31a5cf64a5b8b03ca7d32c15dc', + '473c354cdf627b82e9113e02a337486dd3afc5615eb71ffd311c5a0beda37b8c', + ], + }; + storeAccountGetStub.returns(invalidSender); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + expect(errors[0].message).to.contain('is already voted.'); + expect(errors[0].dataPath).equal('.asset.votes'); + }); + + it('should return error when vote exceeds maximum votes', async () => { + const invalidSender = { + address: '8004805717140184627L', + balance: '100000000', + publicKey: + '30c07dbb72b41e3fda9f29e1a4fc0fce893bb00788515a5e6f50b80312e2f483', + votedDelegatesPublicKeys: generateRandomPublicKeys(101), + }; + storeAccountGetStub.returns(invalidSender); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + expect(errors[0].message).to.contains( + 'Vote cannot exceed 101 but has 102.', + ); + expect(errors[0].dataPath).equal('.asset.votes'); + }); + }); + + describe('#undoAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).undoAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + + expect(storeAccountSetStub).to.be.calledWithExactly( + defaultValidSender.address, + defaultValidSender, + ); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).undoAsset(store); + expect(errors).to.be.empty; + }); + }); +}); diff --git a/elements/lisk-transactions/test/4_multisignature_transaction.ts b/elements/lisk-transactions/test/4_multisignature_transaction.ts new file mode 100644 index 00000000000..47f3e2acd44 --- /dev/null +++ b/elements/lisk-transactions/test/4_multisignature_transaction.ts @@ -0,0 +1,532 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { MULTISIGNATURE_FEE } from '../src/constants'; +import { SignatureObject } from '../src/create_signature_object'; +import { MultisignatureTransaction } from '../src/4_multisignature_transaction'; +import { Account, TransactionJSON } from '../src/transaction_types'; +import { Status } from '../src/response'; +import { addTransactionFields, MockStateStore as store } from './helpers'; +import { + validMultisignatureAccount, + validMultisignatureRegistrationTransaction, + validMultisignatureRegistrationTransactionNoSigs, + validTransaction, +} from '../fixtures'; + +describe('Multisignature transaction class', () => { + const validMultisignatureTransaction = addTransactionFields( + validMultisignatureRegistrationTransaction, + ); + const { + membersPublicKeys, + multiLifetime, + multiMin, + ...nonMultisignatureAccount + } = validMultisignatureAccount; + let validTestTransaction: MultisignatureTransaction; + let nonMultisignatureSender: Account; + let multisignatureSender: Account; + let storeAccountCacheStub: sinon.SinonStub; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountSetStub: sinon.SinonStub; + + beforeEach(async () => { + validTestTransaction = new MultisignatureTransaction( + validMultisignatureTransaction, + ); + nonMultisignatureSender = nonMultisignatureAccount; + multisignatureSender = validMultisignatureAccount; + storeAccountGetStub = sandbox + .stub(store.account, 'getOrDefault') + .returns(nonMultisignatureSender); + storeAccountGetStub = sandbox + .stub(store.account, 'get') + .returns(nonMultisignatureSender); + storeAccountSetStub = sandbox.stub(store.account, 'set'); + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + }); + + describe('#constructor', () => { + it('should create instance of MultisignatureTransaction', async () => { + expect(validTestTransaction) + .to.be.an('object') + .and.be.instanceof(MultisignatureTransaction); + }); + + it('should set multisignature asset', async () => { + expect(validTestTransaction.asset).to.eql( + validMultisignatureRegistrationTransaction.asset, + ); + }); + + it('should set fee to multisignature transaction fee amount', async () => { + expect(validTestTransaction.fee.toString()).to.eql( + ( + MULTISIGNATURE_FEE * + (validTestTransaction.asset.multisignature.keysgroup.length + 1) + ).toString(), + ); + }); + + it('should set _multisignatureStatus to PENDING', async () => { + expect(validTestTransaction).to.have.property('_multisignatureStatus', 2); + }); + + it('should throw TransactionMultiError when asset min is not a number', async () => { + const invalidMultisignatureTransactionData = { + ...validMultisignatureTransaction, + asset: { + multisignature: { + ...validMultisignatureTransaction.asset.multisignature, + min: '2', + }, + }, + }; + expect( + () => + new MultisignatureTransaction(invalidMultisignatureTransactionData), + ).not.to.throw(); + }); + + it('should not throw TransactionMultiError when asset lifetime is not a number', async () => { + const invalidMultisignatureTransactionData = { + ...validMultisignatureTransaction, + asset: { + multisignature: { + ...validMultisignatureTransaction.asset.multisignature, + lifetime: '1', + }, + }, + }; + expect( + () => + new MultisignatureTransaction(invalidMultisignatureTransactionData), + ).not.to.throw(); + }); + }); + + describe('#assetToBytes', () => { + it('should return valid buffer', async () => { + const assetBytes = (validTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql( + Buffer.from( + '02012b343061663634333236356137313838343466336461633536636531376165316437643437643061323461333561323737613061366362306261616131393339662b643034326164336631613562303432646463356161383063343236376235626664336234646461336136383264613061336566373236393430393334376164622b35343266646330303839363465616363353830303839323731333533323638643635356162356563323832393638376161646332373836353366616433336366', + 'hex', + ), + ); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return status true with non conflicting transactions', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validTransaction, + ] as ReadonlyArray); + + expect(errors) + .to.be.an('array') + .of.length(0); + expect(status).to.equal(Status.OK); + }); + + it('should return TransactionResponse with error when other transaction from same account has the same type', async () => { + const conflictTransaction = { + ...validTransaction, + senderPublicKey: + validMultisignatureRegistrationTransaction.senderPublicKey, + type: 4, + }; + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + conflictTransaction, + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(1); + expect(status).to.equal(Status.FAIL); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validTestTransaction.assetToJSON()).to.eql( + validMultisignatureRegistrationTransaction.asset, + ); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + await validTestTransaction.prepare(store); + expect(storeAccountCacheStub).to.have.been.calledWithExactly([ + { address: validTestTransaction.senderId }, + ]); + }); + }); + + describe('#validateSchema', () => { + it('should return no errors', async () => { + const errors = (validTestTransaction as any).validateAsset(); + expect(errors).to.be.empty; + }); + + it('should return error when asset min is over limit', async () => { + const invalidTransaction = { + ...validMultisignatureRegistrationTransaction, + asset: { + multisignature: { + ...validMultisignatureTransaction.asset.multisignature, + min: 18, + }, + }, + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when lifetime is under minimum', async () => { + const invalidTransaction = { + ...validMultisignatureRegistrationTransaction, + asset: { + multisignature: { + ...validMultisignatureTransaction.asset.multisignature, + lifetime: 0, + }, + }, + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when keysgroup includes invalid keys', async () => { + const invalidTransaction = { + ...validMultisignatureTransaction, + asset: { + multisignature: { + ...validMultisignatureTransaction.asset.multisignature, + keysgroup: validMultisignatureTransaction.asset.multisignature.keysgroup.map( + (key: string) => key.replace('+', ''), + ), + }, + }, + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when keysgroup has too many keys', async () => { + const invalidTransaction = { + ...validMultisignatureTransaction, + asset: { + multisignature: { + ...validMultisignatureTransaction.asset.multisignature, + keysgroup: [ + '+40af643265a718844f3dac56ce17ae1d7d47d0a24a35a277a0a6cb0baaa1939f', + '+d042ad3f1a5b042ddc5aa80c4267b5bfd3b4dda3a682da0a3ef7269409347adb', + '+542fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + '+30af643265a718844f3dac56ce17ae1d7d47d0a24a35a277a0a6cb0baaa1939f', + '+a042ad3f1a5b042ddc5aa80c4267b5bfd3b4dda3a682da0a3ef7269409347adb', + '+442fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + '+10af643265a718844f3dac56ce17ae1d7d47d0a24a35a277a0a6cb0baaa1939f', + '+z042ad3f1a5b042ddc5aa80c4267b5bfd3b4dda3a682da0a3ef7269409347adb', + '+x42fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + '+c0af643265a718844f3dac56ce17ae1d7d47d0a24a35a277a0a6cb0baaa1939f', + '+v042ad3f1a5b042ddc5aa80c4267b5bfd3b4dda3a682da0a3ef7269409347adb', + '+b42fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + '+80af643265a718844f3dac56ce17ae1d7d47d0a24a35a277a0a6cb0baaa1939f', + '+n042ad3f1a5b042ddc5aa80c4267b5bfd3b4dda3a682da0a3ef7269409347adb', + '+042fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + '+k42fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + ], + }, + }, + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + + it('should return error when recipientId is not empty', async () => { + const invalidTransaction = { + ...validMultisignatureTransaction, + recipientId: '1L', + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + + expect(errors).not.to.be.empty; + }); + + it('should return error when recipientPublicKey is not empty', async () => { + const invalidTransaction = { + ...validMultisignatureTransaction, + recipientPublicKey: '123', + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + }); + }); + + describe('#processMultisignatures', () => { + it('should return status ok if all signatures are present', async () => { + storeAccountGetStub.returns(nonMultisignatureSender); + const invalidTransaction = { + ...validMultisignatureTransaction, + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + + const { status, errors } = transaction.processMultisignatures(store); + expect(status).to.equal(Status.OK); + expect(errors).to.be.empty; + }); + + it('should return error with pending status when signatures does not include all keysgroup', async () => { + storeAccountGetStub.returns(nonMultisignatureSender); + const invalidTransaction = { + ...validMultisignatureTransaction, + signatures: validMultisignatureTransaction.signatures.slice(1), + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + + const { status, errors } = transaction.processMultisignatures(store); + expect(status).to.equal(Status.PENDING); + expect(errors).to.have.lengthOf(1); + expect(errors[0].dataPath).to.be.equal('.signatures'); + }); + + it('should return error with pending status when transaction signatures missing', async () => { + storeAccountGetStub.returns(nonMultisignatureSender); + const invalidTransaction = { + ...validMultisignatureTransaction, + signatures: [], + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + + const { status, errors } = transaction.processMultisignatures(store); + expect(status).to.equal(Status.PENDING); + expect(errors).to.have.lengthOf(1); + expect(errors[0].dataPath).to.be.equal('.signatures'); + }); + + it('should return error with fail status when transaction signatures are duplicated', async () => { + storeAccountGetStub.returns(nonMultisignatureSender); + const invalidTransaction = { + ...validMultisignatureTransaction, + signatures: [ + ...validMultisignatureTransaction.signatures, + ...validMultisignatureTransaction.signatures.slice(0, 1), + ], + }; + const transaction = new MultisignatureTransaction(invalidTransaction); + + const { status, errors } = transaction.processMultisignatures(store); + expect(status).to.equal(Status.FAIL); + expect(errors).to.have.lengthOf(1); + expect(errors[0].dataPath).to.be.equal('.signatures'); + }); + }); + + describe('#applyAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).applyAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + expect(storeAccountSetStub).to.be.calledWithExactly( + multisignatureSender.address, + multisignatureSender, + ); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).applyAsset(store); + + expect(errors).to.be.empty; + }); + + it('should return error when account is already multisignature', async () => { + storeAccountGetStub.returns(multisignatureSender); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.be.equal('.signatures'); + }); + + it('should return error when keysgroup includes sender key', async () => { + const invalidSender = { + ...multisignatureSender, + membersPublicKeys: [ + ...(multisignatureSender as any).membersPublicKeys, + multisignatureSender.publicKey, + ], + }; + storeAccountGetStub.returns(invalidSender); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.be.equal('.signatures'); + }); + }); + + describe('#undoAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).undoAsset(store); + expect(storeAccountGetStub).to.be.calledWithExactly( + validTestTransaction.senderId, + ); + expect(storeAccountSetStub).to.be.calledWithExactly( + multisignatureSender.address, + { + ...nonMultisignatureAccount, + membersPublicKeys: [], + multiLifetime: 0, + multiMin: 0, + }, + ); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).undoAsset(store); + expect(errors).to.be.empty; + }); + }); + + describe('#addMultisignature', () => { + let membersSignatures: Array; + let multisigTrs: MultisignatureTransaction; + + beforeEach(() => { + multisigTrs = new MultisignatureTransaction( + validMultisignatureRegistrationTransactionNoSigs, + ); + + membersSignatures = [ + { + publicKey: + '142d1f24e17d3c90b0f2abdf49c2b14b02782e49b2ecfe85462ed12f654d60df', + signature: + 'd1b78f5eb35b4e1de7f740d2f62f0e2acab24c5b446719cc70601319f4a3666fbcda7980e5d9c6ff3bfa8b54ee383eed5531723e0f1748d0c84b7a229759b000', + transactionId: multisigTrs.id, + }, + { + publicKey: + 'bb7ef62be03d5c195a132efe82796420abae04638cd3f6321532a5d33031b30c', + signature: + 'aa956854dae10792ba9006e4dddd0d7e370af4645df8708d1b10f088304320f0e7f2427d883755a997c07b53978c4d8cf56b95e0f740d8d50ed8c1f2dc85180f', + transactionId: multisigTrs.id, + }, + ]; + }); + + it('should add signature to transaction', async () => { + const { status } = multisigTrs.addMultisignature( + store, + membersSignatures[0], + ); + + expect(status).to.eql(Status.PENDING); + expect(multisigTrs.signatures).to.include(membersSignatures[0].signature); + }); + + it('should fail when valid signature already present and sent again', async () => { + const { status: arrangeStatus } = multisigTrs.addMultisignature( + store, + membersSignatures[0], + ); + + const { status, errors } = multisigTrs.addMultisignature( + store, + membersSignatures[0], + ); + const expectedError = 'Encountered duplicate signature in transaction'; + + expect(arrangeStatus).to.eql(Status.PENDING); + expect(status).to.eql(Status.FAIL); + expect(errors[0].message).to.be.eql(expectedError); + expect(multisigTrs.signatures).to.include(membersSignatures[0].signature); + }); + + it('should fail to add invalid signature to transaction', async () => { + const { status, errors } = multisigTrs.addMultisignature(store, { + transactionId: multisigTrs.id, + publicKey: + 'bb7ef62be03d5c195a132efe82796420abae04638cd3f6321532a5d33031b30c', + signature: + 'eeee799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c', + }); + + const expectedError = + 'Failed to add signature eeee799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c.'; + + expect(status).to.eql(Status.FAIL); + expect(errors[0].message).to.be.eql(expectedError); + expect(multisigTrs.signatures).to.be.empty; + }); + + it('should fail with valid signature not part of the group', async () => { + const nonMemberSignature: SignatureObject = { + transactionId: multisigTrs.id, + publicKey: + 'cba7d88c54f3844bbab2c64b712e0ba3144921fe7a76c5f9df80b28ab702a35b', + signature: + '35d9bca853353906fbc44b86918b64bc0d21daf3ca16e230aa59352976624bc4ce69ac339f08b45c5e926d60cfa81276778e5858ff2bd2290e40d9da59cc5f0b', + }; + + const expectedError = + "Public Key 'cba7d88c54f3844bbab2c64b712e0ba3144921fe7a76c5f9df80b28ab702a35b' is not a member."; + + const { status, errors } = multisigTrs.addMultisignature( + store, + nonMemberSignature, + ); + + expect(status).to.eql(Status.FAIL); + expect(errors[0].message).to.be.eql(expectedError); + expect(multisigTrs.signatures).to.be.empty; + }); + + it('status should remain pending when invalid signature sent', async () => { + const { status: arrangeStatus } = multisigTrs.addMultisignature( + store, + membersSignatures[0], + ); + + const nonMemberSignature: SignatureObject = { + transactionId: multisigTrs.id, + publicKey: + 'cba7d88c54f3844bbab2c64b712e0ba3144921fe7a76c5f9df80b28ab702a35b', + signature: + '35d9bca853353906fbc44b86918b64bc0d21daf3ca16e230aa59352976624bc4ce69ac339f08b45c5e926d60cfa81276778e5858ff2bd2290e40d9da59cc5f0b', + }; + + multisigTrs.addMultisignature(store, nonMemberSignature); + + expect(arrangeStatus).to.eql(Status.PENDING); + expect((multisigTrs as any)._multisignatureStatus).to.eql(Status.PENDING); + expect(multisigTrs.signatures.length).to.eql(1); + }); + }); +}); diff --git a/elements/lisk-transactions/test/4_register_multisignature_account.ts b/elements/lisk-transactions/test/4_register_multisignature_account.ts new file mode 100644 index 00000000000..0316dde4921 --- /dev/null +++ b/elements/lisk-transactions/test/4_register_multisignature_account.ts @@ -0,0 +1,487 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { registerMultisignature } from '../src/4_register_multisignature_account'; +import { MultiSignatureAsset } from '../src/4_multisignature_transaction'; +import { TransactionJSON } from '../src/transaction_types'; +import * as time from '../src/utils/time'; + +describe('#registerMultisignature transaction', () => { + const fixedPoint = 10 ** 8; + const passphrase = 'secret'; + const secondPassphrase = 'second secret'; + const transactionType = 4; + const keys = { + publicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + privateKey: + '2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + }; + const timeWithOffset = 38350076; + const fee = (15 * fixedPoint).toString(); + const amount = '0'; + const lifetime = 5; + const minimum = 2; + + let tooShortPublicKeyKeysgroup: Array; + let plusPrependedPublicKeyKeysgroup: Array; + let keysgroup: Array; + let getTimeWithOffsetStub: sinon.SinonStub; + let registerMultisignatureTransaction: Partial; + + beforeEach(() => { + getTimeWithOffsetStub = sandbox + .stub(time, 'getTimeWithOffset') + .returns(timeWithOffset); + keysgroup = [ + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + ]; + plusPrependedPublicKeyKeysgroup = [ + '+5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + tooShortPublicKeyKeysgroup = [ + 'd019a4b6fa37e8ebeb64766c7b239d962fb3b3f265b8d3083206097b912cd9', + ]; + return Promise.resolve(); + }); + + describe('with first passphrase', () => { + beforeEach(() => { + registerMultisignatureTransaction = registerMultisignature({ + passphrase, + keysgroup, + lifetime, + minimum, + }); + return Promise.resolve(); + }); + + it('should create a register multisignature transaction', () => { + return expect(registerMultisignatureTransaction).to.be.ok; + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(undefined); + }); + + it('should use time.getTimeWithOffset with an offset of -10 seconds to calculate the timestamp', () => { + const offset = -10; + registerMultisignature({ + passphrase, + keysgroup, + lifetime, + minimum, + timeOffset: offset, + }); + + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(offset); + }); + + describe('returned register multisignature transaction', () => { + it('should be an object', () => { + return expect(registerMultisignatureTransaction).to.be.an('object'); + }); + + it('should have id string', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have type number equal to 4', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('type') + .and.be.a('number') + .and.equal(transactionType); + }); + + it('should have amount string equal to 0', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('amount') + .and.be.a('string') + .and.equal(amount); + }); + + it('should have fee string equal to 15 LSK', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('fee') + .and.be.a('string') + .and.equal(fee); + }); + + it('should have recipientId string equal to empty string', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('recipientId') + .and.equal(''); + }); + + it('should have senderPublicKey hex string equal to sender public key', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('senderPublicKey') + .and.be.hexString.and.equal(keys.publicKey); + }); + + it('should have timestamp number equal to result of time.getTimeWithOffset', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('timestamp') + .and.be.a('number') + .and.equal(timeWithOffset); + }); + + it('should have signature hex string', () => { + return expect(registerMultisignatureTransaction).to.have.property( + 'signature', + ).and.be.hexString; + }); + + it('should have asset', () => { + return expect(registerMultisignatureTransaction).to.have.property( + 'asset', + ).and.not.be.empty; + }); + + it('second signature property should be undefined', () => { + return expect(registerMultisignatureTransaction.signSignature).to.be + .undefined; + }); + + describe('multisignature asset', () => { + it('should be object', () => { + return expect(registerMultisignatureTransaction.asset) + .to.have.property('multisignature') + .and.be.an('object'); + }); + + it('should have a min number equal to provided minimum', () => { + const { + multisignature, + } = registerMultisignatureTransaction.asset as MultiSignatureAsset; + return expect(multisignature) + .to.have.property('min') + .and.be.a('number') + .and.be.equal(minimum); + }); + + it('should have a lifetime number equal to provided lifetime', () => { + const { + multisignature, + } = registerMultisignatureTransaction.asset as MultiSignatureAsset; + return expect(multisignature) + .to.have.property('lifetime') + .and.be.a('number') + .and.be.equal(lifetime); + }); + + it('should have a keysgroup array with plus prepended', () => { + const expectedArray = [ + '+5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + '+922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + ]; + const { + multisignature, + } = registerMultisignatureTransaction.asset as MultiSignatureAsset; + return expect(multisignature) + .to.have.property('keysgroup') + .and.be.eql(expectedArray); + }); + }); + }); + }); + + describe('with first and second passphrase', () => { + beforeEach(() => { + registerMultisignatureTransaction = registerMultisignature({ + passphrase, + secondPassphrase, + keysgroup, + lifetime, + minimum, + }); + return Promise.resolve(); + }); + + it('should have the second signature property as hex string', () => { + return expect(registerMultisignatureTransaction).to.have.property( + 'signSignature', + ).and.be.hexString; + }); + }); + + describe('when the register multisignature account transaction is created with one too short public key', () => { + it('should throw an error', () => { + return expect( + registerMultisignature.bind(null, { + passphrase, + secondPassphrase, + keysgroup: tooShortPublicKeyKeysgroup, + lifetime, + minimum: 1, + }), + ).to.throw( + 'Public key d019a4b6fa37e8ebeb64766c7b239d962fb3b3f265b8d3083206097b912cd9 length differs from the expected 32 bytes for a public key.', + ); + }); + }); + + describe('when the register multisignature account transaction is created with one plus prepended public key', () => { + it('should throw an error', () => { + return expect( + registerMultisignature.bind(null, { + passphrase, + secondPassphrase, + keysgroup: plusPrependedPublicKeyKeysgroup, + lifetime, + minimum: 1, + }), + ).to.throw('Argument must be a valid hex string.'); + }); + }); + + describe('when the register multisignature account transaction is created with one empty keysgroup', () => { + it('should throw an error', () => { + return expect( + registerMultisignature.bind(null, { + passphrase, + secondPassphrase, + keysgroup: [], + lifetime, + minimum, + }), + ).to.throw( + 'Minimum number of signatures is larger than the number of keys in the keysgroup.', + ); + }); + }); + + describe('when the register multisignature account transaction is created with 17 public keys in keysgroup', () => { + beforeEach(() => { + keysgroup = Array(17) + .fill(0) + .map( + (_: number, index: number) => + cryptography.getPrivateAndPublicKeyFromPassphrase(index.toString()) + .publicKey, + ); + return Promise.resolve(); + }); + + it('should throw an error', () => { + return expect( + registerMultisignature.bind(null, { + passphrase, + secondPassphrase, + keysgroup, + lifetime, + minimum, + }), + ).to.throw('Expected between 1 and 15 public keys in the keysgroup.'); + }); + }); + + describe('when the register multisignature account transaction is created with duplicated public keys', () => { + beforeEach(() => { + keysgroup = [keys.publicKey, keys.publicKey]; + return Promise.resolve(); + }); + + it('should throw an error', () => { + return expect( + registerMultisignature.bind(null, { + passphrase, + secondPassphrase, + keysgroup, + lifetime, + minimum, + }), + ).to.throw( + 'Duplicated public key: 5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09.', + ); + }); + }); + + describe('unsigned register multisignature account transaction', () => { + describe('when the register multisignature transaction is created without a passphrase', () => { + beforeEach(() => { + registerMultisignatureTransaction = registerMultisignature({ + keysgroup, + lifetime, + minimum, + }); + return Promise.resolve(); + }); + + describe('validation errors', () => { + describe('when lifetime', () => { + const lifetimeErrorMessage = + 'Please provide a valid lifetime value. Expected integer between 1 and 72.'; + + it('was not provided', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + } as any), + ).to.throw(lifetimeErrorMessage); + }); + + it('is float', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime: 23.45, + } as any), + ).to.throw(lifetimeErrorMessage); + }); + + it('is not number type', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime: '123', + } as any), + ).to.throw(lifetimeErrorMessage); + }); + + it('was more than expected', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime: 73, + } as any), + ).to.throw(lifetimeErrorMessage); + }); + + it('was less than expected', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime: -1, + } as any), + ).to.throw(lifetimeErrorMessage); + }); + }); + }); + + describe('when minimum', () => { + const minimumErrorMessage = + 'Please provide a valid minimum value. Expected integer between 1 and 15.'; + + it('was not provided', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime, + } as any), + ).to.throw(minimumErrorMessage); + }); + + it('is float', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime, + minimum: 1.45, + }), + ).to.throw(minimumErrorMessage); + }); + + it('is not number type', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime, + minimum: '12', + } as any), + ).to.throw(minimumErrorMessage); + }); + + it('was more than expected', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime, + minimum: 16, + }), + ).to.throw(minimumErrorMessage); + }); + + it('was less than expected', () => { + return expect( + registerMultisignature.bind(null, { + keysgroup, + lifetime, + minimum: -1, + }), + ).to.throw(minimumErrorMessage); + }); + }); + + it('should have the type', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('type') + .equal(transactionType); + }); + + it('should have the amount', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the fee', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the recipient id', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('recipientId') + .equal(''); + }); + + it('should have the sender public key', () => { + return expect(registerMultisignatureTransaction) + .to.have.property('senderPublicKey') + .equal(undefined); + }); + + it('should have the timestamp', () => { + return expect(registerMultisignatureTransaction).to.have.property( + 'timestamp', + ); + }); + + it('should have the asset with the multisignature with the minimum, lifetime and keysgroup', () => { + return expect(registerMultisignatureTransaction) + .to.have.nested.property('asset.multisignature') + .with.all.keys('min', 'lifetime', 'keysgroup'); + }); + + it('should not have the signature', () => { + return expect(registerMultisignatureTransaction).not.to.have.property( + 'signature', + ); + }); + + it('should not have the id', () => { + return expect(registerMultisignatureTransaction).not.to.have.property( + 'id', + ); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/5_create_dapp.ts b/elements/lisk-transactions/test/5_create_dapp.ts new file mode 100644 index 00000000000..426074ed7e7 --- /dev/null +++ b/elements/lisk-transactions/test/5_create_dapp.ts @@ -0,0 +1,409 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { createDapp, DappOptions } from '../src/5_create_dapp'; +import { TransactionJSON } from '../src/transaction_types'; +import { DappAsset } from '../src/5_dapp_transaction'; +import * as time from '../src/utils/time'; + +describe('#createDapp transaction', () => { + const fixedPoint = 10 ** 8; + const transactionType = 5; + const amount = '0'; + const passphrase = 'secret'; + const secondPassphrase = 'second secret'; + const publicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const defaultOptions = { + category: 0, + name: 'Lisk Guestbook', + description: 'The official Lisk guestbook', + tags: 'guestbook message sidechain', + type: 0, + link: 'https://github.com/MaxKK/guestbookDapp/archive/master.zip', + icon: + 'https://raw.githubusercontent.com/MaxKK/guestbookDapp/master/icon.png', + }; + const fee = (25 * fixedPoint).toString(); + const timeWithOffset = 38350076; + const noOptionsError = 'Options must be an object.'; + const categoryIntegerError = 'Dapp category must be an integer.'; + const nameStringError = 'Dapp name must be a string.'; + const typeIntegerError = 'Dapp type must be an integer.'; + const linkStringError = 'Dapp link must be a string.'; + const descriptionStringError = + 'Dapp description must be a string if provided.'; + const tagsStringError = 'Dapp tags must be a string if provided.'; + const iconStringError = 'Dapp icon must be a string if provided.'; + + let getTimeWithOffsetStub: sinon.SinonStub; + let options: DappOptions; + let createDappTransaction: Partial; + + beforeEach(() => { + getTimeWithOffsetStub = sandbox + .stub(time, 'getTimeWithOffset') + .returns(timeWithOffset); + options = { + ...defaultOptions, + }; + return Promise.resolve(); + }); + + describe('with first passphrase', () => { + beforeEach(() => { + createDappTransaction = createDapp({ passphrase, options }); + return Promise.resolve(); + }); + + it('should create a create dapp transaction', () => { + return expect(createDappTransaction).to.be.ok; + }); + + it('should throw an error if no options are provided', () => { + return expect(createDapp.bind(null, { passphrase } as any)).to.throw( + noOptionsError, + ); + }); + + it('should throw an error if no category is provided', () => { + const { category, ...invalidOptions } = options; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(categoryIntegerError); + }); + + it('should throw an error if provided category is not an integer', () => { + const invalidOptions = { + ...options, + category: 'not an integer', + }; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(categoryIntegerError); + }); + + it('should throw an error if no name is provided', () => { + const { name, ...invalidOptions } = options; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(nameStringError); + }); + + it('should throw an error if provided name is not a string', () => { + const invalidOptions = { + ...options, + name: 123, + }; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(nameStringError); + }); + + it('should throw an error if no type is provided', () => { + const { type, ...invalidOptions } = options; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(typeIntegerError); + }); + + it('should throw an error if provided type is not an integer', () => { + const invalidOptions = { + ...options, + type: 'not an integer', + }; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(typeIntegerError); + }); + + it('should throw an error if no link is provided', () => { + const { link, ...invalidOptions } = options; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(linkStringError); + }); + + it('should throw an error if provided link is not a string', () => { + const invalidOptions = { + ...options, + link: 123, + }; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(linkStringError); + }); + + it('should throw an error if provided description is not a string', () => { + const invalidOptions = { + ...options, + description: 123, + }; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(descriptionStringError); + }); + + it('should throw an error if provided tags is not a string', () => { + const invalidOptions = { + ...options, + tags: 123, + }; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(tagsStringError); + }); + + it('should throw an error if provided icon is not a string', () => { + const invalidOptions = { + ...options, + icon: 123, + }; + return expect( + createDapp.bind(null, { passphrase, options: invalidOptions as any }), + ).to.throw(iconStringError); + }); + + it('should not require description, tags, or icon', () => { + const { description, tags, icon, ...validOptions } = options; + return expect( + createDapp.bind(null, { passphrase, options: validOptions as any }), + ).not.to.throw(); + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(undefined); + }); + + it('should use time.getTimeWithOffset with an offset of -10 seconds to calculate the timestamp', () => { + const offset = -10; + createDapp({ passphrase, options, timeOffset: offset }); + + return expect(getTimeWithOffsetStub).to.be.calledWithExactly(offset); + }); + + describe('returned create dapp transaction', () => { + it('should be an object', () => { + return expect(createDappTransaction).to.be.an('object'); + }); + + it('should have an id string', () => { + return expect(createDappTransaction) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have type number equal to 5', () => { + return expect(createDappTransaction) + .to.have.property('type') + .and.be.a('number') + .and.equal(5); + }); + + it('should have amount string equal to 0', () => { + return expect(createDappTransaction) + .to.have.property('amount') + .and.be.a('string') + .and.equal('0'); + }); + + it('should have fee string equal to 25 LSK', () => { + return expect(createDappTransaction) + .to.have.property('fee') + .and.be.a('string') + .and.equal(fee); + }); + + it('should have recipientId equal to empty string', () => { + return expect(createDappTransaction) + .to.have.property('recipientId') + .and.equal(''); + }); + + it('should have senderPublicKey hex string equal to sender public key', () => { + return expect(createDappTransaction) + .to.have.property('senderPublicKey') + .and.be.hexString.and.equal(publicKey); + }); + + it('should have timestamp number equal to result of time.getTimeWithOffset', () => { + return expect(createDappTransaction) + .to.have.property('timestamp') + .and.be.a('number') + .and.equal(timeWithOffset); + }); + + it('should have signature hex string', () => { + return expect(createDappTransaction).to.have.property('signature').and + .be.hexString; + }); + + it('second signature property should be undefined', () => { + return expect(createDappTransaction.signSignature).to.be.undefined; + }); + + it('should have asset', () => { + return expect(createDappTransaction).to.have.property('asset').and.not + .be.empty; + }); + + describe('dapps asset', () => { + let asset: DappAsset | any; + + beforeEach(() => { + asset = createDappTransaction.asset; + }); + + it('should be object', () => { + return expect(createDappTransaction.asset) + .to.have.property('dapp') + .and.be.an('object'); + }); + + it('should have a category number equal to provided category', () => { + return expect(asset.dapp) + .to.have.property('category') + .and.be.a('number') + .and.equal(options.category); + }); + + it('should have a name string equal to provided name', () => { + return expect(asset.dapp) + .to.have.property('name') + .and.be.a('string') + .and.equal(options.name); + }); + + it('should have a description string equal to provided description', () => { + return expect(asset.dapp) + .to.have.property('description') + .and.be.a('string') + .and.equal(options.description); + }); + + it('should have a tags string equal to provided tags', () => { + return expect(asset.dapp) + .to.have.property('tags') + .and.be.a('string') + .and.equal(options.tags); + }); + + it('should have a type number equal to provided type', () => { + return expect(asset.dapp) + .to.have.property('type') + .and.be.a('number') + .and.equal(options.type); + }); + + it('should have a link string equal to provided link', () => { + return expect(asset.dapp) + .to.have.property('link') + .and.be.a('string') + .and.equal(options.link); + }); + + it('should have an icon string equal to provided icon', () => { + return expect(asset.dapp) + .to.have.property('icon') + .and.be.a('string') + .and.equal(options.icon); + }); + }); + }); + }); + + describe('with first and second passphrase', () => { + beforeEach(() => { + createDappTransaction = createDapp({ + passphrase, + secondPassphrase, + options, + }); + return Promise.resolve(); + }); + + it('should have the second signature property as hex string', () => { + return expect(createDappTransaction).to.have.property('signSignature').and + .be.hexString; + }); + }); + + describe('unsigned create dapp transaction', () => { + describe('when the create dapp transaction is created without a passphrase', () => { + beforeEach(() => { + createDappTransaction = createDapp({ + options, + }); + return Promise.resolve(); + }); + + it('should have the type', () => { + return expect(createDappTransaction) + .to.have.property('type') + .equal(transactionType); + }); + + it('should have the amount', () => { + return expect(createDappTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the fee', () => { + return expect(createDappTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the recipient id', () => { + return expect(createDappTransaction) + .to.have.property('recipientId') + .equal(''); + }); + + it('should have the sender public key', () => { + return expect(createDappTransaction) + .to.have.property('senderPublicKey') + .equal(undefined); + }); + + it('should have the timestamp', () => { + return expect(createDappTransaction).to.have.property('timestamp'); + }); + + it('should have the asset with dapp with properties category, description, name, tags, type, link, icon', () => { + return expect(createDappTransaction) + .to.have.nested.property('asset.dapp') + .with.all.keys( + 'category', + 'description', + 'name', + 'tags', + 'type', + 'link', + 'icon', + ); + }); + + it('should not have the signature', () => { + return expect(createDappTransaction).not.to.have.property('signature'); + }); + + it('should not have the id', () => { + return expect(createDappTransaction).not.to.have.property('id'); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/5_dapp_transaction.ts b/elements/lisk-transactions/test/5_dapp_transaction.ts new file mode 100644 index 00000000000..f2d408913e7 --- /dev/null +++ b/elements/lisk-transactions/test/5_dapp_transaction.ts @@ -0,0 +1,393 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { MockStateStore as store } from './helpers'; +import { DappTransaction } from '../src/5_dapp_transaction'; +import { validDappTransactions, validVoteTransactions } from '../fixtures'; +import { TransactionJSON } from '../src/transaction_types'; +import { Status } from '../src/response'; +import * as utils from '../src/utils'; + +describe('Dapp transaction class', () => { + const defaultValidDappTransaction = validDappTransactions[0]; + let validTestTransaction: DappTransaction; + let storeAccountCacheStub: sinon.SinonStub; + let storeTransactionCacheStub: sinon.SinonStub; + let storeTransactionFindStub: sinon.SinonStub; + + beforeEach(async () => { + validTestTransaction = new DappTransaction(defaultValidDappTransaction); + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + storeTransactionCacheStub = sandbox.stub(store.transaction, 'cache'); + storeTransactionFindStub = sandbox.stub(store.transaction, 'find'); + }); + + describe('#constructor', () => { + it('should create instance of DappTransaction', async () => { + expect(validTestTransaction).to.be.instanceOf(DappTransaction); + }); + + it('should set the dapp asset', async () => { + expect(validTestTransaction.asset.dapp).to.be.an('object'); + }); + + it('should not throw TransactionMultiError when asset is not string array', async () => { + const invalidDappTransactionData = { + ...defaultValidDappTransaction, + asset: { + dapp: { + name: 123, + }, + }, + }; + expect( + () => new DappTransaction(invalidDappTransactionData), + ).not.to.throw(); + }); + }); + + describe('#assetToBytes', () => { + const defaultCategory = 0; + const defaultDappName = 'Lisk Guestbook'; + const defaultDescription = 'The official Lisk guestbook'; + const defaultTags = 'guestbook message sidechain'; + const defaultType = 0; + const defaultLink = + 'https://github.com/MaxKK/guestbookDapp/archive/master.zip'; + const defaultIcon = + 'https://raw.githubusercontent.com/MaxKK/guestbookDapp/master/icon.png'; + const dappNameBuffer = Buffer.from('4c69736b204775657374626f6f6b', 'hex'); + const dappDescriptionBuffer = Buffer.from( + '546865206f6666696369616c204c69736b206775657374626f6f6b', + 'hex', + ); + const dappTagsBuffer = Buffer.from( + '6775657374626f6f6b206d6573736167652073696465636861696e', + 'hex', + ); + const dappLinkBuffer = Buffer.from( + '68747470733a2f2f6769746875622e636f6d2f4d61784b4b2f6775657374626f6f6b446170702f617263686976652f6d61737465722e7a6970', + 'hex', + ); + const dappIconBuffer = Buffer.from( + '68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f4d61784b4b2f6775657374626f6f6b446170702f6d61737465722f69636f6e2e706e67', + 'hex', + ); + const dappTypeBuffer = Buffer.alloc(4, defaultType); + const dappCategoryBuffer = Buffer.alloc(4, defaultCategory); + const expectedBuffer = Buffer.concat([ + dappNameBuffer, + dappDescriptionBuffer, + dappTagsBuffer, + dappLinkBuffer, + dappIconBuffer, + dappTypeBuffer, + dappCategoryBuffer, + ]); + + it('should return valid buffer', async () => { + (validTestTransaction as any).asset = { + dapp: { + category: defaultCategory, + name: defaultDappName, + description: defaultDescription, + tags: defaultTags, + type: defaultType, + link: defaultLink, + icon: defaultIcon, + }, + }; + const assetBytes = (validTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql(expectedBuffer); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return status true with non conflicting transactions', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validDappTransactions[1], + validDappTransactions[2], + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(0); + expect(status).to.equal(Status.OK); + }); + + it('should return status true with non related transactions', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions( + validVoteTransactions, + ); + expect(errors) + .to.be.an('array') + .of.length(0); + expect(status).to.equal(Status.OK); + }); + + it('should return TransactionResponse with error when other transaction has the same dapp name', async () => { + const conflictTransaction = { + ...validDappTransactions[2], + asset: { + dapp: { + ...validDappTransactions[2].asset.dapp, + name: defaultValidDappTransaction.asset.dapp.name, + }, + }, + }; + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + conflictTransaction, + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(1); + expect(status).to.equal(Status.FAIL); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validTestTransaction.assetToJSON()) + .to.be.an('object') + .and.to.have.property('dapp'); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + await validTestTransaction.prepare(store); + expect(storeAccountCacheStub).to.have.been.calledWithExactly([ + { address: validTestTransaction.senderId }, + ]); + expect(storeTransactionCacheStub).to.have.been.calledWithExactly([ + { dapp_name: validTestTransaction.asset.dapp.name }, + { dapp_link: validTestTransaction.asset.dapp.link }, + ]); + }); + }); + + describe('#validateAsset', () => { + beforeEach(async () => { + sandbox.stub(utils, 'getId').returns(validTestTransaction.id); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).validateAsset(); + expect(errors).to.be.an('array').and.empty; + }); + + it('should not return error when optional field contains null', async () => { + const validTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + description: null, + icon: null, + tags: null, + }, + }, + }; + const transaction = new DappTransaction(validTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).to.be.empty; + }); + + it('should return error when amount is not zero', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + amount: '100', + }; + const transaction = new DappTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.amount'); + }); + + it('should return error when link is in invalid suffix', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + link: + 'https://github.com/m-schmoock/lisk-dapps-sdk/archive/development.zippo', + }, + }, + }; + const transaction = new DappTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.asset.dapp.link'); + }); + + it('should return error when link is not url', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + link: + 'github.com/m-schmoock/lisk-dapps-sdk/archive/development.zip', + }, + }, + }; + const transaction = new DappTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.dapp.link'); + }); + + it('should return error when icon is in invalid suffix', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + icon: 'https://iconverticons.com/img/logo.gif', + }, + }, + }; + const transaction = new DappTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.asset.dapp.icon'); + }); + + it('should return error when type is not zero', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + type: 3, + }, + }, + }; + const transaction = new DappTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.dapp.type'); + }); + + it('should return error when tags contains non unique key', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + tags: 'game,ftw, game, sidechain', + }, + }, + }; + const transaction = new DappTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.asset.dapp.tags'); + }); + + it('should return error when category is out of range', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + category: 10, + }, + }, + }; + const transaction = new DappTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.dapp.category'); + }); + + it('should return error when dapp name exceeds maximum', async () => { + const invalidTransaction = { + ...defaultValidDappTransaction, + asset: { + dapp: { + ...defaultValidDappTransaction.asset.dapp, + name: 'Excepteur sint occaecocsd rutrume', + }, + }, + }; + const transaction = new DappTransaction(invalidTransaction); + + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.dapp.name'); + }); + }); + + describe('#applyAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).applyAsset(store); + expect(storeTransactionFindStub).to.be.calledTwice; + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).to.be.empty; + }); + + it('should return error when store includes the transaction with same dapp name', async () => { + const invalidDappTransaction = { + ...validDappTransactions[2], + asset: { + dapp: { + ...validDappTransactions[2].asset.dapp, + name: defaultValidDappTransaction.asset.dapp.name, + }, + }, + }; + store.transaction.find = () => invalidDappTransaction; + + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + }); + + it('should return error when store includes the transaction with same dapp link', async () => { + const invalidDappTransaction = { + ...validDappTransactions[2], + asset: { + dapp: { + ...validDappTransactions[2].asset.dapp, + link: defaultValidDappTransaction.asset.dapp.link, + }, + }, + }; + store.transaction.find = () => invalidDappTransaction; + + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + }); + }); + + describe('#undoAsset', () => { + it('should return no errors', async () => { + const errors = (validTestTransaction as any).undoAsset(store); + expect(errors).to.be.empty; + }); + }); +}); diff --git a/elements/lisk-transactions/test/6_in_transfer_transaction.ts b/elements/lisk-transactions/test/6_in_transfer_transaction.ts new file mode 100644 index 00000000000..e2dfb89f8e4 --- /dev/null +++ b/elements/lisk-transactions/test/6_in_transfer_transaction.ts @@ -0,0 +1,286 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { expect } from 'chai'; +import { MockStateStore as store } from './helpers'; +import { InTransferTransaction } from '../src/6_in_transfer_transaction'; +import { + validInTransferTransactions, + validDappTransactions, +} from '../fixtures'; +import { TransactionJSON } from '../src/transaction_types'; +import { Status } from '../src/response'; + +describe('InTransfer transaction class', () => { + const defaultTransaction = validInTransferTransactions[0]; + const defaultValidSender = { + address: '13155556493249255133L', + balance: '1000000000', + publicKey: + '305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad', + }; + const defaultValidTxs = [ + { + id: '13227044664082109069', + type: 5, + senderId: '18237045742439723234L', + }, + ]; + const dappRegistrationTx = validDappTransactions[3]; + + let validTestTransaction: InTransferTransaction; + let storeAccountCacheStub: sinon.SinonStub; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountSetStub: sinon.SinonStub; + let storeTransactionCacheStub: sinon.SinonStub; + let storeTransactionGetStub: sinon.SinonStub; + let storeTransactionFindStub: sinon.SinonStub; + + beforeEach(async () => { + validTestTransaction = new InTransferTransaction(defaultTransaction); + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + storeAccountGetStub = sandbox + .stub(store.account, 'get') + .returns(defaultValidSender); + storeAccountSetStub = sandbox.stub(store.account, 'set'); + storeTransactionCacheStub = sandbox.stub(store.transaction, 'cache'); + storeTransactionGetStub = sandbox + .stub(store.transaction, 'get') + .returns(dappRegistrationTx); + storeTransactionFindStub = sandbox + .stub(store.transaction, 'find') + .returns(() => defaultValidTxs[0]); + }); + + describe('#constructor', () => { + it('should create instance of InTransferTransaction', async () => { + expect(validTestTransaction).to.be.instanceOf(InTransferTransaction); + }); + + it('should set the inTransfer asset', async () => { + expect(validTestTransaction.asset.inTransfer).to.be.an('object'); + expect(validTestTransaction.asset.inTransfer.dappId).to.equal( + defaultTransaction.asset.inTransfer.dappId, + ); + }); + + it('should not throw TransactionMultiError when asset is not string', async () => { + const invalidInTransferTransactionData = { + ...defaultTransaction, + asset: { + inTransfer: { + dappId: 1, + }, + }, + }; + expect( + () => new InTransferTransaction(invalidInTransferTransactionData), + ).not.to.throw(); + }); + }); + + describe('#assetToBytes', () => { + it('should return valid buffer', async () => { + const assetBytes = (validTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql( + Buffer.from(defaultTransaction.asset.inTransfer.dappId, 'utf8'), + ); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return status true', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validInTransferTransactions[1], + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(0); + expect(status).to.equal(Status.OK); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validTestTransaction.assetToJSON()) + .to.be.an('object') + .and.to.have.property('inTransfer'); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + storeTransactionCacheStub.onCall(0).returns([dappRegistrationTx]); + await validTestTransaction.prepare(store); + expect( + storeAccountCacheStub + .getCall(0) + .calledWithExactly([{ address: validTestTransaction.senderId }]), + ); + expect( + storeAccountCacheStub + .getCall(1) + .calledWithExactly([{ id: dappRegistrationTx.senderId }]), + ); + }); + }); + + describe('#validateAsset', () => { + it('should return no errors', async () => { + const errors = (validTestTransaction as any).validateAsset(); + expect(errors).to.be.empty; + }); + + it('should return error when asset includes non id format dappId', async () => { + const invalidTransaction = { + ...defaultTransaction, + id: '17748758437863626387', + asset: { + inTransfer: { + dappId: 'id-not-id-format-zzzzz', + }, + }, + }; + const transaction = new InTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.inTransfer.dappId'); + }); + + it('should return error when recipientId is not empty', async () => { + const invalidTransaction = { + ...defaultTransaction, + id: '1070575047580588345', + recipientId: '13155556493249255133L', + }; + const transaction = new InTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.recipientId'); + }); + + it('should return error when recipientPublicKey is not empty', async () => { + const invalidTransaction = { + ...defaultTransaction, + recipientPublicKey: + '305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad', + }; + const transaction = new InTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.recipientPublicKey'); + }); + + it('should return error when amount is zero', async () => { + const invalidTransaction = { + ...defaultTransaction, + id: '16332529042692216279', + amount: '0', + }; + const transaction = new InTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.amount'); + }); + }); + + describe('#applyAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).applyAsset(store); + expect(storeTransactionFindStub).to.be.calledOnce; + expect( + storeAccountGetStub + .getCall(0) + .calledWithExactly(validTestTransaction.senderId), + ); + expect( + storeAccountSetStub + .getCall(0) + .calledWithExactly(defaultValidSender.address, { + ...defaultValidSender, + balance: new BigNum(defaultValidSender.balance) + .sub(validTestTransaction.amount) + .toString(), + }), + ); + expect(storeTransactionGetStub).to.be.calledWithExactly( + validTestTransaction.asset.inTransfer.dappId, + ); + expect( + storeAccountGetStub + .getCall(1) + .calledWithExactly(dappRegistrationTx.senderId), + ); + }); + + it('should return error when dapp registration tx not found', async () => { + storeTransactionFindStub.returns(undefined); + + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + }); + + it('should return error when sender balance insufficient', async () => { + storeAccountGetStub.returns({ ...defaultValidSender, balance: '0' }); + + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).not.to.be.empty; + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).applyAsset(store); + + expect(errors).to.be.empty; + }); + }); + + describe('#undoAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).undoAsset(store); + expect( + storeAccountGetStub + .getCall(0) + .calledWithExactly(validTestTransaction.senderId), + ); + expect( + storeAccountSetStub + .getCall(0) + .calledWithExactly(defaultValidSender.address, { + ...defaultValidSender, + balance: new BigNum(defaultValidSender.balance) + .add(validTestTransaction.amount) + .toString(), + }), + ); + expect(storeTransactionGetStub).to.be.calledWithExactly( + validTestTransaction.asset.inTransfer.dappId, + ); + expect( + storeAccountGetStub + .getCall(1) + .calledWithExactly(dappRegistrationTx.senderId), + ); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).undoAsset(store); + + expect(errors).to.be.empty; + }); + }); +}); diff --git a/elements/lisk-transactions/test/7_out_transfer_transaction.ts b/elements/lisk-transactions/test/7_out_transfer_transaction.ts new file mode 100644 index 00000000000..7f82c3a3739 --- /dev/null +++ b/elements/lisk-transactions/test/7_out_transfer_transaction.ts @@ -0,0 +1,339 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { expect } from 'chai'; +import { MockStateStore as store } from './helpers'; +import { OutTransferTransaction } from '../src/7_out_transfer_transaction'; +import { + validOutTransferTransactions, + validTransaction, + validDappTransactions, +} from '../fixtures'; +import { TransactionJSON } from '../src/transaction_types'; +import { Status } from '../src/response'; + +describe('outTransfer transaction class', () => { + const defaultTransaction = validOutTransferTransactions[3]; + const defaultValidSender = { + address: '13155556493249255133L', + balance: '4700483466477', + publicKey: + '305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad', + }; + const defaultValidRecipient = { + address: '13155556493249255133L', + balance: '4700483466477', + publicKey: + '305b4897abc230c1cc9d0aa3bf0c75747bfa42f32f83f5a92348edea528850ad', + }; + const dappRegistrationTx = validDappTransactions[3]; + + let validTestTransaction: OutTransferTransaction; + let storeTransactionCacheStub: sinon.SinonStub; + let storeTransactionGetStub: sinon.SinonStub; + let storeAccountCacheStub: sinon.SinonStub; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountGetOrDefaultStub: sinon.SinonStub; + let storeAccountSetStub: sinon.SinonStub; + + beforeEach(async () => { + validTestTransaction = new OutTransferTransaction(defaultTransaction); + storeTransactionCacheStub = sandbox.stub(store.transaction, 'cache'); + storeTransactionGetStub = sandbox + .stub(store.transaction, 'get') + .returns(dappRegistrationTx); + storeAccountCacheStub = sandbox.stub(store.account, 'cache'); + storeAccountGetStub = sandbox + .stub(store.account, 'get') + .returns(defaultValidSender); + storeAccountGetOrDefaultStub = sandbox + .stub(store.account, 'getOrDefault') + .returns(defaultValidRecipient); + storeAccountSetStub = sandbox.stub(store.account, 'set'); + }); + + describe('#constructor', () => { + it('should create instance of OutTransferTransaction', async () => { + expect(validTestTransaction).to.be.instanceOf(OutTransferTransaction); + }); + + it('should set the outTransfer asset', async () => { + expect(validTestTransaction.asset.outTransfer).to.be.an('object'); + expect(validTestTransaction.asset.outTransfer.dappId).to.equal( + defaultTransaction.asset.outTransfer.dappId, + ); + expect(validTestTransaction.asset.outTransfer.transactionId).to.equal( + defaultTransaction.asset.outTransfer.transactionId, + ); + }); + + it('should not throw TransactionMultiError when asset.dappId is not string', async () => { + const invalidOutTransferTransactionData = { + ...defaultTransaction, + asset: { + outTransfer: { + dappId: 1, + transactionId: '1', + }, + }, + }; + expect( + () => new OutTransferTransaction(invalidOutTransferTransactionData), + ).not.to.throw(); + }); + + it('should not throw TransactionMultiError when asset.transactionId is not string', async () => { + const invalidOutTransferTransactionData = { + ...defaultTransaction, + asset: { + outTransfer: { + dappId: '1', + transactionId: 1, + }, + }, + }; + expect( + () => new OutTransferTransaction(invalidOutTransferTransactionData), + ).not.to.throw(); + }); + }); + + describe('#assetToBytes', () => { + it('should return valid buffer', async () => { + const assetBytes = (validTestTransaction as any).assetToBytes(); + expect(assetBytes).to.eql( + Buffer.concat([ + Buffer.from(defaultTransaction.asset.outTransfer.dappId, 'utf8'), + Buffer.from( + defaultTransaction.asset.outTransfer.transactionId, + 'utf8', + ), + ]), + ); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return status true', async () => { + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + validDappTransactions[1], + ] as ReadonlyArray); + expect(errors) + .to.be.an('array') + .of.length(0); + expect(status).to.equal(Status.OK); + }); + + it('should return TransactionResponse with errors when it has conflicting asset transaction id', async () => { + const invalidTransaction = { + ...validOutTransferTransactions[1], + asset: { + outTransfer: { + dappId: validOutTransferTransactions[1].asset.outTransfer.dappId, + transactionId: defaultTransaction.asset.outTransfer.transactionId, + }, + }, + }; + const { + errors, + status, + } = validTestTransaction.verifyAgainstOtherTransactions([ + invalidTransaction, + ] as ReadonlyArray); + expect(status).to.equal(Status.FAIL); + expect(errors) + .to.be.an('array') + .of.length(1); + expect(errors[0].dataPath).to.equal('.asset.outTransfer.transactionId'); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transfer asset', async () => { + expect(validTestTransaction.assetToJSON()) + .to.be.an('object') + .and.to.have.property('outTransfer'); + }); + }); + + describe('#prepare', async () => { + it('should call state store', async () => { + await validTestTransaction.prepare(store); + expect(storeAccountCacheStub).to.be.calledWithExactly([ + { address: validTestTransaction.senderId }, + { address: validTestTransaction.recipientId }, + ]); + expect(storeTransactionCacheStub).to.be.calledWithExactly([ + { id: validTestTransaction.asset.outTransfer.dappId }, + { id: validTestTransaction.asset.outTransfer.transactionId }, + ]); + }); + }); + + describe('#validateAsset', () => { + it('should return no errors', async () => { + const errors = (validTestTransaction as any).validateAsset(); + expect(errors).to.be.empty; + }); + + it('should return error when asset includes non id format dappId', async () => { + const invalidTransaction = { + ...defaultTransaction, + id: '16003217217288827597', + asset: { + outTransfer: { + dappId: 'id-not-id-format-zzzzz', + transactionId: '17748758437863626387', + }, + }, + }; + const transaction = new OutTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.outTransfer.dappId'); + }); + + it('should return error when asset includes non id format transaction id', async () => { + const invalidTransaction = { + ...defaultTransaction, + id: '14791901133590540608', + asset: { + outTransfer: { + dappId: '17748758437863626387', + transactionId: 'id-not-id-format-zzzzz', + }, + }, + }; + const transaction = new OutTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.outTransfer.transactionId'); + }); + + it('should return error when recipientId is empty', async () => { + const invalidTransaction = { + ...defaultTransaction, + recipientId: '', + id: '13921832040819226757', + }; + const transaction = new OutTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.recipientId'); + }); + + it('should return error when amount is zero', async () => { + const invalidTransaction = { + ...defaultTransaction, + id: '16972514353304288599', + amount: '0', + }; + const transaction = new OutTransferTransaction(invalidTransaction); + const errors = (transaction as any).validateAsset(); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.amount'); + }); + }); + + describe('#applyAsset', () => { + it('should return no errors', async () => { + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors).to.be.empty; + }); + + it('should call state store', async () => { + (validTestTransaction as any).applyAsset(store); + expect(storeTransactionGetStub).to.be.calledWithExactly( + validTestTransaction.asset.outTransfer.dappId, + ); + expect( + storeAccountGetStub + .getCall(0) + .calledWithExactly(validTestTransaction.senderId), + ); + expect( + storeAccountSetStub + .getCall(0) + .calledWithExactly(defaultValidSender.address, { + ...defaultValidSender, + balance: new BigNum(defaultValidSender.balance) + .sub(validTestTransaction.amount) + .toString(), + }), + ); + expect( + storeAccountGetOrDefaultStub + .getCall(0) + .calledWithExactly(validTestTransaction.recipientId), + ); + }); + + it('should return error when transaction is not a dapp', async () => { + const invalidTestTransaction = new OutTransferTransaction({ + ...defaultTransaction, + asset: { + outTransfer: { + dappId: '123', + }, + }, + }); + storeTransactionGetStub.returns(validTransaction); + + const errors = (invalidTestTransaction as any).applyAsset(store); + expect(errors[0].message).to.equal( + `Application not found: ${ + invalidTestTransaction.asset.outTransfer.dappId + }`, + ); + }); + + it('should return error when sender balance is insufficient', async () => { + storeAccountGetStub.returns({ + ...defaultValidSender, + balance: '0', + }); + const errors = (validTestTransaction as any).applyAsset(store); + expect(errors[0].message).to.equal( + `Account does not have enough LSK: ${ + defaultValidSender.address + }, balance: 0.1`, + ); + }); + }); + + describe('#undoAsset', () => { + it('should call state store', async () => { + (validTestTransaction as any).undoAsset(store); + expect( + storeAccountGetStub + .getCall(0) + .calledWithExactly(validTestTransaction.senderId), + ); + expect( + storeAccountGetOrDefaultStub + .getCall(0) + .calledWithExactly(validTestTransaction.recipientId), + ); + }); + + it('should return no errors', async () => { + const errors = (validTestTransaction as any).undoAsset(store); + expect(errors).to.be.empty; + }); + }); +}); diff --git a/elements/lisk-transactions/test/_global_hooks.ts b/elements/lisk-transactions/test/_global_hooks.ts new file mode 100644 index 00000000000..21464e90f21 --- /dev/null +++ b/elements/lisk-transactions/test/_global_hooks.ts @@ -0,0 +1,3 @@ +afterEach(() => { + return sandbox.restore(); +}); diff --git a/elements/lisk-transactions/test/_setup.ts b/elements/lisk-transactions/test/_setup.ts new file mode 100644 index 00000000000..d938e5c4f90 --- /dev/null +++ b/elements/lisk-transactions/test/_setup.ts @@ -0,0 +1,56 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as sinon from 'sinon'; +import * as chai from 'chai'; +import 'chai/register-expect'; +import * as sinonChai from 'sinon-chai'; + +process.env.NODE_ENV = 'test'; + +chai.Assertion.addProperty('hexString', function handleAssert( + this: Chai.ChaiStatic, +) { + const actual = this._obj; + + new chai.Assertion(actual).to.be.a('string'); + + const expected = Buffer.from(actual, 'hex').toString('hex'); + this.assert( + expected === actual, + 'expected #{this} to be a hexString', + 'expected #{this} not to be a hexString', + ); +}); + +chai.Assertion.addProperty('integer', function handleAssert( + this: Chai.ChaiStatic, +) { + const actual = this._obj; + + new chai.Assertion(actual).to.be.a('number'); + + const expected = parseInt(actual, 10); + this.assert( + actual === expected, + 'expected #{this} to be an integer', + 'expected #{this} not to be an integer', + ); +}); + +[sinonChai].forEach(plugin => chai.use(plugin)); + +global.sandbox = sinon.createSandbox({ + useFakeTimers: true, +}); diff --git a/elements/lisk-transactions/test/base_transaction.ts b/elements/lisk-transactions/test/base_transaction.ts new file mode 100644 index 00000000000..8853a46a7f7 --- /dev/null +++ b/elements/lisk-transactions/test/base_transaction.ts @@ -0,0 +1,921 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { SinonStub } from 'sinon'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { BYTESIZES, MAX_TRANSACTION_AMOUNT } from '../src/constants'; +import { BaseTransaction, MultisignatureStatus } from '../src/base_transaction'; +import { TransactionJSON } from '../src/transaction_types'; +import { Status } from '../src/response'; +import { TransactionError, TransactionPendingError } from '../src/errors'; +import * as BigNum from '@liskhq/bignum'; +import { + addTransactionFields, + MockStateStore as store, + TestTransaction, +} from './helpers'; +import { + validAccount as defaultSenderAccount, + validMultisignatureAccount as defaultMultisignatureAccount, + validMultisignatureTransaction, + validTransaction, + validSecondSignatureTransaction, +} from '../fixtures'; +import * as utils from '../src/utils'; +import { TransferTransaction } from '../src'; +import { SignatureObject } from '../src/create_signature_object'; + +describe('Base transaction class', () => { + const defaultTransaction = addTransactionFields(validTransaction); + const defaultSecondSignatureTransaction = addTransactionFields( + validSecondSignatureTransaction, + ); + const defaultMultisignatureTransaction = addTransactionFields( + validMultisignatureTransaction, + ); + + let validTestTransaction: BaseTransaction; + let validSecondSignatureTestTransaction: BaseTransaction; + let validMultisignatureTestTransaction: BaseTransaction; + let storeAccountGetStub: sinon.SinonStub; + let storeAccountGetOrDefaultStub: sinon.SinonStub; + + beforeEach(async () => { + validTestTransaction = new TestTransaction(defaultTransaction); + validSecondSignatureTestTransaction = new TestTransaction( + defaultSecondSignatureTransaction, + ); + validMultisignatureTestTransaction = new TestTransaction( + defaultMultisignatureTransaction, + ); + storeAccountGetStub = sandbox + .stub(store.account, 'get') + .returns(defaultSenderAccount); + storeAccountGetOrDefaultStub = sandbox + .stub(store.account, 'getOrDefault') + .returns(defaultSenderAccount); + }); + + describe('#constructor', () => { + it('should create a new instance of BaseTransaction', async () => { + expect(validTestTransaction) + .to.be.an('object') + .and.be.instanceof(BaseTransaction); + }); + + it('should have amount of type BigNum', async () => { + expect(validTestTransaction) + .to.have.property('amount') + .and.be.instanceof(BigNum); + }); + + it('should have fee of type BigNum', async () => { + expect(validTestTransaction) + .to.have.property('fee') + .and.be.instanceof(BigNum); + }); + + it('should have id string', async () => { + expect(validTestTransaction) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have recipientId string', async () => { + expect(validTestTransaction) + .to.have.property('recipientId') + .and.be.a('string'); + }); + + it('should have recipientPublicKey string', async () => { + expect(validTestTransaction) + .to.have.property('recipientPublicKey') + .and.be.a('string'); + }); + + it('should have senderId string', async () => { + expect(validTestTransaction) + .to.have.property('senderId') + .and.be.a('string'); + }); + + it('should have senderPublicKey string', async () => { + expect(validTestTransaction) + .to.have.property('senderPublicKey') + .and.be.a('string'); + }); + + it('should have signature string', async () => { + expect(validTestTransaction) + .to.have.property('senderPublicKey') + .and.be.a('string'); + }); + + it('should have signSignature string', async () => { + expect(validTestTransaction) + .to.have.property('senderPublicKey') + .and.be.a('string'); + }); + + it('should have signatures array', async () => { + expect(validTestTransaction) + .to.have.property('signatures') + .and.be.a('array'); + }); + + it('should have timestamp number', async () => { + expect(validTestTransaction) + .to.have.property('timestamp') + .and.be.a('number'); + }); + + it('should have type number', async () => { + expect(validTestTransaction) + .to.have.property('type') + .and.be.a('number'); + }); + + it('should have receivedAt Date', async () => { + expect(validTestTransaction) + .to.have.property('receivedAt') + .and.be.instanceOf(Date); + }); + + it('should have _multisignatureStatus number', async () => { + expect(validTestTransaction) + .to.have.property('_multisignatureStatus') + .and.be.a('number'); + }); + + it('should not throw with undefined input', async () => { + expect(() => new TestTransaction(undefined as any)).not.to.throw(); + }); + + it('should not throw with null input', async () => { + expect(() => new TestTransaction(null as any)).not.to.throw(); + }); + + it('should not throw with string input', async () => { + expect(() => new TestTransaction('abc' as any)).not.to.throw(); + }); + + it('should not throw with number input', async () => { + expect(() => new TestTransaction(123 as any)).not.to.throw(); + }); + + it('should not throw with incorrectly typed transaction properties', async () => { + const invalidTransaction = { + ...defaultTransaction, + amount: 0, + fee: 10, + }; + expect( + () => + new TestTransaction( + (invalidTransaction as unknown) as TransactionJSON, + ), + ).not.to.throw(); + }); + }); + + describe('#assetToJSON', async () => { + it('should return an object of type transaction asset', async () => { + expect(validTestTransaction.assetToJSON()).to.be.an('object'); + }); + }); + + describe('#toJSON', () => { + it('should call assetToJSON', async () => { + const assetToJSONStub = sandbox + .stub(validTestTransaction, 'assetToJSON') + .returns({}); + validTestTransaction.toJSON(); + + expect(assetToJSONStub).to.be.calledOnce; + }); + + it('should return transaction json', async () => { + const transactionJSON = validTestTransaction.toJSON(); + + expect(transactionJSON).to.be.eql(defaultTransaction); + }); + }); + + describe('#assetToBytes', () => { + it('should return a buffer', async () => { + expect( + (validTestTransaction as TestTransaction).assetToBytes(), + ).to.be.an.instanceOf(Buffer); + }); + }); + + describe('#isReady', async () => { + it('should return false on initialization of unknown transaction', async () => { + expect(validTestTransaction.isReady()).to.be.false; + }); + + it('should return true on verification of non-multisignature transaction', async () => { + validTestTransaction.apply(store); + expect(validTestTransaction.isReady()).to.be.true; + }); + + it('should return false on verification of multisignature transaction with missing signatures', async () => { + storeAccountGetStub.returns(defaultMultisignatureAccount); + const multisignaturesTransaction = new TestTransaction({ + ...defaultMultisignatureTransaction, + signatures: defaultMultisignatureTransaction.signatures.slice(0, 2), + }); + multisignaturesTransaction.apply(store); + + expect(validMultisignatureTestTransaction.isReady()).to.be.false; + }); + }); + + describe('#getBasicBytes', () => { + it('should call cryptography hexToBuffer', async () => { + const cryptographyHexToBufferStub = sandbox + .stub(cryptography, 'hexToBuffer') + .returns( + Buffer.from( + '62b13b81836f3f1e371eba2f7f8306ff23d00a87d9473793eda7f742f4cfc21c', + 'hex', + ), + ); + (validTestTransaction as any).getBasicBytes(); + + expect(cryptographyHexToBufferStub).to.be.calledWithExactly( + defaultTransaction.senderPublicKey, + ); + }); + + it('should call cryptography bigNumberToBuffer for non-empty recipientId', async () => { + const cryptographyBigNumberToBufferStub = sandbox + .stub(cryptography, 'bigNumberToBuffer') + .returns( + Buffer.from(defaultTransaction.recipientId.slice(0, -1), 'hex'), + ); + (validTestTransaction as any).getBasicBytes(); + + expect(cryptographyBigNumberToBufferStub).to.be.calledWithExactly( + defaultTransaction.recipientId.slice(0, -1), + BYTESIZES.RECIPIENT_ID, + ); + }); + + it('should call assetToBytes for transaction with asset', async () => { + const transactionWithAsset = { + ...defaultTransaction, + asset: { data: 'data' }, + }; + const testTransactionWithAsset = new TestTransaction( + transactionWithAsset, + ); + const assetToBytesStub = sandbox + .stub(testTransactionWithAsset, 'assetToBytes') + .returns(Buffer.from('data')); + (testTransactionWithAsset as any).getBasicBytes(); + + expect(assetToBytesStub).to.be.calledOnce; + }); + + it('should return a buffer without signatures bytes', async () => { + const expectedBuffer = Buffer.from( + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b02000000', + 'hex', + ); + + expect((validTestTransaction as any).getBasicBytes()).to.eql( + expectedBuffer, + ); + }); + }); + + describe('#getBytes', () => { + it('should call getBasicBytes', async () => { + const getBasicBytesStub = sandbox + .stub(validTestTransaction as any, 'getBasicBytes') + .returns( + Buffer.from( + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b02000000', + 'hex', + ), + ); + validTestTransaction.getBytes(); + + expect(getBasicBytesStub).to.be.calledOnce; + }); + + it('should call cryptography hexToBuffer for transaction with signature', async () => { + const cryptographyHexToBufferStub = sandbox + .stub(cryptography, 'hexToBuffer') + .returns( + Buffer.from( + '2092abc5dd72d42b289f69ddfa85d0145d0bfc19a0415be4496c189e5fdd5eff02f57849f484192b7d34b1671c17e5c22ce76479b411cad83681132f53d7b309', + 'hex', + ), + ); + validTestTransaction.getBytes(); + + expect(cryptographyHexToBufferStub.secondCall).to.have.been.calledWith( + validTestTransaction.signature, + ); + }); + + it('should call cryptography hexToBuffer for transaction with signSignature', async () => { + const cryptographyHexToBufferStub = sandbox + .stub(cryptography, 'hexToBuffer') + .returns( + Buffer.from( + '2092abc5dd72d42b289f69ddfa85d0145d0bfc19a0415be4496c189e5fdd5eff02f57849f484192b7d34b1671c17e5c22ce76479b411cad83681132f53d7b309', + 'hex', + ), + ); + validSecondSignatureTestTransaction.getBytes(); + + expect(cryptographyHexToBufferStub.thirdCall).to.have.been.calledWith( + validSecondSignatureTestTransaction.signSignature, + ); + }); + + it('should return a buffer with signature bytes', async () => { + const expectedBuffer = Buffer.from( + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b020000002092abc5dd72d42b289f69ddfa85d0145d0bfc19a0415be4496c189e5fdd5eff02f57849f484192b7d34b1671c17e5c22ce76479b411cad83681132f53d7b309', + 'hex', + ); + + expect(validTestTransaction.getBytes()).to.eql(expectedBuffer); + }); + + it('should return a buffer with signSignature bytes', async () => { + const expectedBuffer = Buffer.from( + '004529cf04bc10685b802c8dd127e5d78faadc9fad1903f09d562fdcf632462408d4ba52e8b95af897b7e23cb900e40b54020000003357658f70b9bece24bd42769b984b3e7b9be0b2982f82e6eef7ffbd841598d5868acd45f8b1e2f8ab5ccc8c47a245fe9d8e3dc32fc311a13cc95cc851337e0111f77b8596df14400f5dd5cf9ef9bd2a20f66a48863455a163cabc0c220ea235d8b98dec684bd86f62b312615e7f64b23d7b8699775e7c15dad0aef0abd4f503', + 'hex', + ); + + expect(validSecondSignatureTestTransaction.getBytes()).to.eql( + expectedBuffer, + ); + }); + + it('should take first 8 bytes when recipientId exceeds 8 bytes buffer', async () => { + const rawTransaction = { + id: '393955899193580559', + type: 0, + timestamp: 33817764, + senderPublicKey: + 'fe8f1a47180e7f318cb162b06470fbe259bc1d9d5359a8792cda3f087e49f72b', + recipientPublicKey: '', + senderId: '9961131544040416558L', + recipientId: '19961131544040416558L', + amount: '100000000', + fee: '10000000', + signature: + '02a806771711ecb9ffa676d8f6c85c5ffb87398cddbd0d55ae6c1e83f0e8e74c50490979e85633715b66d42090e9b37af918b1f823d706e900f5e2b72f876408', + signatures: [], + asset: {}, + }; + const tx = new TestTransaction(rawTransaction); + // 37 Bytes from 45 bytes corresponds to recipientId + expect(tx.getBytes().slice(37, 45)).to.eql( + new BigNum('1').toBuffer({ size: 8, endian: 'big' }), + ); + }); + }); + + describe('_validateSchema', () => { + it('should call toJSON', async () => { + const toJSONStub = sandbox + .stub(validTestTransaction, 'toJSON') + .returns({} as any); + (validTestTransaction as any)._validateSchema(); + + expect(toJSONStub).to.be.calledOnce; + }); + + it('should call cryptography getAddressFromPublicKey for transaction with valid senderPublicKey', async () => { + sandbox + .stub(cryptography, 'getAddressFromPublicKey') + .returns('18278674964748191682L'); + (validTestTransaction as any)._validateSchema(); + + expect( + cryptography.getAddressFromPublicKey, + ).to.have.been.calledWithExactly(validTestTransaction.senderPublicKey); + }); + + it('should return a successful transaction response with a valid transaction', async () => { + const errors = (validTestTransaction as any)._validateSchema(); + expect(errors).to.be.empty; + }); + + it('should return a failed transaction response with invalid formatting', async () => { + const invalidTransaction = { + type: 0, + amount: '00001', + fee: '0000', + recipientId: '', + senderPublicKey: '11111111', + senderId: '11111111', + timestamp: 79289378, + asset: {}, + signature: '1111111111', + id: '1', + }; + const invalidTestTransaction = new TestTransaction( + invalidTransaction as any, + ); + const errors = (invalidTestTransaction as any)._validateSchema(); + + expect(errors).to.not.be.empty; + }); + + it('should return a failed transaction response with unmatching senderId and senderPublicKey', async () => { + const invalidSenderIdTransaction = { + ...defaultTransaction, + senderId: defaultTransaction.senderId.replace('1', '0'), + }; + const invalidSenderIdTestTransaction = new TestTransaction( + invalidSenderIdTransaction as any, + ); + const errors = (invalidSenderIdTestTransaction as any)._validateSchema(); + + expect(errors).to.not.be.empty; + }); + }); + + describe('#validate', () => { + it('should return a successful transaction response with a valid transaction', async () => { + const { id, status, errors } = validTestTransaction.validate(); + + expect(id).to.be.eql(validTestTransaction.id); + expect(errors).to.be.empty; + expect(status).to.eql(Status.OK); + }); + + it('should call getBasicBytes', async () => { + const getBasicBytesStub = sandbox + .stub(validTestTransaction as any, 'getBasicBytes') + .returns( + Buffer.from( + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b02000000', + 'hex', + ), + ); + validTestTransaction.validate(); + + expect(getBasicBytesStub).to.be.calledTwice; + }); + + it('should call validateSignature', async () => { + sandbox.stub(utils, 'validateSignature').returns({ valid: true }); + validTestTransaction.validate(); + + expect(utils.validateSignature).to.be.calledWithExactly( + validTestTransaction.senderPublicKey, + validTestTransaction.signature, + Buffer.from( + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b02000000', + 'hex', + ), + validTestTransaction.id, + ); + }); + + it('should return a failed transaction response with invalid signature', async () => { + const invalidSignature = defaultTransaction.signature.replace('1', '0'); + const invalidSignatureTransaction = { + ...defaultTransaction, + signature: invalidSignature, + }; + const invalidSignatureTestTransaction = new TestTransaction( + invalidSignatureTransaction as any, + ); + sandbox + .stub(invalidSignatureTestTransaction as any, '_validateSchema') + .returns([]); + const { id, status, errors } = invalidSignatureTestTransaction.validate(); + + expect(id).to.be.eql(invalidSignatureTestTransaction.id); + expect((errors as ReadonlyArray)[0]) + .to.be.instanceof(TransactionError) + .and.to.have.property( + 'message', + `Failed to validate signature ${invalidSignature}`, + ); + expect(status).to.eql(Status.FAIL); + }); + + it('should return a failed transaction response with duplicate signatures', async () => { + const invalidSignaturesTransaction = { + ...defaultTransaction, + signatures: [ + defaultTransaction.signature, + defaultTransaction.signature, + ], + }; + const invalidSignaturesTestTransaction = new TestTransaction( + invalidSignaturesTransaction as any, + ); + const { + id, + status, + errors, + } = invalidSignaturesTestTransaction.validate(); + + expect(id).to.be.eql(invalidSignaturesTestTransaction.id); + expect((errors as ReadonlyArray)[0]) + .to.be.instanceof(TransactionError) + .and.to.have.property('dataPath', '.signatures'); + expect(status).to.eql(Status.FAIL); + }); + }); + + describe('#verifyAgainstOtherTransactions', () => { + it('should return a transaction response', async () => { + const otherTransactions = [defaultTransaction, defaultTransaction]; + const { + id, + status, + errors, + } = validTestTransaction.verifyAgainstOtherTransactions( + otherTransactions, + ); + expect(id).to.be.eql(validTestTransaction.id); + expect(errors).to.be.empty; + expect(status).to.eql(Status.OK); + }); + }); + + describe('#processMultisignatures', () => { + it('should return a successful transaction response with valid signatures', async () => { + sandbox.stub(utils, 'verifyMultiSignatures').returns({ + status: MultisignatureStatus.READY, + errors: [], + }); + const { + id, + status, + errors, + } = validMultisignatureTestTransaction.processMultisignatures(store); + + expect(id).to.be.eql(validMultisignatureTestTransaction.id); + expect(errors).to.be.eql([]); + expect(status).to.eql(Status.OK); + }); + + it('should return a pending transaction response with missing signatures', async () => { + const pendingErrors = [ + new TransactionPendingError( + `Missing signatures`, + validMultisignatureTestTransaction.id, + '.signatures', + ), + ]; + sandbox.stub(utils, 'verifyMultiSignatures').returns({ + status: MultisignatureStatus.PENDING, + errors: pendingErrors, + }); + const { + id, + status, + errors, + } = validMultisignatureTestTransaction.processMultisignatures(store); + + expect(id).to.be.eql(validMultisignatureTestTransaction.id); + expect(errors).to.be.eql(pendingErrors); + expect(status).to.eql(Status.PENDING); + }); + }); + + describe('#addVerifiedMultisignature', () => { + it('should return a successful transaction response if no duplicate signatures', async () => { + const { + id, + status, + errors, + } = validMultisignatureTestTransaction.addVerifiedMultisignature( + '3df1fae6865ec72783dcb5f87a7d906fe20b71e66ad9613c01a89505ebd77279e67efa2c10b5ad880abd09efd27ea350dd8a094f44efa3b4b2c8785fbe0f7e00', + ); + + expect(id).to.be.eql(validMultisignatureTestTransaction.id); + expect(errors).to.be.eql([]); + expect(status).to.eql(Status.OK); + }); + + it('should return a failed transaction response if duplicate signatures', async () => { + const { + id, + status, + errors, + } = validMultisignatureTestTransaction.addVerifiedMultisignature( + 'f223799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c', + ); + + expect(id).to.be.eql(validMultisignatureTestTransaction.id); + expect(status).to.eql(Status.FAIL); + (errors as ReadonlyArray).forEach(error => + expect(error) + .to.be.instanceof(TransactionError) + .and.to.have.property('message', 'Failed to add signature.'), + ); + }); + }); + + describe('#addMultisignature', () => { + let transferFromMultiSigAccountTrs: TransferTransaction; + let multisigMember: SignatureObject; + beforeEach(async () => { + storeAccountGetStub.returns(defaultMultisignatureAccount); + const { signatures, ...rawTrs } = validMultisignatureTransaction; + transferFromMultiSigAccountTrs = new TransferTransaction(rawTrs); + multisigMember = { + transactionId: transferFromMultiSigAccountTrs.id, + publicKey: + '542fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + signature: + 'f223799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c', + }; + }); + + it('should add signature to transaction from multisig account', async () => { + const { + status, + errors, + } = transferFromMultiSigAccountTrs.addMultisignature( + store, + multisigMember, + ); + + expect(status).to.eql(Status.PENDING); + expect(errors[0]).to.be.instanceof(TransactionPendingError); + expect(transferFromMultiSigAccountTrs.signatures).to.include( + multisigMember.signature, + ); + }); + + it('should fail when valid signature already present and sent again', async () => { + const { + status: arrangeStatus, + } = transferFromMultiSigAccountTrs.addMultisignature( + store, + multisigMember, + ); + + expect(arrangeStatus).to.eql(Status.PENDING); + + const { + status, + errors, + } = transferFromMultiSigAccountTrs.addMultisignature( + store, + multisigMember, + ); + const expectedError = + "Signature 'f223799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c' already present in transaction."; + + expect(status).to.eql(Status.FAIL); + expect(errors[0].message).to.be.eql(expectedError); + expect(transferFromMultiSigAccountTrs.signatures).to.include( + multisigMember.signature, + ); + }); + + it('should fail to add invalid signature to transaction from multisig account', () => { + storeAccountGetStub.returns(defaultMultisignatureAccount); + const { signatures, ...rawTrs } = validMultisignatureTransaction; + const transferFromMultiSigAccountTrs = new TransferTransaction(rawTrs); + const multisigMember = { + transactionId: transferFromMultiSigAccountTrs.id, + publicKey: + '542fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33cf', + signature: + 'eeee799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c', + }; + + const { + status, + errors, + } = transferFromMultiSigAccountTrs.addMultisignature( + store, + multisigMember, + ); + + const expectedError = + "Failed to add signature 'eeee799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c'."; + + expect(status).to.eql(Status.FAIL); + expect(errors[0].message).to.be.eql(expectedError); + expect(transferFromMultiSigAccountTrs.signatures).to.be.empty; + }); + + it('should fail with signature not part of the group', () => { + storeAccountGetStub.returns(defaultMultisignatureAccount); + const { signatures, ...rawTrs } = validMultisignatureTransaction; + const transferFromMultiSigAccountTrs = new TransferTransaction(rawTrs); + const multisigMember = { + transactionId: transferFromMultiSigAccountTrs.id, + publicKey: + '542fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33c2', + signature: + 'eeee799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c', + }; + + const { + status, + errors, + } = transferFromMultiSigAccountTrs.addMultisignature( + store, + multisigMember, + ); + + const expectedError = + "Public Key '542fdc008964eacc580089271353268d655ab5ec2829687aadc278653fad33c2' is not a member for account '9999142599245349337L'."; + + expect(status).to.eql(Status.FAIL); + expect(errors[0].message).to.be.eql(expectedError); + expect(transferFromMultiSigAccountTrs.signatures).to.be.empty; + }); + }); + + describe('#apply', () => { + it('should return a successful transaction response with an updated sender account', async () => { + store.account.getOrDefault = () => defaultSenderAccount; + const { id, status, errors } = validTestTransaction.apply(store); + expect(id).to.be.eql(validTestTransaction.id); + expect(status).to.eql(Status.OK); + expect(errors).to.be.empty; + }); + + it('should return a failed transaction response with insufficient account balance', async () => { + storeAccountGetOrDefaultStub.returns({ + ...defaultSenderAccount, + balance: '0', + }); + const { id, status, errors } = validTestTransaction.apply(store); + + expect(id).to.be.eql(validTestTransaction.id); + expect(status).to.eql(Status.FAIL); + expect((errors as ReadonlyArray)[0]) + .to.be.instanceof(TransactionError) + .and.to.have.property( + 'message', + `Account does not have enough LSK: ${ + defaultSenderAccount.address + }, balance: 0`, + ); + }); + }); + + describe('#undo', () => { + it('should return a successful transaction response with an updated sender account', async () => { + const { id, status, errors } = validTestTransaction.undo(store); + expect(id).to.be.eql(validTestTransaction.id); + expect(status).to.eql(Status.OK); + expect(errors).to.be.eql([]); + }); + + it('should return a failed transaction response with account balance exceeding max amount', async () => { + storeAccountGetOrDefaultStub.returns({ + ...defaultSenderAccount, + balance: MAX_TRANSACTION_AMOUNT.toString(), + }); + const { id, status, errors } = validTestTransaction.undo(store); + expect(id).to.be.eql(validTestTransaction.id); + expect(status).to.eql(Status.FAIL); + expect((errors as ReadonlyArray)[0]) + .to.be.instanceof(TransactionError) + .and.to.have.property('message', 'Invalid balance amount'); + }); + }); + + describe('#isExpired', () => { + let unexpiredTestTransaction: BaseTransaction; + let expiredTestTransaction: BaseTransaction; + beforeEach(async () => { + const unexpiredTransaction = { + ...defaultTransaction, + receivedAt: new Date().toISOString(), + }; + const expiredTransaction = { + ...defaultTransaction, + receivedAt: new Date(+new Date() - 1300 * 60000).toISOString(), + }; + unexpiredTestTransaction = new TestTransaction(unexpiredTransaction); + expiredTestTransaction = new TestTransaction(expiredTransaction); + }); + + it('should return false for unexpired transaction', async () => { + expect(unexpiredTestTransaction.isExpired()).to.be.false; + }); + + it('should return true for expired transaction', async () => { + expect(expiredTestTransaction.isExpired(new Date())).to.be.true; + }); + }); + + describe('#sign', () => { + const defaultPassphrase = 'passphrase'; + const defaultSecondPassphrase = 'second-passphrase'; + const defaultHash = Buffer.from( + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b02111111', + 'hex', + ); + const defaultSecondHash = Buffer.from( + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b02000000', + 'hex', + ); + const defaultSignature = + 'dc8fe25f817c81572585b3769f3c6df13d3dc93ff470b2abe807f43a3359ed94e9406d2539013971431f2d540e42dc7d3d71c7442da28572c827d59adc5dfa08'; + const defaultSecondSignature = + '2092abc5dd72d42b289f69ddfa85d0145d0bfc19a0415be4496c189e5fdd5eff02f57849f484192b7d34b1671c17e5c22ce76479b411cad83681132f53d7b309'; + + let signDataStub: SinonStub; + + beforeEach(async () => { + const hashStub = sandbox + .stub(cryptography, 'hash') + .onFirstCall() + .returns(defaultHash) + .onSecondCall() + .returns(defaultSecondHash); + hashStub.returns(defaultHash); + signDataStub = sandbox + .stub(cryptography, 'signData') + .onFirstCall() + .returns(defaultSignature) + .onSecondCall() + .returns(defaultSecondSignature); + }); + + describe('when sign is called with passphrase', () => { + beforeEach(async () => { + validTestTransaction.sign(defaultPassphrase); + }); + + it('should set signature property', async () => { + expect(validTestTransaction.signature).to.equal(defaultSignature); + }); + + it('should not set signSignature property', async () => { + expect(validTestTransaction.signSignature).to.be.undefined; + }); + + it('should set id property', async () => { + expect(validTestTransaction.id).not.to.be.empty; + }); + + it('should call signData with the hash result and the passphrase', async () => { + expect(signDataStub).to.be.calledWithExactly( + defaultHash, + defaultPassphrase, + ); + }); + }); + + describe('when sign is called with passphrase and second passphrase', () => { + beforeEach(async () => { + validTestTransaction.sign(defaultPassphrase, defaultSecondPassphrase); + }); + + it('should set signature property', async () => { + expect(validTestTransaction.signature).to.equal(defaultSignature); + }); + + it('should set signSignature property', async () => { + expect(validTestTransaction.signSignature).to.equal( + defaultSecondSignature, + ); + }); + + it('should set id property', async () => { + expect(validTestTransaction.id).not.to.be.empty; + }); + + it('should call signData with the hash result and the passphrase', async () => { + expect(signDataStub).to.be.calledWithExactly( + defaultHash, + defaultPassphrase, + ); + }); + + it('should call signData with the hash result and the passphrase', async () => { + expect(signDataStub).to.be.calledWithExactly( + defaultSecondHash, + defaultSecondPassphrase, + ); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/constants.ts b/elements/lisk-transactions/test/constants.ts new file mode 100644 index 00000000000..af09c1930e8 --- /dev/null +++ b/elements/lisk-transactions/test/constants.ts @@ -0,0 +1,97 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + FIXED_POINT, + DAPP_FEE, + DELEGATE_FEE, + IN_TRANSFER_FEE, + OUT_TRANSFER_FEE, + MULTISIGNATURE_FEE, + SIGNATURE_FEE, + TRANSFER_FEE, + VOTE_FEE, + BYTESIZES, +} from '../src/constants'; + +describe('transactions constants module', () => { + it('FIXED_POINT to be an integer', () => { + return expect(FIXED_POINT).to.be.an.integer; + }); + + it('DAPP_FEE to be an integer', () => { + return expect(DAPP_FEE).to.be.an.integer; + }); + + it('DELEGATE_FEE to be an integer', () => { + return expect(DELEGATE_FEE).to.be.an.integer; + }); + + it('IN_TRANSFER_FEE to be an integer', () => { + return expect(IN_TRANSFER_FEE).to.be.an.integer; + }); + + it('OUT_TRANSFER_FEE to be an integer', () => { + return expect(OUT_TRANSFER_FEE).to.be.an.integer; + }); + + it('MULTISIGNATURE_FEE to be an integer', () => { + return expect(MULTISIGNATURE_FEE).to.be.an.integer; + }); + + it('SIGNATURE_FEE to be an integer', () => { + return expect(SIGNATURE_FEE).to.be.an.integer; + }); + + it('TRANSFER_FEE to be an integer', () => { + return expect(TRANSFER_FEE).to.be.an.integer; + }); + + it('VOTE_FEE to be an integer', () => { + return expect(VOTE_FEE).to.be.an.integer; + }); + + it('BYTESIZES.TYPE to be an integer', () => { + return expect(BYTESIZES.TYPE).to.be.an.integer; + }); + + it('BYTESIZES.TIMESTAMP to be an integer', () => { + return expect(BYTESIZES.TIMESTAMP).to.be.an.integer; + }); + + it('BYTESIZES.MULTISIGNATURE_PUBLICKEY to be an integer', () => { + return expect(BYTESIZES.MULTISIGNATURE_PUBLICKEY).to.be.an.integer; + }); + + it('BYTESIZES.RECIPIENT_ID to be an integer', () => { + return expect(BYTESIZES.RECIPIENT_ID).to.be.an.integer; + }); + + it('BYTESIZES.AMOUNT to be an integer', () => { + return expect(BYTESIZES.AMOUNT).to.be.an.integer; + }); + + it('BYTESIZES.SIGNATURE_TRANSACTION to be an integer', () => { + return expect(BYTESIZES.SIGNATURE_TRANSACTION).to.be.an.integer; + }); + + it('BYTESIZES.SECOND_SIGNATURE_TRANSACTION to be an integer', () => { + return expect(BYTESIZES.SECOND_SIGNATURE_TRANSACTION).to.be.an.integer; + }); + + it('BYTESIZES.DATA to be an integer', () => { + return expect(BYTESIZES.DATA).to.be.an.integer; + }); +}); diff --git a/elements/lisk-transactions/test/create_signature_object.ts b/elements/lisk-transactions/test/create_signature_object.ts new file mode 100644 index 00000000000..a48877f5091 --- /dev/null +++ b/elements/lisk-transactions/test/create_signature_object.ts @@ -0,0 +1,127 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + createSignatureObject, + SignatureObject, +} from '../src/create_signature_object'; +import { TransactionJSON } from '../src/transaction_types'; + +describe('#createSignatureObject', () => { + const transaction = { + amount: '10', + recipientId: '8050281191221330746L', + senderId: '1050281191221330746L', + senderPublicKey: + '3358a1562f9babd523a768e700bb12ad58f230f84031055802dc0ea58cef1e1b', + timestamp: 59353522, + type: 0, + fee: '10000000', + recipientPublicKey: + '3358a1562f9babd523a768e700bb12ad58f230f84031055802dc0ea58cef1e1b', + asset: {}, + signature: + 'b84b95087c381ad25b5701096e2d9366ffd04037dcc941cd0747bfb0cf93111834a6c662f149018be4587e6fc4c9f5ba47aa5bbbd3dd836988f153aa8258e604', + id: '3694188453012384790', + }; + const account = { + passphrase: + 'love road panic horn cover grape nerve mechanic slice relax mobile salon', + publicKey: + '87696cfc48f5f5bd4ec2473615ac1618ffedfdc20005ae71a3d0dba209471c04', + }; + const generatedSignature = + '8222dc7c26cc0ed649af71ebef5d292deb6ad029dadec0cf061b40e2ea9572d1b691e92302ac8cb64e5ea5f8fd846410c8fa033236c8930203ae3b7f3c6bd30c'; + + describe('when invalid transaction is used', () => { + it("should throw an Error when id doesn't exist", () => { + const { id, ...mutatedTransaction } = transaction; + return expect( + createSignatureObject.bind( + null, + mutatedTransaction as TransactionJSON, + account.passphrase, + ), + ).to.throw('Transaction ID is required to create a signature object.'); + }); + it('should throw an Error when sender public key is mutated', () => { + const mutatedTransaction = { + ...transaction, + senderPublicKey: + '3358a1562f9babd523a768e700bb12ad58f230f84031055802dc0ea58cef1000', + }; + return expect( + createSignatureObject.bind( + null, + mutatedTransaction, + account.passphrase, + ), + ).to.throw('Invalid transaction.'); + }); + + it('should throw an Error when signature is mutated', () => { + const mutatedTransaction = { + ...transaction, + signature: + 'b84b95087c381ad25b5701096e2d9366ffd04037dcc941cd0747bfb0cf93111834a6c662f149018be4587e6fc4c9f5ba47aa5bbbd3dd836988f153aa8258e600', + }; + return expect( + createSignatureObject.bind( + null, + mutatedTransaction, + account.passphrase, + ), + ).to.throw('Invalid transaction.'); + }); + }); + + describe('when valid transaction and invalid passphrase is used', () => { + it('should throw an Error if passphrase is number', () => { + const passphrase = 1; + return expect( + createSignatureObject.bind( + null, + transaction, + (passphrase as unknown) as string, + ), + ).to.throw( + 'Unsupported data format. Currently only Buffers or `hex` and `utf8` strings are supported.', + ); + }); + }); + + describe('when valid transaction and passphrase is used', () => { + let signatureObject: SignatureObject; + beforeEach(() => { + signatureObject = createSignatureObject( + transaction as TransactionJSON, + account.passphrase, + ); + return Promise.resolve(); + }); + + it('should have the same transaction id as the input', () => { + return expect(signatureObject.transactionId).to.equal(transaction.id); + }); + + it('should have the corresponding public key with the passphrase', () => { + return expect(signatureObject.publicKey).to.equal(account.publicKey); + }); + + it('should have non-empty hex string signature', () => { + return expect(signatureObject.signature).to.equal(generatedSignature); + }); + }); +}); diff --git a/elements/lisk-transactions/test/errors.ts b/elements/lisk-transactions/test/errors.ts new file mode 100644 index 00000000000..f138caa179e --- /dev/null +++ b/elements/lisk-transactions/test/errors.ts @@ -0,0 +1,61 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { VError } from 'verror'; +import { TransactionError } from '../src/errors'; + +describe('errors', () => { + describe('TransactionError', () => { + let TxError: TransactionError; + + describe('#constructor', () => { + beforeEach(() => { + TxError = new TransactionError( + 'error message', + 'transaction id', + '.dataPath', + ); + }); + + it('should create a new instance of TransactionError', () => { + return expect(TxError) + .to.be.an('object') + .and.be.instanceof(TransactionError) + .and.be.instanceof(VError); + }); + + it('should have a `message` string', () => { + expect(TxError.message).to.eql('error message'); + return expect(TxError) + .to.have.property('message') + .and.be.a('string'); + }); + + it('should have a `id` string', () => { + expect(TxError.id).to.eql('transaction id'); + return expect(TxError) + .to.have.property('id') + .and.be.a('string'); + }); + + it('should have a `dataPath` string', () => { + expect(TxError.dataPath).to.eql('.dataPath'); + return expect(TxError) + .to.have.property('dataPath') + .and.be.a('string'); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/helpers/add_transaction_fields.ts b/elements/lisk-transactions/test/helpers/add_transaction_fields.ts new file mode 100644 index 00000000000..28ea5066150 --- /dev/null +++ b/elements/lisk-transactions/test/helpers/add_transaction_fields.ts @@ -0,0 +1,24 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +export const addTransactionFields = (transaction: any) => { + return { + ...transaction, + signSignature: transaction.signSignature + ? transaction.signSignature + : undefined, + receivedAt: new Date().toISOString(), + signatures: [...transaction.signatures], + }; +}; diff --git a/elements/lisk-transactions/test/helpers/cryptography.ts b/elements/lisk-transactions/test/helpers/cryptography.ts new file mode 100644 index 00000000000..9e6c572e28f --- /dev/null +++ b/elements/lisk-transactions/test/helpers/cryptography.ts @@ -0,0 +1,25 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { getAddressAndPublicKeyFromPassphrase } from '@liskhq/lisk-cryptography'; + +export const generateRandomPublicKeys = ( + amount: number = 1, +): ReadonlyArray => + new Array(amount).fill(0).map(_ => { + const { publicKey } = getAddressAndPublicKeyFromPassphrase( + Math.random().toString(16), + ); + return publicKey; + }); diff --git a/elements/lisk-transactions/test/helpers/index.ts b/elements/lisk-transactions/test/helpers/index.ts new file mode 100644 index 00000000000..ab30acd9443 --- /dev/null +++ b/elements/lisk-transactions/test/helpers/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { addTransactionFields } from './add_transaction_fields'; +import { TestTransaction } from './test_transaction_class'; +import { MockStateStore } from './state_store'; +export { addTransactionFields, MockStateStore, TestTransaction }; diff --git a/elements/lisk-transactions/test/helpers/state_store.ts b/elements/lisk-transactions/test/helpers/state_store.ts new file mode 100644 index 00000000000..0cb9c151762 --- /dev/null +++ b/elements/lisk-transactions/test/helpers/state_store.ts @@ -0,0 +1,38 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const getter = { + get: () => {}, + find: () => [], + cache: () => {} +}; + +const setter = { + get: () => {}, + getOrDefault: () => {}, + set: () => { + return; + }, + find: () => [], + cache: () => {} +}; + +export const MockStateStore: any = { + account: { + ...setter, + }, + transaction: { + ...getter, + }, +}; diff --git a/elements/lisk-transactions/test/helpers/test_transaction_class.ts b/elements/lisk-transactions/test/helpers/test_transaction_class.ts new file mode 100644 index 00000000000..2c8d475f7cc --- /dev/null +++ b/elements/lisk-transactions/test/helpers/test_transaction_class.ts @@ -0,0 +1,51 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { BaseTransaction } from '../../src/base_transaction'; +import { TransactionJSON } from '../../src/transaction_types'; +import { TransactionError } from '../../src/errors'; + +export class TestTransaction extends BaseTransaction { + public assetToJSON(): object { + return {}; + } + + public async prepare() { + return; + } + + public assetToBytes(): Buffer { + return Buffer.alloc(0); + } + + public validateAsset() { + return []; + } + + public applyAsset() { + return []; + } + + public undoAsset() { + return []; + } + + public verifyAgainstTransactions( + transactions: ReadonlyArray, + ): ReadonlyArray { + transactions.forEach(() => true); + + return []; + } +} diff --git a/elements/lisk-transactions/test/index.ts b/elements/lisk-transactions/test/index.ts new file mode 100644 index 00000000000..816ebd80398 --- /dev/null +++ b/elements/lisk-transactions/test/index.ts @@ -0,0 +1,50 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as transaction from '../src'; + +describe('transaction', () => { + describe('exports', () => { + it('should have #transfer', () => { + return expect(transaction) + .to.have.property('transfer') + .and.be.a('function'); + }); + + it('should have #registerMultisignature', () => { + return expect(transaction) + .to.have.property('registerMultisignature') + .and.be.a('function'); + }); + + it('should have #createSignatureObject', () => { + return expect(transaction) + .to.have.property('createSignatureObject') + .and.be.a('function'); + }); + + it('should have #utils', () => { + return expect(transaction) + .to.have.property('utils') + .and.be.an('object'); + }); + + it('should have #constants', () => { + return expect(transaction) + .to.have.property('constants') + .and.be.an('object'); + }); + }); +}); diff --git a/elements/lisk-transactions/test/mocha.opts b/elements/lisk-transactions/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-transactions/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/test/tsconfig.json b/elements/lisk-transactions/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-transactions/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/test/tslint.json b/elements/lisk-transactions/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-transactions/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/test/utils/format.ts b/elements/lisk-transactions/test/utils/format.ts new file mode 100644 index 00000000000..46fbfd71f82 --- /dev/null +++ b/elements/lisk-transactions/test/utils/format.ts @@ -0,0 +1,129 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + convertBeddowsToLSK, + convertLSKToBeddows, + prependPlusToPublicKeys, + prependMinusToPublicKeys, +} from '../../src/utils/format'; + +describe('format', () => { + describe('#convertBeddowsToLSK', () => { + it('should error if not given a string', () => { + return expect(convertBeddowsToLSK.bind(null, 12345678 as any)).to.throw( + 'Cannot convert non-string amount', + ); + }); + it('should error on 0.1', () => { + return expect(convertBeddowsToLSK.bind(null, '0.1')).to.throw( + 'Beddows amount should not have decimal points', + ); + }); + it('should error on 9223372036854775808', () => { + return expect( + convertBeddowsToLSK.bind(null, '9223372036854775808'), + ).to.throw('Beddows amount out of range'); + }); + it('should convert 100000000 to 1', () => { + return expect(convertBeddowsToLSK('100000000')).to.equal('1'); + }); + it('should convert 1 to 0.00000001', () => { + return expect(convertBeddowsToLSK('1')).to.equal('0.00000001'); + }); + it('should convert 10000000000000000 to 100000000', () => { + return expect(convertBeddowsToLSK('10000000000000000')).to.equal( + '100000000', + ); + }); + it('should convert 9223372036854775807 to 92233720368.54775807', () => { + return expect(convertBeddowsToLSK('9223372036854775807')).to.equal( + '92233720368.54775807', + ); + }); + }); + describe('#convertLSKToBeddows', () => { + it('should error if not given a string', () => { + return expect(convertLSKToBeddows.bind(null, 12345678 as any)).to.throw( + 'Cannot convert non-string amount', + ); + }); + it('should error on 0.000000001', () => { + return expect(convertLSKToBeddows.bind(null, '0.000000001')).to.throw( + 'LSK amount has too many decimal points', + ); + }); + it('should error on 92233720368.54775808', () => { + return expect( + convertLSKToBeddows.bind(null, '92233720368.54775808'), + ).to.throw('LSK amount out of range'); + }); + it('should convert 1 to 100000000', () => { + return expect(convertLSKToBeddows('1')).to.equal('100000000'); + }); + it('should convert 0.00000001 to 1', () => { + return expect(convertLSKToBeddows('0.00000001')).to.equal('1'); + }); + it('should convert 100000000 to 10000000000000000', () => { + return expect(convertLSKToBeddows('100000000')).to.equal( + '10000000000000000', + ); + }); + it('should convert 92233720368.54775807 to 9223372036854775807', () => { + return expect(convertLSKToBeddows('92233720368.54775807')).to.equal( + '9223372036854775807', + ); + }); + }); + describe('#prependPlusToPublicKeys', () => { + describe('Given an array of public keys', () => { + it('should append plus to each public key', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + const expectedOutput = [ + '+215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '+922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '+5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + return expect(prependPlusToPublicKeys(publicKeys)).to.be.eql( + expectedOutput, + ); + }); + }); + }); + + describe('#prependMinusToPublicKeys', () => { + describe('Given an array of public keys', () => { + it('should append minus to each public key', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + const expectedOutput = [ + '-215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '-922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '-5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + return expect(prependMinusToPublicKeys(publicKeys)).to.be.eql( + expectedOutput, + ); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/get_transaction_bytes.ts b/elements/lisk-transactions/test/utils/get_transaction_bytes.ts new file mode 100644 index 00000000000..697383e2989 --- /dev/null +++ b/elements/lisk-transactions/test/utils/get_transaction_bytes.ts @@ -0,0 +1,835 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { expect } from 'chai'; +import { + getTransactionBytes, + getAssetDataForTransferTransaction, + getAssetDataForRegisterSecondSignatureTransaction, + getAssetDataForRegisterDelegateTransaction, + getAssetDataForCastVotesTransaction, + getAssetDataForRegisterMultisignatureAccountTransaction, + getAssetDataForCreateDappTransaction, + getAssetDataForTransferIntoDappTransaction, + getAssetDataForTransferOutOfDappTransaction, + checkTransaction, + checkRequiredFields, + isValidValue, +} from '../../src/utils/get_transaction_bytes'; +import { TransactionJSON } from '../../src/transaction_types'; +import { MultiSignatureAsset } from '../../src/4_multisignature_transaction'; + +const fixedPoint = 10 ** 8; +const defaultRecipient = '58191285901858109L'; +const defaultSenderPublicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; +const defaultSenderId = '18160565574430594874L'; +const defaultSenderSecondPublicKey = + '0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f'; +const defaultRecipientPublicKey = + '0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82z'; +// Use (1<<62) + 3 to ensure the highest and the lowest bytes are set and contain different data. +// This exceeds the safe integer range of JavaScript numbers and thus is expressed as a string. +const defaultAmount = '10000000000000000'; +const defaultNoAmount = '0'; +const defaultTimestamp = 141738; +const defaultTransactionId = '13987348420913138422'; +const defaultSignature = + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a'; +const defaultSecondSignature = + 'b00c4ad1988bca245d74435660a278bfe6bf2f5efa8bda96d927fabf8b4f6fcfdcb2953f6abacaa119d6880987a55dea0e6354bc8366052b45fa23145522020f'; +const defaultAppId = '1234213'; +const defaultDelegateUsername = 'MyDelegateUsername'; + +describe('getTransactionBytes module', () => { + describe('#getTransactionBytes', () => { + describe('transfer transaction, type 0', () => { + let defaultTransaction: TransactionJSON; + + beforeEach(() => { + defaultTransaction = { + type: 0, + fee: (0.1 * fixedPoint).toString(), + amount: defaultAmount, + recipientId: defaultRecipient, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: {}, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + return Promise.resolve(); + }); + + it('should return Buffer of type 0 (transfer LSK) transaction', () => { + const expectedBuffer = Buffer.from( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d0000c16ff2862300618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(defaultTransaction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + + it('should return Buffer of type 0 (transfer LSK) with data', () => { + const transferTransaction: TransactionJSON = { + ...defaultTransaction, + asset: { + data: 'Hello Lisk! Some data in here!...', + }, + }; + const expectedBuffer = Buffer.from( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d0000c16ff286230048656c6c6f204c69736b2120536f6d65206461746120696e2068657265212e2e2e618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(transferTransaction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + + it('should throw on type 0 with too much data', () => { + const maxDataLength = 64; + const transferTransaction: TransactionJSON = { + ...defaultTransaction, + asset: { + data: new Array(maxDataLength + 1).fill('1').join(''), + }, + }; + return expect( + getTransactionBytes.bind(null, transferTransaction), + ).to.throw('Transaction asset data exceeds size of 64.'); + }); + + it('should throw on type 0 with an amount that is too small', () => { + const amount = -1; + const transaction = { + ...defaultTransaction, + amount, + }; + return expect( + getTransactionBytes.bind( + null, + (transaction as unknown) as TransactionJSON, + ), + ).to.throw('Transaction amount must not be negative.'); + }); + + it('should throw on type 0 with an amount that is too large', () => { + const amount = BigNum.fromBuffer( + Buffer.from(new Array(8).fill(255)), + ).plus(1); + const transaction = { + ...defaultTransaction, + amount, + }; + return expect( + getTransactionBytes.bind( + null, + (transaction as unknown) as TransactionJSON, + ), + ).to.throw('Transaction amount is too large.'); + }); + + it('should return Buffer of transaction with second signature', () => { + const transaction = { + ...defaultTransaction, + signSignature: defaultSecondSignature, + }; + const expectedBuffer = Buffer.from( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d0000c16ff2862300618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0ab00c4ad1988bca245d74435660a278bfe6bf2f5efa8bda96d927fabf8b4f6fcfdcb2953f6abacaa119d6880987a55dea0e6354bc8366052b45fa23145522020f', + 'hex', + ); + const transactionBytes = getTransactionBytes(transaction); + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + + it('should return Buffer from multisignature type 0 (transfer LSK) transaction', () => { + const multiSignatureTransaction = { + ...defaultTransaction, + signatures: [], + }; + const expectedBuffer = Buffer.from( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d0000c16ff2862300618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes( + multiSignatureTransaction as any, + ); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + + it('should return Buffer of type 0 (transfer LSK) with additional properties', () => { + const transaction = { + ...defaultTransaction, + skip: false, + }; + const expectedBuffer = Buffer.from( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d0000c16ff2862300618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(transaction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + + it('should throw on missing required parameter type', () => { + const { type, ...defaultTransactionClone } = defaultTransaction; + expect( + getTransactionBytes.bind( + null, + (defaultTransactionClone as unknown) as TransactionJSON, + ), + ).to.throw(`type is a required parameter.`); + }); + + it('should throw on missing required parameter timestamp', () => { + const { timestamp, ...defaultTransactionClone } = defaultTransaction; + expect( + getTransactionBytes.bind( + null, + (defaultTransactionClone as unknown) as TransactionJSON, + ), + ).to.throw(`timestamp is a required parameter.`); + }); + + it('should throw on missing required parameter senderPublicKey', () => { + const { + senderPublicKey, + ...defaultTransactionClone + } = defaultTransaction; + expect( + getTransactionBytes.bind( + null, + (defaultTransactionClone as unknown) as TransactionJSON, + ), + ).to.throw(`senderPublicKey is a required parameter.`); + }); + + it('should throw on missing required parameter amount', () => { + const { amount, ...defaultTransactionClone } = defaultTransaction; + expect( + getTransactionBytes.bind( + null, + (defaultTransactionClone as unknown) as TransactionJSON, + ), + ).to.throw(`amount is a required parameter.`); + }); + }); + + describe('signature transaction, type 1', () => { + const signatureTransaction = { + type: 1, + amount: defaultNoAmount, + fee: (5 * fixedPoint).toString(), + recipientId: defaultRecipient, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: { signature: { publicKey: defaultSenderSecondPublicKey } }, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + + it('should return Buffer of type 1 (register second signature) transaction', () => { + const expectedBuffer = Buffer.from( + '01aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d00000000000000000401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(signatureTransaction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + }); + + describe('delegate registration transaction, type 2', () => { + const delegateRegistrationTransaction = { + type: 2, + amount: defaultNoAmount, + fee: (25 * fixedPoint).toString(), + recipientId: defaultRecipient, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: { delegate: { username: defaultDelegateUsername } }, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + + it('should return Buffer of type 2 (register delegate) transaction', () => { + const expectedBuffer = Buffer.from( + '02aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d00000000000000004d7944656c6567617465557365726e616d65618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes( + delegateRegistrationTransaction, + ); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + }); + + describe('vote transaction, type 3', () => { + const voteTransaction = { + type: 3, + amount: '0', + fee: (1 * fixedPoint).toString(), + recipientId: defaultRecipient, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: { + votes: [ + `+${defaultSenderPublicKey}`, + `+${defaultSenderSecondPublicKey}`, + ], + }, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + + it('should return Buffer of type 3 (vote) transaction', () => { + const expectedBuffer = Buffer.from( + '03aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d00000000000000002b356430333661383538636538396638343434393137363265623839653262666264353061346130613064613635386534623236323862323562313137616530392b30343031633861633966323964656439653165346435623662343330353163623235623232663237633762376233353039323136316538353139343666383266618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(voteTransaction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + }); + + describe('multisignature transaction, type 4', () => { + const createMultiSignatureTransaction = { + type: 4, + amount: '0', + fee: (15 * fixedPoint).toString(), + recipientId: defaultRecipient, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: { + multisignature: { + min: 2, + lifetime: 5, + keysgroup: [ + `+${defaultSenderPublicKey}`, + `+${defaultSenderSecondPublicKey}`, + ], + }, + }, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + + it('should return Buffer from type 4 (register multisignature) transaction', () => { + const expectedBuffer = Buffer.from( + '04aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d000000000000000002052b356430333661383538636538396638343434393137363265623839653262666264353061346130613064613635386534623236323862323562313137616530392b30343031633861633966323964656439653165346435623662343330353163623235623232663237633762376233353039323136316538353139343666383266618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes( + createMultiSignatureTransaction, + ); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + }); + + describe('dapp transaction, type 5', () => { + const dappTransaction = { + type: 5, + amount: '0', + fee: (25 * fixedPoint).toString(), + recipientId: defaultRecipient, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: { + dapp: { + category: 0, + name: 'Lisk Guestbook', + description: 'The official Lisk guestbook', + tags: 'guestbook message sidechain', + type: 0, + link: 'https://github.com/MaxKK/guestbookDapp/archive/master.zip', + icon: + 'https://raw.githubusercontent.com/MaxKK/guestbookDapp/master/icon.png', + }, + }, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + + it('should return Buffer of type 5 (register dapp) transaction', () => { + const expectedBuffer = Buffer.from( + '05aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d00000000000000004c69736b204775657374626f6f6b546865206f6666696369616c204c69736b206775657374626f6f6b6775657374626f6f6b206d6573736167652073696465636861696e68747470733a2f2f6769746875622e636f6d2f4d61784b4b2f6775657374626f6f6b446170702f617263686976652f6d61737465722e7a697068747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f4d61784b4b2f6775657374626f6f6b446170702f6d61737465722f69636f6e2e706e670000000000000000618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(dappTransaction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + }); + + describe('inTransfer transaction, type 6', () => { + const inTransferTransction = { + type: 6, + amount: defaultAmount, + fee: (1 * fixedPoint).toString(), + recipientId: defaultRecipient, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: { inTransfer: { dappId: defaultAppId } }, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + + it('should return Buffer of type 6 (dapp inTransfer) transaction', () => { + const expectedBuffer = Buffer.from( + '06aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d0000c16ff286230031323334323133618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(inTransferTransction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + }); + + describe('outTransfer transaction, type 7', () => { + const outTransferTransaction = { + type: 7, + amount: defaultAmount, + fee: (1 * fixedPoint).toString(), + recipientId: defaultRecipient, + senderPublicKey: defaultSenderPublicKey, + senderId: defaultSenderId, + recipientPublicKey: defaultRecipientPublicKey, + timestamp: defaultTimestamp, + asset: { + outTransfer: { + dappId: defaultAppId, + transactionId: defaultTransactionId, + }, + }, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + + it('should return Buffer of type 7 (dapp outTransfer) transaction', () => { + const expectedBuffer = Buffer.from( + '07aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153d0000c16ff2862300313233343231333133393837333438343230393133313338343232618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + const transactionBytes = getTransactionBytes(outTransferTransaction); + + return expect(transactionBytes).to.be.eql(expectedBuffer); + }); + }); + }); + + describe('getTransactionBytes functions', () => { + describe('#checkRequiredFields', () => { + const arrayToCheck = ['OneValue', 'SecondValue', 'ThirdValue']; + it('should accept array and object to check for required fields', () => { + const objectParameter = { + OneValue: '1', + SecondValue: '2', + ThirdValue: '3', + }; + + return expect(checkRequiredFields(arrayToCheck, objectParameter)).to.be + .true; + }); + + it('should throw on missing value', () => { + const objectParameter = { + OneValue: '1', + SecondValue: '2', + }; + + return expect( + checkRequiredFields.bind(null, arrayToCheck, objectParameter), + ).to.throw('ThirdValue is a required parameter.'); + }); + }); + + describe('#getAssetDataForTransferTransaction', () => { + const defaultEmptyBuffer = Buffer.alloc(0); + it('should return Buffer for data asset', () => { + const expectedBuffer = Buffer.from('my data input', 'utf8'); + const assetDataBuffer = getAssetDataForTransferTransaction({ + data: 'my data input', + }); + + return expect(assetDataBuffer).to.be.eql(expectedBuffer); + }); + + it('should return empty Buffer for no asset data', () => { + const assetDataBuffer = getAssetDataForTransferTransaction({} as any); + return expect(assetDataBuffer).to.be.eql(defaultEmptyBuffer); + }); + }); + + describe('#getAssetDataForRegisterSecondSignatureTransaction', () => { + it('should return Buffer for signature asset', () => { + const expectedBuffer = Buffer.from(defaultSenderPublicKey, 'hex'); + const assetSignaturesPublicKeyBuffer = getAssetDataForRegisterSecondSignatureTransaction( + { + signature: { + publicKey: defaultSenderPublicKey, + }, + }, + ); + + return expect(assetSignaturesPublicKeyBuffer).to.be.eql(expectedBuffer); + }); + + it('should throw on missing publicKey in the signature asset', () => { + return expect( + getAssetDataForRegisterSecondSignatureTransaction.bind(null, { + signature: {} as any, + }), + ).to.throw('publicKey is a required parameter.'); + }); + }); + + describe('#getAssetDataForRegisterDelegateTransaction', () => { + it('should return Buffer for delegate asset', () => { + const expectedBuffer = Buffer.from(defaultDelegateUsername, 'utf8'); + const assetDelegateUsernameBuffer = getAssetDataForRegisterDelegateTransaction( + { + delegate: { + username: defaultDelegateUsername, + }, + }, + ); + + return expect(assetDelegateUsernameBuffer).to.be.eql(expectedBuffer); + }); + + it('should throw on missing username in the delegate asset', () => { + return expect( + getAssetDataForRegisterDelegateTransaction.bind(null, { + delegate: {} as any, + }), + ).to.throw('username is a required parameter.'); + }); + }); + + describe('#getAssetDataForCastVotesTransaction', () => { + it('should return Buffer for votes asset', () => { + const votesAsset = { + votes: [ + `+${defaultSenderPublicKey}`, + `+${defaultSenderSecondPublicKey}`, + ], + }; + const expectedBuffer = Buffer.from( + `+${defaultSenderPublicKey}+${defaultSenderSecondPublicKey}`, + 'utf8', + ); + const assetVoteBuffer = getAssetDataForCastVotesTransaction(votesAsset); + + return expect(assetVoteBuffer).to.be.eql(expectedBuffer); + }); + + it('should throw on missing votes in the vote asset', () => { + return expect( + getAssetDataForCastVotesTransaction.bind(null, { votes: {} as any }), + ).to.throw('votes parameter must be an Array.'); + }); + }); + + describe('#getAssetDataForRegisterMultisignatureAccountTransaction', () => { + const min = 2; + const lifetime = 5; + const keysgroup = ['+123456789', '-987654321']; + let multisignatureAsset: MultiSignatureAsset; + + beforeEach(() => { + multisignatureAsset = { + multisignature: { + min, + lifetime, + keysgroup, + }, + }; + return Promise.resolve(); + }); + + it('should return Buffer for multisignature asset', () => { + const minBuffer = Buffer.alloc(1, min); + const lifetimeBuffer = Buffer.alloc(1, lifetime); + const keysgroupBuffer = Buffer.from('+123456789-987654321', 'utf8'); + + const expectedBuffer = Buffer.concat([ + minBuffer, + lifetimeBuffer, + keysgroupBuffer, + ]); + const multisignatureBuffer = getAssetDataForRegisterMultisignatureAccountTransaction( + multisignatureAsset, + ); + + return expect(multisignatureBuffer).to.be.eql(expectedBuffer); + }); + + it('should throw on missing required parameter min', () => { + const { min, ...multisigAsset } = multisignatureAsset.multisignature; + expect( + getAssetDataForRegisterMultisignatureAccountTransaction.bind(null, { + multisignature: multisigAsset as any, + }), + ).to.throw(`min is a required parameter.`); + }); + + it('should throw on missing required parameter lifetime', () => { + const { + lifetime, + ...multisigAsset + } = multisignatureAsset.multisignature; + expect( + getAssetDataForRegisterMultisignatureAccountTransaction.bind(null, { + multisignature: multisigAsset as any, + }), + ).to.throw(`lifetime is a required parameter.`); + }); + + it('should throw on missing required parameter keysgroup', () => { + const { + keysgroup, + ...multisigAsset + } = multisignatureAsset.multisignature; + expect( + getAssetDataForRegisterMultisignatureAccountTransaction.bind(null, { + multisignature: multisigAsset as any, + }), + ).to.throw(`keysgroup is a required parameter.`); + }); + }); + + describe('#getAssetDataForCreateDappTransaction', () => { + const defaultCategory = 0; + const defaultDappName = 'Lisk Guestbook'; + const defaultDescription = 'The official Lisk guestbook'; + const defaultTags = 'guestbook message sidechain'; + const defaultType = 0; + const defaultLink = + 'https://github.com/MaxKK/guestbookDapp/archive/master.zip'; + const defaultIcon = + 'https://raw.githubusercontent.com/MaxKK/guestbookDapp/master/icon.png'; + const dappNameBuffer = Buffer.from('4c69736b204775657374626f6f6b', 'hex'); + const dappDescriptionBuffer = Buffer.from( + '546865206f6666696369616c204c69736b206775657374626f6f6b', + 'hex', + ); + const dappTagsBuffer = Buffer.from( + '6775657374626f6f6b206d6573736167652073696465636861696e', + 'hex', + ); + const dappLinkBuffer = Buffer.from( + '68747470733a2f2f6769746875622e636f6d2f4d61784b4b2f6775657374626f6f6b446170702f617263686976652f6d61737465722e7a6970', + 'hex', + ); + const dappIconBuffer = Buffer.from( + '68747470733a2f2f7261772e67697468756275736572636f6e74656e742e636f6d2f4d61784b4b2f6775657374626f6f6b446170702f6d61737465722f69636f6e2e706e67', + 'hex', + ); + const dappTypeBuffer = Buffer.alloc(4, defaultType); + const dappCategoryBuffer = Buffer.alloc(4, defaultCategory); + + it('should return Buffer for create dapp asset', () => { + const dappAsset = { + dapp: { + category: defaultCategory, + name: defaultDappName, + description: defaultDescription, + tags: defaultTags, + type: defaultType, + link: defaultLink, + icon: defaultIcon, + }, + }; + + const expectedBuffer = Buffer.concat([ + dappNameBuffer, + dappDescriptionBuffer, + dappTagsBuffer, + dappLinkBuffer, + dappIconBuffer, + dappTypeBuffer, + dappCategoryBuffer, + ]); + const dappBuffer = getAssetDataForCreateDappTransaction(dappAsset); + + return expect(dappBuffer).to.be.eql(expectedBuffer); + }); + + it('should throw for create dapp asset without required fields', () => { + const dapp: { readonly [key: string]: string | number } = { + category: defaultCategory, + name: defaultDappName, + description: defaultDescription, + tags: defaultTags, + type: defaultType, + link: defaultLink, + icon: defaultIcon, + }; + const requiredProperties = ['name', 'link', 'type', 'category']; + + return requiredProperties.forEach(parameter => { + const { [parameter]: deletedValue, ...dappClone } = dapp; + expect( + getAssetDataForCreateDappTransaction.bind(null, { + dapp: dappClone as any, + }), + ).to.throw(`${parameter} is a required parameter.`); + }); + }); + }); + + describe('#getAssetDataForTransferIntoDappTransaction', () => { + it('should return Buffer for dappIn asset', () => { + const dappInAsset = { + inTransfer: { + dappId: defaultAppId, + }, + }; + const expectedBuffer = Buffer.from(defaultAppId, 'utf8'); + const dappInTransferBuffer = getAssetDataForTransferIntoDappTransaction( + dappInAsset, + ); + + return expect(dappInTransferBuffer).to.be.eql(expectedBuffer); + }); + + it('should throw on missing votes in the vote asset', () => { + return expect( + getAssetDataForTransferIntoDappTransaction.bind(null, { + inTransfer: {} as any, + }), + ).to.throw('dappId is a required parameter.'); + }); + }); + + describe('#getAssetDataForTransferOutOfDappTransaction', () => { + it('should return Buffer for dappOut asset', () => { + const dappOutAsset = { + outTransfer: { + dappId: defaultAppId, + transactionId: defaultTransactionId, + }, + }; + const dappIdBuffer = Buffer.from(defaultAppId, 'utf8'); + const transactionIdBuffer = Buffer.from(defaultTransactionId); + const expectedBuffer = Buffer.concat([ + dappIdBuffer, + transactionIdBuffer, + ]); + const dappOutTransferBuffer = getAssetDataForTransferOutOfDappTransaction( + dappOutAsset, + ); + + return expect(dappOutTransferBuffer).to.be.eql(expectedBuffer); + }); + + it('should throw on missing votes in the vote asset', () => { + return expect( + getAssetDataForTransferOutOfDappTransaction.bind(null, { + outTransfer: {} as any, + }), + ).to.throw('dappId is a required parameter.'); + }); + }); + + describe('#checkTransaction', () => { + const maxDataLength = 64; + let defaultTransaction: TransactionJSON; + beforeEach(() => { + defaultTransaction = { + type: 0, + fee: (0.1 * fixedPoint).toString(), + amount: defaultAmount, + recipientId: defaultRecipient, + timestamp: defaultTimestamp, + asset: {}, + senderPublicKey: defaultSenderPublicKey, + recipientPublicKey: defaultRecipientPublicKey, + senderId: defaultSenderId, + signature: defaultSignature, + signatures: [], + id: defaultTransactionId, + }; + return Promise.resolve(); + }); + + it('should throw on too many data in transfer asset', () => { + const transaction = { + ...defaultTransaction, + asset: { + data: new Array(maxDataLength + 1).fill('1').join(''), + }, + }; + return expect(checkTransaction.bind(null, transaction)).to.throw( + 'Transaction asset data exceeds size of 64.', + ); + }); + + it('should return true on asset data exactly at max data length', () => { + const transaction = { + ...defaultTransaction, + asset: { + data: new Array(maxDataLength).fill('1').join(''), + }, + }; + return expect(checkTransaction(transaction)).to.be.true; + }); + }); + + describe('#isInvalidValue', () => { + it('should return false on invalid values', () => { + const allInvalidValues = [NaN, false, undefined]; + return allInvalidValues.forEach(value => { + const invalid = isValidValue(value); + expect(invalid).to.be.false; + }); + }); + it('should return true on valid values', () => { + const exampleValidValues = ['123', 123, { 1: 2, 3: 4 }, [1, 2, 3]]; + return exampleValidValues.forEach(value => { + const valid = isValidValue(value); + expect(valid).to.be.true; + }); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/get_transaction_hash.ts b/elements/lisk-transactions/test/utils/get_transaction_hash.ts new file mode 100644 index 00000000000..721b320f45f --- /dev/null +++ b/elements/lisk-transactions/test/utils/get_transaction_hash.ts @@ -0,0 +1,64 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { getTransactionHash } from '../../src/utils'; +import { TransactionJSON } from '../../src/transaction_types'; +import * as getTransactionBytesModule from '../../src/utils/get_transaction_bytes'; + +describe('#getTransactionHash', () => { + let defaultTransactionBytes; + let transaction: unknown; + let result: Buffer; + + beforeEach(() => { + defaultTransactionBytes = Buffer.from( + '00aa2902005d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae0900cebcaa8d34153de803000000000000618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + 'hex', + ); + sandbox + .stub(getTransactionBytesModule, 'getTransactionBytes') + .returns(defaultTransactionBytes); + transaction = { + type: 0, + amount: '1000', + fee: '0', + recipientId: '58191285901858109L', + timestamp: 141738, + asset: {}, + senderPublicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + signature: + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + signatures: [], + id: '13987348420913138422', + }; + result = getTransactionHash(transaction as TransactionJSON); + return Promise.resolve(); + }); + + it('should get transaction bytes', () => { + return expect( + getTransactionBytesModule.getTransactionBytes, + ).to.be.calledWithExactly(transaction); + }); + + it('should return a hash for a transaction object as a Buffer', () => { + const expected = Buffer.from( + 'f60a26da470b1dc233fd526ed7306c1d84836f9e2ecee82c9ec47319e0910474', + 'hex', + ); + return expect(result).to.be.eql(expected); + }); +}); diff --git a/elements/lisk-transactions/test/utils/index.ts b/elements/lisk-transactions/test/utils/index.ts new file mode 100644 index 00000000000..c475a16caac --- /dev/null +++ b/elements/lisk-transactions/test/utils/index.ts @@ -0,0 +1,146 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + checkPublicKeysForDuplicates, + convertBeddowsToLSK, + convertLSKToBeddows, + getTimeFromBlockchainEpoch, + getTimeWithOffset, + getTransactionBytes, + getTransactionHash, + getId, + getTransactionId, + prepareTransaction, + prependMinusToPublicKeys, + prependPlusToPublicKeys, + signRawTransaction, + signTransaction, + multiSignTransaction, + validateMultisignatures, + validateSignature, + verifyTransaction, + validateAddress, + validateNonTransferAmount, + isValidInteger, + validateKeysgroup, + validatePublicKey, + validatePublicKeys, + validateTransaction, +} from '../../src/utils'; + +describe('transaction utils', () => { + describe('exports', () => { + it('should have checkPublicKeysForDuplicates', () => { + return expect(checkPublicKeysForDuplicates).to.be.a('function'); + }); + + it('should have convertBeddowsToLSK', () => { + return expect(convertBeddowsToLSK).to.be.a('function'); + }); + + it('should have convertLSKToBeddows', () => { + return expect(convertLSKToBeddows).to.be.a('function'); + }); + + it('should have getTimeFromBlockchainEpoch', () => { + return expect(getTimeFromBlockchainEpoch).to.be.a('function'); + }); + + it('should have getTimeWithOffset', () => { + return expect(getTimeWithOffset).to.be.a('function'); + }); + + it('should have getTransactionBytes', () => { + return expect(getTransactionBytes).to.be.a('function'); + }); + + it('should have getTransactionHash', () => { + return expect(getTransactionHash).to.be.a('function'); + }); + + it('should have getId', () => { + return expect(getId).to.be.a('function'); + }); + + it('should have getTransactionId', () => { + return expect(getTransactionId).to.be.a('function'); + }); + + it('should have prepareTransaction', () => { + return expect(prepareTransaction).to.be.a('function'); + }); + + it('should have prependMinusToPublicKeys', () => { + return expect(prependMinusToPublicKeys).to.be.a('function'); + }); + + it('should have prependPlusToPublicKeys', () => { + return expect(prependPlusToPublicKeys).to.be.a('function'); + }); + + it('should have signRawTransaction', () => { + return expect(signRawTransaction).to.be.a('function'); + }); + + it('should have signTransaction', () => { + return expect(signTransaction).to.be.a('function'); + }); + + it('should have multiSignTransaction', () => { + return expect(multiSignTransaction).to.be.a('function'); + }); + + it('should have verifySignature', () => { + return expect(validateSignature).to.be.a('function'); + }); + + it('should have verifyMultisignatures', () => { + return expect(validateMultisignatures).to.be.a('function'); + }); + + it('should have verifyTransaction', () => { + return expect(verifyTransaction).to.be.a('function'); + }); + + it('should have validateAddress', () => { + return expect(validateAddress).to.be.a('function'); + }); + + it('should have validateNonTransferAmount', () => { + return expect(validateNonTransferAmount).to.be.a('function'); + }); + + it('should have isValidInteger', () => { + return expect(isValidInteger).to.be.a('function'); + }); + + it('should have validateKeysgroup', () => { + return expect(validateKeysgroup).to.be.a('function'); + }); + + it('should have validatePublicKey', () => { + return expect(validatePublicKey).to.be.a('function'); + }); + + it('should have validatePublicKeys', () => { + return expect(validatePublicKeys).to.be.a('function'); + }); + + it('should have validateTransaction', () => { + return expect(validateTransaction).to.be.a('function'); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/prepare_transaction.ts b/elements/lisk-transactions/test/utils/prepare_transaction.ts new file mode 100644 index 00000000000..7098f2bb790 --- /dev/null +++ b/elements/lisk-transactions/test/utils/prepare_transaction.ts @@ -0,0 +1,151 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { prepareTransaction } from '../../src/utils/prepare_transaction'; +import { getTimeWithOffset } from '../../src/utils/time'; +import { TransactionJSON } from '../../src/transaction_types'; + +describe('#prepareTransaction', () => { + const passphrase = 'secret'; + const keys = { + privateKey: + '2bb80d537b1da3e38bd30361aa855686bde0eacd7162fef6a25fe97bf527a25b5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + publicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + }; + const signature = + 'a00835fe0ad89d8b8a26cc3ffa8238d89bd38999f39d712fe8745707c8e18ea70337a7dfde725fddaa858dd64843170de3e481f54438b8aad734b0e75bbad706'; + const secondPassphrase = 'second secret'; + const secondSignature = + '08ce78b2382c396596cc38ea8b9dbc2df62f0d919ddc817070902eeaf1b93ca17ced0766bb4e10f565ae9e55f673691d966dea45e60922fd2685556b441ffb0e'; + const id = '8330167589806376997'; + const defaultTransaction = { + type: 0, + amount: (10e8).toString(), + timestamp: 10, + senderPublicKey: keys.publicKey, + asset: {}, + signatures: [], + }; + let inputTransaction: Partial; + let preparedTransaction: TransactionJSON; + + beforeEach(() => { + inputTransaction = { ...defaultTransaction }; + return Promise.resolve(); + }); + + describe('without type', () => { + it('should throw an error when it is not transaction', () => { + const { type, ...invalidTransaction } = inputTransaction; + return expect( + prepareTransaction.bind(null, invalidTransaction, passphrase), + ).to.throw('Invalid transaction to process'); + }); + }); + + describe('without signature', () => { + beforeEach(() => { + preparedTransaction = prepareTransaction(inputTransaction); + return Promise.resolve(); + }); + + it('should not mutate the original transaction', () => { + return expect(inputTransaction).to.eql(defaultTransaction); + }); + + it('should not add a signature to a transaction', () => { + return expect(preparedTransaction.signature).to.be.undefined; + }); + + it('should not add an id to a transaction', () => { + return expect(preparedTransaction.id).to.be.undefined; + }); + + it('should add timestamp with the offset', () => { + const { timestamp, ...transactionWithoutTimestamp } = inputTransaction; + const currentTimestamp = getTimeWithOffset(); + preparedTransaction = prepareTransaction( + transactionWithoutTimestamp, + undefined, + undefined, + 50, + ); + return expect(preparedTransaction.timestamp).to.be.gt(currentTimestamp); + }); + }); + + describe('without second signature', () => { + beforeEach(() => { + preparedTransaction = prepareTransaction(inputTransaction, passphrase); + return Promise.resolve(); + }); + + it('should not mutate the original transaction', () => { + return expect(inputTransaction).to.eql(defaultTransaction); + }); + + it('should add a signature to a transaction', () => { + return expect(preparedTransaction) + .to.have.property('signature') + .and.be.hexString.and.equal(signature); + }); + + it('should add an id to a transaction', () => { + return expect(preparedTransaction) + .to.have.property('id') + .and.match(/^[0-9]+$/) + .and.equal(id); + }); + }); + + describe('with second signature', () => { + beforeEach(() => { + preparedTransaction = prepareTransaction( + inputTransaction, + passphrase, + secondPassphrase, + ); + return Promise.resolve(); + }); + + it('should not mutate the original transaction', () => { + return expect(inputTransaction).to.eql(defaultTransaction); + }); + + it('should add a second signature to a transaction if a second passphrase is provided', () => { + return expect(preparedTransaction) + .to.have.property('signSignature') + .and.be.hexString.and.equal(secondSignature); + }); + + it('should not add a second signature to a type 1 transaction', () => { + inputTransaction = Object.assign({}, defaultTransaction, { + type: 1, + asset: { + signature: { + publicKey: keys.publicKey, + }, + }, + }); + preparedTransaction = prepareTransaction( + inputTransaction, + passphrase, + secondPassphrase, + ); + return expect(preparedTransaction).not.to.have.property('signSignature'); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/sign_and_validate.ts b/elements/lisk-transactions/test/utils/sign_and_validate.ts new file mode 100644 index 00000000000..c17f9f8179f --- /dev/null +++ b/elements/lisk-transactions/test/utils/sign_and_validate.ts @@ -0,0 +1,556 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { addTransactionFields } from '../helpers'; +import { + signTransaction, + multiSignTransaction, + validateMultisignatures, + validateSignature, + verifyTransaction, +} from '../../src/utils'; +import { TransactionError, TransactionPendingError } from '../../src/errors'; +// The list of valid transactions was created with lisk-js v0.5.1 +// using the below mentioned passphrases. +import * as fixtureTransactions from '../../fixtures/transactions.json'; +import { Account, TransactionJSON } from '../../src/transaction_types'; +import * as getTransactionHashModule from '../../src/utils/get_transaction_hash'; +import { + validMultisignatureAccount as defaultMultisignatureAccount, + validMultisignatureTransaction, + validSecondSignatureTransaction, +} from '../../fixtures'; + +// Require is used for stubbing +const validTransactions = (fixtureTransactions as unknown) as ReadonlyArray< + TransactionJSON +>; + +describe('signAndVerify module', () => { + describe('#validateSignature', () => { + const defaultSecondSignatureTransaction = addTransactionFields( + validSecondSignatureTransaction, + ); + const defaultSecondSignatureTransactionBytes = Buffer.from( + '004529cf04bc10685b802c8dd127e5d78faadc9fad1903f09d562fdcf632462408d4ba52e8b95af897b7e23cb900e40b54020000003357658f70b9bece24bd42769b984b3e7b9be0b2982f82e6eef7ffbd841598d5868acd45f8b1e2f8ab5ccc8c47a245fe9d8e3dc32fc311a13cc95cc851337e01', + 'hex', + ); + const defaultSecondPublicKey = + 'bc10685b802c8dd127e5d78faadc9fad1903f09d562fdcf632462408d4ba52e8'; + const defaultTransactionBytes = Buffer.from( + '004529cf04bc10685b802c8dd127e5d78faadc9fad1903f09d562fdcf632462408d4ba52e8b95af897b7e23cb900e40b5402000000', + 'hex', + ); + + it('should call cryptography hash', async () => { + const cryptographyHashStub = sandbox + .stub(cryptography, 'hash') + .returns( + Buffer.from( + '62b13b81836f3f1e371eba2f7f8306ff23d00a87d9473793eda7f742f4cfc21c', + 'hex', + ), + ); + + validateSignature( + defaultSecondSignatureTransaction.senderPublicKey, + defaultSecondSignatureTransaction.signature, + defaultTransactionBytes, + ); + + expect(cryptographyHashStub).to.be.calledOnce; + }); + + it('should call cryptography verifyData', async () => { + const cryptographyVerifyDataStub = sandbox + .stub(cryptography, 'verifyData') + .returns(true); + + validateSignature( + defaultSecondSignatureTransaction.senderPublicKey, + defaultSecondSignatureTransaction.signature, + defaultTransactionBytes, + ); + + expect(cryptographyVerifyDataStub).to.be.calledOnce; + }); + + it('should return a valid response with valid signature', async () => { + const { valid } = validateSignature( + defaultSecondSignatureTransaction.senderPublicKey, + defaultSecondSignatureTransaction.signature, + defaultTransactionBytes, + ); + + expect(valid).to.be.true; + }); + + it('should return an unvalid response with invalid signature', async () => { + const { valid, error } = validateSignature( + defaultSecondSignatureTransaction.senderPublicKey, + defaultSecondSignatureTransaction.signature.replace('1', '0'), + Buffer.from(defaultTransactionBytes), + ); + + expect(valid).to.be.false; + expect(error) + .to.be.instanceof(TransactionError) + .and.have.property( + 'message', + `Failed to validate signature ${defaultSecondSignatureTransaction.signature.replace( + '1', + '0', + )}`, + ); + }); + + it('should return a valid response with valid signSignature', async () => { + const { valid } = validateSignature( + defaultSecondPublicKey, + defaultSecondSignatureTransaction.signSignature, + defaultSecondSignatureTransactionBytes, + ); + + expect(valid).to.be.true; + }); + + it('should return an unvalid response with invalid signSignature', async () => { + const { valid, error } = validateSignature( + defaultSecondPublicKey, + defaultSecondSignatureTransaction.signSignature.replace('1', '0'), + defaultSecondSignatureTransactionBytes, + ); + + expect(valid).to.be.false; + expect(error) + .to.be.instanceof(TransactionError) + .and.have.property( + 'message', + `Failed to validate signature ${defaultSecondSignatureTransaction.signSignature.replace( + '1', + '0', + )}`, + ); + }); + }); + + describe('#validateMultisignatures', () => { + const defaultMultisignatureTransaction = addTransactionFields( + validMultisignatureTransaction, + ); + const defaultTransactionBytes = Buffer.from( + '002c497801500660b67a2ade1e2528b7f648feef8f3b46e2f4f90ca7f5439101b5119f309d572c095724f7f2b7600a3a4200000000', + 'hex', + ); + + const { + membersPublicKeys: memberPublicKeys, + } = defaultMultisignatureAccount as Account; + + it('should return a valid response with valid signatures', async () => { + const { valid } = validateMultisignatures( + memberPublicKeys as ReadonlyArray, + defaultMultisignatureTransaction.signatures, + 2, + defaultTransactionBytes, + ); + + expect(valid).to.be.true; + }); + + it('should return a verification fail response with invalid signatures', async () => { + const { valid, errors } = validateMultisignatures( + memberPublicKeys as ReadonlyArray, + defaultMultisignatureTransaction.signatures.map((signature: string) => + signature.replace('1', '0'), + ), + 2, + defaultTransactionBytes, + ); + + expect(valid).to.be.false; + (errors as ReadonlyArray).forEach((error, i) => { + expect(error) + .to.be.instanceof(TransactionError) + .and.have.property( + 'message', + `Failed to validate signature ${defaultMultisignatureTransaction.signatures[ + i + ].replace('1', '0')}`, + ); + }); + }); + + it('should return a verification fail response with invalid extra signatures', async () => { + const { valid, errors } = validateMultisignatures( + memberPublicKeys as ReadonlyArray, + [ + ...defaultMultisignatureTransaction.signatures, + 'f321799c2d30d2be6e7b70aa29b57f9b1d6f2801d3fccf5c99623ffe45526104b1f0652c2cb586c7ae201d2557d8041b41b60154f079180bb9b85f8d06b3010c', + ], + 2, + defaultTransactionBytes, + ); + + expect(valid).to.be.false; + (errors as ReadonlyArray).forEach(error => { + expect(error).to.be.instanceof(TransactionError); + }); + }); + + it('should return a verification fail response with duplicate signatures', async () => { + const { valid, errors } = validateMultisignatures( + memberPublicKeys as ReadonlyArray, + [ + ...defaultMultisignatureTransaction.signatures, + defaultMultisignatureTransaction.signatures[0], + ], + 2, + defaultTransactionBytes, + ); + + expect(valid).to.be.false; + (errors as ReadonlyArray).forEach(error => { + expect(error).to.be.instanceof(TransactionError); + }); + }); + + it('should return a transaction pending error when missing signatures', async () => { + const { valid, errors } = validateMultisignatures( + memberPublicKeys as ReadonlyArray, + defaultMultisignatureTransaction.signatures.slice(0, 2), + 3, + defaultTransactionBytes, + ); + + expect(valid).to.be.false; + (errors as ReadonlyArray).forEach(error => { + expect(error) + .to.be.instanceof(TransactionPendingError) + .and.have.property('message', 'Missing signatures'); + }); + }); + }); + + describe('signAndVerify transaction utils', () => { + const defaultPassphrase = + 'minute omit local rare sword knee banner pair rib museum shadow juice'; + const defaultPublicKey = + '7ef45cd525e95b7a86244bbd4eb4550914ad06301013958f4dd64d32ef7bc588'; + const defaultSecondPublicKey = + '0401c8ac9f29ded9e1e4d5b6b43051cb25b22f27c7b7b35092161e851946f82f'; + const defaultSignature = + 'bb3f2d12d098c59a0af03bb1157eeb7bc7141b21cea57861c4eac72a7c55f122b5befb1391c3f8509b562fa748fdc7359f6e6051526d979915157c5bcba34e01'; + const defaultSecondSignature = + '897090248c0ecdad749d869ddeae59e5029bdbe4806da92d82d6eb7142b624011f4302941db184a2e70bd29a6adac5ce0b4cf780af893db2f504375bdef6850b'; + const defaultHash = Buffer.from( + 'c62214460d66eeb1d9db3fb708e31040d2629fbdb6c93887c5eb0f3243912f91', + 'hex', + ); + + let defaultTransaction: TransactionJSON; + let cryptoSignDataStub: sinon.SinonStub; + let cryptoVerifyDataStub: sinon.SinonStub; + let getTransactionHashStub: sinon.SinonStub; + + beforeEach(() => { + defaultTransaction = { + type: 0, + amount: '1000', + fee: '1', + recipientId: '58191285901858109L', + recipientPublicKey: '', + senderId: '', + timestamp: 141738, + asset: {}, + id: '13987348420913138422', + signatures: [], + senderPublicKey: defaultPublicKey, + }; + + cryptoSignDataStub = sandbox + .stub(cryptography, 'signData') + .returns(defaultSignature); + cryptoVerifyDataStub = sandbox + .stub(cryptography, 'verifyData') + .returns(true); + getTransactionHashStub = sandbox + .stub(getTransactionHashModule, 'getTransactionHash') + .returns(defaultHash); + return Promise.resolve(); + }); + + describe('#signTransaction', () => { + let transaction: TransactionJSON; + let signature: string; + + beforeEach(() => { + transaction = { ...defaultTransaction } as TransactionJSON; + signature = signTransaction(transaction, defaultPassphrase); + return Promise.resolve(); + }); + + it('should get the transaction hash', () => { + return expect(getTransactionHashStub).to.be.calledWithExactly( + transaction, + ); + }); + + it('should sign the transaction hash with the passphrase', () => { + return expect(cryptoSignDataStub).to.be.calledWithExactly( + defaultHash, + defaultPassphrase, + ); + }); + + it('should return the signature', () => { + return expect(signature).to.be.equal(defaultSignature); + }); + }); + + describe('#multiSignTransaction', () => { + const defaultMultisignatureHash = Buffer.from( + 'd43eed9049dd8f35106c720669a1148b2c6288d9ea517b936c33a1d84117a760', + 'hex', + ); + + let multiSignatureTransaction: TransactionJSON; + let signature: string; + + beforeEach(() => { + multiSignatureTransaction = { + type: 0, + amount: '1000', + recipientId: '58191285901858109L', + timestamp: 141738, + asset: {}, + senderPublicKey: + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + signature: + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + signSignature: + '508a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a', + id: '13987348420913138422', + } as TransactionJSON; + getTransactionHashStub.returns(defaultMultisignatureHash); + signature = multiSignTransaction( + multiSignatureTransaction, + defaultPassphrase, + ); + return Promise.resolve(); + }); + + it('should remove the signature and second signature before getting transaction hash', () => { + expect(getTransactionHashStub.args[0]).not.to.have.property( + 'signature', + ); + return expect(getTransactionHashStub.args[0]).not.to.have.property( + 'signSignature', + ); + }); + + it('should sign the transaction hash with the passphrase', () => { + return expect(cryptoSignDataStub).to.be.calledWithExactly( + defaultMultisignatureHash, + defaultPassphrase, + ); + }); + + it('should return the signature', () => { + return expect(signature).to.be.equal(defaultSignature); + }); + }); + + describe('#verifyTransaction', () => { + let transaction: TransactionJSON; + + describe('with a single signed transaction', () => { + beforeEach(() => { + transaction = { + ...defaultTransaction, + signature: defaultSignature, + } as TransactionJSON; + return Promise.resolve(); + }); + + it('should throw if attempting to verify without a secondPublicKey', () => { + const { signature, ...invalidTransaction } = transaction; + return expect( + verifyTransaction.bind(null, invalidTransaction), + ).to.throw('Cannot verify transaction without signature.'); + }); + + it('should remove the signature before getting transaction hash', () => { + verifyTransaction(transaction); + return expect(getTransactionHashStub.args[0]).not.to.have.property( + 'signature', + ); + }); + + it('should verify the transaction using the hash, the signature and the public key', () => { + verifyTransaction(transaction); + return expect(cryptoVerifyDataStub).to.be.calledWithExactly( + defaultHash, + defaultSignature, + defaultPublicKey, + ); + }); + + it('should return false for an invalid signature', () => { + cryptoVerifyDataStub.returns(false); + const verification = verifyTransaction(transaction); + return expect(verification).to.be.false; + }); + + it('should return true for a valid signature', () => { + const verification = verifyTransaction(transaction); + return expect(verification).to.be.true; + }); + }); + + describe('with a second signed transaction', () => { + beforeEach(() => { + transaction = { + ...defaultTransaction, + signature: defaultSignature, + signSignature: defaultSecondSignature, + } as TransactionJSON; + return getTransactionHashStub + .onFirstCall() + .returns( + Buffer.from( + '951bb4580dcb6a412de28844e0e06439c5c51dfea2a16730fd94ff20e355f1bd', + 'hex', + ), + ); + }); + + it('should throw if attempting to verify without a secondPublicKey', () => { + const { signature, ...invalidTransaction } = transaction; + return expect( + verifyTransaction.bind(null, invalidTransaction), + ).to.throw('Cannot verify transaction without signature.'); + }); + + it('should throw if attempting to verify without a secondPublicKey', () => { + return expect(verifyTransaction.bind(null, transaction)).to.throw( + 'Cannot verify signSignature without secondPublicKey.', + ); + }); + + it('should remove the second signature before getting the first transaction hash', () => { + verifyTransaction(transaction, defaultSecondPublicKey); + return expect( + getTransactionHashStub.firstCall.args[0], + ).not.to.have.property('signSignature'); + }); + + it('should remove the first signature before getting the second transaction hash', () => { + verifyTransaction(transaction, defaultSecondPublicKey); + return expect( + getTransactionHashStub.secondCall.args[0], + ).not.to.have.property('signature'); + }); + + it('should return false for an invalid second signature', () => { + cryptoVerifyDataStub.returns(false); + const verification = verifyTransaction( + transaction, + defaultSecondPublicKey, + ); + return expect(verification).to.be.false; + }); + + it('should return false for an invalid first signature', () => { + cryptoVerifyDataStub.onSecondCall().returns(false); + getTransactionHashStub + .onFirstCall() + .returns( + Buffer.from( + 'aef147521619556572f204585332aac247dc2b024cb975518d847e4587bab756', + 'hex', + ), + ); + const verification = verifyTransaction( + transaction, + defaultSecondPublicKey, + ); + return expect(verification).to.be.false; + }); + + it('should return true for a valid signature', () => { + const verification = verifyTransaction( + transaction, + defaultSecondPublicKey, + ); + return expect(verification).to.be.true; + }); + }); + }); + }); + + describe('integration sign and verify', () => { + describe('given a set of transactions', () => { + describe('#signTransaction', () => { + describe('given a passphrase and a second passphrase', () => { + const passphrase = + 'wagon stock borrow episode laundry kitten salute link globe zero feed marble'; + const secondPassphrase = + 'trouble float modify long valve group ozone possible remove dirt bicycle riot'; + + describe('when tested on the first signature', () => { + it('should create the correct signature', () => { + return validTransactions.forEach(transaction => { + const { signature, signSignature, ...rawTx } = transaction; + return expect(signTransaction(rawTx, passphrase)).to.be.equal( + signature, + ); + }); + }); + }); + + describe('when tested on the second signature', () => { + it('should create the correct signature', () => { + return validTransactions.forEach(transaction => { + const { signSignature } = transaction; + if (signSignature) { + const { signSignature, ...rawTx } = transaction; + return expect( + signTransaction(rawTx, secondPassphrase), + ).to.be.equal(signSignature); + } + return true; + }); + }); + }); + }); + }); + + describe('#verifyTransaction', () => { + describe('when executed', () => { + const secondPublicKey = + 'f9666bfed9ef2ff52a04408f22f2bfffaa81384c9433463697330224f10032a4'; + it('should verify all the transactions', () => { + return validTransactions.forEach(transaction => { + return expect(verifyTransaction(transaction, secondPublicKey)).to + .be.true; + }); + }); + }); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/sign_raw_transaction.ts b/elements/lisk-transactions/test/utils/sign_raw_transaction.ts new file mode 100644 index 00000000000..ffac03ca9d5 --- /dev/null +++ b/elements/lisk-transactions/test/utils/sign_raw_transaction.ts @@ -0,0 +1,353 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { signRawTransaction } from '../../src/utils/sign_raw_transaction'; +import { TransactionJSON } from '../../src/transaction_types'; +import * as time from '../../src/utils/time'; + +describe('#signRawTransaction', () => { + const timeWithOffset = 38350076; + const amount = '100'; + const recipientId = '123456789L'; + const timestamp = 12345; + const fee = '10000000'; + const type = 0; + const asset = {}; + let getTimeWithOffsetStub: sinon.SinonStub; + + beforeEach(() => { + getTimeWithOffsetStub = sandbox + .stub(time, 'getTimeWithOffset') + .returns(timeWithOffset); + return Promise.resolve(); + }); + + describe('given a raw transaction', () => { + let transaction: TransactionJSON; + + beforeEach(() => { + transaction = { + amount, + recipientId, + recipientPublicKey: '', + timestamp, + type, + fee, + asset, + } as TransactionJSON; + return Promise.resolve(); + }); + + describe('given a passphrase', () => { + const passphrase = + 'wagon stock borrow episode laundry kitten salute link globe zero feed marble'; + const senderPublicKey = + 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f'; + const senderId = '16313739661670634666L'; + const signature = + 'd09288d22a1ac860f625db950340cd26e435d0d98a00ffb92d55c16b76d83ed4fd1acf974c28c9dede8fb15a49ccaddb6325f4e750d968e515e1f0d90e0fb30d'; + const transactionId = '9248517814265997446'; + describe('when executed', () => { + let signedTransaction: TransactionJSON; + let signingProperties; + + beforeEach(() => { + signingProperties = { + passphrase, + transaction, + }; + signedTransaction = signRawTransaction(signingProperties); + return Promise.resolve(); + }); + + it('should have the type', () => { + return expect(signedTransaction) + .to.have.property('type') + .equal(type); + }); + + it('should have the amount', () => { + return expect(signedTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the asset', () => { + return expect(signedTransaction) + .to.have.property('asset') + .eql(asset); + }); + + it('should have the senderPublicKey', () => { + return expect(signedTransaction) + .to.have.property('senderPublicKey') + .equal(senderPublicKey); + }); + + it('should have the senderId', () => { + return expect(signedTransaction) + .to.have.property('senderId') + .equal(senderId); + }); + + it('should have the recipientId', () => { + return expect(signedTransaction) + .to.have.property('recipientId') + .equal(recipientId); + }); + + it('should have the fee', () => { + return expect(signedTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the updated timestamp', () => { + return expect(signedTransaction) + .to.have.property('timestamp') + .be.equal(timeWithOffset); + }); + + it('should have the senderSecondPublicKey', () => { + return expect(signedTransaction) + .to.have.property('senderSecondPublicKey') + .equal(undefined); + }); + + it('should have the signature', () => { + return expect(signedTransaction) + .to.have.property('signature') + .be.equal(signature); + }); + + it('should have the id', () => { + return expect(signedTransaction) + .to.have.property('id') + .be.equal(transactionId); + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly( + undefined, + ); + }); + }); + + describe('given a second passphrase', () => { + const secondPassphrase = + 'guitar couch salmon subject review urban heavy autumn crush tribe home plunge'; + const senderSecondPublicKey = + 'c465d74511c2bfd136cf9764172acd3c1514fa7ad76475e03bc91cf679757a5c'; + const signSignature = + '31ef8fcf4e1815def245ad32d0d0e3e86993a4029c41e8ca1dc2674c9794d31cefc2226ac539dea8049c7085fdcb29768389b96104ac05a0ddabfb8b523af409'; + const secondSignedTransactionId = '5702597341252953087'; + describe('when executed', () => { + let signedTransaction: TransactionJSON; + let signingProperties; + + beforeEach(() => { + signingProperties = { + passphrase, + transaction, + secondPassphrase, + }; + signedTransaction = signRawTransaction(signingProperties); + return Promise.resolve(); + }); + + it('should have the type', () => { + return expect(signedTransaction) + .to.have.property('type') + .equal(type); + }); + + it('should have the amount', () => { + return expect(signedTransaction) + .to.have.property('amount') + .equal(amount); + }); + + it('should have the asset', () => { + return expect(signedTransaction) + .to.have.property('asset') + .eql(asset); + }); + + it('should have the senderPublicKey', () => { + return expect(signedTransaction) + .to.have.property('senderPublicKey') + .equal(senderPublicKey); + }); + + it('should have the senderId', () => { + return expect(signedTransaction) + .to.have.property('senderId') + .equal(senderId); + }); + + it('should have the recipientId', () => { + return expect(signedTransaction) + .to.have.property('recipientId') + .equal(recipientId); + }); + + it('should have the fee', () => { + return expect(signedTransaction) + .to.have.property('fee') + .equal(fee); + }); + + it('should have the updated timestamp', () => { + return expect(signedTransaction) + .to.have.property('timestamp') + .be.equal(timeWithOffset); + }); + + it('should have the senderSecondPublicKey', () => { + return expect(signedTransaction) + .to.have.property('senderSecondPublicKey') + .equal(senderSecondPublicKey); + }); + + it('should have the signature', () => { + return expect(signedTransaction) + .to.have.property('signature') + .be.eql(signature); + }); + + it('should have the second signature', () => { + return expect(signedTransaction) + .to.have.property('signSignature') + .be.equal(signSignature); + }); + + it('should have the id', () => { + return expect(signedTransaction) + .to.have.property('id') + .be.equal(secondSignedTransactionId); + }); + + it('should use time.getTimeWithOffset to calculate the timestamp', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly( + undefined, + ); + }); + }); + + describe('given an offset', () => { + const timeOffset = 1000; + let signingProperties; + + describe('when executed', () => { + beforeEach(() => { + signingProperties = { + passphrase, + transaction, + secondPassphrase, + timeOffset, + }; + return signRawTransaction(signingProperties); + }); + + it('should calculate the time with the time offset', () => { + return expect(getTimeWithOffsetStub).to.be.calledWithExactly( + timeOffset, + ); + }); + }); + }); + }); + }); + }); + + describe('given a signed transaction', () => { + const amount = '100'; + const senderPublicKey = + 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f'; + const senderId = '16313739661670634666L'; + const signature = + 'd09288d22a1ac860f625db950340cd26e435d0d98a00ffb92d55c16b76d83ed4fd1acf974c28c9dede8fb15a49ccaddb6325f4e750d968e515e1f0d90e0fb30d'; + const transactionId = '9248517814265997446'; + const updatedSignerPassphrase = + 'wagon stock borrow episode laundry kitten salute link globe zero feed'; + const updatedSignerPublicKey = + '798974780475d8d7d6c6c9bb3dabf10efb16b7b380469223ee3ecc711c8e1396'; + const updatedSignerAddress = '5752844829611395697L'; + const updatedSignerSignature = + '647ca03394d0fefeeaa018e6943feb61c0ec64f3110ab96fe87564f1c915a40f25ac19324802684de87cdc5a0947f774d8b0ae78f9144635996d0450bcd5760c'; + const updatedSignerId = '9495608349801955934'; + let transaction: TransactionJSON; + + beforeEach(() => { + transaction = { + amount, + recipientId, + senderPublicKey, + timestamp, + type, + fee, + senderId, + signature, + id: transactionId, + recipientPublicKey: '', + asset, + signatures: [], + }; + return Promise.resolve(); + }); + + describe('when executed', () => { + let signedTransaction: TransactionJSON; + let signingProperties; + + beforeEach(() => { + signingProperties = { + passphrase: updatedSignerPassphrase, + transaction, + }; + signedTransaction = signRawTransaction(signingProperties); + return Promise.resolve(); + }); + + it('should sign the transaction', () => { + return expect(signedTransaction).to.be.ok; + }); + + it('should have the updated senderPublicKey', () => { + return expect(signedTransaction) + .to.have.property('senderPublicKey') + .equal(updatedSignerPublicKey); + }); + + it('should have the updated senderId', () => { + return expect(signedTransaction) + .to.have.property('senderId') + .equal(updatedSignerAddress); + }); + + it('should have the updated transactionId', () => { + return expect(signedTransaction) + .to.have.property('id') + .equal(updatedSignerId); + }); + + it('should have the updated signature', () => { + return expect(signedTransaction) + .to.have.property('signature') + .equal(updatedSignerSignature); + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/time.ts b/elements/lisk-transactions/test/utils/time.ts new file mode 100644 index 00000000000..a28831df51c --- /dev/null +++ b/elements/lisk-transactions/test/utils/time.ts @@ -0,0 +1,69 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { + getTimeFromBlockchainEpoch, + getTimeWithOffset, +} from '../../src/utils/time'; + +describe('time module', () => { + const nowRealTime = new Date(1464109220000); + const nowEpochTime = 20; + + beforeEach(() => { + return sandbox.useFakeTimers(nowRealTime.getTime()); + }); + + afterEach(() => { + return sandbox.clock.restore(); + }); + + describe('#getTimeFromBlockchainEpoch', () => { + it('should return current time as number', () => { + const time = getTimeFromBlockchainEpoch(); + + return expect(time).to.be.equal(nowEpochTime); + }); + + it('should return epoch time for provided time as number, equal to 10', () => { + const realTime = 1464109210001; + const time = getTimeFromBlockchainEpoch(realTime); + + return expect(time).to.be.equal(10); + }); + }); + + describe('#getTimeWithOffset', () => { + it('should get time with undefined offset', () => { + const time = getTimeWithOffset(); + + return expect(time).to.be.equal(nowEpochTime); + }); + + it('should get time with positive offset', () => { + const offset = 3; + const time = getTimeWithOffset(offset); + + return expect(time).to.be.equal(23); + }); + + it('should get time with negative offset', () => { + const offset = -3; + const time = getTimeWithOffset(offset); + + return expect(time).to.be.equal(17); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/transaction_id.ts b/elements/lisk-transactions/test/utils/transaction_id.ts new file mode 100644 index 00000000000..d65be0af494 --- /dev/null +++ b/elements/lisk-transactions/test/utils/transaction_id.ts @@ -0,0 +1,102 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { addTransactionFields } from '../helpers'; +import { getId, getTransactionId } from '../../src/utils'; +import { TransactionJSON } from '../../src/transaction_types'; +import { validTransaction } from '../../fixtures'; +// Require is used for stubbing +const utils = require('../../src/utils'); + +describe('#getId', () => { + const defaultTransaction = addTransactionFields(validTransaction); + const defaultTransactionBytes = + '0022dcb9040eb0a6d7b862dc35c856c02c47fde3b4f60f2f3571a888b9a8ca7540c6793243ef4d6324449e824f6319182b020000002092abc5dd72d42b289f69ddfa85d0145d0bfc19a0415be4496c189e5fdd5eff02f57849f484192b7d34b1671c17e5c22ce76479b411cad83681132f53d7b309'; + + it('should return a valid id', async () => { + expect(getId(Buffer.from(defaultTransactionBytes, 'hex'))).to.be.eql( + defaultTransaction.id, + ); + }); + + it('should call cryptography hash', async () => { + const cryptographyHashStub = sandbox + .stub(cryptography, 'hash') + .returns( + Buffer.from( + 'da63e78daf2096db8316a157a839c8b9a616d3ce6692cfe61d6d380a623a1902', + 'hex', + ), + ); + + getId(Buffer.from(defaultTransactionBytes, 'hex')); + expect(cryptographyHashStub).to.be.calledOnce; + }); + + it('should call cryptography getFirstEightBytesReversed', async () => { + const cryptographygetFirstEightBytesReversedStub = sandbox + .stub(cryptography, 'getFirstEightBytesReversed') + .returns('db9620af8de763da' as any); + + getId(Buffer.from(defaultTransactionBytes, 'hex')); + expect(cryptographygetFirstEightBytesReversedStub).to.be.calledOnce; + }); + + it('should call cryptography bufferToBigNumberString', async () => { + const cryptographyBufferToBigNumberStringStub = sandbox + .stub(cryptography, 'bufferToBigNumberString') + .returns('15822870279184933850'); + + getId(Buffer.from(defaultTransactionBytes, 'hex')); + expect(cryptographyBufferToBigNumberStringStub).to.be.calledOnce; + }); +}); + +describe('#getTransactionId', () => { + const defaultPublicKey = + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09'; + const defaultTransactionId = '13987348420913138422'; + const defaultTransactionHash = Buffer.from( + 'f60a26da470b1dc233fd526ed7306c1d84836f9e2ecee82c9ec47319e0910474', + 'hex', + ); + const defaultAmount = '1000'; + const defaultTimestamp = 141738; + const defaultRecipientId = '58191285901858109L'; + const defaultSignature = + '618a54975212ead93df8c881655c625544bce8ed7ccdfe6f08a42eecfb1adebd051307be5014bb051617baf7815d50f62129e70918190361e5d4dd4796541b0a'; + + beforeEach(() => { + sandbox.stub(cryptography, 'hash').returns(defaultTransactionHash); + return sandbox.stub(utils, 'getTransactionBytes'); + }); + + it('should return an id of 13987348420913138422 for a transaction', () => { + const transaction: unknown = { + type: 0, + amount: defaultAmount, + fee: '0', + recipientId: defaultRecipientId, + timestamp: defaultTimestamp, + asset: {}, + senderPublicKey: defaultPublicKey, + signature: defaultSignature, + }; + const id = getTransactionId(transaction as TransactionJSON); + + return expect(id).to.be.equal(defaultTransactionId); + }); +}); diff --git a/elements/lisk-transactions/test/utils/validation/validate_transaction.ts b/elements/lisk-transactions/test/utils/validation/validate_transaction.ts new file mode 100644 index 00000000000..7b4c647eef2 --- /dev/null +++ b/elements/lisk-transactions/test/utils/validation/validate_transaction.ts @@ -0,0 +1,189 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import * as fixtures from '../../../fixtures/transactions.json'; +import * as invalidFixtures from '../../../fixtures/invalid_transactions.json'; +import { validateTransaction } from '../../../src/utils/validation/validate_transaction'; +import { TransactionJSON } from '../../../src/transaction_types'; +import { ErrorObject } from 'ajv'; + +describe('validateTransaction', () => { + describe('#validateTransaction', () => { + describe('when fixtures provided', () => { + it('should be all valid for the fixtures', () => { + return fixtures.forEach((tx: unknown) => { + const { valid, errors } = validateTransaction(tx as TransactionJSON); + expect(valid).to.be.true; + expect(errors).to.be.undefined; + }); + }); + }); + + describe('when transaction does not contain type', () => { + const invalidTransaction = { + amount: '0', + fee: '10000000', + recipientId: 'recipientID', + senderPublicKey: + 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + timestamp: 54196078, + asset: {}, + signature: + '4c8a3bfaacfab18a7ef34ce8d7176ea2701dfd7221a1c95ecbc1cce778bbccdb7cbbe1a87b3e9e47330f1cae6665c4a44666e132aa324de9a5ab9b6a1e2b1d0c', + id: '18066659039293493823', + }; + it('should throw an error', () => { + return expect( + validateTransaction.bind(null, invalidTransaction as TransactionJSON), + ).to.throw(Error, 'Transaction type is required.'); + }); + }); + + describe('when invalid fixtures provided', () => { + it('should be all invalid for the invalid fixtures (except type 6 and 7)', () => { + return invalidFixtures + .filter((tx: any) => tx.type !== 6 && tx.type !== 7) + .forEach((tx: any) => { + const { valid, errors } = validateTransaction(tx); + expect(valid).to.be.false; + expect(errors).not.to.be.undefined; + }); + }); + + it('should throw an unsupported transaction type error for type 6 and 7', () => { + return invalidFixtures + .filter((tx: any) => tx.type === 6 || tx.type === 7) + .forEach((tx: any) => { + expect(validateTransaction.bind(null, tx)).to.throw( + Error, + 'Unsupported transaction type.', + ); + }); + }); + }); + + describe('when the transaction contains invalid data in merged schema', () => { + const invalidTransaction = { + type: 0, + amount: '0', + fee: '10000000', + recipientId: 'recipientID', + senderPublicKey: + 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + timestamp: 54196078, + asset: {}, + signature: + '4c8a3bfaacfab18a7ef34ce8d7176ea2701dfd7221a1c95ecbc1cce778bbccdb7cbbe1a87b3e9e47330f1cae6665c4a44666e132aa324de9a5ab9b6a1e2b1d0c', + id: '18066659039293493823', + }; + + it('should not include $merge error when the merged schema has error', () => { + const { valid, errors } = validateTransaction( + invalidTransaction as TransactionJSON, + ); + expect(valid).to.be.false; + expect(errors).not.to.be.undefined; + const errorsArray = errors as ReadonlyArray; + expect(errorsArray[0].dataPath).to.equal('.amount'); + expect(errorsArray[1].dataPath).to.equal('.recipientId'); + return expect(errors).to.have.length(2); + }); + }); + }); + + describe('#getTransactionSchemaValidator', () => { + const type6Tx = { + type: 6, + amount: '166413', + fee: '10000000', + recipientId: '', + senderPublicKey: + 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + timestamp: 54196078, + asset: { inTransfer: { dappId: '1000000' } }, + signature: + 'f2b1a66d9bd8ae0c1b3404fe397a11bd696e5aea274e6a8d9fea2f976503d006b8ca65484daf2498f854a0c0109b924b653a8d6ba31a568cb70727b7d3472902', + id: '9501694969515165251', + }; + + const type7Tx = { + type: 7, + amount: '835151', + fee: '10000000', + recipientId: '1859190791819301L', + senderPublicKey: + 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + timestamp: 54196079, + asset: { + outTransfer: { dappId: '614143983', transactionId: '749591467' }, + }, + signature: + '646cd6be9f385bfa4f914b66a675a77080a3c1093278cfbca16d3d7fbf768350c9a7e270a8e5a72347e2792d3cfc770f3a3bb9ea542c300cba3976f34bd040e', + }; + + it('should throw an error when type 6 transaction is provided', () => { + return expect( + validateTransaction.bind(null, type6Tx as TransactionJSON), + ).to.throw(Error, 'Unsupported transaction type.'); + }); + + it('should throw an error when type 7 transaction is provided', () => { + return expect( + validateTransaction.bind(null, type7Tx as TransactionJSON), + ).to.throw(Error, 'Unsupported transaction type.'); + }); + }); + + describe('#validateMultiTransaction', () => { + const invalidMultiTransaction = { + type: 4, + amount: '0', + fee: '3000000000', + recipientId: '', + senderPublicKey: + 'c094ebee7ec0c50ebee32918655e089f6e1a604b83bcaa760293c61e0f18ab6f', + timestamp: 54196078, + asset: { + multisignature: { + min: 6, + lifetime: 1, + keysgroup: [ + '+e64df51060a2ce43f91b24ae75cc83f1866f9fead2ca2420cf3df153e6368a97', + '+4ef26ed51f4b82134b16f25a2556bed98a0b3963a17c0d2f0fa87f67cc6f29fe', + '+818d34925549e0aea67f1b82190c3e288b1c66de95ce699c2f5c87f1e622012c', + '+a2eece2bf0ee74e492939ac84723646270bfefab84914a5cf68baffd9bb84858', + '+46f3ec44dbcffe28c6bcd4eb494ce24ceea51677eb67005bdd4dd3202db55251', + ], + }, + }, + signature: + '4c8a3bfaacfab18a7ef34ce8d7176ea2701dfd7221a1c95ecbc1cce778bbccdb7cbbe1a87b3e9e47330f1cae6665c4a44666e132aa324de9a5ab9b6a1e2b1d0c', + id: '18066659039293493823', + }; + + it('should be invalid when min is greater than the keysgroup', () => { + const { valid, errors } = validateTransaction( + invalidMultiTransaction as any, + ); + expect(valid).to.be.false; + expect(errors).not.to.be.undefined; + const errorsArray = errors as ReadonlyArray; + expect(errorsArray[0].dataPath).to.equal('.asset.multisignature.min'); + return expect(errorsArray[0].message).to.equal( + '.asset.multisignature.min cannot be greater than .asset.multisignature.keysgroup.length', + ); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/validation/validation.ts b/elements/lisk-transactions/test/utils/validation/validation.ts new file mode 100644 index 00000000000..3d942469c21 --- /dev/null +++ b/elements/lisk-transactions/test/utils/validation/validation.ts @@ -0,0 +1,416 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { expect } from 'chai'; +import { + checkPublicKeysForDuplicates, + validatePublicKey, + validatePublicKeys, + validateKeysgroup, + validateAddress, + validateNonTransferAmount, + validateTransferAmount, + validateFee, + isGreaterThanMaxTransactionAmount, + isGreaterThanZero, + isGreaterThanMaxTransactionId, + isNumberString, + isValidInteger, + isNullByteIncluded, +} from '../../../src/utils/validation/validation'; + +describe('validation', () => { + describe('#validatePublicKey', () => { + describe('Given a hex string with odd length', () => { + const invalidHexPublicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bc'; + it('should throw an error', () => { + return expect( + validatePublicKey.bind(null, invalidHexPublicKey), + ).to.throw('Argument must have a valid length of hex string.'); + }); + }); + + describe('Given a hex string with additional non-hex characters', () => { + const invalidHexPublicKey = + '12345678123456781234567812345678123456781234567812345678123456gg'; + it('should throw an error', () => { + return expect( + validatePublicKey.bind(null, invalidHexPublicKey), + ).to.throw('Argument must be a valid hex string.'); + }); + }); + + describe('Given a too long public key', () => { + const tooLongPublicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca12'; + it('should throw an error', () => { + return expect(validatePublicKey.bind(null, tooLongPublicKey)).to.throw( + 'Public key 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca12 length differs from the expected 32 bytes for a public key.', + ); + }); + }); + + describe('Given a too short public key', () => { + const tooShortPublicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452b'; + it('should throw an error', () => { + return expect(validatePublicKey.bind(null, tooShortPublicKey)).to.throw( + 'Public key 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452b length differs from the expected 32 bytes for a public key.', + ); + }); + }); + + describe('Given a valid public key', () => { + const publicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca'; + it('should return true', () => { + return expect(validatePublicKey(publicKey)).to.be.true; + }); + }); + + describe('Given a valid public key with only numeric characters', () => { + const publicKey = + '1234567812345678123456781234567812345678123456781234567812345678'; + it('should return true', () => { + return expect(validatePublicKey(publicKey)).to.be.true; + }); + }); + }); + + describe('#validatePublicKeys', () => { + describe('Given an array of public keys with one invalid public key', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bc', + ]; + it('should throw an error', () => { + return expect(validatePublicKeys.bind(null, publicKeys)).to.throw( + 'Argument must have a valid length of hex string.', + ); + }); + }); + + describe('Given an array of valid public keys', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '1234567812345678123456781234567812345678123456781234567812345678', + ]; + it('should return true', () => { + return expect(validatePublicKeys(publicKeys)).to.be.true; + }); + }); + }); + + describe('#validateKeysgroup', () => { + let keysgroup: ReadonlyArray; + describe('Given a keysgroup with three public keys', () => { + beforeEach(() => { + keysgroup = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + return Promise.resolve(); + }); + it('the validated keysgroup should return true', () => { + return expect(validateKeysgroup(keysgroup)).to.be.true; + }); + }); + + describe('Given an empty keysgroup', () => { + beforeEach(() => { + keysgroup = []; + return Promise.resolve(); + }); + it('should throw the error', () => { + return expect(validateKeysgroup.bind(null, keysgroup)).to.throw( + 'Expected between 1 and 15 public keys in the keysgroup.', + ); + }); + }); + + describe('Given a keysgroup with 17 public keys', () => { + beforeEach(() => { + keysgroup = new Array(17) + .fill(0) + .map( + (_: number, index: number) => + cryptography.getPrivateAndPublicKeyFromPassphrase( + index.toString(), + ).publicKey, + ); + return Promise.resolve(); + }); + it('should throw the error', () => { + return expect(validateKeysgroup.bind(null, keysgroup)).to.throw( + 'Expected between 1 and 15 public keys in the keysgroup.', + ); + }); + }); + }); + + describe('#checkPublicKeysForDuplicates', () => { + describe('Given an array of public keys without duplication', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + it('should return true', () => { + return expect(checkPublicKeysForDuplicates(publicKeys)).to.be.true; + }); + }); + + describe('Given an array of public keys with duplication', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + ]; + it('should throw an error', () => { + return expect( + checkPublicKeysForDuplicates.bind(null, publicKeys), + ).to.throw( + 'Duplicated public key: 922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa.', + ); + }); + }); + }); + + describe('#validateAddress', () => { + describe('Given valid addresses', () => { + const addresses = [ + '13133549779353512613L', + '18446744073709551615L', + '1L', + ]; + + it('should return true', () => { + return addresses.forEach(address => { + return expect(validateAddress(address)).to.be.true; + }); + }); + }); + + describe('Given an address that is too short', () => { + const address = 'L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address length does not match requirements. Expected between 2 and 22 characters.', + ); + }); + }); + + describe('Given an address that is too long', () => { + const address = '12345678901234567890123L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address length does not match requirements. Expected between 2 and 22 characters.', + ); + }); + }); + + describe('Given an address without L at the end', () => { + const address = '1234567890'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address format does not match requirements. Expected "L" at the end.', + ); + }); + }); + + describe('Given an address that includes `.`', () => { + const address = '14.15133512790761431L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address format does not match requirements. Address includes invalid character: `.`.', + ); + }); + }); + + describe('Given an address that is out of range', () => { + const address = '18446744073709551616L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address format does not match requirements. Address out of maximum range.', + ); + }); + }); + + describe('Given an address that has leading zeros', () => { + const address = '00015133512790761431L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + "Address string format does not match it's number representation.", + ); + }); + }); + }); + + describe('#validateNonTransferAmount', () => { + it('should return true when amount is 0', () => { + return expect(validateNonTransferAmount('0')).to.be.true; + }); + + it('should return false when amount is greater than 0', () => { + return expect(validateNonTransferAmount('1')).to.be.false; + }); + + it('should return false when amount is less than 0', () => { + return expect(validateNonTransferAmount('-1')).to.be.false; + }); + }); + + describe('#validateTransferAmount', () => { + it('should return false is amount is 0', () => { + return expect(validateTransferAmount('0')).to.be.false; + }); + + it('should return true when amount is a number greater than 0 and less than maximum transaction amount', () => { + return expect(validateTransferAmount('100')).to.be.true; + }); + }); + + describe('#validateFee', () => { + it('should return false is amount is 0', () => { + return expect(validateFee('0')).to.be.false; + }); + + it('should return true when amount is a number greater than 0 and less than maximum transaction amount', () => { + return expect(validateFee('100')).to.be.true; + }); + }); + + describe('#isGreaterThanZero', () => { + it('should return false when amount is 0', () => { + return expect(isGreaterThanZero(new BigNum('0'))).to.be.false; + }); + + it('should return true when amount is greater than 0', () => { + return expect( + isGreaterThanZero(new BigNum('9223372036854775808987234289782357')), + ).to.be.true; + }); + }); + + describe('#isGreaterThanMaxTransactionAmount', () => { + it('should return false when amount is less than maximum transaction amount', () => { + return expect( + isGreaterThanMaxTransactionAmount(new BigNum('9223372036854775807')), + ).to.be.false; + }); + + it('should return true when amount is more than maximum transaction amount', () => { + return expect( + isGreaterThanMaxTransactionAmount(new BigNum('9223372036854775808')), + ).to.be.true; + }); + }); + + describe('#isGreaterThanMaxTransactionId', () => { + it('should return false when id is less than 8 bytes integer maximum', () => { + return expect( + isGreaterThanMaxTransactionId(new BigNum('18446744073709551615')), + ).to.be.false; + }); + + it('should return true when id is more than 8 bytes integer maximum', () => { + return expect( + isGreaterThanMaxTransactionId(new BigNum('18446744073709551616')), + ).to.be.true; + }); + }); + + describe('#isNumberString', () => { + it('should return false when number is not string', () => { + const invalidFunction = isNumberString as (input: any) => boolean; + return expect(invalidFunction(1)).to.be.false; + }); + + it('should return false when string contains non number', () => { + return expect(isNumberString('12345abc68789')).to.be.false; + }); + + it('should return true when string contains only number', () => { + return expect(isNumberString('1234568789')).to.be.true; + }); + }); + + describe('#isValidInteger', () => { + it('should return false when string was provided', () => { + return expect(isValidInteger('1234')).to.be.false; + }); + + it('should return false when float was provided', () => { + return expect(isValidInteger(123.4)).to.be.false; + }); + + it('should return true when integer was provided', () => { + return expect(isValidInteger(6)).to.be.true; + }); + + it('should return true when negative integer was provided', () => { + return expect(isValidInteger(-6)).to.be.true; + }); + }); + + describe('#isNullByteIncluded', () => { + const validStrings = [ + 'lorem ipsum', + 'lorem\u0001 ipsum', + 'loremU00000001 ipsum', + '\u0001', + '\x01', + 'l©rem', + '❤', + ]; + + const invalidStrings = [ + '\0', + '\0lorem', + 'ipsum\0', + 'lorem\0 ipsum', + '\x00', + '\x00lorem', + 'ipsum\x00', + 'lorem\x00 ipsum', + '\u0000', + '\u0000lorem', + 'ipsum\u0000', + 'lorem\u0000 ipsum', + '\\U00000000', + '\\U00000000lorem', + 'ipsum\\U00000000', + 'lorem\\U00000000 ipsum', + ]; + + it('should return false when valid string was provided', () => { + validStrings.forEach(input => { + expect(isNullByteIncluded(input)).to.be.false; + }); + }); + + it('should return true using unicode null characters', () => { + invalidStrings.forEach(input => { + expect(isNullByteIncluded(input)).to.be.true; + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/validation/validator.ts b/elements/lisk-transactions/test/utils/validation/validator.ts new file mode 100644 index 00000000000..e7398a723dd --- /dev/null +++ b/elements/lisk-transactions/test/utils/validation/validator.ts @@ -0,0 +1,638 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { validator } from '../../../src/utils/validation/validator'; +import { ValidateFunction } from 'ajv'; + +describe('validator', () => { + const baseSchemaId = 'test/schema'; + + before(() => { + const baseSchema = { + $id: baseSchemaId, + type: 'object', + }; + return validator.addSchema(baseSchema); + }); + + describe('signature', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'signature', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid signature is provided', () => { + return expect( + validate({ + target: + 'd5bdb0577f53fe5d79009c42facdf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b7304', + }), + ).to.be.true; + }); + + it('should validate to false when non-hex character is in the signature', () => { + return expect( + validate({ + target: + 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b7304', + }), + ).to.be.false; + }); + + it('should validate to false when the signature is under 128 characters', () => { + return expect( + validate({ + target: + 'd5bdb0577f53fe5d79009c42facdf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b730', + }), + ).to.be.false; + }); + + it('should validate to false when the signature is over 128 characters', () => { + return expect( + validate({ + target: + 'd5bdb0577f53fe5d79009c42facdf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b7304a', + }), + ).to.be.false; + }); + }); + + describe('id', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'id', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid id is provided', () => { + return expect(validate({ target: '3543510233978718399' })).to.be.true; + }); + + it('should validate to true when valid id with leading zeros is provided', () => { + return expect(validate({ target: '00123' })).to.be.true; + }); + + it('should validate to false when number greater than maximum is provided', () => { + return expect(validate({ target: '18446744073709551616' })).to.be.false; + }); + + it('should validate to false when number is provided', () => { + return expect(validate({ target: 3543510233978718399 })).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('address', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'address', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid address is provided', () => { + return expect(validate({ target: '14815133512790761431L' })).to.be.true; + }); + + it('should validate to false when address with leading zeros is provided', () => { + return expect(validate({ target: '00015133512790761431L' })).to.be.false; + }); + + it('should validate to false when address including `.` is provided', () => { + return expect(validate({ target: '14.15133512790761431L' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', () => { + return expect(validate({ target: '18446744073709551616L' })).to.be.false; + }); + + it('should validate to false when the address does not end with "L"', () => { + return expect(validate({ target: '14815133512790761431X' })).to.be.false; + }); + + it('should validate to false when the address only contains numbers', () => { + return expect(validate({ target: '18446744073709551616' })).to.be.false; + }); + + it('should validate to false when the address is less than 2 characters', () => { + return expect(validate({ target: 'L' })).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('non-transfer amount', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'nonTransferAmount', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid amount is provided', () => { + return expect(validate({ target: '0' })).to.be.true; + }); + + it('should validate to false when invalid amount with leading zeros is provided', () => { + return expect(validate({ target: '000001' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', () => { + return expect(validate({ target: '9223372036854775808' })).to.be.false; + }); + + it('should validate to false when decimal number is provided', () => { + return expect(validate({ target: '190.105310' })).to.be.false; + }); + + it('should validate to false when number is provided', () => { + return expect(validate({ target: 190105310 })).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('transfer amount', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'transferAmount', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid amount is provided', () => { + return expect(validate({ target: '100' })).to.be.true; + }); + + it('should validate to true when valid amount with leading zeros is provided', () => { + return expect(validate({ target: '000000100' })).to.be.true; + }); + + it('should validate to false when amount is 0', () => { + return expect(validate({ target: '0' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', () => { + return expect(validate({ target: '9223372036854775808' })).to.be.false; + }); + + it('should validate to false when decimal number is provided', () => { + return expect(validate({ target: '190.105310' })).to.be.false; + }); + + it('should validate to false when number is provided', () => { + return expect(validate({ target: 190105310 })).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('fee', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'fee', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid fee is provided', () => { + return expect(validate({ target: '100' })).to.be.true; + }); + + it('should validate to true when valid fee with leading zeros is provided', () => { + return expect(validate({ target: '000000100' })).to.be.true; + }); + + it('should validate to false when amount is 0', () => { + return expect(validate({ target: '0' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', () => { + return expect(validate({ target: '9223372036854775808' })).to.be.false; + }); + + it('should validate to false when decimal number is provided', () => { + return expect(validate({ target: '190.105310' })).to.be.false; + }); + + it('should validate to false when number is provided', () => { + return expect(validate({ target: 190105310 })).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('publicKey', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'publicKey', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid publicKey is provided', () => { + return expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to false when non-hex character is in the publicKey', () => { + return expect( + validate({ + target: + 'zzzzze75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is shorter', () => { + return expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is longer', () => { + return expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when signed publicKey is provided', () => { + return expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('signedPublicKey', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'signedPublicKey', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid + and publicKey is provided', () => { + return expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to true when valid - and publicKey is provided', () => { + return expect( + validate({ + target: + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to false when non-hex character is in the publicKey', () => { + return expect( + validate({ + target: + '+zzzzze75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is shorter', () => { + return expect( + validate({ + target: + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is longer', () => { + return expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when non-signed publicKey is provided', () => { + return expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('additionPublicKey', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'additionPublicKey', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid + and publicKey is provided', () => { + return expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to false when valid - and publicKey is provided', () => { + return expect( + validate({ + target: + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when non-hex character is in the publicKey', () => { + return expect( + validate({ + target: + '+zzzzze75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is shorter', () => { + return expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is longer', () => { + return expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when non-signed publicKey is provided', () => { + return expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when it is empty', () => { + return expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('uniqueSignedPublicKeys', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'array', + uniqueSignedPublicKeys: true, + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when unique signedPublicKey is provided', () => { + return expect( + validate({ + target: [ + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + '+278a9aecf13e324c42d73cae7e21e5efc1520afb1abcda084d086d24441ed2b4', + ], + }), + ).to.be.true; + }); + + it('should validate to false when publicKeys are duplicated without the sign', () => { + return expect( + validate({ + target: [ + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + ], + }), + ).to.be.false; + }); + + it('should validate to false when publicKeys are duplicated with the same sign', () => { + return expect( + validate({ + target: [ + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + ], + }), + ).to.be.false; + }); + }); + + describe('noNullBytes', () => { + let validate: ValidateFunction; + beforeEach(() => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'noNullByte', + }, + }, + }, + }, + }); + return Promise.resolve(); + }); + + it('should validate to true when valid string is provided', () => { + return expect( + validate({ + target: 'some normal string', + }), + ).to.be.true; + }); + + it('should validate to true when it is empty', () => { + return expect(validate({ target: '' })).to.be.true; + }); + + it('should validate to false when string with null byte is provided', () => { + const nullCharacterList = ['\0', '\x00', '\u0000', '\\U00000000']; + nullCharacterList.forEach(nullChar => { + expect( + validate({ + target: `${nullChar} hey \x01 :)`, + }), + ).to.be.false; + }); + }); + }); +}); diff --git a/elements/lisk-transactions/test/utils/verify.ts b/elements/lisk-transactions/test/utils/verify.ts new file mode 100644 index 00000000000..4667f632875 --- /dev/null +++ b/elements/lisk-transactions/test/utils/verify.ts @@ -0,0 +1,299 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { expect } from 'chai'; +import { + verifySenderPublicKey, + verifySenderId, + verifyBalance, + verifySecondSignature, + verifyMultiSignatures, +} from '../../src/utils'; +import * as validator from '../../src/utils/sign_and_validate'; +import { TransactionError, TransactionPendingError } from '../../src/errors'; +import { MultisignatureStatus } from '../../src/base_transaction'; + +describe('#verify', () => { + const defaultId = '4838520211125422557'; + + describe('#verifySenderPublicKey', () => { + it('should return undefined when sender public key and public key is the same', async () => { + const publicKey = 'sender-public-key'; + expect(verifySenderPublicKey(defaultId, { publicKey } as any, publicKey)) + .to.be.undefined; + }); + + it('should return TransactionError when sender public key and account public key is not the same', async () => { + const publicKey = 'sender-public-key'; + expect( + verifySenderPublicKey( + defaultId, + { publicKey } as any, + 'different public key', + ), + ) + .to.be.instanceOf(TransactionError) + .and.have.property('dataPath', '.senderPublicKey'); + }); + }); + + describe('#verifySenderId', () => { + const defaultAddress = '15610000000000000000L'; + + it('should return undefined when sender id and address is the same', async () => { + const address = '15610000000000000000L'; + expect( + verifySenderId(defaultId, { address: defaultAddress } as any, address), + ).to.be.undefined; + }); + + it('should return undefined when sender id has lower case', async () => { + const address = '15610000000000000000l'; + expect( + verifySenderId(defaultId, { address: defaultAddress } as any, address), + ).to.be.undefined; + }); + + it('should return TransactionError when sender id and account address is not the same', async () => { + const address = '15610000000000005555L'; + expect( + verifySenderId(defaultId, { address: defaultAddress } as any, address), + ) + .to.be.instanceOf(TransactionError) + .and.have.property('dataPath', '.senderId'); + }); + }); + + describe('#verifyBalance', () => { + const defaultAccount = { balance: '1000000000' } as any; + it('should return undefined when sender has exact amount', async () => { + expect(verifyBalance(defaultId, defaultAccount, new BigNum('1000000000'))) + .to.be.undefined; + }); + + it('should return undefined when sender has enoguh balance', async () => { + expect(verifyBalance(defaultId, defaultAccount, new BigNum('100'))).to.be + .undefined; + }); + + it('should return TransactionError when sender does not have enoguh balance', async () => { + expect(verifyBalance(defaultId, defaultAccount, new BigNum('1000000001'))) + .to.be.instanceOf(TransactionError) + .and.have.property('dataPath', '.balance'); + }); + }); + + describe('#verifySecondSignature', () => { + const defaultPublicKey = 'default-public-key'; + const defaultAccount = { + balance: '1000000000', + secondPublicKey: defaultPublicKey, + } as any; + const defaultSignSignature = 'default-sign-signature'; + const fakeTransactionBuffer = Buffer.from( + 'fake transaction buffer', + 'utf8', + ); + const successResult = { valid: true, error: undefined }; + const failResult = { valid: false, error: new TransactionError('fail') }; + + beforeEach(async () => { + sandbox.stub(validator, 'validateSignature').returns(successResult); + }); + + it('should return TransactionError when sender does not have second signature but signSignature is provided', async () => { + const { secondPublicKey, ...invalidAccount } = defaultAccount; + expect( + verifySecondSignature( + defaultId, + invalidAccount, + defaultSignSignature, + fakeTransactionBuffer, + ), + ) + .to.be.instanceOf(TransactionError) + .and.have.property('dataPath', '.signSignature'); + }); + + it('should return undefined when sender does not have second public key and signSignature is not provided', async () => { + const { secondPublicKey, ...invalidAccount } = defaultAccount; + expect( + verifySecondSignature( + defaultId, + invalidAccount, + undefined, + fakeTransactionBuffer, + ), + ).to.be.undefined; + }); + + it('should call validateSignature with currect arguments', async () => { + verifySecondSignature( + defaultId, + defaultAccount, + defaultSignSignature, + fakeTransactionBuffer, + ); + expect(validator.validateSignature).to.be.calledWithExactly( + defaultPublicKey, + defaultSignSignature, + fakeTransactionBuffer, + defaultId, + ); + }); + + it('should return undefined when valid', async () => { + expect( + verifySecondSignature( + defaultId, + defaultAccount, + defaultSignSignature, + fakeTransactionBuffer, + ), + ).to.be.undefined; + }); + + it('should return error from validateSignature when not valid', async () => { + (validator.validateSignature as any).returns(failResult); + expect( + verifySecondSignature( + defaultId, + defaultAccount, + defaultSignSignature, + fakeTransactionBuffer, + ), + ).to.equal(failResult.error); + }); + + it('should return TransactionError when sender have second public key but signSignature is not provided', async () => { + expect( + verifySecondSignature( + defaultId, + defaultAccount, + undefined, + fakeTransactionBuffer, + ), + ) + .to.be.instanceOf(TransactionError) + .and.have.property('dataPath', '.signSignature'); + }); + }); + + describe('#verifyMultiSignatures', () => { + const defaultAccount = { + address: '123L', + membersPublicKeys: [ + 'c465d74511c2bfd136cf9764172acd3c1514fa7ad76475e03bc91cf679757a5a', + 'c465d74511c2bfd136cf9764172acd3c1514fa7ad76475e03bc91cf679757a5b', + 'c465d74511c2bfd136cf9764172acd3c1514fa7ad76475e03bc91cf679757a5c', + ], + multiMin: 3, + }; + const signatures = [ + '00ef8fcf4e1815def245ad32d0d0e3e86993a4029c41e8ca1dc2674c9794d31cefc2226ac539dea8049c7085fdcb29768389b96104ac05a0ddabfb8b523af409', + '00ef8fcf4e1815def245ad32d0d0e3e86993a4029c41e8ca1dc2674c9794d31cefc2226ac539dea8049c7085fdcb29768389b96104ac05a0ddabfb8b523af400', + '00ef8fcf4e1815def245ad32d0d0e3e86993a4029c41e8ca1dc2674c9794d31cefc2226ac539dea8049c7085fdcb29768389b96104ac05a0ddabfb8b523af401', + ]; + const successResult = { valid: true, errors: [] }; + const pendingResult = { + valid: false, + errors: [new TransactionPendingError('fail')], + }; + const failResult = { valid: false, errors: [new TransactionError('fail')] }; + const fakeTransactionBuffer = Buffer.from( + 'fake transaction buffer', + 'utf8', + ); + + beforeEach(async () => { + sandbox.stub(validator, 'validateMultisignatures').returns(successResult); + }); + + it('should return FAIL status with error if sender is not multi-signature account but signatures are provided', async () => { + const { status, errors } = verifyMultiSignatures( + defaultId, + {} as any, + signatures, + fakeTransactionBuffer, + ); + expect(status).to.equal(MultisignatureStatus.FAIL); + expect(errors).not.to.be.empty; + expect(errors[0].dataPath).to.equal('.signatures'); + }); + + it('should return NONMULTISIGNATURE status without error if sender is not multi-signature account and signatures are not provided', async () => { + const { status, errors } = verifyMultiSignatures( + defaultId, + {} as any, + [], + fakeTransactionBuffer, + ); + expect(status).to.equal(MultisignatureStatus.NONMULTISIGNATURE); + expect(errors).to.be.empty; + }); + + it('should call validateMultisignature with correct argument', async () => { + verifyMultiSignatures( + defaultId, + defaultAccount as any, + signatures, + fakeTransactionBuffer, + ); + expect(validator.validateMultisignatures).to.be.calledWithExactly( + defaultAccount.membersPublicKeys, + signatures, + defaultAccount.multiMin, + fakeTransactionBuffer, + defaultId, + ); + }); + + it('should return READY status without error if transaction is valid', async () => { + const { status, errors } = verifyMultiSignatures( + defaultId, + defaultAccount as any, + signatures, + fakeTransactionBuffer, + ); + expect(status).to.equal(MultisignatureStatus.READY); + expect(errors).to.be.empty; + }); + + it('should return PENDING status with pending error if only error is the pending error', async () => { + (validator.validateMultisignatures as any).returns(pendingResult); + const { status, errors } = verifyMultiSignatures( + defaultId, + defaultAccount as any, + signatures, + fakeTransactionBuffer, + ); + expect(status).to.equal(MultisignatureStatus.PENDING); + expect(errors).not.to.be.empty; + expect(errors[0]).to.be.instanceOf(TransactionPendingError); + }); + + it('should return FAIL status with errors', async () => { + (validator.validateMultisignatures as any).returns(failResult); + const { status, errors } = verifyMultiSignatures( + defaultId, + defaultAccount as any, + signatures, + fakeTransactionBuffer, + ); + expect(status).to.equal(MultisignatureStatus.FAIL); + expect(errors).to.eql(failResult.errors); + }); + }); +}); diff --git a/elements/lisk-transactions/tsconfig.browsertest.json b/elements/lisk-transactions/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-transactions/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/tsconfig.json b/elements/lisk-transactions/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-transactions/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/tslint.json b/elements/lisk-transactions/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-transactions/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-transactions/types/ajv-merge-patch/index.d.ts b/elements/lisk-transactions/types/ajv-merge-patch/index.d.ts new file mode 100644 index 00000000000..97918a6dc3a --- /dev/null +++ b/elements/lisk-transactions/types/ajv-merge-patch/index.d.ts @@ -0,0 +1,4 @@ +declare module 'ajv-merge-patch' { + const addKeywords: (ajv: object) => void; + export = addKeywords; +} diff --git a/elements/lisk-validator/.npmignore b/elements/lisk-validator/.npmignore new file mode 120000 index 00000000000..8a0be70f3ed --- /dev/null +++ b/elements/lisk-validator/.npmignore @@ -0,0 +1 @@ +../../templates/.npmignore.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/.npmrc b/elements/lisk-validator/.npmrc new file mode 120000 index 00000000000..5cc817c4313 --- /dev/null +++ b/elements/lisk-validator/.npmrc @@ -0,0 +1 @@ +../../templates/.npmrc.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/.nycrc b/elements/lisk-validator/.nycrc new file mode 120000 index 00000000000..6ca7ee8dddd --- /dev/null +++ b/elements/lisk-validator/.nycrc @@ -0,0 +1 @@ +../../templates/.nycrc.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/.prettierignore b/elements/lisk-validator/.prettierignore new file mode 120000 index 00000000000..044e4a3df69 --- /dev/null +++ b/elements/lisk-validator/.prettierignore @@ -0,0 +1 @@ +../../templates/.prettierignore.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/.prettierrc.json b/elements/lisk-validator/.prettierrc.json new file mode 120000 index 00000000000..00ecd510aaf --- /dev/null +++ b/elements/lisk-validator/.prettierrc.json @@ -0,0 +1 @@ +../../templates/.prettierrc.json.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/README.md b/elements/lisk-validator/README.md new file mode 100644 index 00000000000..d21af5c426e --- /dev/null +++ b/elements/lisk-validator/README.md @@ -0,0 +1,37 @@ +# @liskhq/lisk-validator + +@liskhq/lisk-validator is a wrapper of validation libraries. It includes custom validations related to Lisk protocol. + +## Installation + +```sh +$ npm install --save @liskhq/lisk-validator +``` + +## License + +Copyright © 2016-2018 Lisk Foundation + +This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the [GNU General Public License](https://github.com/LiskHQ/lisk-elements/tree/master/LICENSE) along with this program. If not, see . + +*** + +This program also incorporates work previously released with lisk-js `v0.5.2` (and earlier) versions under the [MIT License](https://opensource.org/licenses/MIT). To comply with the requirements of that license, the following permission notice, applicable to those parts of the code only, is included below: + +Copyright © 2016-2017 Lisk Foundation + +Copyright © 2015 Crypti + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + +[Lisk Core GitHub]: https://github.com/LiskHQ/lisk +[Lisk documentation site]: https://lisk.io/documentation/lisk-elements diff --git a/elements/lisk-validator/browsertest b/elements/lisk-validator/browsertest new file mode 120000 index 00000000000..c5e729e5c6f --- /dev/null +++ b/elements/lisk-validator/browsertest @@ -0,0 +1 @@ +../../templates/browsertest.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/cypress b/elements/lisk-validator/cypress new file mode 120000 index 00000000000..958c42d1965 --- /dev/null +++ b/elements/lisk-validator/cypress @@ -0,0 +1 @@ +../../templates/cypress.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/cypress.json b/elements/lisk-validator/cypress.json new file mode 120000 index 00000000000..f9d7d1e5ad7 --- /dev/null +++ b/elements/lisk-validator/cypress.json @@ -0,0 +1 @@ +../../templates/cypress.json.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/package-lock.json b/elements/lisk-validator/package-lock.json new file mode 100644 index 00000000000..14a69343a55 --- /dev/null +++ b/elements/lisk-validator/package-lock.json @@ -0,0 +1,4923 @@ +{ + "name": "@liskhq/lisk-validator", + "version": "0.1.0-alpha.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/generator": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.4.tgz", + "integrity": "sha512-8EXhHRFqlVVWXPezBW5keTiQi/rJMQTg/Y9uVCEZ0CAF3PKtCCaVRnp64Ii1ujhkoDhhF1fVsImoN4yJ2uz4Wg==", + "dev": true, + "requires": { + "@babel/types": "^7.3.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.0.0.tgz", + "integrity": "sha512-MXkOJqva62dfC0w85mEf/LucPPS/1+04nmmRMPEBUB++hiiThQ2zPtX/mEWQ3mtzCEjIJvPY8nuwxXtQeQwUag==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.4.tgz", + "integrity": "sha512-tXZCqWtlOOP4wgCp6RjRvLmfuhnqTLy9VHwRochJBCP2nDm27JnnuFEnXFASVyQNHk36jD1tAammsCEEqgscIQ==", + "dev": true + }, + "@babel/template": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.2.2.tgz", + "integrity": "sha512-zRL0IMM02AUDwghf5LMSSDEz7sBCO2YnNmpg3uWTZj/v1rcG2BmQUvaGU8GhU8BvfMh1k2KIAYZ7Ji9KXPUg7g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.2.2", + "@babel/types": "^7.2.2" + } + }, + "@babel/traverse": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.3.4.tgz", + "integrity": "sha512-TvTHKp6471OYEcE/91uWmhR6PrrYywQntCHSaZ8CM8Vmp+pjAusal4nGB2WCCQd0rvI7nOMKn9GnbcvTUz3/ZQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.3.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.3.4", + "@babel/types": "^7.3.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.3.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.4.tgz", + "integrity": "sha512-WEkp8MsLftM7O/ty580wAmZzN1nDmCACc5+jFzUt+GUFNNIi3LdRlueYz0YIlmJhlZx1QYDMZL5vdWCL0fNjFQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "@cypress/listr-verbose-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@cypress/listr-verbose-renderer/-/listr-verbose-renderer-0.4.1.tgz", + "integrity": "sha1-p3SS9LEdzHxEajSz4ochr9M8ZCo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-cursor": "^1.0.2", + "date-fns": "^1.27.2", + "figures": "^1.7.0" + }, + "dependencies": { + "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" + } + }, + "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 + } + } + }, + "@cypress/xvfb": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@cypress/xvfb/-/xvfb-1.2.3.tgz", + "integrity": "sha512-yYrK+/bgL3hwoRHMZG4r5fyLniCy1pXex5fimtewAY6vE/jsVs8Q37UsEO03tFlcmiLnQ3rBNMaZBYTi/+C1cw==", + "dev": true, + "requires": { + "debug": "^3.1.0", + "lodash.once": "^4.1.1" + } + }, + "@liskhq/bignum": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@liskhq/bignum/-/bignum-1.3.1.tgz", + "integrity": "sha512-q9+NvqbpmXOqpPmV8Y+XSEIUJFMZDGyfW6rkN9Ej3nzPb/qurY/Ic2UPTeTTaj8+q/bcw5JUwTb86hi7PIziDg==", + "requires": { + "@types/node": "11.11.2" + }, + "dependencies": { + "@types/node": { + "version": "11.11.2", + "resolved": "https://registry.npmjs.org/@types/node/-/node-11.11.2.tgz", + "integrity": "sha512-iEaHiDNkHv4Jrm9O5T37OYEUwjJesiyt6ZlhLFK0sbo4CLD0jyCOB4Pc2F9iD3MbW2397SLNxZKdDGntGaBjQQ==" + } + } + }, + "@sinonjs/commons": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.4.0.tgz", + "integrity": "sha512-9jHK3YF/8HtJ9wCAbG+j8cD0i0+ATS9A7gXFqS36TblLPNy6rEEc+SB0imo91eCboGaBYGV/MT1/br/J+EE7Tw==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/formatio": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@sinonjs/formatio/-/formatio-3.2.1.tgz", + "integrity": "sha512-tsHvOB24rvyvV2+zKMmPkZ7dXX6LSLKZ7aOtXY6Edklp0uRcgGpOsQTTGTcWViFyx4uhWc6GV8QdnALbIbIdeQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1", + "@sinonjs/samsam": "^3.1.0" + } + }, + "@sinonjs/samsam": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-3.3.0.tgz", + "integrity": "sha512-beHeJM/RRAaLLsMJhsCvHK31rIqZuobfPLa/80yGH5hnD8PV1hyh9xJBJNFfNmO7yWqm+zomijHsXpI6iTQJfQ==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.0.2", + "array-from": "^2.1.1", + "lodash": "^4.17.11" + } + }, + "@sinonjs/text-encoding": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.1.tgz", + "integrity": "sha512-+iTbntw2IZPb/anVDbypzfQa+ay64MW0Zo8aJ8gZPWMMK6/OubMVb6lUPMagqjOPnmtauXnFCACVl3O7ogjeqQ==", + "dev": true + }, + "@types/blob-util": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@types/blob-util/-/blob-util-1.3.3.tgz", + "integrity": "sha512-4ahcL/QDnpjWA2Qs16ZMQif7HjGP2cw3AGjHabybjw7Vm1EKu+cfQN1D78BaZbS1WJNa1opSMF5HNMztx7lR0w==", + "dev": true + }, + "@types/bluebird": { + "version": "3.5.18", + "resolved": "https://registry.npmjs.org/@types/bluebird/-/bluebird-3.5.18.tgz", + "integrity": "sha512-OTPWHmsyW18BhrnG5x8F7PzeZ2nFxmHGb42bZn79P9hl+GI5cMzyPgQTwNjbem0lJhoru/8vtjAFCUOu3+gE2w==", + "dev": true + }, + "@types/chai": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.1.7.tgz", + "integrity": "sha512-2Y8uPt0/jwjhQ6EiluT0XCri1Dbplr0ZxfFXUz+ye13gaqE8u5gL5ppao1JrUYr9cIip5S6MvQzBS7Kke7U9VA==", + "dev": true + }, + "@types/chai-jquery": { + "version": "1.1.35", + "resolved": "https://registry.npmjs.org/@types/chai-jquery/-/chai-jquery-1.1.35.tgz", + "integrity": "sha512-7aIt9QMRdxuagLLI48dPz96YJdhu64p6FCa6n4qkGN5DQLHnrIjZpD9bXCvV2G0NwgZ1FAmfP214dxc5zNCfgQ==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/jquery": "*" + } + }, + "@types/expect": { + "version": "1.20.3", + "resolved": "https://registry.npmjs.org/@types/expect/-/expect-1.20.3.tgz", + "integrity": "sha512-g0+CQosizg1hjNn06fKB2tEvS5kExrvVOkIfsGuIRfsQ/A9u/Xjp/6/czJVyLuCYdkmMbplDUXvQW+YjBQK7dA==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.29", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.29.tgz", + "integrity": "sha512-FhJvBninYD36v3k6c+bVk1DSZwh7B5Dpb/Pyk3HKVsiohn0nhbefZZ+3JXbWQhFyt0MxSl2jRDdGQPHeOHFXrQ==", + "dev": true, + "requires": { + "@types/sizzle": "*" + } + }, + "@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/lodash": { + "version": "4.14.87", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.87.tgz", + "integrity": "sha512-AqRC+aEF4N0LuNHtcjKtvF9OTfqZI0iaBoe3dA6m/W+/YZJBZjBmW/QIZ8fBeXC6cnytSY9tBoFBqZ9uSCeVsw==", + "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/mocha": { + "version": "5.2.5", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.5.tgz", + "integrity": "sha512-lAVp+Kj54ui/vLUFxsJTMtWvZraZxum3w3Nwkble2dNuV5VnPA+Mi2oGX9XYJAaIvZi3tn3cbjS/qcJXRb6Bww==", + "dev": true + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==" + }, + "@types/semver": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-5.5.0.tgz", + "integrity": "sha512-41qEJgBH/TWgo5NFSvBCJ1qkoi3Q6ONSF2avrHq1LVEZfYpdHmj0y9SuTK+u9ZhG1sYQKBL1AWXKyLWP4RaUoQ==" + }, + "@types/sinon": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.0.tgz", + "integrity": "sha512-kcYoPw0uKioFVC/oOqafk2yizSceIQXCYnkYts9vJIwQklFRsMubTObTDrjQamUyBRd47332s85074cd/hCwxg==", + "dev": true + }, + "@types/sinon-chai": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@types/sinon-chai/-/sinon-chai-3.2.2.tgz", + "integrity": "sha512-5zSs2AslzyPZdOsbm2NRtuSNAI2aTWzNKOHa/GRecKo7a5efYD7qGcPxMZXQDayVXT2Vnd5waXxBvV31eCZqiA==", + "dev": true, + "requires": { + "@types/chai": "*", + "@types/sinon": "*" + } + }, + "@types/sizzle": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.2.tgz", + "integrity": "sha512-7EJYyKTL7tFR8+gDbB6Wwz/arpGa0Mywk1TJbNzKzHtzbwVmY4HR9WqS5VV7dsBUKQmPNr192jHr/VpBluj/hg==", + "dev": true + }, + "@types/validator": { + "version": "10.9.0", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-10.9.0.tgz", + "integrity": "sha512-mf0VpXk+NoTmkUmuJCsdwBYxjYZW41amCSzd4t/fABMKl+qGMViwFP0pR7ukFdZRXWI1LIkca3VIbXVBmWZ4kQ==" + }, + "@types/verror": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.3.tgz", + "integrity": "sha512-7Jz0MPsW2pWg5dJfEp9nJYI0RDCYfgjg2wIo5HfQ8vOJvUq0/BxT7Mv2wNQvkKBmV9uT++6KF3reMnLmh/0HrA==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-dynamic-import": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/acorn-dynamic-import/-/acorn-dynamic-import-4.0.0.tgz", + "integrity": "sha512-d3OEjQV4ROpoflsnUA8HozoIR504TFxNivYEUi6uwz0IYhBkTDXGuWlNdMtybRt3nqVx/L6XqMt0FxkXuWKZhw==", + "dev": true + }, + "acorn-node": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.6.2.tgz", + "integrity": "sha512-rIhNEZuNI8ibQcL7ANm/mGyPukIaZsRNX9psFNQURyJW0nu6k8wjSDld20z6v2mDBWqX13pIEnk9gGZJHIlEXg==", + "dev": true, + "requires": { + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", + "xtend": "^4.0.1" + } + }, + "acorn-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, + "ajv": { + "version": "6.9.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz", + "integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==", + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-merge-patch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ajv-merge-patch/-/ajv-merge-patch-4.1.0.tgz", + "integrity": "sha512-0mAYXMSauA8RZ7r+B4+EAOYcZEcO9OK5EiQCR7W7Cv4E44pJj56ZnkKLJ9/PAcOc0dT+LlV9fdDcq2TxVJfOYw==", + "requires": { + "fast-json-patch": "^2.0.6", + "json-merge-patch": "^0.2.3" + } + }, + "ansi-escapes": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", + "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 + }, + "arg": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.0.tgz", + "integrity": "sha512-ZWc51jO3qegGkVh8Hwpv636EkbesNV5ZNQPCtRa+0qytRYPEs9IYT9qITY9buezqUH5uqyzlWLcufrzU2rffdg==", + "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" + } + }, + "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-from": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/array-from/-/array-from-2.1.1.tgz", + "integrity": "sha1-z+nYwmYoudxa7MYqn12PHzUsEZU=", + "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 + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "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" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "async": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/async/-/async-2.4.0.tgz", + "integrity": "sha1-SZAgDxjqW4N8LMT4wDGmmFw4VhE=", + "dev": true, + "requires": { + "lodash": "^4.14.0" + } + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=", + "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.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "babel-runtime": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", + "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", + "dev": true, + "requires": { + "core-js": "^2.4.0", + "regenerator-runtime": "^0.11.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base64-js": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", + "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", + "dev": true + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + } + }, + "bluebird": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz", + "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw=", + "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==", + "dev": true + }, + "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" + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browser-pack": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.1.0.tgz", + "integrity": "sha512-erYug8XoqzU3IfcU8fUgyHqyOXqIE4tUTTQ+7mqUjQlvnXkOO6OlT9c/ZoJVHYoAaqGxr09CN53G7XIsO4KtWA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "combine-source-map": "~0.8.0", + "defined": "^1.0.0", + "safe-buffer": "^5.1.1", + "through2": "^2.0.0", + "umd": "^3.0.0" + } + }, + "browser-resolve": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.3.tgz", + "integrity": "sha512-exDi1BYWB/6raKHmDTCicQfTkqwN5fioMFV4j8BsfMU4R2DK/QfZfK7kOVkmWCNANf0snkBzqGqAJBao9gZMdQ==", + "dev": true, + "requires": { + "resolve": "1.1.7" + }, + "dependencies": { + "resolve": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", + "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", + "dev": true + } + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "browserify": { + "version": "16.2.3", + "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.2.3.tgz", + "integrity": "sha512-zQt/Gd1+W+IY+h/xX2NYMW4orQWhqSwyV+xsblycTtpOuB27h1fZhhNQuipJ4t79ohw4P4mMem0jp/ZkISQtjQ==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "assert": "^1.4.0", + "browser-pack": "^6.0.1", + "browser-resolve": "^1.11.0", + "browserify-zlib": "~0.2.0", + "buffer": "^5.0.2", + "cached-path-relative": "^1.0.0", + "concat-stream": "^1.6.0", + "console-browserify": "^1.1.0", + "constants-browserify": "~1.0.0", + "crypto-browserify": "^3.0.0", + "defined": "^1.0.0", + "deps-sort": "^2.0.0", + "domain-browser": "^1.2.0", + "duplexer2": "~0.1.2", + "events": "^2.0.0", + "glob": "^7.1.0", + "has": "^1.0.0", + "htmlescape": "^1.1.0", + "https-browserify": "^1.0.0", + "inherits": "~2.0.1", + "insert-module-globals": "^7.0.0", + "labeled-stream-splicer": "^2.0.0", + "mkdirp": "^0.5.0", + "module-deps": "^6.0.0", + "os-browserify": "~0.3.0", + "parents": "^1.0.1", + "path-browserify": "~0.0.0", + "process": "~0.11.0", + "punycode": "^1.3.2", + "querystring-es3": "~0.2.0", + "read-only-stream": "^2.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.1.4", + "shasum": "^1.0.0", + "shell-quote": "^1.6.1", + "stream-browserify": "^2.0.0", + "stream-http": "^2.0.0", + "string_decoder": "^1.1.1", + "subarg": "^1.0.0", + "syntax-error": "^1.1.1", + "through2": "^2.0.0", + "timers-browserify": "^1.0.1", + "tty-browserify": "0.0.1", + "url": "~0.11.0", + "util": "~0.10.1", + "vm-browserify": "^1.0.0", + "xtend": "^4.0.0" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "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.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "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" + } + }, + "buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "cached-path-relative": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.2.tgz", + "integrity": "sha512-5r2GqsoEb4qMTTN9J+WzXfjov+hjxT+j3u5K+kIVNIwAd99DLCJE9pBIMP1qVeybV6JiijL385Oz0DcYxfbOIg==", + "dev": true + }, + "cachedir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-1.3.0.tgz", + "integrity": "sha512-O1ji32oyON9laVPJL1IZ5bmwd2cB46VfpxkDequezH+15FDzzVddEyrGEeX4WusDSqKxdyFdDQDEG1yo1GoWkg==", + "dev": true, + "requires": { + "os-homedir": "^1.0.1" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "chalk": { + "version": "2.4.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" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "check-more-types": { + "version": "2.24.0", + "resolved": "https://registry.npmjs.org/check-more-types/-/check-more-types-2.24.0.tgz", + "integrity": "sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=", + "dev": true + }, + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "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==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "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" + } + }, + "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-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" + } + }, + "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 + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "colors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", + "dev": true + }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha1-pY0N8ELBhvz4IqjoAV9UUNLXmos=", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "dev": true + }, + "common-tags": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/common-tags/-/common-tags-1.4.0.tgz", + "integrity": "sha1-EYe+Tz1M8MBCfUP3Tu8fc1AWFMA=", + "dev": true, + "requires": { + "babel-runtime": "^6.18.0" + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha1-SCnId+n+SbMWHzvzZziI4gRpmGA=", + "dev": true + }, + "core-js": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", + "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "corser": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", + "integrity": "sha1-jtolLsqrWEDc2XXOuQ2TcMgZ/4c=", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "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" + } + }, + "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" + } + }, + "cypress": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/cypress/-/cypress-3.1.5.tgz", + "integrity": "sha512-jzYGKJqU1CHoNocPndinf/vbG28SeU+hg+4qhousT/HDBMJxYgjecXOmSgBX/ga9/TakhqSrIrSP2r6gW/OLtg==", + "dev": true, + "requires": { + "@cypress/listr-verbose-renderer": "0.4.1", + "@cypress/xvfb": "1.2.3", + "@types/blob-util": "1.3.3", + "@types/bluebird": "3.5.18", + "@types/chai": "4.0.8", + "@types/chai-jquery": "1.1.35", + "@types/jquery": "3.3.6", + "@types/lodash": "4.14.87", + "@types/minimatch": "3.0.3", + "@types/mocha": "2.2.44", + "@types/sinon": "7.0.0", + "@types/sinon-chai": "3.2.2", + "bluebird": "3.5.0", + "cachedir": "1.3.0", + "chalk": "2.4.1", + "check-more-types": "2.24.0", + "commander": "2.11.0", + "common-tags": "1.4.0", + "debug": "3.1.0", + "execa": "0.10.0", + "executable": "4.1.1", + "extract-zip": "1.6.6", + "fs-extra": "4.0.1", + "getos": "3.1.0", + "glob": "7.1.2", + "is-ci": "1.0.10", + "is-installed-globally": "0.1.0", + "lazy-ass": "1.6.0", + "listr": "0.12.0", + "lodash": "4.17.11", + "log-symbols": "2.2.0", + "minimist": "1.2.0", + "moment": "2.22.2", + "ramda": "0.24.1", + "request": "2.87.0", + "request-progress": "0.3.1", + "supports-color": "5.1.0", + "tmp": "0.0.31", + "url": "0.11.0", + "yauzl": "2.8.0" + }, + "dependencies": { + "@types/chai": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.0.8.tgz", + "integrity": "sha512-m812CONwdZn/dMzkIJEY0yAs4apyTkTORgfB2UsMOxgkUbC205AHnm4T8I0I5gPg9MHrFc1dJ35iS75c0CJkjg==", + "dev": true + }, + "@types/jquery": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.3.6.tgz", + "integrity": "sha512-403D4wN95Mtzt2EoQHARf5oe/jEPhzBOBNrunk+ydQGW8WmkQ/E8rViRAEB1qEt/vssfGfNVD6ujP4FVeegrLg==", + "dev": true + }, + "@types/mocha": { + "version": "2.2.44", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz", + "integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + } + } + }, + "dash-ast": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dash-ast/-/dash-ast-1.0.0.tgz", + "integrity": "sha512-Vy4dx7gquTeMcQR/hDkYLGUnwVil6vk4FOOct+djUnHOUWt+zJPJAaRIXaAFkPXtJjvlY7o3rfRu0/3hpnwoUA==", + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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 + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "deep-equal": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", + "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU=" + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "defined": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz", + "integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM=", + "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 + }, + "deps-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/deps-sort/-/deps-sort-2.0.0.tgz", + "integrity": "sha1-CRckkC6EZYJg65EHSMzNGvbiH7U=", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "shasum": "^1.0.0", + "subarg": "^1.0.0", + "through2": "^2.0.0" + } + }, + "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" + } + }, + "detective": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/detective/-/detective-5.2.0.tgz", + "integrity": "sha512-6SsIx+nUUbuK0EthKjv0zrdnajCCXVYGmbYYiYjFVpzcjwEs/JMDZ8tPRG29J/HhN56t3GJp2cGSWDRjjot8Pg==", + "dev": true, + "requires": { + "acorn-node": "^1.6.1", + "defined": "^1.0.0", + "minimist": "^1.1.1" + } + }, + "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" + } + }, + "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 + }, + "duplexer2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", + "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "ecc-jsbn": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "ecstatic": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/ecstatic/-/ecstatic-3.3.1.tgz", + "integrity": "sha512-/rrctvxZ78HMI/tPIsqdvFKHHscxR3IJuKrZI2ZoUgkt2SiufyLFBmcco+aqQBIu6P1qBsUNG3drAAGLx80vTQ==", + "dev": true, + "requires": { + "he": "^1.1.1", + "mime": "^1.6.0", + "minimist": "^1.1.0", + "url-join": "^2.0.5" + } + }, + "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.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", + "dev": true, + "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" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "eventemitter3": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz", + "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==", + "dev": true + }, + "events": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", + "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" + } + }, + "execa": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.10.0.tgz", + "integrity": "sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "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" + } + }, + "executable": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz", + "integrity": "sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==", + "dev": true, + "requires": { + "pify": "^2.2.0" + } + }, + "exit-hook": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz", + "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g=", + "dev": true + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extract-zip": { + "version": "1.6.6", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz", + "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=", + "dev": true, + "requires": { + "concat-stream": "1.6.0", + "debug": "2.6.9", + "mkdirp": "0.5.0", + "yauzl": "2.4.1" + }, + "dependencies": { + "concat-stream": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz", + "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "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" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz", + "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "yauzl": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", + "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "dev": true, + "requires": { + "fd-slicer": "~1.0.1" + } + } + } + }, + "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": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" + }, + "fast-json-patch": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-2.0.7.tgz", + "integrity": "sha512-DQeoEyPYxdTtfmB3yDlxkLyKTdbJ6ABfFGcMynDqjvGhPYLto/pZyb/dG2Nyd/n9CArjEWN9ZST++AFmgzgbGw==", + "requires": { + "deep-equal": "^1.0.1" + } + }, + "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=" + }, + "fd-slicer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", + "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "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" + } + }, + "follow-redirects": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.7.0.tgz", + "integrity": "sha512-m/pZQy4Gj287eNy94nivy5wchN3Kp+Q5WgUPNy5lJSZ3sgkVKSYV/ZChMAQVIgx1SqfZ2zBZtPA2YlXIWxxJOQ==", + "dev": true, + "requires": { + "debug": "^3.2.6" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "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.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + } + }, + "fs-extra": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.1.tgz", + "integrity": "sha1-f8DGyJV/mD9X8waiTlud3Y0N2IA=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^3.0.0", + "universalify": "^0.1.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-assigned-identifiers": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-assigned-identifiers/-/get-assigned-identifiers-1.2.0.tgz", + "integrity": "sha512-mBBwmeGTrxEMO4pMaaf/uUEFHnYtwr8FTe8Y/mer4rcV/bye0qGm6pw1bGZFGStxC5O76c5ZAVBGnqHmOaJpdQ==", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", + "dev": true + }, + "getos": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/getos/-/getos-3.1.0.tgz", + "integrity": "sha512-i9vrxtDu5DlLVFcrbqUqGWYlZN/zZ4pGMICCAcZoYsX3JA54nYp8r5EThw5K+m2q3wszkx4Th746JstspB0H4Q==", + "dev": true, + "requires": { + "async": "2.4.0" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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" + } + }, + "global-dirs": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/global-dirs/-/global-dirs-0.1.1.tgz", + "integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=", + "dev": true, + "requires": { + "ini": "^1.3.4" + } + }, + "globals": { + "version": "11.11.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.11.0.tgz", + "integrity": "sha512-WHq43gS+6ufNOEqlrDBxVEbb8ntfXrfAUU2ZOpCxrBdGKW3gyv8mCxAfIBD0DroPKGrJ2eSsXsLtY9MPntsyTw==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=", + "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" + }, + "dependencies": { + "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" + } + }, + "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 + }, + "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 + } + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "hash-base": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", + "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "hoek": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.4.tgz", + "integrity": "sha512-Alr4ZQgoMlnere5FZJsIyfIjORBqZll5POhDsF4q64dPuJR6rNxXdDxtHSQq8OXRurhmx+PWYEE8bXRROY8h0w==", + "dev": true + }, + "htmlescape": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", + "dev": true + }, + "http-proxy": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz", + "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==", + "dev": true, + "requires": { + "eventemitter3": "^3.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-server": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/http-server/-/http-server-0.11.1.tgz", + "integrity": "sha512-6JeGDGoujJLmhjiRGlt8yK8Z9Kl0vnl/dQoQZlc4oeqaUoAKQg94NILLfrY3oWzSyFaQCVNTcKE5PZ3cH8VP9w==", + "dev": true, + "requires": { + "colors": "1.0.3", + "corser": "~2.0.0", + "ecstatic": "^3.0.0", + "http-proxy": "^1.8.1", + "opener": "~1.4.0", + "optimist": "0.6.x", + "portfinder": "^1.0.13", + "union": "~0.4.3" + } + }, + "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 + }, + "ieee754": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.12.tgz", + "integrity": "sha512-GguP+DRY+pJ3soyIiGPTvdiVXjZ+DbXOxGpXn3eMvNW4x4irjqXm4wHKscC+TfxSJ0yw/S1F24tqdMNsMZTiLA==", + "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" + } + }, + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha1-+Tk0ccGKedFyT4Y/o4tYY3Ct4qU=", + "dev": true, + "requires": { + "source-map": "~0.5.3" + } + }, + "insert-module-globals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.2.0.tgz", + "integrity": "sha512-VE6NlW+WGn2/AeOMd496AHFYmE7eLKkUY6Ty31k4og5vmA3Fjuwe9v6ifH6Xx/Hz27QvdoMoviw1/pqWRB09Sw==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", + "is-buffer": "^1.1.0", + "path-is-absolute": "^1.0.1", + "process": "~0.11.0", + "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", + "xtend": "^4.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-ci": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.0.10.tgz", + "integrity": "sha1-9zkzayYyNlBhqdSCcM1WrjNpMY4=", + "dev": true, + "requires": { + "ci-info": "^1.0.0" + } + }, + "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": "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" + } + }, + "is-installed-globally": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-installed-globally/-/is-installed-globally-0.1.0.tgz", + "integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=", + "dev": true, + "requires": { + "global-dirs": "^0.1.0", + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isemail": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.2.0.tgz", + "integrity": "sha512-zKqkK+O+dGqevc93KNsbZ/TqTUFd46MwWjYOoMrjIMZ51eU7DtQG3Wmd9SQQT7i7RVnuTPEiYEWHU3MSbxC1Tg==", + "dev": true, + "requires": { + "punycode": "2.x.x" + } + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "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-lib-coverage": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.3.tgz", + "integrity": "sha512-dKWuzRGCs4G+67VfW9pBFFz2Jpi4vSp/k7zBcJ888ofV5Mi1g5CUML5GvMvV6u9Cjybftu+E8Cgp+k0dI1E5lw==", + "dev": true + }, + "istanbul-lib-instrument": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-3.1.0.tgz", + "integrity": "sha512-ooVllVGT38HIk8MxDj/OIHXSYvH+1tq/Vb38s8ixt9GoJadXska4WkGY+0wkmtYCZNYtaARniH/DixUGGLZ0uA==", + "dev": true, + "requires": { + "@babel/generator": "^7.0.0", + "@babel/parser": "^7.0.0", + "@babel/template": "^7.0.0", + "@babel/traverse": "^7.0.0", + "@babel/types": "^7.0.0", + "istanbul-lib-coverage": "^2.0.3", + "semver": "^5.5.0" + } + }, + "joi": { + "version": "13.7.0", + "resolved": "https://registry.npmjs.org/joi/-/joi-13.7.0.tgz", + "integrity": "sha512-xuY5VkHfeOYK3Hdi91ulocfuFopwgbSORmIwzcwHKESQhC7w1kD5jaVSPnqDxS2I8t3RZ9omCKAxNwXN5zG1/Q==", + "dev": true, + "requires": { + "hoek": "5.x.x", + "isemail": "3.x.x", + "topo": "3.x.x" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.2.tgz", + "integrity": "sha512-QHn/Lh/7HhZ/Twc7vJYQTkjuCa0kaCcDcjK5Zlk2rvnUpy7DxMJ23+Jc2dcyvltwQVg1nygAVlB2oRDFHoRS5Q==", + "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 + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-merge-patch": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/json-merge-patch/-/json-merge-patch-0.2.3.tgz", + "integrity": "sha1-+ixrWvh9p3uuKWalidUuI+2B/kA=", + "requires": { + "deep-equal": "^1.0.0" + } + }, + "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.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + }, + "json-stable-stringify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-0.0.1.tgz", + "integrity": "sha1-YRwj6BTbN1Un34URk9tZ3Sryf0U=", + "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": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "jsonfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-3.0.1.tgz", + "integrity": "sha1-pezG9l9T9mLEQVx2daAzHQmS7GY=", + "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 + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "just-extend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.0.2.tgz", + "integrity": "sha512-FrLwOgm+iXrPV+5zDU6Jqu4gCRXbWEQg2O3SKONsWE4w7AXFRkryS53bpWdaL9cNol+AmR3AEYz6kn+o0fCPnw==", + "dev": true + }, + "labeled-stream-splicer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.1.tgz", + "integrity": "sha512-MC94mHZRvJ3LfykJlTUipBqenZz1pacOZEMhhQ8dMGcDHs0SBE5GbsavUXV7YtP3icBW17W0Zy1I0lfASmo9Pg==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "isarray": "^2.0.4", + "stream-splicer": "^2.0.0" + }, + "dependencies": { + "isarray": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", + "dev": true + } + } + }, + "lazy-ass": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/lazy-ass/-/lazy-ass-1.6.0.tgz", + "integrity": "sha1-eZllXoZGwX8In90YfRUNMyTVRRM=", + "dev": true + }, + "listr": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.12.0.tgz", + "integrity": "sha1-a84sD1YD+klYDqF81qAMwOX6RRo=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "cli-truncate": "^0.2.1", + "figures": "^1.7.0", + "indent-string": "^2.1.0", + "is-promise": "^2.1.0", + "is-stream": "^1.1.0", + "listr-silent-renderer": "^1.1.1", + "listr-update-renderer": "^0.2.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": "^5.0.0-beta.11", + "stream-to-observable": "^0.1.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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.2.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.2.0.tgz", + "integrity": "sha1-yoDhd5tOcCZoB+ju0a1qvjmFUPk=", + "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": { + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "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": { + "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" + } + }, + "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 + } + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha1-LcvSwofLwKVcxCMovQxzYVDVPj8=", + "dev": true + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=", + "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" + } + }, + "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" + } + }, + "lolex": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-3.1.0.tgz", + "integrity": "sha512-zFo5MgCJ0rZ7gQg69S4pqBsLURbFw11X68C18OcJjJQbqaXm2NoTrGl1IMM3TIz0/BnN1tIs2tzmmqvCsOMMjw==", + "dev": true + }, + "make-error": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.5.tgz", + "integrity": "sha512-c3sIjNUow0+8swNwVpqoH4YCShKNFkMaw6oH1mNS2haDZQqkeZFlHS3dhoeEbKKmJB4vXpJucU6oH75aDYeE9g==", + "dev": true + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.38.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.38.0.tgz", + "integrity": "sha512-bqVioMFFzc2awcdJZIzR3HjZFX20QhilVS7hytkKrv7xFAn8bM1gzc/FOX2awLISvWe0PV8ptFKcon+wZ5qYkg==", + "dev": true + }, + "mime-types": { + "version": "2.1.22", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.22.tgz", + "integrity": "sha512-aGl6TZGnhm/li6F7yx82bJiBZwgiEa4Hf6CNr8YO+r5UHr53tSTYZb102zyU50DOWWKeOv0uQLRL0/9EiKWCog==", + "dev": true, + "requires": { + "mime-db": "~1.38.0" + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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=", + "dev": true + }, + "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": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + } + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + }, + "dependencies": { + "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 + }, + "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" + } + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "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" + } + } + } + }, + "module-deps": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.2.0.tgz", + "integrity": "sha512-hKPmO06so6bL/ZvqVNVqdTVO8UAYsi3tQWlCa+z9KuWhoN4KDQtb5hcqQQv58qYiDE21wIvnttZEPiDgEbpwbA==", + "dev": true, + "requires": { + "JSONStream": "^1.0.3", + "browser-resolve": "^1.7.0", + "cached-path-relative": "^1.0.0", + "concat-stream": "~1.6.0", + "defined": "^1.0.0", + "detective": "^5.0.2", + "duplexer2": "^0.1.2", + "inherits": "^2.0.1", + "parents": "^1.0.0", + "readable-stream": "^2.0.2", + "resolve": "^1.4.0", + "stream-combiner2": "^1.1.1", + "subarg": "^1.0.0", + "through2": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "moment": { + "version": "2.22.2", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.2.tgz", + "integrity": "sha1-PCV/mDn8DpP/UxSWMiOeuQeD/2Y=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "nise": { + "version": "1.4.10", + "resolved": "https://registry.npmjs.org/nise/-/nise-1.4.10.tgz", + "integrity": "sha512-sa0RRbj53dovjc7wombHmVli9ZihXbXCQ2uH3TNm03DyvOSIQbxg+pbqDKrk2oxMK1rtLGVlKxcB9rrc6X5YjA==", + "dev": true, + "requires": { + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/text-encoding": "^0.7.1", + "just-extend": "^4.0.2", + "lolex": "^2.3.2", + "path-to-regexp": "^1.7.0" + }, + "dependencies": { + "lolex": { + "version": "2.7.5", + "resolved": "https://registry.npmjs.org/lolex/-/lolex-2.7.5.tgz", + "integrity": "sha512-l9x0+1offnKKIzYVjyXU2SiwhXDLekRzKyhnbyldPHvC7BvLPVpdNUNR2KeMAiCN2D/kLNttZgQD5WjSxuBx3Q==", + "dev": true + } + } + }, + "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 + }, + "nyc": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-13.2.0.tgz", + "integrity": "sha512-gQBlOqvfpYt9b2PZ7qElrHWt8x4y8ApNfbMBoDPdl3sY4/4RJwCxDGTSqhA9RnaguZjS5nW7taW8oToe86JLgQ==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "arrify": "^1.0.1", + "caching-transform": "^3.0.1", + "convert-source-map": "^1.6.0", + "find-cache-dir": "^2.0.0", + "find-up": "^3.0.0", + "foreground-child": "^1.5.6", + "glob": "^7.1.3", + "istanbul-lib-coverage": "^2.0.3", + "istanbul-lib-hook": "^2.0.3", + "istanbul-lib-instrument": "^3.0.1", + "istanbul-lib-report": "^2.0.4", + "istanbul-lib-source-maps": "^3.0.2", + "istanbul-reports": "^2.1.0", + "make-dir": "^1.3.0", + "merge-source-map": "^1.1.0", + "resolve-from": "^4.0.0", + "rimraf": "^2.6.3", + "signal-exit": "^3.0.2", + "spawn-wrap": "^1.4.2", + "test-exclude": "^5.1.0", + "uuid": "^3.3.2", + "yargs": "^12.0.5", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "append-transform": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "default-require-extensions": "^2.0.0" + } + }, + "archy": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "arrify": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "async": { + "version": "2.6.1", + "bundled": true, + "dev": true, + "requires": { + "lodash": "^4.17.10" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "bundled": true, + "dev": true + }, + "caching-transform": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "hasha": "^3.0.0", + "make-dir": "^1.3.0", + "package-hash": "^3.0.0", + "write-file-atomic": "^2.3.0" + } + }, + "camelcase": { + "version": "5.0.0", + "bundled": true, + "dev": true + }, + "cliui": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "commander": { + "version": "2.17.1", + "bundled": true, + "dev": true, + "optional": true + }, + "commondir": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "bundled": true, + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cross-spawn": { + "version": "4.0.2", + "bundled": true, + "dev": true, + "requires": { + "lru-cache": "^4.0.1", + "which": "^1.2.9" + } + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "decamelize": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "default-require-extensions": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "strip-bom": "^3.0.0" + } + }, + "end-of-stream": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "error-ex": { + "version": "1.3.2", + "bundled": true, + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-error": { + "version": "4.1.1", + "bundled": true, + "dev": true + }, + "execa": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "bundled": true, + "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" + } + } + } + }, + "find-cache-dir": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^1.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "foreground-child": { + "version": "1.5.6", + "bundled": true, + "dev": true, + "requires": { + "cross-spawn": "^4", + "signal-exit": "^3.0.0" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "bundled": true, + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "bundled": true, + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "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" + } + }, + "graceful-fs": { + "version": "4.1.15", + "bundled": true, + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "bundled": true, + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "has-flag": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "hasha": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "is-stream": "^1.0.1" + } + }, + "hosted-git-info": { + "version": "2.7.1", + "bundled": true, + "dev": true + }, + "imurmurhash": { + "version": "0.1.4", + "bundled": true, + "dev": true + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "invert-kv": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "bundled": true, + "dev": true + }, + "is-builtin-module": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "builtin-modules": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "isexe": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "istanbul-lib-coverage": { + "version": "2.0.3", + "bundled": true, + "dev": true + }, + "istanbul-lib-hook": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "requires": { + "append-transform": "^1.0.0" + } + }, + "istanbul-lib-report": { + "version": "2.0.4", + "bundled": true, + "dev": true, + "requires": { + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "supports-color": "^6.0.0" + }, + "dependencies": { + "supports-color": { + "version": "6.1.0", + "bundled": true, + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "istanbul-lib-source-maps": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "requires": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^2.0.3", + "make-dir": "^1.3.0", + "rimraf": "^2.6.2", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "istanbul-reports": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "handlebars": "^4.0.11" + } + }, + "json-parse-better-errors": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "lcid": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "load-json-file": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "bundled": true, + "dev": true + }, + "lodash.flattendeep": { + "version": "4.4.0", + "bundled": true, + "dev": true + }, + "lru-cache": { + "version": "4.1.5", + "bundled": true, + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "make-dir": { + "version": "1.3.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "bundled": true, + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "mem": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^1.1.0" + } + }, + "merge-source-map": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true + } + } + }, + "mimic-fn": { + "version": "1.2.0", + "bundled": true, + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.10", + "bundled": true, + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "0.0.8" + }, + "dependencies": { + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "bundled": true, + "dev": true + }, + "normalize-package-data": { + "version": "2.4.0", + "bundled": true, + "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" + } + }, + "npm-run-path": { + "version": "2.0.2", + "bundled": true, + "dev": true, + "requires": { + "path-key": "^2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "optimist": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "requires": { + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "p-is-promise": { + "version": "1.1.0", + "bundled": true, + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "package-hash": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^3.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + } + }, + "parse-json": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "path-key": { + "version": "2.0.1", + "bundled": true, + "dev": true + }, + "path-type": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "pify": "^3.0.0" + } + }, + "pify": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "pkg-dir": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "pump": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "read-pkg": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "find-up": "^3.0.0", + "read-pkg": "^3.0.0" + } + }, + "release-zalgo": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, + "require-directory": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "bundled": true, + "dev": true + }, + "resolve-from": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true + }, + "semver": { + "version": "5.6.0", + "bundled": true, + "dev": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true + }, + "spawn-wrap": { + "version": "1.4.2", + "bundled": true, + "dev": true, + "requires": { + "foreground-child": "^1.5.6", + "mkdirp": "^0.5.0", + "os-homedir": "^1.0.1", + "rimraf": "^2.6.2", + "signal-exit": "^3.0.2", + "which": "^1.3.0" + } + }, + "spdx-correct": { + "version": "3.1.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "bundled": true, + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "bundled": true, + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.3", + "bundled": true, + "dev": true + }, + "string-width": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "bundled": true, + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "bundled": true, + "dev": true + }, + "test-exclude": { + "version": "5.1.0", + "bundled": true, + "dev": true, + "requires": { + "arrify": "^1.0.1", + "minimatch": "^3.0.4", + "read-pkg-up": "^4.0.0", + "require-main-filename": "^1.0.1" + } + }, + "uglify-js": { + "version": "3.4.9", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "uuid": { + "version": "3.3.2", + "bundled": true, + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "bundled": true, + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "bundled": true, + "dev": true + }, + "wordwrap": { + "version": "0.0.3", + "bundled": true, + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "bundled": true, + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true + }, + "write-file-atomic": { + "version": "2.4.2", + "bundled": true, + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "y18n": { + "version": "4.0.0", + "bundled": true, + "dev": true + }, + "yallist": { + "version": "2.1.2", + "bundled": true, + "dev": true + }, + "yargs": { + "version": "12.0.5", + "bundled": true, + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + } + }, + "yargs-parser": { + "version": "11.1.1", + "bundled": true, + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "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 + }, + "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": "1.1.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz", + "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=", + "dev": true + }, + "opener": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", + "integrity": "sha1-XG2ixdflgx6P+jlklQ+NZnSskLg=", + "dev": true + }, + "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" + }, + "dependencies": { + "minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", + "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": { + "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" + } + }, + "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 + } + } + }, + "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-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-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "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 + }, + "pako": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", + "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", + "dev": true + }, + "parents": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parents/-/parents-1.0.1.tgz", + "integrity": "sha1-/t1NK/GTp3dF/nHjcdc8MwfZx1E=", + "dev": true, + "requires": { + "path-platform": "~0.11.15" + } + }, + "parse-asn1": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", + "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", + "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", + "safe-buffer": "^5.1.1" + } + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-platform": { + "version": "0.11.15", + "resolved": "https://registry.npmjs.org/path-platform/-/path-platform-0.11.15.tgz", + "integrity": "sha1-6GQhf3TDaFDwhSt43Hv31KVyG/I=", + "dev": true + }, + "path-to-regexp": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.7.0.tgz", + "integrity": "sha1-Wf3g9DW62suhA6hOnTvGTpa5k30=", + "dev": true, + "requires": { + "isarray": "0.0.1" + }, + "dependencies": { + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + } + } + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "pbkdf2": { + "version": "3.0.17", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", + "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", + "dev": true + }, + "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": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "portfinder": { + "version": "1.0.20", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.20.tgz", + "integrity": "sha512-Yxe4mTyDzTd59PZJY4ojZR8F+E5e97iq2ZOHPz3HDgSvYC5siNad2tLooQ5y5QHyQhc3xVqvyk/eNA3wuoa7Sw==", + "dev": true, + "requires": { + "async": "^1.5.2", + "debug": "^2.2.0", + "mkdirp": "0.5.x" + }, + "dependencies": { + "async": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "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", + "safe-buffer": "^5.1.2" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" + }, + "qs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz", + "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==", + "dev": true + }, + "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 + }, + "ramda": { + "version": "0.24.1", + "resolved": "https://registry.npmjs.org/ramda/-/ramda-0.24.1.tgz", + "integrity": "sha1-w7d1UZfzW43DUCIoJixMkd22uFc=", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "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-only-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-only-stream/-/read-only-stream-2.0.0.tgz", + "integrity": "sha1-JyT9aoET1zdkrCiNQ4YnDB2/F/A=", + "dev": true, + "requires": { + "readable-stream": "^2.0.2" + } + }, + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "regenerator-runtime": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "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" + } + }, + "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-progress": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-0.3.1.tgz", + "integrity": "sha1-ByHBBdipasayzossia4tXs/Pazo=", + "dev": true, + "requires": { + "throttleit": "~0.0.2" + } + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "rx": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz", + "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=", + "dev": true + }, + "rxjs": { + "version": "5.5.12", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-5.5.12.tgz", + "integrity": "sha512-xx2itnL5sBbqeeiVgNPVuQQ1nC8Jp2WfNJhXWHmElW9YmrpS9UVnNzhP3EH3HFqexO5Tlp8GhYY+WEcqcVMvGw==", + "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==", + "dev": true + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==" + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shasum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", + "dev": true, + "requires": { + "json-stable-stringify": "~0.0.0", + "sha.js": "~2.4.4" + } + }, + "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" + } + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, + "sinon": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-7.2.3.tgz", + "integrity": "sha512-i6j7sqcLEqTYqUcMV327waI745VASvYuSuQMCjbAwlpAeuCgKZ3LtrjDxAbu+GjNQR0FEDpywtwGCIh8GicNyg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.3.0", + "@sinonjs/formatio": "^3.1.0", + "@sinonjs/samsam": "^3.0.2", + "diff": "^3.5.0", + "lolex": "^3.0.0", + "nise": "^1.4.8", + "supports-color": "^5.5.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "sinon-chai": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.3.0.tgz", + "integrity": "sha512-r2JhDY7gbbmh5z3Q62pNbrjxZdOAjpsqW/8yxAZRSqLZqowmfGZPGUZPFf3UX36NLis0cv8VEM5IJh9HgkSOAA==", + "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 + }, + "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-support": { + "version": "0.5.10", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.10.tgz", + "integrity": "sha512-YfQ3tQFTK/yzlGJuX8pTwa4tifQj4QS2Mj7UegOu8jAz59MqIiMGPXxQhVQiIMNzayuUSF/jEuVnfFF5JqybmQ==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.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 + } + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + } + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-combiner2": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/stream-combiner2/-/stream-combiner2-1.1.1.tgz", + "integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=", + "dev": true, + "requires": { + "duplexer2": "~0.1.0", + "readable-stream": "^2.0.2" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-splicer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-2.0.0.tgz", + "integrity": "sha1-G2O+Q4oTPktnHMGTUZdgAXWRDYM=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-to-observable": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/stream-to-observable/-/stream-to-observable-0.1.0.tgz", + "integrity": "sha1-Rb8dny19wJvtgfHDB8Qw5ouEz/4=", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz", + "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==", + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "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" + } + }, + "supports-color": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.1.0.tgz", + "integrity": "sha512-Ry0AwkoKjDpVKK4sV4h6o3UJmNRbjYm2uXhwfj3J56lMVdvnUNqzQVRztOOMGQ++w1K/TjNDFvpJk0F/LoeBCQ==", + "dev": true, + "requires": { + "has-flag": "^2.0.0" + }, + "dependencies": { + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "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 + }, + "syntax-error": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/syntax-error/-/syntax-error-1.4.0.tgz", + "integrity": "sha512-YPPlu67mdnHGTup2A8ff7BC2Pjq0e0Yp/IyTFN03zWO0RcK07uLcbi7C2KpGR2FvWbaB0+bfE27a+sBKebSo7w==", + "dev": true, + "requires": { + "acorn-node": "^1.2.0" + } + }, + "throttleit": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz", + "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8=", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "timers-browserify": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-1.4.2.tgz", + "integrity": "sha1-ycWLV1voQHN1y14kYtrO50NZ9B0=", + "dev": true, + "requires": { + "process": "~0.11.0" + } + }, + "tmp": { + "version": "0.0.31", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", + "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.1" + } + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "topo": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.3.tgz", + "integrity": "sha512-IgpPtvD4kjrJ7CRA3ov2FhWQADwv+Tdqbsf1ZnPUSAtCJ9e1Z44MmoSGDXGk4IppoZA7jd/QRkNddlLJWlUZsQ==", + "dev": true, + "requires": { + "hoek": "6.x.x" + }, + "dependencies": { + "hoek": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/hoek/-/hoek-6.1.2.tgz", + "integrity": "sha512-6qhh/wahGYZHFSFw12tBbJw5fsAhhwrrG/y3Cs0YMTv2WzMnL0oLPnQJjv1QJvEfylRSOFuP+xCu+tdx0tD16Q==", + "dev": true + } + } + }, + "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 + } + } + }, + "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-node": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.0.2.tgz", + "integrity": "sha512-MosTrinKmaAcWgO8tqMjMJB22h+sp3Rd1i4fdoWY4mhBDekOwIAKI/bzmRi7IcbCmjquccYg2gcF6NBkLgr0Tw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^3.1.0", + "make-error": "^1.1.1", + "source-map-support": "^0.5.6", + "yn": "^3.0.0" + } + }, + "tsconfig-paths": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.8.0.tgz", + "integrity": "sha512-zZEYFo4sjORK8W58ENkRn9s+HmQFkkwydDG7My5s/fnfr2YYCaiyXe/HBUcIgU8epEKOXwiahOO+KZYjiXlWyQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "deepmerge": "^2.0.1", + "json5": "^1.0.1", + "minimist": "^1.2.0", + "strip-bom": "^3.0.0" + } + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + } + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "tty-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.1.tgz", + "integrity": "sha512-C3TaO7K81YvjCgQH9Q1S3R3P3BtN3RIM8n+OvX4il1K1zgE8ZhI0op7kClgkxtutIE8hQrcrHBXvIheqKUUCxw==", + "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 + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "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" + }, + "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 + } + } + }, + "umd": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/umd/-/umd-3.0.3.tgz", + "integrity": "sha512-4IcGSufhFshvLNcMCV80UnQVlZ5pMOC8mvNPForqwA4+lzYQuetTESLDQkeLmihq8bRcnpbQa48Wb8Lh16/xow==", + "dev": true + }, + "undeclared-identifiers": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/undeclared-identifiers/-/undeclared-identifiers-1.1.3.tgz", + "integrity": "sha512-pJOW4nxjlmfwKApE4zvxLScM/njmwj/DiUBv7EabwE4O8kRUy+HIwxQtZLBPll/jx1LJyBcqNfB3/cpv9EZwOw==", + "dev": true, + "requires": { + "acorn-node": "^1.3.0", + "dash-ast": "^1.0.0", + "get-assigned-identifiers": "^1.2.0", + "simple-concat": "^1.0.0", + "xtend": "^4.0.1" + } + }, + "union": { + "version": "0.4.6", + "resolved": "https://registry.npmjs.org/union/-/union-0.4.6.tgz", + "integrity": "sha1-GY+9rrolTniLDvy2MLwR8kopWeA=", + "dev": true, + "requires": { + "qs": "~2.3.3" + }, + "dependencies": { + "qs": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz", + "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ=", + "dev": true + } + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "requires": { + "punycode": "^2.1.0" + } + }, + "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-join": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/url-join/-/url-join-2.0.5.tgz", + "integrity": "sha1-WvIvGMBSoACkjXuCxenC4v7tpyg=", + "dev": true + }, + "util": { + "version": "0.10.4", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.4.tgz", + "integrity": "sha512-0Pm9hTQ3se5ll1XihRic3FDIku70C+iHUdT/W926rSgHV5QgXsYbKZN8MSC3tJtSkhuROzvsQjAaFENRXr+19A==", + "dev": true, + "requires": { + "inherits": "2.0.3" + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "validator": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-10.11.0.tgz", + "integrity": "sha512-X/p3UZerAIsbBfN/IwahhYaBbY68EN/UQBWHtsbXGT5bfrH/p4NQzUCG1kF/rtKaNpnJ7jAu6NGTdSNtyNIXMw==" + }, + "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" + } + }, + "vm-browserify": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", + "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", + "dev": true + }, + "wait-on": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-3.2.0.tgz", + "integrity": "sha512-QUGNKlKLDyY6W/qHdxaRlXUAgLPe+3mLL/tRByHpRNcHs/c7dZXbu+OnJWGNux6tU1WFh/Z8aEwvbuzSAu79Zg==", + "dev": true, + "requires": { + "core-js": "^2.5.7", + "joi": "^13.0.0", + "minimist": "^1.2.0", + "request": "^2.88.0", + "rx": "^4.1.0" + }, + "dependencies": { + "har-validator": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true + }, + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + } + } + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "yauzl": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.8.0.tgz", + "integrity": "sha1-eUUK/yKyqcWkHvVOAtuQfM+/nuI=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.0.1" + } + }, + "yn": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.0.0.tgz", + "integrity": "sha512-+Wo/p5VRfxUgBUGy2j/6KX2mj9AYJWOHuhMjMcbBFc3y54o9/4buK1ksBvuiK01C3kby8DH9lSmJdSxw+4G/2Q==", + "dev": true + } + } +} diff --git a/elements/lisk-validator/package.json b/elements/lisk-validator/package.json new file mode 100644 index 00000000000..1d8a97294ff --- /dev/null +++ b/elements/lisk-validator/package.json @@ -0,0 +1,98 @@ +{ + "name": "@liskhq/lisk-validator", + "version": "0.1.0-alpha.0", + "description": "Validation library according to the Lisk protocol", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain", + "validation" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-validator#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "prestart": "./scripts/prestart.sh", + "start": "./scripts/start.sh", + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s liskValidator", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s liskValidator", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/,/**/**/}/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p 11547 ./browsertest &", + "serve:stop": "kill $(lsof -t -i:11547) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:11547 && cypress run --config baseUrl=http://localhost:11547 --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "NODE_ENV=test nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@liskhq/bignum": "1.3.1", + "@liskhq/lisk-cryptography": "2.1.0-alpha.0", + "@types/node": "10.12.21", + "@types/semver": "5.5.0", + "@types/validator": "10.9.0", + "ajv": "6.9.2", + "ajv-merge-patch": "4.1.0", + "semver": "5.6.0", + "validator": "10.11.0" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "@types/verror": "1.10.3", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "sinon": "7.2.3", + "sinon-chai": "3.3.0", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/elements/lisk-validator/scripts b/elements/lisk-validator/scripts new file mode 120000 index 00000000000..f81ccd0a763 --- /dev/null +++ b/elements/lisk-validator/scripts @@ -0,0 +1 @@ +../../templates/scripts.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/src/constants.ts b/elements/lisk-validator/src/constants.ts new file mode 100644 index 00000000000..af8fd02f3a9 --- /dev/null +++ b/elements/lisk-validator/src/constants.ts @@ -0,0 +1,20 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ + +// Largest possible number which can be stored in eight bytes. +// Derived from bignum.fromBuffer(Buffer.from(new Array(8).fill(255))). +export const MAX_EIGHT_BYTE_NUMBER = '18446744073709551615'; +export const MAX_PUBLIC_KEY_LENGTH = 32; +export const MAX_INT64 = '9223372036854775807'; diff --git a/elements/lisk-validator/src/formatter.ts b/elements/lisk-validator/src/formatter.ts new file mode 100644 index 00000000000..68a5f5f4294 --- /dev/null +++ b/elements/lisk-validator/src/formatter.ts @@ -0,0 +1,123 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import * as Ajv from 'ajv'; +// tslint:disable-next-line no-require-imports +import addKeywords = require('ajv-merge-patch'); +import { + isGreaterThanMaxTransactionId, + isNullCharacterIncluded, + isNumberString, + isSignature, + isUsername, + validateAddress, + validateFee, + validateNonTransferAmount, + validatePublicKey, + validateTransferAmount, +} from './validation'; + +export const validator = new Ajv({ allErrors: true, removeAdditional: 'all' }); +addKeywords(validator); + +validator.addFormat('signature', isSignature); + +validator.addFormat( + 'id', + data => + isNumberString(data) && !isGreaterThanMaxTransactionId(new BigNum(data)), +); + +validator.addFormat('address', data => { + try { + validateAddress(data); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('amount', isNumberString); + +validator.addFormat('transferAmount', validateTransferAmount); + +validator.addFormat('nonTransferAmount', validateNonTransferAmount); + +validator.addFormat('fee', validateFee); + +validator.addFormat('emptyOrPublicKey', data => { + if (data === null || data === '') { + return true; + } + + try { + validatePublicKey(data); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('publicKey', data => { + try { + validatePublicKey(data); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('signedPublicKey', data => { + try { + const action = data[0]; + if (action !== '+' && action !== '-') { + return false; + } + const publicKey = data.slice(1); + validatePublicKey(publicKey); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('additionPublicKey', data => { + const action = data[0]; + if (action !== '+') { + return false; + } + try { + const publicKey = data.slice(1); + validatePublicKey(publicKey); + + return true; + } catch (error) { + return false; + } +}); + +validator.addFormat('username', isUsername); + +validator.addFormat('noNullCharacter', data => !isNullCharacterIncluded(data)); + +validator.addKeyword('uniqueSignedPublicKeys', { + type: 'array', + compile: () => (data: ReadonlyArray) => + new Set(data.map((key: string) => key.slice(1))).size === data.length, +}); diff --git a/elements/lisk-validator/src/index.ts b/elements/lisk-validator/src/index.ts new file mode 100644 index 00000000000..3bb90206c8d --- /dev/null +++ b/elements/lisk-validator/src/index.ts @@ -0,0 +1,18 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { validator } from './formatter'; + +export * from './validation'; +export { validator }; diff --git a/elements/lisk-validator/src/validation.ts b/elements/lisk-validator/src/validation.ts new file mode 100644 index 00000000000..3db64fe896f --- /dev/null +++ b/elements/lisk-validator/src/validation.ts @@ -0,0 +1,244 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import { hexToBuffer } from '@liskhq/lisk-cryptography'; +import { + gte as isVersionGte, + gtr as isGreaterThanVersionInRange, + ltr as isLessThanVersionInRange, + valid as isValidVersion, + validRange as isValidRangeVersion, +} from 'semver'; +import * as validator from 'validator'; +import { + MAX_EIGHT_BYTE_NUMBER, + MAX_INT64, + MAX_PUBLIC_KEY_LENGTH, +} from './constants'; + +export const isNullCharacterIncluded = (input: string): boolean => + new RegExp('\\0|\\U00000000').test(input); + +export const isUsername = (username: string): boolean => { + if (isNullCharacterIncluded(username)) { + return false; + } + + if (username !== username.trim().toLowerCase()) { + return false; + } + + if (/^[0-9]{1,21}[L|l]$/g.test(username)) { + return false; + } + + if (!/^[a-z0-9!@$&_.]+$/g.test(username)) { + return false; + } + + return true; +}; + +export const isSignature = (signature: string): boolean => + /^[a-f0-9]{128}$/i.test(signature); + +export const isGreaterThanZero = (amount: BigNum): boolean => amount.cmp(0) > 0; + +export const isGreaterThanMaxTransactionAmount = (amount: BigNum): boolean => + amount.cmp(MAX_INT64) > 0; + +export const isGreaterThanMaxTransactionId = (id: BigNum): boolean => + id.cmp(MAX_EIGHT_BYTE_NUMBER) > 0; + +export const isNumberString = (num: string): boolean => { + if (typeof num !== 'string') { + return false; + } + + return validator.isInt(num); +}; + +export const isValidInteger = (num: unknown): boolean => + typeof num === 'number' ? Math.floor(num) === num : false; + +export const hasNoDuplicate = (values: ReadonlyArray): boolean => { + const unique = [...new Set(values)]; + + return unique.length === values.length; +}; + +export const isStringBufferLessThan = (data: unknown, max: number): boolean => { + if (typeof data !== 'string') { + return false; + } + + return Buffer.from(data).length <= max; +}; + +export const isHexString = (data: unknown): boolean => { + if (typeof data !== 'string') { + return false; + } + + return data === '' || /^[a-f0-9]+$/i.test(data); +}; + +export const isEncryptedPassphrase = (data: string): boolean => { + // Explanation of regex structure: + // - 1 or more 'key=value' pairs delimited with '&' + // Examples: + // - cipherText=abcd1234 + // - cipherText=abcd1234&iterations=10000&iv=ef012345 + // NOTE: Maximum lengths chosen here are arbitrary + const keyRegExp = /[a-zA-Z0-9]{2,15}/; + const valueRegExp = /[a-f0-9]{1,256}/; + const keyValueRegExp = new RegExp( + `${keyRegExp.source}=${valueRegExp.source}`, + ); + const encryptedPassphraseRegExp = new RegExp( + `^(${keyValueRegExp.source})(?:&(${keyValueRegExp.source})){0,10}$`, + ); + + return encryptedPassphraseRegExp.test(data); +}; + +export const isSemVer = (version: string): boolean => !!isValidVersion(version); + +export const isRangedSemVer = (version: string): boolean => + !!isValidRangeVersion(version); + +export const isLessThanRangedVersion = isLessThanVersionInRange; +export const isGreaterThanRangedVersion = isGreaterThanVersionInRange; + +export const isProtocolString = (data: string) => + /^(\d|[1-9]\d{1,2})\.(\d|[1-9]\d{1,2})$/.test(data); + +const IPV4_NUMBER = 4; +const IPV6_NUMBER = 6; + +export const isIPV4 = (data: string): boolean => + validator.isIP(data, IPV4_NUMBER); + +export const isIPV6 = (data: string): boolean => + validator.isIP(data, IPV6_NUMBER); + +export const isIP = (data: string): boolean => isIPV4(data) || isIPV6(data); + +export const isPort = (port: string) => validator.isPort(port); + +export const validatePublicKeysForDuplicates = ( + publicKeys: ReadonlyArray, +): boolean => + publicKeys.every((element, index) => { + if (publicKeys.slice(index + 1).includes(element)) { + throw new Error(`Duplicated public key: ${publicKeys[index]}.`); + } + + return true; + }); + +export const isStringEndsWith = ( + target: string, + suffixes: ReadonlyArray, +): boolean => suffixes.some(suffix => target.endsWith(suffix)); + +export const isVersionMatch = isVersionGte; + +export const validatePublicKey = (publicKey: string): boolean => { + const publicKeyBuffer = hexToBuffer(publicKey); + if (publicKeyBuffer.length !== MAX_PUBLIC_KEY_LENGTH) { + throw new Error( + `Public key ${publicKey} length differs from the expected 32 bytes for a public key.`, + ); + } + + return true; +}; + +export const validatePublicKeys = ( + publicKeys: ReadonlyArray, +): boolean => + publicKeys.every(validatePublicKey) && + validatePublicKeysForDuplicates(publicKeys); + +export const validateKeysgroup = ( + keysgroup: ReadonlyArray, + min: number, + max: number, +): boolean => { + if (keysgroup.length < min || keysgroup.length > max) { + throw new Error( + `Expected between ${min} and ${max} public keys in the keysgroup.`, + ); + } + + return validatePublicKeys(keysgroup); +}; + +const MIN_ADDRESS_LENGTH = 2; +const MAX_ADDRESS_LENGTH = 22; +const BASE_TEN = 10; +export const validateAddress = (address: string): boolean => { + if ( + address.length < MIN_ADDRESS_LENGTH || + address.length > MAX_ADDRESS_LENGTH + ) { + throw new Error( + 'Address length does not match requirements. Expected between 2 and 22 characters.', + ); + } + + if (address[address.length - 1] !== 'L') { + throw new Error( + 'Address format does not match requirements. Expected "L" at the end.', + ); + } + + if (address.includes('.')) { + throw new Error( + 'Address format does not match requirements. Address includes invalid character: `.`.', + ); + } + + const addressString = address.slice(0, -1); + const addressNumber = new BigNum(addressString); + + if (addressNumber.cmp(new BigNum(MAX_EIGHT_BYTE_NUMBER)) > 0) { + throw new Error( + 'Address format does not match requirements. Address out of maximum range.', + ); + } + + if (addressString !== addressNumber.toString(BASE_TEN)) { + throw new Error( + "Address string format does not match it's number representation.", + ); + } + + return true; +}; + +export const validateNonTransferAmount = (data: string): boolean => + isNumberString(data) && data === '0'; + +export const validateTransferAmount = (data: string): boolean => + isNumberString(data) && + isGreaterThanZero(new BigNum(data)) && + !isGreaterThanMaxTransactionAmount(new BigNum(data)); + +export const validateFee = (data: string): boolean => + isNumberString(data) && + isGreaterThanZero(new BigNum(data)) && + !isGreaterThanMaxTransactionAmount(new BigNum(data)); diff --git a/elements/lisk-validator/test/_global_hooks.ts b/elements/lisk-validator/test/_global_hooks.ts new file mode 100644 index 00000000000..21464e90f21 --- /dev/null +++ b/elements/lisk-validator/test/_global_hooks.ts @@ -0,0 +1,3 @@ +afterEach(() => { + return sandbox.restore(); +}); diff --git a/elements/lisk-validator/test/_setup.ts b/elements/lisk-validator/test/_setup.ts new file mode 100644 index 00000000000..d938e5c4f90 --- /dev/null +++ b/elements/lisk-validator/test/_setup.ts @@ -0,0 +1,56 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as sinon from 'sinon'; +import * as chai from 'chai'; +import 'chai/register-expect'; +import * as sinonChai from 'sinon-chai'; + +process.env.NODE_ENV = 'test'; + +chai.Assertion.addProperty('hexString', function handleAssert( + this: Chai.ChaiStatic, +) { + const actual = this._obj; + + new chai.Assertion(actual).to.be.a('string'); + + const expected = Buffer.from(actual, 'hex').toString('hex'); + this.assert( + expected === actual, + 'expected #{this} to be a hexString', + 'expected #{this} not to be a hexString', + ); +}); + +chai.Assertion.addProperty('integer', function handleAssert( + this: Chai.ChaiStatic, +) { + const actual = this._obj; + + new chai.Assertion(actual).to.be.a('number'); + + const expected = parseInt(actual, 10); + this.assert( + actual === expected, + 'expected #{this} to be an integer', + 'expected #{this} not to be an integer', + ); +}); + +[sinonChai].forEach(plugin => chai.use(plugin)); + +global.sandbox = sinon.createSandbox({ + useFakeTimers: true, +}); diff --git a/elements/lisk-validator/test/formatter.ts b/elements/lisk-validator/test/formatter.ts new file mode 100644 index 00000000000..da6d732448e --- /dev/null +++ b/elements/lisk-validator/test/formatter.ts @@ -0,0 +1,688 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import { expect } from 'chai'; +import { validator } from '../src/formatter'; +import { ValidateFunction } from 'ajv'; + +describe('validator', () => { + const baseSchemaId = 'test/schema'; + + before(async () => { + const baseSchema = { + $id: baseSchemaId, + type: 'object', + }; + validator.addSchema(baseSchema); + }); + + describe('signature', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'signature', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid signature is provided', async () => { + expect( + validate({ + target: + 'd5bdb0577f53fe5d79009c42facdf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b7304', + }), + ).to.be.true; + }); + + it('should validate to false when non-hex character is in the signature', async () => { + expect( + validate({ + target: + 'zzzzzzzzzzzzzzzzzzzzzzzzzzzzf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b7304', + }), + ).to.be.false; + }); + + it('should validate to false when the signature is under 128 characters', async () => { + expect( + validate({ + target: + 'd5bdb0577f53fe5d79009c42facdf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b730', + }), + ).to.be.false; + }); + + it('should validate to false when the signature is over 128 characters', async () => { + expect( + validate({ + target: + 'd5bdb0577f53fe5d79009c42facdf295a555e9542c851ec49feef1680f824a1ebae00733d935f078c3ef621bc20ee88d81390f9c97f75adb14731504861b7304a', + }), + ).to.be.false; + }); + }); + + describe('id', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'id', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid id is provided', async () => { + expect(validate({ target: '3543510233978718399' })).to.be.true; + }); + + it('should validate to true when valid id with leading zeros is provided', async () => { + expect(validate({ target: '00123' })).to.be.true; + }); + + it('should validate to false when number greater than maximum is provided', async () => { + expect(validate({ target: '18446744073709551616' })).to.be.false; + }); + + it('should validate to false when number is provided', async () => { + expect(validate({ target: 3543510233978718399 })).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('address', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'address', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid address is provided', async () => { + expect(validate({ target: '14815133512790761431L' })).to.be.true; + }); + + it('should validate to false when address with leading zeros is provided', async () => { + expect(validate({ target: '00015133512790761431L' })).to.be.false; + }); + + it('should validate to false when address including `.` is provided', async () => { + expect(validate({ target: '14.15133512790761431L' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', async () => { + expect(validate({ target: '18446744073709551616L' })).to.be.false; + }); + + it('should validate to false when the address does not end with "L"', async () => { + expect(validate({ target: '14815133512790761431X' })).to.be.false; + }); + + it('should validate to false when the address only contains numbers', async () => { + expect(validate({ target: '18446744073709551616' })).to.be.false; + }); + + it('should validate to false when the address is less than 2 characters', async () => { + expect(validate({ target: 'L' })).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('non-transfer amount', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'nonTransferAmount', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid amount is provided', async () => { + expect(validate({ target: '0' })).to.be.true; + }); + + it('should validate to false when invalid amount with leading zeros is provided', async () => { + expect(validate({ target: '000001' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', async () => { + expect(validate({ target: '9223372036854775808' })).to.be.false; + }); + + it('should validate to false when decimal number is provided', async () => { + expect(validate({ target: '190.105310' })).to.be.false; + }); + + it('should validate to false when number is provided', async () => { + expect(validate({ target: 190105310 })).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('transfer amount', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'transferAmount', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid amount is provided', async () => { + expect(validate({ target: '100' })).to.be.true; + }); + + it('should validate to true when valid amount with leading zeros is provided', async () => { + expect(validate({ target: '000000100' })).to.be.true; + }); + + it('should validate to false when amount is 0', async () => { + expect(validate({ target: '0' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', async () => { + expect(validate({ target: '9223372036854775808' })).to.be.false; + }); + + it('should validate to false when decimal number is provided', async () => { + expect(validate({ target: '190.105310' })).to.be.false; + }); + + it('should validate to false when number is provided', async () => { + expect(validate({ target: 190105310 })).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('fee', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'fee', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid fee is provided', async () => { + expect(validate({ target: '100' })).to.be.true; + }); + + it('should validate to true when valid fee with leading zeros is provided', async () => { + expect(validate({ target: '000000100' })).to.be.true; + }); + + it('should validate to false when amount is 0', async () => { + expect(validate({ target: '0' })).to.be.false; + }); + + it('should validate to false when number greater than maximum is provided', async () => { + expect(validate({ target: '9223372036854775808' })).to.be.false; + }); + + it('should validate to false when decimal number is provided', async () => { + expect(validate({ target: '190.105310' })).to.be.false; + }); + + it('should validate to false when number is provided', async () => { + expect(validate({ target: 190105310 })).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('emptyOrPublicKey', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: ['string', 'null'], + format: 'emptyOrPublicKey', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid publicKey is provided', async () => { + expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to true when null is provided', async () => { + expect( + validate({ + target: null, + }), + ).to.be.true; + }); + + it('should validate to true when undefined is provided', async () => { + expect( + validate({ + target: undefined, + }), + ).to.be.true; + }); + + it('should validate to true when empty string is provided', async () => { + expect( + validate({ + target: '', + }), + ).to.be.true; + }); + + it('should validate to false when non-hex character is in the publicKey', async () => { + expect( + validate({ + target: + 'zzzzze75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + }); + + describe('publicKey', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'publicKey', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid publicKey is provided', async () => { + expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to false when non-hex character is in the publicKey', async () => { + expect( + validate({ + target: + 'zzzzze75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is shorter', async () => { + expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is longer', async () => { + expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when signed publicKey is provided', async () => { + expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('signedPublicKey', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'signedPublicKey', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid + and publicKey is provided', async () => { + expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to true when valid - and publicKey is provided', async () => { + expect( + validate({ + target: + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to false when non-hex character is in the publicKey', async () => { + expect( + validate({ + target: + '+zzzzze75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is shorter', async () => { + expect( + validate({ + target: + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is longer', async () => { + expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when non-signed publicKey is provided', async () => { + expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('additionPublicKey', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'additionPublicKey', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid + and publicKey is provided', async () => { + expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.true; + }); + + it('should validate to false when valid - and publicKey is provided', async () => { + expect( + validate({ + target: + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when non-hex character is in the publicKey', async () => { + expect( + validate({ + target: + '+zzzzze75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is shorter', async () => { + expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021', + }), + ).to.be.false; + }); + + it('should validate to false when publicKey is longer', async () => { + expect( + validate({ + target: + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when non-signed publicKey is provided', async () => { + expect( + validate({ + target: + '05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b1', + }), + ).to.be.false; + }); + + it('should validate to false when it is empty', async () => { + expect(validate({ target: '' })).to.be.false; + }); + }); + + describe('uniqueSignedPublicKeys', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'array', + uniqueSignedPublicKeys: true, + }, + }, + }, + }, + }); + }); + + it('should validate to true when unique signedPublicKey is provided', async () => { + expect( + validate({ + target: [ + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + '+278a9aecf13e324c42d73cae7e21e5efc1520afb1abcda084d086d24441ed2b4', + ], + }), + ).to.be.true; + }); + + it('should validate to false when publicKeys are duplicated without the sign', async () => { + expect( + validate({ + target: [ + '-05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + ], + }), + ).to.be.false; + }); + + it('should validate to false when publicKeys are duplicated with the same sign', async () => { + expect( + validate({ + target: [ + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + '+05e1ce75b98d6051030e4e416483515cf8360be1a1bd6d2c14d925700dae021b', + ], + }), + ).to.be.false; + }); + }); + + describe('noNullCharacter', () => { + let validate: ValidateFunction; + beforeEach(async () => { + validate = validator.compile({ + $merge: { + source: { $ref: baseSchemaId }, + with: { + properties: { + target: { + type: 'string', + format: 'noNullCharacter', + }, + }, + }, + }, + }); + }); + + it('should validate to true when valid string is provided', async () => { + expect( + validate({ + target: 'some normal string', + }), + ).to.be.true; + }); + + it('should validate to true when it is empty', async () => { + expect(validate({ target: '' })).to.be.true; + }); + + it('should validate to false when string with null byte is provided', async () => { + const nullCharacterList = ['\0', '\x00', '\u0000', '\\U00000000']; + nullCharacterList.forEach(nullChar => { + expect( + validate({ + target: `${nullChar} hey \x01 :)`, + }), + ).to.be.false; + }); + }); + }); +}); diff --git a/elements/lisk-validator/test/index.ts b/elements/lisk-validator/test/index.ts new file mode 100644 index 00000000000..f5d6fe19135 --- /dev/null +++ b/elements/lisk-validator/test/index.ts @@ -0,0 +1,17 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +// import { expect } from 'chai'; + +describe('index', () => {}); diff --git a/elements/lisk-validator/test/mocha.opts b/elements/lisk-validator/test/mocha.opts new file mode 120000 index 00000000000..a83c64fccf7 --- /dev/null +++ b/elements/lisk-validator/test/mocha.opts @@ -0,0 +1 @@ +../../../templates/test/mocha.opts.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/test/tsconfig.json b/elements/lisk-validator/test/tsconfig.json new file mode 120000 index 00000000000..c73c54e77b4 --- /dev/null +++ b/elements/lisk-validator/test/tsconfig.json @@ -0,0 +1 @@ +../../../templates/test/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/test/tslint.json b/elements/lisk-validator/test/tslint.json new file mode 120000 index 00000000000..cfef1680c62 --- /dev/null +++ b/elements/lisk-validator/test/tslint.json @@ -0,0 +1 @@ +../../../templates/test/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/test/validation.ts b/elements/lisk-validator/test/validation.ts new file mode 100644 index 00000000000..f3ddd3deb89 --- /dev/null +++ b/elements/lisk-validator/test/validation.ts @@ -0,0 +1,602 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +import * as BigNum from '@liskhq/bignum'; +import * as cryptography from '@liskhq/lisk-cryptography'; +import { expect } from 'chai'; +import { + validatePublicKeysForDuplicates, + validatePublicKey, + validatePublicKeys, + validateKeysgroup, + validateAddress, + validateNonTransferAmount, + validateTransferAmount, + validateFee, + isGreaterThanMaxTransactionAmount, + isGreaterThanZero, + isGreaterThanMaxTransactionId, + isNumberString, + isValidInteger, + isNullCharacterIncluded, + isIPV6, + isIPV4, + isIP, + isPort, + isStringEndsWith, + isProtocolString, + isRangedSemVer, + isEncryptedPassphrase, + isHexString, + isStringBufferLessThan, + hasNoDuplicate, + isUsername, +} from '../src/validation'; + +describe('validation', () => { + describe('#validatePublicKey', () => { + describe('Given a hex string with odd length', () => { + const invalidHexPublicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bc'; + it('should throw an error', () => { + return expect( + validatePublicKey.bind(null, invalidHexPublicKey), + ).to.throw('Argument must have a valid length of hex string.'); + }); + }); + + describe('Given a hex string with additional non-hex characters', () => { + const invalidHexPublicKey = + '12345678123456781234567812345678123456781234567812345678123456gg'; + it('should throw an error', () => { + return expect( + validatePublicKey.bind(null, invalidHexPublicKey), + ).to.throw('Argument must be a valid hex string.'); + }); + }); + + describe('Given a too long public key', () => { + const tooLongPublicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca12'; + it('should throw an error', () => { + return expect(validatePublicKey.bind(null, tooLongPublicKey)).to.throw( + 'Public key 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca12 length differs from the expected 32 bytes for a public key.', + ); + }); + }); + + describe('Given a too short public key', () => { + const tooShortPublicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452b'; + it('should throw an error', () => { + return expect(validatePublicKey.bind(null, tooShortPublicKey)).to.throw( + 'Public key 215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452b length differs from the expected 32 bytes for a public key.', + ); + }); + }); + + describe('Given a valid public key', () => { + const publicKey = + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca'; + it('should return true', () => { + return expect(validatePublicKey(publicKey)).to.be.true; + }); + }); + + describe('Given a valid public key with only numeric characters', () => { + const publicKey = + '1234567812345678123456781234567812345678123456781234567812345678'; + it('should return true', () => { + return expect(validatePublicKey(publicKey)).to.be.true; + }); + }); + }); + + describe('#validatePublicKeys', () => { + describe('Given an array of public keys with one invalid public key', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bc', + ]; + it('should throw an error', () => { + return expect(validatePublicKeys.bind(null, publicKeys)).to.throw( + 'Argument must have a valid length of hex string.', + ); + }); + }); + + describe('Given an array of valid public keys', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '1234567812345678123456781234567812345678123456781234567812345678', + ]; + it('should return true', () => { + return expect(validatePublicKeys(publicKeys)).to.be.true; + }); + }); + }); + + describe('#validateKeysgroup', () => { + let keysgroup: ReadonlyArray; + describe('Given a keysgroup with three public keys', () => { + beforeEach(() => { + keysgroup = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + return Promise.resolve(); + }); + it('the validated keysgroup should return true', () => { + return expect(validateKeysgroup(keysgroup, 1, 15)).to.be.true; + }); + }); + + describe('Given an empty keysgroup', () => { + beforeEach(() => { + keysgroup = []; + return Promise.resolve(); + }); + it('should throw the error', () => { + return expect(validateKeysgroup.bind(null, keysgroup, 1, 15)).to.throw( + 'Expected between 1 and 15 public keys in the keysgroup.', + ); + }); + }); + + describe('Given a keysgroup with 17 public keys', () => { + beforeEach(() => { + keysgroup = new Array(17) + .fill(0) + .map( + (_: number, index: number) => + cryptography.getPrivateAndPublicKeyFromPassphrase( + index.toString(), + ).publicKey, + ); + return Promise.resolve(); + }); + it('should throw the error', () => { + return expect(validateKeysgroup.bind(null, keysgroup, 1, 15)).to.throw( + 'Expected between 1 and 15 public keys in the keysgroup.', + ); + }); + }); + }); + + describe('#checkPublicKeysForDuplicates', () => { + describe('Given an array of public keys without duplication', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '5d036a858ce89f844491762eb89e2bfbd50a4a0a0da658e4b2628b25b117ae09', + ]; + it('should return true', () => { + return expect(validatePublicKeysForDuplicates(publicKeys)).to.be.true; + }); + }); + + describe('Given an array of public keys with duplication', () => { + const publicKeys = [ + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bca', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + '922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa', + ]; + it('should throw an error', () => { + return expect( + validatePublicKeysForDuplicates.bind(null, publicKeys), + ).to.throw( + 'Duplicated public key: 922fbfdd596fa78269bbcadc67ec2a1cc15fc929a19c462169568d7a3df1a1aa.', + ); + }); + }); + }); + + describe('#validateAddress', () => { + describe('Given valid addresses', () => { + const addresses = [ + '13133549779353512613L', + '18446744073709551615L', + '1L', + ]; + + it('should return true', () => { + return addresses.forEach(address => { + return expect(validateAddress(address)).to.be.true; + }); + }); + }); + + describe('Given an address that is too short', () => { + const address = 'L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address length does not match requirements. Expected between 2 and 22 characters.', + ); + }); + }); + + describe('Given an address that is too long', () => { + const address = '12345678901234567890123L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address length does not match requirements. Expected between 2 and 22 characters.', + ); + }); + }); + + describe('Given an address without L at the end', () => { + const address = '1234567890'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address format does not match requirements. Expected "L" at the end.', + ); + }); + }); + + describe('Given an address that includes `.`', () => { + const address = '14.15133512790761431L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address format does not match requirements. Address includes invalid character: `.`.', + ); + }); + }); + + describe('Given an address that is out of range', () => { + const address = '18446744073709551616L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + 'Address format does not match requirements. Address out of maximum range.', + ); + }); + }); + + describe('Given an address that has leading zeros', () => { + const address = '00015133512790761431L'; + it('should throw an error', () => { + return expect(validateAddress.bind(null, address)).to.throw( + "Address string format does not match it's number representation.", + ); + }); + }); + }); + + describe('#validateNonTransferAmount', () => { + it('should return true when amount is 0', () => { + return expect(validateNonTransferAmount('0')).to.be.true; + }); + + it('should return false when amount is greater than 0', () => { + return expect(validateNonTransferAmount('1')).to.be.false; + }); + + it('should return false when amount is less than 0', () => { + return expect(validateNonTransferAmount('-1')).to.be.false; + }); + }); + + describe('#validateTransferAmount', () => { + it('should return false is amount is 0', () => { + return expect(validateTransferAmount('0')).to.be.false; + }); + + it('should return true when amount is a number greater than 0 and less than maximum transaction amount', () => { + return expect(validateTransferAmount('100')).to.be.true; + }); + }); + + describe('#validateFee', () => { + it('should return false is amount is 0', () => { + return expect(validateFee('0')).to.be.false; + }); + + it('should return true when amount is a number greater than 0 and less than maximum transaction amount', () => { + return expect(validateFee('100')).to.be.true; + }); + }); + + describe('#isGreaterThanZero', () => { + it('should return false when amount is 0', () => { + return expect(isGreaterThanZero(new BigNum('0'))).to.be.false; + }); + + it('should return true when amount is greater than 0', () => { + return expect( + isGreaterThanZero(new BigNum('9223372036854775808987234289782357')), + ).to.be.true; + }); + }); + + describe('#isGreaterThanMaxTransactionAmount', () => { + it('should return false when amount is less than maximum transaction amount', () => { + return expect( + isGreaterThanMaxTransactionAmount(new BigNum('9223372036854775807')), + ).to.be.false; + }); + + it('should return true when amount is more than maximum transaction amount', () => { + return expect( + isGreaterThanMaxTransactionAmount(new BigNum('9223372036854775808')), + ).to.be.true; + }); + }); + + describe('#isGreaterThanMaxTransactionId', () => { + it('should return false when id is less than 8 bytes integer maximum', () => { + return expect( + isGreaterThanMaxTransactionId(new BigNum('18446744073709551615')), + ).to.be.false; + }); + + it('should return true when id is more than 8 bytes integer maximum', () => { + return expect( + isGreaterThanMaxTransactionId(new BigNum('18446744073709551616')), + ).to.be.true; + }); + }); + + describe('#isNumberString', () => { + it('should return false when number is not string', () => { + const invalidFunction = isNumberString as (input: any) => boolean; + return expect(invalidFunction(1)).to.be.false; + }); + + it('should return false when string contains non number', () => { + return expect(isNumberString('12345abc68789')).to.be.false; + }); + + it('should return true when string contains only number', () => { + return expect(isNumberString('1234568789')).to.be.true; + }); + }); + + describe('#isValidInteger', () => { + it('should return false when string was provided', () => { + return expect(isValidInteger('1234')).to.be.false; + }); + + it('should return false when float was provided', () => { + return expect(isValidInteger(123.4)).to.be.false; + }); + + it('should return true when integer was provided', () => { + return expect(isValidInteger(6)).to.be.true; + }); + + it('should return true when negative integer was provided', () => { + return expect(isValidInteger(-6)).to.be.true; + }); + }); + + describe('#isUsername', () => { + it('should return true when valid username is provided', () => { + return expect(isUsername('4miners.net')).to.be.true; + }); + + it('should return false when username includes capirtal', () => { + return expect(isUsername('4miners.Net')).to.be.false; + }); + + it('should return false when username is like address', () => { + return expect(isUsername('17670127987160191762l')).to.be.false; + }); + + it('should return false when username includes forbidden character', () => { + return expect(isUsername('4miners^net')).to.be.false; + }); + + it('should return false when username includes forbidden character', () => { + return expect(isUsername('4miners\0net')).to.be.false; + }); + }); + + describe('#hasNoDuplicate', () => { + it('should return true when string array is unique', () => { + return expect(hasNoDuplicate(['1234', '4567'])).to.be.true; + }); + + it('should return false when array contains duplicate', () => { + return expect(hasNoDuplicate(['1234', 'a', '1234'])).to.be.false; + }); + }); + + describe('#isStringBufferLessThan', () => { + it('should return true when 32 character is provided with max 64', () => { + return expect( + isStringBufferLessThan('abcdefghijklmnopqrstuwxyzabcdefg', 32), + ).to.be.true; + }); + + it('should return false when 33 character is provided with max 64', () => { + return expect( + isStringBufferLessThan('abcdefghijklmnopqrstuwxyzabcdefgh', 32), + ).to.be.false; + }); + + it('should return false when number was provided', () => { + return expect(isStringBufferLessThan(123, 3)).to.be.false; + }); + }); + + describe('#isHexString', () => { + it('should return true when valid hex was provided', () => { + return expect( + isHexString( + '215b667a32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bc', + ), + ).to.be.true; + }); + + it('should return false when number was provided', () => { + return expect(isHexString(123.4)).to.be.false; + }); + + it('should return false when non hex string was provided', () => { + return expect( + isHexString( + 'zzzzzzza32a5cd51a94c9c2046c11fffb08c65748febec099451e3b164452bc', + ), + ).to.be.false; + }); + }); + + describe('#isEncryptedPassphrase', () => { + it('should return true when value is valid encrypted passphrase', () => { + return expect( + isEncryptedPassphrase( + 'iterations=1&salt=d3e4c10d1f889d45fc1f23dd1a55a4ed&cipherText=c030aae98cb41b3cadf6cf8b71d8dc1304c709696880e09c6c5f41361666ced2ce804407ac99c05799f06ea513be9cb80bbb824db6e0e69fa252f3ce2fe654d34d4f7344fcaeafe143d3b1&iv=03414e5d5e79f22c04f20a57&tag=5025de28a5134e2cf6c4cc3a3212723b&version=1', + ), + ).to.be.true; + }); + + it('should return false when value includes invalud query', () => { + return expect( + isEncryptedPassphrase( + 'cipherText=abcd1234&&iterations=10000&iv=ef012345', + ), + ).to.be.false; + }); + + it('should return false when value is empty', () => { + return expect(isEncryptedPassphrase('')).to.be.false; + }); + }); + + describe('#isRangedSemVer', () => { + it('should return true when it is valid ranged semver', () => { + return expect(isRangedSemVer('>=10.0')).to.be.true; + }); + + it('should return false when value is not valid ranged semver', () => { + return expect(isRangedSemVer('>>10.0')).to.be.false; + }); + }); + + describe('#isProtocolString', () => { + it('should return true when it is protocol version', () => { + return expect(isProtocolString('10.0')).to.be.true; + }); + + it('should return false when value is semver', () => { + return expect(isProtocolString('1.0.2')).to.be.false; + }); + }); + + describe('#isIPV4', () => { + it('should return true when the value is IPV4', () => { + return expect(isIPV4('127.0.0.0')).to.be.true; + }); + + it('should return false when the value is not IPV4', () => { + return expect(isIPV4('FE80:0000:0000:0000:0202:B3FF:FE1E:8329')).to.be + .false; + }); + }); + + describe('#isIPV6', () => { + it('should return true when the value is IPV6', () => { + return expect(isIPV6('FE80:0000:0000:0000:0202:B3FF:FE1E:8329')).to.be + .true; + }); + + it('should return false when the value is not IPV6', () => { + return expect(isIPV6('127.0.0.0')).to.be.false; + }); + }); + + describe('#isIP', () => { + it('should return true when the value is IPV6', () => { + return expect(isIP('FE80:0000:0000:0000:0202:B3FF:FE1E:8329')).to.be.true; + }); + + it('should return true when the value is IPV4', () => { + return expect(isIP('127.0.0.0')).to.be.true; + }); + + it('should return false when the value is not ip', () => { + return expect(isIP('0.0.0.0.0.0')).to.be.false; + }); + }); + + describe('#isPort', () => { + it('should return true when the value is port', () => { + return expect(isPort('3000')).to.be.true; + }); + + it('should return true when the value is invalid port number', () => { + return expect(isPort('999999')).to.be.false; + }); + + it('should return false when the value is not number', () => { + return expect(isPort('abc')).to.be.false; + }); + }); + + describe('#isStringEndsWith', () => { + it('should return true when the value ends with suffix', () => { + return expect(isStringEndsWith('sample', ['le', 'e'])).to.be.true; + }); + + it('should return false when the suffix does not match', () => { + return expect(isStringEndsWith('samp', ['le', 'e'])).to.be.false; + }); + }); + + describe('#isNullByteIncluded', () => { + const validStrings = [ + 'lorem ipsum', + 'lorem\u0001 ipsum', + 'loremU00000001 ipsum', + '\u0001', + '\x01', + 'l©rem', + '❤', + ]; + + const invalidStrings = [ + '\0', + '\0lorem', + 'ipsum\0', + 'lorem\0 ipsum', + '\x00', + '\x00lorem', + 'ipsum\x00', + 'lorem\x00 ipsum', + '\u0000', + '\u0000lorem', + 'ipsum\u0000', + 'lorem\u0000 ipsum', + '\\U00000000', + '\\U00000000lorem', + 'ipsum\\U00000000', + 'lorem\\U00000000 ipsum', + ]; + + it('should return false when valid string was provided', () => { + validStrings.forEach(input => { + expect(isNullCharacterIncluded(input)).to.be.false; + }); + }); + + it('should return true using unicode null characters', () => { + invalidStrings.forEach(input => { + expect(isNullCharacterIncluded(input)).to.be.true; + }); + }); + }); +}); diff --git a/elements/lisk-validator/tsconfig.browsertest.json b/elements/lisk-validator/tsconfig.browsertest.json new file mode 120000 index 00000000000..c7fec284078 --- /dev/null +++ b/elements/lisk-validator/tsconfig.browsertest.json @@ -0,0 +1 @@ +../../templates/tsconfig.browsertest.json.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/tsconfig.json b/elements/lisk-validator/tsconfig.json new file mode 120000 index 00000000000..900bb05c680 --- /dev/null +++ b/elements/lisk-validator/tsconfig.json @@ -0,0 +1 @@ +../../templates/tsconfig.json.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/tslint.json b/elements/lisk-validator/tslint.json new file mode 120000 index 00000000000..7566d21211d --- /dev/null +++ b/elements/lisk-validator/tslint.json @@ -0,0 +1 @@ +../../templates/tslint.json.tmpl \ No newline at end of file diff --git a/elements/lisk-validator/types/ajv-merge-patch/index.d.ts b/elements/lisk-validator/types/ajv-merge-patch/index.d.ts new file mode 100644 index 00000000000..97918a6dc3a --- /dev/null +++ b/elements/lisk-validator/types/ajv-merge-patch/index.d.ts @@ -0,0 +1,4 @@ +declare module 'ajv-merge-patch' { + const addKeywords: (ajv: object) => void; + export = addKeywords; +} diff --git a/lerna.json b/lerna.json new file mode 100644 index 00000000000..489b252e590 --- /dev/null +++ b/lerna.json @@ -0,0 +1,10 @@ +{ + "lerna": "2.11.0", + "packages": [ + "frameworrk", + "elements/*", + "commander" + ], + "version": "independent", + "stream": true +} diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 00000000000..2d76ba98dfd --- /dev/null +++ b/package-lock.json @@ -0,0 +1,6819 @@ +{ + "name": "lisk-elements-monorepo", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/runtime": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.0.0.tgz", + "integrity": "sha512-7hGhzlcmg01CvH1EHdSPVXYX1aJ8KCEyz6I9xYIi/asDtzBPMyMhVibhM/K6g/5qnKBwjZtp10bNZIEFTRW1MA==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.12.0" + } + }, + "@iamstarkov/listr-update-renderer": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/@iamstarkov/listr-update-renderer/-/listr-update-renderer-0.4.1.tgz", + "integrity": "sha512-IJyxQWsYDEkf8C8QthBn5N8tIUR9V9je6j3sMIpAkonaadjbvxmRC6RAhpa3RKxndhNnU2M6iNbtJwd7usQYIA==", + "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": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "@lerna/add": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/add/-/add-3.10.6.tgz", + "integrity": "sha512-FxQ5Bmyb5fF+3BQiNffM6cTeGCrl4uaAuGvxFIWF6Pgz6U14tUc1e16xgKDvVb1CurzJgIV5sLOT5xmCOqv1kA==", + "dev": true, + "requires": { + "@lerna/bootstrap": "3.10.6", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", + "@lerna/npm-conf": "3.7.0", + "@lerna/validation-error": "3.6.0", + "dedent": "^0.7.0", + "libnpm": "^2.0.1", + "p-map": "^1.2.0", + "semver": "^5.5.0" + } + }, + "@lerna/batch-packages": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/batch-packages/-/batch-packages-3.10.6.tgz", + "integrity": "sha512-sInr3ZQJFMh9Zq+ZUoVjX8R67j9ViRkVy0uEMsOfG+jZlXj1lRPRMPRiRgU0jXSYEwCdwuAB5pTd9tTx0VCJUw==", + "dev": true, + "requires": { + "@lerna/package-graph": "3.10.6", + "@lerna/validation-error": "3.6.0", + "libnpm": "^2.0.1" + } + }, + "@lerna/bootstrap": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/bootstrap/-/bootstrap-3.10.6.tgz", + "integrity": "sha512-qbGjAxRpV/eiI9CboUIpsPPGpSogs8mN2/iDaAUBTaWVFVz/YyU64nui84Gll0kbdaHOyPput+kk2S8NCSCCdg==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.10.6", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", + "@lerna/has-npm-version": "3.10.0", + "@lerna/npm-install": "3.10.0", + "@lerna/package-graph": "3.10.6", + "@lerna/pulse-till-done": "3.7.1", + "@lerna/rimraf-dir": "3.10.0", + "@lerna/run-lifecycle": "3.10.5", + "@lerna/run-parallel-batches": "3.0.0", + "@lerna/symlink-binary": "3.10.0", + "@lerna/symlink-dependencies": "3.10.0", + "@lerna/validation-error": "3.6.0", + "dedent": "^0.7.0", + "get-port": "^3.2.0", + "libnpm": "^2.0.1", + "multimatch": "^2.1.0", + "p-finally": "^1.0.0", + "p-map": "^1.2.0", + "p-map-series": "^1.0.0", + "p-waterfall": "^1.0.0", + "read-package-tree": "^5.1.6", + "semver": "^5.5.0" + } + }, + "@lerna/changed": { + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/@lerna/changed/-/changed-3.10.8.tgz", + "integrity": "sha512-K2BQPpSS93uNJqi8A5mwrFR9I6Pa/a0jgR/26jun0Wa39DTOjf5WP7EDvXQ8Pftx5kMdHb5hQDwvMCcBJw25mA==", + "dev": true, + "requires": { + "@lerna/collect-updates": "3.10.1", + "@lerna/command": "3.10.6", + "@lerna/listable": "3.10.6", + "@lerna/output": "3.6.0", + "@lerna/version": "3.10.8" + } + }, + "@lerna/check-working-tree": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/check-working-tree/-/check-working-tree-3.10.0.tgz", + "integrity": "sha512-NdIPhDgEtGHfeGjB9F0oAoPLywgMpjnJhLLwTNQkelDHo2xNAVpG8kV+A2UJ+cU5UXCZA4RZFxKNmw86rO+Drw==", + "dev": true, + "requires": { + "@lerna/describe-ref": "3.10.0", + "@lerna/validation-error": "3.6.0" + } + }, + "@lerna/child-process": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/@lerna/child-process/-/child-process-3.3.0.tgz", + "integrity": "sha512-q2d/OPlNX/cBXB6Iz1932RFzOmOHq6ZzPjqebkINNaTojHWuuRpvJJY4Uz3NGpJ3kEtPDvBemkZqUBTSO5wb1g==", + "dev": true, + "requires": { + "chalk": "^2.3.1", + "execa": "^1.0.0", + "strong-log-transformer": "^2.0.0" + } + }, + "@lerna/clean": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/clean/-/clean-3.10.6.tgz", + "integrity": "sha512-MuL8HOwnyvVtr6GOiAN/Ofjbx+BJdCrtjrM1Uuh8FFnbnZTPVf+0MPxL2jVzPMo0PmoIrX3fvlwvzKNk/lH0Ug==", + "dev": true, + "requires": { + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", + "@lerna/prompt": "3.6.0", + "@lerna/pulse-till-done": "3.7.1", + "@lerna/rimraf-dir": "3.10.0", + "p-map": "^1.2.0", + "p-map-series": "^1.0.0", + "p-waterfall": "^1.0.0" + } + }, + "@lerna/cli": { + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@lerna/cli/-/cli-3.10.7.tgz", + "integrity": "sha512-yuoz/24mIfYit3neKqoE5NVs42Rj9A6A6SlkNPDfsy3v/Vh7SgYkU3cwiGyvwBGzIdhqL4/SWYo8H7YJLs0C+g==", + "dev": true, + "requires": { + "@lerna/global-options": "3.10.6", + "dedent": "^0.7.0", + "libnpm": "^2.0.1", + "yargs": "^12.0.1" + } + }, + "@lerna/collect-updates": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/@lerna/collect-updates/-/collect-updates-3.10.1.tgz", + "integrity": "sha512-vb0wEJ8k63G+2CR/ud1WeVHNJ21Fs6Ew6lbdGZXnF4ZvaFWxWJZpoHeWwzjhMdJ75QdTzUaIhTG1hnH9faQNMw==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/describe-ref": "3.10.0", + "libnpm": "^2.0.1", + "minimatch": "^3.0.4", + "slash": "^1.0.0" + }, + "dependencies": { + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "@lerna/command": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/command/-/command-3.10.6.tgz", + "integrity": "sha512-jPZswMZXOpAaIuSF5hrz+eaWQzbDrvwbrkCoRJKfiAHx7URAkE6MQe9DeAnqrTKMqwfg0RciSrZLc8kWYfrzCQ==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/package-graph": "3.10.6", + "@lerna/project": "3.10.0", + "@lerna/validation-error": "3.6.0", + "@lerna/write-log-file": "3.6.0", + "dedent": "^0.7.0", + "execa": "^1.0.0", + "is-ci": "^1.0.10", + "libnpm": "^2.0.1", + "lodash": "^4.17.5" + }, + "dependencies": { + "ci-info": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.6.0.tgz", + "integrity": "sha512-vsGdkwSCDpWmP80ncATX7iea5DWQemg1UgCW5J8tqjU3lYw4FBYuj89J0CTVomA7BEfvSZd84GmHko+MxFQU2A==", + "dev": true + }, + "is-ci": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.2.1.tgz", + "integrity": "sha512-s6tfsaQaQi3JNciBH6shVqEDvhGut0SUXr31ag8Pd8BBbVVlcGfWhpPmEOoM6RJ5TFhbypvf5yyRw/VXW1IiWg==", + "dev": true, + "requires": { + "ci-info": "^1.5.0" + } + } + } + }, + "@lerna/conventional-commits": { + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/@lerna/conventional-commits/-/conventional-commits-3.10.8.tgz", + "integrity": "sha512-kjODN5f++nsvNT6w9zPuzN+tfNlq7QaKzy6KOMUb+AvGfI4+AKw8z9Uhr8AGvyuFgyNVI69/vdFaXrWC4iTKtQ==", + "dev": true, + "requires": { + "@lerna/validation-error": "3.6.0", + "conventional-changelog-angular": "^5.0.2", + "conventional-changelog-core": "^3.1.5", + "conventional-recommended-bump": "^4.0.4", + "fs-extra": "^7.0.0", + "get-stream": "^4.0.0", + "libnpm": "^2.0.1", + "pify": "^3.0.0", + "semver": "^5.5.0" + } + }, + "@lerna/create": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/create/-/create-3.10.6.tgz", + "integrity": "sha512-OddQtGBHM2/eJONggLWoTE6275XGbnJ6dIVF+fLsKS93o4GC6g+qcc6Y7lUWHm5bfpeOwNOVKwj0tvqBZ6MgoA==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/command": "3.10.6", + "@lerna/npm-conf": "3.7.0", + "@lerna/validation-error": "3.6.0", + "camelcase": "^4.1.0", + "dedent": "^0.7.0", + "fs-extra": "^7.0.0", + "globby": "^8.0.1", + "init-package-json": "^1.10.3", + "libnpm": "^2.0.1", + "p-reduce": "^1.0.0", + "pify": "^3.0.0", + "semver": "^5.5.0", + "slash": "^1.0.0", + "validate-npm-package-license": "^3.0.3", + "validate-npm-package-name": "^3.0.0", + "whatwg-url": "^7.0.0" + }, + "dependencies": { + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "@lerna/create-symlink": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/create-symlink/-/create-symlink-3.6.0.tgz", + "integrity": "sha512-YG3lTb6zylvmGqKU+QYA3ylSnoLn+FyLH5XZmUsD0i85R884+EyJJeHx/zUk+yrL2ZwHS4RBUgJfC24fqzgPoA==", + "dev": true, + "requires": { + "cmd-shim": "^2.0.2", + "fs-extra": "^7.0.0", + "libnpm": "^2.0.1" + } + }, + "@lerna/describe-ref": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/describe-ref/-/describe-ref-3.10.0.tgz", + "integrity": "sha512-fouh3FQS07QxJJp/mW8LkGnH0xMRAzpBlejtZaiRwfDkW2kd6EuHaj8I/2/p21Wsprcvuu4dqmyia2YS1xFb/w==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "libnpm": "^2.0.1" + } + }, + "@lerna/diff": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/diff/-/diff-3.10.6.tgz", + "integrity": "sha512-0MqFhosjrqsIdXiKIu7t3CiJELqiU9mkjFBhYPB7JruAzpPwjMXJnC6/Ur5/7LXJYYVpqGQwZI9ZaZlOYJhhrw==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/command": "3.10.6", + "@lerna/validation-error": "3.6.0", + "libnpm": "^2.0.1" + } + }, + "@lerna/exec": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/exec/-/exec-3.10.6.tgz", + "integrity": "sha512-cdHqaRBMYceJu8rZLO8b4ZeR27O+xKPHgzi13OOOfBJQjrTuacjMWyHgmpy8jWc/0f7QnTl4VsHks7VJ3UK+vw==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.10.6", + "@lerna/child-process": "3.3.0", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", + "@lerna/run-parallel-batches": "3.0.0", + "@lerna/validation-error": "3.6.0" + } + }, + "@lerna/filter-options": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/filter-options/-/filter-options-3.10.6.tgz", + "integrity": "sha512-r/dQbqN+RGFKZNn+DyWehswFmAkny/fkdMB2sRM2YVe7zRTtSl95YxD9DtdYnpJTG/jbOVICS/L5QJakrI6SSw==", + "dev": true, + "requires": { + "@lerna/collect-updates": "3.10.1", + "@lerna/filter-packages": "3.10.0", + "dedent": "^0.7.0" + } + }, + "@lerna/filter-packages": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/filter-packages/-/filter-packages-3.10.0.tgz", + "integrity": "sha512-3Acdj+jbany6LnQSuImU4ttcK5ULHSVug8Gh/EvwTewKCDpHAuoI3eyuzZOnSBdMvDOjE03uIESQK0dNNsn6Ow==", + "dev": true, + "requires": { + "@lerna/validation-error": "3.6.0", + "libnpm": "^2.0.1", + "multimatch": "^2.1.0" + } + }, + "@lerna/get-npm-exec-opts": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/get-npm-exec-opts/-/get-npm-exec-opts-3.6.0.tgz", + "integrity": "sha512-ruH6KuLlt75aCObXfUIdVJqmfVq7sgWGq5mXa05vc1MEqxTIiU23YiJdWzofQOOUOACaZkzZ4K4Nu7wXEg4Xgg==", + "dev": true, + "requires": { + "libnpm": "^2.0.1" + } + }, + "@lerna/get-packed": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@lerna/get-packed/-/get-packed-3.7.0.tgz", + "integrity": "sha512-yuFtjsUZIHjeIvIYQ/QuytC+FQcHwo3peB+yGBST2uWCLUCR5rx6knoQcPzbxdFDCuUb5IFccFGd3B1fHFg3RQ==", + "dev": true, + "requires": { + "fs-extra": "^7.0.0", + "ssri": "^6.0.1", + "tar": "^4.4.8" + }, + "dependencies": { + "tar": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } + } + }, + "@lerna/global-options": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/global-options/-/global-options-3.10.6.tgz", + "integrity": "sha512-k5Xkq1M/uREFC2R9uwN5gcvIgjj4iOXo0YyeEXCMWBiW3j2GL9xN4d1MmAIcrYlAzVYh6kLlWaFWl/rNIneHIw==", + "dev": true + }, + "@lerna/has-npm-version": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/has-npm-version/-/has-npm-version-3.10.0.tgz", + "integrity": "sha512-N4RRYxGeivuaKgPDzrhkQOQs1Sg4tOnxnEe3akfqu1wDA4Ng5V6Y2uW3DbkAjFL3aNJhWF5Vbf7sBsGtfgDQ8w==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "semver": "^5.5.0" + } + }, + "@lerna/import": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/import/-/import-3.10.6.tgz", + "integrity": "sha512-LlGxhfDhovoNoBJLF3PYd3j/G2GFTnfLh0V38+hBQ6lomMNJbjkACfiLVomQxPWWpYLk0GTlpWYR8YGv6L7Ifw==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/command": "3.10.6", + "@lerna/prompt": "3.6.0", + "@lerna/pulse-till-done": "3.7.1", + "@lerna/validation-error": "3.6.0", + "dedent": "^0.7.0", + "fs-extra": "^7.0.0", + "p-map-series": "^1.0.0" + } + }, + "@lerna/init": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/init/-/init-3.10.6.tgz", + "integrity": "sha512-RIlEx+ofWLYRNjxCkkV3G0XQPM+/KA5RXRDb5wKQLYO1f+tZAaHoUh8fHDIvxGf/ohY/OIjYYGSsU+ysimfwiQ==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/command": "3.10.6", + "fs-extra": "^7.0.0", + "p-map": "^1.2.0", + "write-json-file": "^2.3.0" + } + }, + "@lerna/link": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/link/-/link-3.10.6.tgz", + "integrity": "sha512-dwD6qftRWitgLDYbqtDrgO7c8uF5C0fHVew5M6gU5m9tBJidqd7cDwHv/bXboLEI63U7tt5y6LY+wEpYUFsBRw==", + "dev": true, + "requires": { + "@lerna/command": "3.10.6", + "@lerna/package-graph": "3.10.6", + "@lerna/symlink-dependencies": "3.10.0", + "p-map": "^1.2.0", + "slash": "^1.0.0" + }, + "dependencies": { + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "@lerna/list": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/list/-/list-3.10.6.tgz", + "integrity": "sha512-3ElQBj2dOB4uUkpsjC1bxdeZwEzRBuV1pBBs5E1LncwsZf7D9D99Z32fuZsDaCHpEMgHAD4/j8juI3/7m5dkaQ==", + "dev": true, + "requires": { + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", + "@lerna/listable": "3.10.6", + "@lerna/output": "3.6.0" + } + }, + "@lerna/listable": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/listable/-/listable-3.10.6.tgz", + "integrity": "sha512-F7ZuvesSgeuMiJf99eOum5p1MQGQStykcmHH1ek+LQRMiGGF1o3PkBxPvHTZBADGOFarek8bFA5TVmRAMX7NIw==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.10.6", + "chalk": "^2.3.1", + "columnify": "^1.5.4" + } + }, + "@lerna/log-packed": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/log-packed/-/log-packed-3.6.0.tgz", + "integrity": "sha512-T/J41zMkzpWB5nbiTRS5PmYTFn74mJXe6RQA2qhkdLi0UqnTp97Pux1loz3jsJf2yJtiQUnyMM7KuKIAge0Vlw==", + "dev": true, + "requires": { + "byte-size": "^4.0.3", + "columnify": "^1.5.4", + "has-unicode": "^2.0.1", + "libnpm": "^2.0.1" + } + }, + "@lerna/npm-conf": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-conf/-/npm-conf-3.7.0.tgz", + "integrity": "sha512-+WSMDfPKcKzMfqq283ydz9RRpOU6p9wfx0wy4hVSUY/6YUpsyuk8SShjcRtY8zTM5AOrxvFBuuV90H4YpZ5+Ng==", + "dev": true, + "requires": { + "config-chain": "^1.1.11", + "pify": "^3.0.0" + } + }, + "@lerna/npm-dist-tag": { + "version": "3.8.5", + "resolved": "https://registry.npmjs.org/@lerna/npm-dist-tag/-/npm-dist-tag-3.8.5.tgz", + "integrity": "sha512-VO57yKTB4NC2LZuTd4w0LmlRpoFm/gejQ1gqqLGzSJuSZaBXmieElFovzl21S07cqiy7FNVdz75x7/a6WCZ6XA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "libnpm": "^2.0.1" + } + }, + "@lerna/npm-install": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-install/-/npm-install-3.10.0.tgz", + "integrity": "sha512-/6/XyLY9/4jaMPBOVYUr4wZxQURIfwoELY0qCQ8gZ5zv4cOiFiiCUxZ0i4fxqFtD7nJ084zq1DsZW0aH0CIWYw==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/get-npm-exec-opts": "3.6.0", + "fs-extra": "^7.0.0", + "libnpm": "^2.0.1", + "signal-exit": "^3.0.2", + "write-pkg": "^3.1.0" + } + }, + "@lerna/npm-publish": { + "version": "3.10.7", + "resolved": "https://registry.npmjs.org/@lerna/npm-publish/-/npm-publish-3.10.7.tgz", + "integrity": "sha512-oU3/Q+eHC1fRjh7bk6Nn4tRD1OLR6XZVs3v+UWMWMrF4hVSV61pxcP5tpeI1n4gDQjSgh7seI4EzKVJe/WfraA==", + "dev": true, + "requires": { + "@lerna/run-lifecycle": "3.10.5", + "figgy-pudding": "^3.5.1", + "fs-extra": "^7.0.0", + "libnpm": "^2.0.1" + } + }, + "@lerna/npm-run-script": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/npm-run-script/-/npm-run-script-3.10.0.tgz", + "integrity": "sha512-c21tBXLF1Wje4tx/Td9jKIMrlZo/8QQiyyadjdKpwyyo7orSMsVNXGyJwvZ4JVVDcwC3GPU6HQvkt63v7rcyaw==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "@lerna/get-npm-exec-opts": "3.6.0", + "libnpm": "^2.0.1" + } + }, + "@lerna/output": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/output/-/output-3.6.0.tgz", + "integrity": "sha512-9sjQouf6p7VQtVCRnzoTGlZyURd48i3ha3WBHC/UBJnHZFuXMqWVPKNuvnMf2kRXDyoQD+2mNywpmEJg5jOnRg==", + "dev": true, + "requires": { + "libnpm": "^2.0.1" + } + }, + "@lerna/pack-directory": { + "version": "3.10.5", + "resolved": "https://registry.npmjs.org/@lerna/pack-directory/-/pack-directory-3.10.5.tgz", + "integrity": "sha512-Ulj24L9XdgjJIxBr6ZjRJEoBULVH3c10lqunUdW41bswXhzhirRtQIxv0+5shngNjDwgMmJfOBcuCVKPSez4tg==", + "dev": true, + "requires": { + "@lerna/get-packed": "3.7.0", + "@lerna/package": "3.7.2", + "@lerna/run-lifecycle": "3.10.5", + "figgy-pudding": "^3.5.1", + "libnpm": "^2.0.1", + "npm-packlist": "^1.1.12", + "tar": "^4.4.8", + "temp-write": "^3.4.0" + }, + "dependencies": { + "tar": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } + } + }, + "@lerna/package": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/@lerna/package/-/package-3.7.2.tgz", + "integrity": "sha512-8A5hN2CekM1a0Ix4VUO/g+REo+MsnXb8lnQ0bGjr1YGWzSL5NxYJ0Z9+0pwTfDpvRDYlFYO0rMVwBUW44b4dUw==", + "dev": true, + "requires": { + "libnpm": "^2.0.1", + "load-json-file": "^4.0.0", + "write-pkg": "^3.1.0" + } + }, + "@lerna/package-graph": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/package-graph/-/package-graph-3.10.6.tgz", + "integrity": "sha512-mpIOJbhi+xLqT9BcUrLVD4We8WUdousQf/QndbEWl8DWAW1ethtRHVsCm9ufdBB3F9nj4PH/hqnDWWwqE+rS4w==", + "dev": true, + "requires": { + "@lerna/validation-error": "3.6.0", + "libnpm": "^2.0.1", + "semver": "^5.5.0" + } + }, + "@lerna/project": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/project/-/project-3.10.0.tgz", + "integrity": "sha512-9QRl8aGHuyU4zVEELQmNPnJTlS7XHqX7w9I9isCXdnilKc2R0MyvUs21lj6Yyt6xTuQnqD158TR9tbS4QufYQQ==", + "dev": true, + "requires": { + "@lerna/package": "3.7.2", + "@lerna/validation-error": "3.6.0", + "cosmiconfig": "^5.0.2", + "dedent": "^0.7.0", + "dot-prop": "^4.2.0", + "glob-parent": "^3.1.0", + "globby": "^8.0.1", + "libnpm": "^2.0.1", + "load-json-file": "^4.0.0", + "p-map": "^1.2.0", + "resolve-from": "^4.0.0", + "write-json-file": "^2.3.0" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "@lerna/prompt": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/prompt/-/prompt-3.6.0.tgz", + "integrity": "sha512-nyAjPMolJ/ZRAAVcXrUH89C4n1SiWvLh4xWNvWYKLcf3PI5yges35sDFP/HYrM4+cEbkNFuJCRq6CxaET4PRsg==", + "dev": true, + "requires": { + "inquirer": "^6.2.0", + "libnpm": "^2.0.1" + } + }, + "@lerna/publish": { + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/@lerna/publish/-/publish-3.10.8.tgz", + "integrity": "sha512-kS3zia6knsoN8nd+6ihuwRhicBM6HRmbDgoa4uii4+ZqLVz4dniHYfHCMcZzHYSN8Kj35MsT25Ax1iq5eCjxmQ==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.10.6", + "@lerna/check-working-tree": "3.10.0", + "@lerna/child-process": "3.3.0", + "@lerna/collect-updates": "3.10.1", + "@lerna/command": "3.10.6", + "@lerna/describe-ref": "3.10.0", + "@lerna/log-packed": "3.6.0", + "@lerna/npm-conf": "3.7.0", + "@lerna/npm-dist-tag": "3.8.5", + "@lerna/npm-publish": "3.10.7", + "@lerna/output": "3.6.0", + "@lerna/pack-directory": "3.10.5", + "@lerna/prompt": "3.6.0", + "@lerna/pulse-till-done": "3.7.1", + "@lerna/run-lifecycle": "3.10.5", + "@lerna/run-parallel-batches": "3.0.0", + "@lerna/validation-error": "3.6.0", + "@lerna/version": "3.10.8", + "figgy-pudding": "^3.5.1", + "fs-extra": "^7.0.0", + "libnpm": "^2.0.1", + "p-finally": "^1.0.0", + "p-map": "^1.2.0", + "p-pipe": "^1.2.0", + "p-reduce": "^1.0.0", + "semver": "^5.5.0" + } + }, + "@lerna/pulse-till-done": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/@lerna/pulse-till-done/-/pulse-till-done-3.7.1.tgz", + "integrity": "sha512-MzpesZeW3Mc+CiAq4zUt9qTXI9uEBBKrubYHE36voQTSkHvu/Rox6YOvfUr+U7P6k8frFPeCgGpfMDTLhiqe6w==", + "dev": true, + "requires": { + "libnpm": "^2.0.1" + } + }, + "@lerna/resolve-symlink": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/resolve-symlink/-/resolve-symlink-3.6.0.tgz", + "integrity": "sha512-TVOAEqHJSQVhNDMFCwEUZPaOETqHDQV1TQWQfC8ZlOqyaUQ7veZUbg0yfG7RPNzlSpvF0ZaGFeR0YhYDAW03GA==", + "dev": true, + "requires": { + "fs-extra": "^7.0.0", + "libnpm": "^2.0.1", + "read-cmd-shim": "^1.0.1" + } + }, + "@lerna/rimraf-dir": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/rimraf-dir/-/rimraf-dir-3.10.0.tgz", + "integrity": "sha512-RSKSfxPURc58ERCD/PuzorR86lWEvIWNclXYGvIYM76yNGrWiDF44pGHQvB4J+Lxa5M+52ZtZC/eOC7A7YCH4g==", + "dev": true, + "requires": { + "@lerna/child-process": "3.3.0", + "libnpm": "^2.0.1", + "path-exists": "^3.0.0", + "rimraf": "^2.6.2" + } + }, + "@lerna/run": { + "version": "3.10.6", + "resolved": "https://registry.npmjs.org/@lerna/run/-/run-3.10.6.tgz", + "integrity": "sha512-KS2lWbu/8WUUscQPi9U8sPO6yYpzf/0GmODjpruR1nRi1u/tuncdjTiG+hjGAeFC1BD7YktT9Za6imIpE8RXmA==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.10.6", + "@lerna/command": "3.10.6", + "@lerna/filter-options": "3.10.6", + "@lerna/npm-run-script": "3.10.0", + "@lerna/output": "3.6.0", + "@lerna/run-parallel-batches": "3.0.0", + "@lerna/timer": "3.5.0", + "@lerna/validation-error": "3.6.0", + "p-map": "^1.2.0" + } + }, + "@lerna/run-lifecycle": { + "version": "3.10.5", + "resolved": "https://registry.npmjs.org/@lerna/run-lifecycle/-/run-lifecycle-3.10.5.tgz", + "integrity": "sha512-YPmXviaxVlhcKM6IkDTIpTq24mxOuMCilo+MTr1RLoafgB9ZTmP2AHRiFt/sy14wOsq2Zqr0wJyj8KFlDYLTkA==", + "dev": true, + "requires": { + "@lerna/npm-conf": "3.7.0", + "figgy-pudding": "^3.5.1", + "libnpm": "^2.0.1" + } + }, + "@lerna/run-parallel-batches": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@lerna/run-parallel-batches/-/run-parallel-batches-3.0.0.tgz", + "integrity": "sha512-Mj1ravlXF7AkkewKd9YFq9BtVrsStNrvVLedD/b2wIVbNqcxp8lS68vehXVOzoL/VWNEDotvqCQtyDBilCodGw==", + "dev": true, + "requires": { + "p-map": "^1.2.0", + "p-map-series": "^1.0.0" + } + }, + "@lerna/symlink-binary": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-binary/-/symlink-binary-3.10.0.tgz", + "integrity": "sha512-6mQsG+iVjBo8cD8s24O+YgFrwDyUGfUQbK4ryalAXFHI817Zd4xlI3tjg3W99whCt6rt6D0s1fpf8eslMN6dSw==", + "dev": true, + "requires": { + "@lerna/create-symlink": "3.6.0", + "@lerna/package": "3.7.2", + "fs-extra": "^7.0.0", + "p-map": "^1.2.0" + } + }, + "@lerna/symlink-dependencies": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/@lerna/symlink-dependencies/-/symlink-dependencies-3.10.0.tgz", + "integrity": "sha512-vGpg5ydwGgQCuWNX5y7CRL38mGpuLhf1GRq9wMm7IGwnctEsdSNqvvE+LDgqtwEZASu5+vffYUkL0VlFXl8uWA==", + "dev": true, + "requires": { + "@lerna/create-symlink": "3.6.0", + "@lerna/resolve-symlink": "3.6.0", + "@lerna/symlink-binary": "3.10.0", + "fs-extra": "^7.0.0", + "p-finally": "^1.0.0", + "p-map": "^1.2.0", + "p-map-series": "^1.0.0" + } + }, + "@lerna/timer": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@lerna/timer/-/timer-3.5.0.tgz", + "integrity": "sha512-TAb99hqQN6E3JBGtG9iyZNPq1/DbmqgBOeNrKtdJsGvIeX/NGLgUDWMrj2h04V4O+jpBFmSf6HIld6triKmxCA==", + "dev": true + }, + "@lerna/validation-error": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/validation-error/-/validation-error-3.6.0.tgz", + "integrity": "sha512-MWltncGO5VgMS0QedTlZCjFUMF/evRjDMMHrtVorkIB2Cp5xy0rkKa8iDBG43qpUWeG1giwi58yUlETBcWfILw==", + "dev": true, + "requires": { + "libnpm": "^2.0.1" + } + }, + "@lerna/version": { + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/@lerna/version/-/version-3.10.8.tgz", + "integrity": "sha512-Iko2OkwwkjyK+tIklnH/72M/f54muSiRJurCsC3JqdM8aZaeDXeUrHmAyl7nQLfBlSsHfHyRax/ELkREmO5Tng==", + "dev": true, + "requires": { + "@lerna/batch-packages": "3.10.6", + "@lerna/check-working-tree": "3.10.0", + "@lerna/child-process": "3.3.0", + "@lerna/collect-updates": "3.10.1", + "@lerna/command": "3.10.6", + "@lerna/conventional-commits": "3.10.8", + "@lerna/output": "3.6.0", + "@lerna/prompt": "3.6.0", + "@lerna/run-lifecycle": "3.10.5", + "@lerna/validation-error": "3.6.0", + "chalk": "^2.3.1", + "dedent": "^0.7.0", + "libnpm": "^2.0.1", + "minimatch": "^3.0.4", + "p-map": "^1.2.0", + "p-pipe": "^1.2.0", + "p-reduce": "^1.0.0", + "p-waterfall": "^1.0.0", + "semver": "^5.5.0", + "slash": "^1.0.0", + "temp-write": "^3.4.0" + }, + "dependencies": { + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "@lerna/write-log-file": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/@lerna/write-log-file/-/write-log-file-3.6.0.tgz", + "integrity": "sha512-OkLK99V6sYXsJsYg+O9wtiFS3z6eUPaiz2e6cXJt80mfIIdI1t2dnmyua0Ib5cZWExQvx2z6Y32Wlf0MnsoNsA==", + "dev": true, + "requires": { + "libnpm": "^2.0.1", + "write-file-atomic": "^2.3.0" + } + }, + "@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.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@samverschueren/stream-to-observable": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@samverschueren/stream-to-observable/-/stream-to-observable-0.3.0.tgz", + "integrity": "sha512-MI4Xx6LHs4Webyvi6EbspgyAb4D2Q2VtnCQ1blOJcoLS6mVa8lNN2rkIy1CVxfTUpoyIbCTkXES1rLXztFD1lg==", + "dev": true, + "requires": { + "any-observable": "^0.3.0" + } + }, + "@types/node": { + "version": "10.12.21", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.12.21.tgz", + "integrity": "sha512-CBgLNk4o3XMnqMc0rhb6lc77IwShMEglz05deDcn2lQxyXEZivfwgYJu7SMha9V5XcrP6qZuevTHV/QrN2vjKQ==", + "dev": true + }, + "@types/sinon": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/sinon/-/sinon-7.0.5.tgz", + "integrity": "sha512-4DShbH857bZVOY4tPi1RQJNrLcf89hEtU0klZ9aYTMbtt95Ok4XdPqqcbtGOHIbAHMLSzQP8Uw/6qtBBqyloww==", + "dev": true + }, + "JSONStream": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz", + "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==", + "dev": true, + "requires": { + "jsonparse": "^1.2.0", + "through": ">=2.2.7 <3" + } + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "agent-base": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz", + "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==", + "dev": true, + "requires": { + "es6-promisify": "^5.0.0" + } + }, + "agentkeepalive": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-3.5.2.tgz", + "integrity": "sha512-e0L/HNe6qkQ7H19kTlRRqUibEAwDK5AFk6y3PtMsuut2VAH6+Q4xZml1tNDJD7kSAyqmbG/K08K5WEJYtUrSlQ==", + "dev": true, + "requires": { + "humanize-ms": "^1.2.1" + } + }, + "ajv": { + "version": "6.9.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.9.2.tgz", + "integrity": "sha512-4UFy0/LgDo7Oa/+wOAlj44tp9K78u38E5/359eSrqEp1Z5PdVfimCcs7SluXMP755RUQu6d2b4AvF0R1C9RZjg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "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" + } + }, + "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 + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", + "integrity": "sha512-5hYdAkZlcG8tOLujVDTgCT+uPX0VnpAH28gWsLfzpXYm7wP6mp5Q/gYyR7YQ0cKVJcXJnl3j2kpBan13PtQf6w==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "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-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true + }, + "array-ify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz", + "integrity": "sha1-nlKHYrSpBmrRY6aWKjZEGOlibs4=", + "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 + }, + "asap": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/asap/-/asap-2.0.6.tgz", + "integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=", + "dev": true + }, + "asn1": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz", + "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==", + "dev": true, + "requires": { + "safer-buffer": "~2.1.0" + } + }, + "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 + }, + "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" + } + }, + "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.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "aws-sign2": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz", + "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=", + "dev": true + }, + "aws4": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", + "dev": true + }, + "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" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "http://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" + } + }, + "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 + } + } + }, + "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" + } + } + } + }, + "bcrypt-pbkdf": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", + "dev": true, + "requires": { + "tweetnacl": "^0.14.3" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + } + } + }, + "bin-links": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/bin-links/-/bin-links-1.1.2.tgz", + "integrity": "sha512-8eEHVgYP03nILphilltWjeIjMbKyJo3wvp9K816pHbhP301ismzw15mxAAEVQ/USUwcP++1uNrbERbp8lOA6Fg==", + "dev": true, + "requires": { + "bluebird": "^3.5.0", + "cmd-shim": "^2.0.2", + "gentle-fs": "^2.0.0", + "graceful-fs": "^4.1.11", + "write-file-atomic": "^2.3.0" + } + }, + "block-stream": { + "version": "0.0.9", + "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", + "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", + "dev": true, + "requires": { + "inherits": "~2.0.0" + } + }, + "bluebird": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true + }, + "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" + } + } + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "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 + }, + "builtins": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/builtins/-/builtins-1.0.3.tgz", + "integrity": "sha1-y5T662HIaWRR2zZTThQi+U8K7og=", + "dev": true + }, + "byline": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/byline/-/byline-5.0.0.tgz", + "integrity": "sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=", + "dev": true + }, + "byte-size": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/byte-size/-/byte-size-4.0.4.tgz", + "integrity": "sha512-82RPeneC6nqCdSwCX2hZUz3JPOvN5at/nTEw/CMf05Smu3Hrpo9Psb7LjN+k+XndNArG1EY8L4+BM3aTM4BCvw==", + "dev": true + }, + "cacache": { + "version": "11.3.2", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-11.3.2.tgz", + "integrity": "sha512-E0zP4EPGDOaT2chM08Als91eYnf8Z+eH1awwwVsngUmgppfM5jjJ8l3z5vO5p5w/I3LsiXawb1sW0VY65pQABg==", + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.3", + "graceful-fs": "^4.1.15", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.2", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "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" + } + }, + "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 + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "dev": true + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + } + }, + "caseless": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz", + "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chownr": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz", + "integrity": "sha512-j38EvO5+LHX84jlo6h4UzmOwi0UgW61WRyPtJz4qaadK5eY3BTS5TY/S1Stc3Uk2lIM6TPevAlULiEJwie860g==", + "dev": true + }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-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" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.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 + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "cmd-shim": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/cmd-shim/-/cmd-shim-2.0.2.tgz", + "integrity": "sha1-b8vamUg6j9FdfTChlspp1oii79s=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "mkdirp": "~0.5.0" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "columnify": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/columnify/-/columnify-1.5.4.tgz", + "integrity": "sha1-Rzfd8ce2mop8NAVweC6UfuyOeLs=", + "dev": true, + "requires": { + "strip-ansi": "^3.0.0", + "wcwidth": "^1.0.0" + } + }, + "combined-stream": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz", + "integrity": "sha512-brWl9y6vOB1xYPZcpZde3N9zDByXTosAeMDo4p1wzo6UMOX4vumB+TP1RZ76sfE6Md68Q0NJSrE/gbezd4Ul+w==", + "dev": true, + "requires": { + "delayed-stream": "~1.0.0" + } + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "compare-func": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-1.3.2.tgz", + "integrity": "sha1-md0LpFfh+bxyKxLAjsM+6rMfpkg=", + "dev": true, + "requires": { + "array-ify": "^1.0.0", + "dot-prop": "^3.0.0" + }, + "dependencies": { + "dot-prop": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-3.0.0.tgz", + "integrity": "sha1-G3CK8JSknJoOfbyteQq6U52sEXc=", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + } + } + }, + "component-emitter": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "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" + } + }, + "config-chain": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.12.tgz", + "integrity": "sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA==", + "dev": true, + "requires": { + "ini": "^1.3.4", + "proto-list": "~1.2.1" + } + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "conventional-changelog-angular": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-5.0.2.tgz", + "integrity": "sha512-yx7m7lVrXmt4nKWQgWZqxSALEiAKZhOAcbxdUaU9575mB0CzXVbgrgpfSnSP7OqWDUTYGD0YVJ0MSRdyOPgAwA==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "q": "^1.5.1" + } + }, + "conventional-changelog-core": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/conventional-changelog-core/-/conventional-changelog-core-3.1.5.tgz", + "integrity": "sha512-iwqAotS4zk0wA4S84YY1JCUG7X3LxaRjJxuUo6GI4dZuIy243j5nOg/Ora35ExT4DOiw5dQbMMQvw2SUjh6moQ==", + "dev": true, + "requires": { + "conventional-changelog-writer": "^4.0.2", + "conventional-commits-parser": "^3.0.1", + "dateformat": "^3.0.0", + "get-pkg-repo": "^1.0.0", + "git-raw-commits": "2.0.0", + "git-remote-origin-url": "^2.0.0", + "git-semver-tags": "^2.0.2", + "lodash": "^4.2.1", + "normalize-package-data": "^2.3.5", + "q": "^1.5.1", + "read-pkg": "^3.0.0", + "read-pkg-up": "^3.0.0", + "through2": "^2.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "conventional-changelog-preset-loader": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-preset-loader/-/conventional-changelog-preset-loader-2.0.2.tgz", + "integrity": "sha512-pBY+qnUoJPXAXXqVGwQaVmcye05xi6z231QM98wHWamGAmu/ghkBprQAwmF5bdmyobdVxiLhPY3PrCfSeUNzRQ==", + "dev": true + }, + "conventional-changelog-writer": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/conventional-changelog-writer/-/conventional-changelog-writer-4.0.2.tgz", + "integrity": "sha512-d8/FQY/fix2xXEBUhOo8u3DCbyEw3UOQgYHxLsPDw+wHUDma/GQGAGsGtoH876WyNs32fViHmTOUrgRKVLvBug==", + "dev": true, + "requires": { + "compare-func": "^1.3.1", + "conventional-commits-filter": "^2.0.1", + "dateformat": "^3.0.0", + "handlebars": "^4.0.2", + "json-stringify-safe": "^5.0.1", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "semver": "^5.5.0", + "split": "^1.0.0", + "through2": "^2.0.0" + } + }, + "conventional-commits-filter": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/conventional-commits-filter/-/conventional-commits-filter-2.0.1.tgz", + "integrity": "sha512-92OU8pz/977udhBjgPEbg3sbYzIxMDFTlQT97w7KdhR9igNqdJvy8smmedAAgn4tPiqseFloKkrVfbXCVd+E7A==", + "dev": true, + "requires": { + "is-subset": "^0.1.1", + "modify-values": "^1.0.0" + } + }, + "conventional-commits-parser": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-3.0.1.tgz", + "integrity": "sha512-P6U5UOvDeidUJ8ebHVDIoXzI7gMlQ1OF/id6oUvp8cnZvOXMt1n8nYl74Ey9YMn0uVQtxmCtjPQawpsssBWtGg==", + "dev": true, + "requires": { + "JSONStream": "^1.0.4", + "is-text-path": "^1.0.0", + "lodash": "^4.2.1", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0", + "trim-off-newlines": "^1.0.0" + } + }, + "conventional-recommended-bump": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/conventional-recommended-bump/-/conventional-recommended-bump-4.0.4.tgz", + "integrity": "sha512-9mY5Yoblq+ZMqJpBzgS+RpSq+SUfP2miOR3H/NR9drGf08WCrY9B6HAGJZEm6+ThsVP917VHAahSOjM6k1vhPg==", + "dev": true, + "requires": { + "concat-stream": "^1.6.0", + "conventional-changelog-preset-loader": "^2.0.2", + "conventional-commits-filter": "^2.0.1", + "conventional-commits-parser": "^3.0.1", + "git-raw-commits": "2.0.0", + "git-semver-tags": "^2.0.2", + "meow": "^4.0.0", + "q": "^1.5.1" + } + }, + "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-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 + }, + "cosmiconfig": { + "version": "5.0.7", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.0.7.tgz", + "integrity": "sha512-PcLqxTKiDmNT6pSpy4N6KtuPwb53W+2tzNvwOZw0WH9N6O0vLIBq0x8aj8Oj75ere4YcGi48bDFCL+3fRJdlNA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.9.0", + "parse-json": "^4.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" + } + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "cyclist": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", + "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", + "dev": true + }, + "dargs": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/dargs/-/dargs-4.1.0.tgz", + "integrity": "sha1-A6nbtLXC8Tm/FK5T8LiipqhvThc=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "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" + } + }, + "date-fns": { + "version": "1.30.1", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz", + "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==", + "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==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "debuglog": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/debuglog/-/debuglog-1.0.1.tgz", + "integrity": "sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=", + "dev": true + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decamelize-keys": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", + "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=", + "dev": true, + "requires": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "dependencies": { + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "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 + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": true + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "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" + } + } + } + }, + "del": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz", + "integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=", + "dev": true, + "requires": { + "globby": "^6.1.0", + "is-path-cwd": "^1.0.0", + "is-path-in-cwd": "^1.0.0", + "p-map": "^1.1.1", + "pify": "^3.0.0", + "rimraf": "^2.2.8" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "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 + } + } + } + } + }, + "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 + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "detect-indent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-5.0.0.tgz", + "integrity": "sha1-OHHMCmoALow+Wzz38zYmRnXwa50=", + "dev": true + }, + "dezalgo": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz", + "integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=", + "dev": true, + "requires": { + "asap": "^2.0.0", + "wrappy": "1" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "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" + } + }, + "dot-prop": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz", + "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==", + "dev": true, + "requires": { + "is-obj": "^1.0.0" + } + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "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.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", + "dev": true, + "requires": { + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" + } + }, + "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 + }, + "encoding": { + "version": "0.1.12", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz", + "integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=", + "dev": true, + "requires": { + "iconv-lite": "~0.4.13" + } + }, + "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" + } + }, + "err-code": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-1.1.2.tgz", + "integrity": "sha1-BuARbTAo9q70gGhJ6w6mp0iuaWA=", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es6-promise": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.5.tgz", + "integrity": "sha512-n6wvpdE43VFtJq+lUDYDBFUwV8TZbuGXLV4D6wKafg13ldznKsyEvatubnmUe31zcvelSzOHF+XbaT+Bl9ObDg==", + "dev": true + }, + "es6-promisify": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", + "dev": true, + "requires": { + "es6-promise": "^4.0.3" + } + }, + "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 + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "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": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "extsprintf": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz", + "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=", + "dev": true + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-glob": { + "version": "2.2.6", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.6.tgz", + "integrity": "sha512-0BvMaZc1k9F+MeWWMe8pL6YltFzZYcJsYU7D4JyDA6PAczaXvxqQQ/z+mDF7/4Mw01DeUc+i3CTKajnkANkV4w==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "dependencies": { + "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" + } + } + } + }, + "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 + }, + "figgy-pudding": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", + "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "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-npm-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz", + "integrity": "sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA==", + "dev": true + }, + "find-parent-dir": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/find-parent-dir/-/find-parent-dir-0.3.0.tgz", + "integrity": "sha1-M8RLQpqysvBkYpnF+fcY83b/jVQ=", + "dev": true + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "flush-write-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.0.tgz", + "integrity": "sha512-6MHED/cmsyux1G4/Cek2Z776y9t7WCNd3h2h/HW91vFeU7pzMhA8XvAlDhHcanG5IWuIh/xcC7JASY4WQpG6xg==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^3.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.1.1.tgz", + "integrity": "sha512-DkN66hPyqDhnIQ6Jcsvx9bFjhw214O4poMBcIMgPVpQvNy9a0e0Uhg5SqySyDKAmUlwt8LonTBz1ezOnM8pUdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "fn-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fn-name/-/fn-name-2.0.1.tgz", + "integrity": "sha1-UhTXU3pNBqSjAcDMJi/rhBiAAuc=", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forever-agent": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", + "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=", + "dev": true + }, + "form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "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": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-1.2.5.tgz", + "integrity": "sha512-JhBl0skXjUPCFH7x6x61gQxrKyXsxB5gcgePLZCwfyCGGsTISMoIeObbrvVeP6Xmyaudw4TT43qV2Gz+iyd2oQ==", + "dev": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs-vacuum": { + "version": "1.2.10", + "resolved": "https://registry.npmjs.org/fs-vacuum/-/fs-vacuum-1.2.10.tgz", + "integrity": "sha1-t2Kb7AekAxolSP35n17PHMizHjY=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "path-is-inside": "^1.0.1", + "rimraf": "^2.5.2" + } + }, + "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 + }, + "fstream": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", + "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "inherits": "~2.0.0", + "mkdirp": ">=0.5 0", + "rimraf": "2" + } + }, + "g-status": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/g-status/-/g-status-2.0.2.tgz", + "integrity": "sha512-kQoE9qH+T1AHKgSSD0Hkv98bobE90ILQcXAF4wvGgsr7uFqNvwmh8j+Lq3l0RVt3E3HjSbv2B9biEGcEtpHLCA==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "matcher": "^1.0.0", + "simple-git": "^1.85.0" + } + }, + "gauge": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz", + "integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=", + "dev": 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" + } + }, + "genfun": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/genfun/-/genfun-5.0.0.tgz", + "integrity": "sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA==", + "dev": true + }, + "gentle-fs": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/gentle-fs/-/gentle-fs-2.0.1.tgz", + "integrity": "sha512-cEng5+3fuARewXktTEGbwsktcldA+YsnUEaXZwcK/3pjSE1X9ObnTs+/8rYf8s+RnIcQm2D5x3rwpN7Zom8Bew==", + "dev": true, + "requires": { + "aproba": "^1.1.2", + "fs-vacuum": "^1.2.10", + "graceful-fs": "^4.1.11", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "path-is-inside": "^1.0.2", + "read-cmd-shim": "^1.0.1", + "slide": "^1.1.6" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "get-own-enumerable-property-symbols": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-3.0.0.tgz", + "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", + "dev": true + }, + "get-pkg-repo": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", + "integrity": "sha1-xztInAbYDMVTbCyFP54FIyBWly0=", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "meow": "^3.3.0", + "normalize-package-data": "^2.3.0", + "parse-github-repo-url": "^1.3.0", + "through2": "^2.0.0" + }, + "dependencies": { + "camelcase": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true + }, + "camelcase-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", + "dev": true, + "requires": { + "camelcase": "^2.0.0", + "map-obj": "^1.0.0" + } + }, + "find-up": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", + "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=", + "dev": true, + "requires": { + "path-exists": "^2.0.0", + "pinkie-promise": "^2.0.0" + } + }, + "get-stdin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "map-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true + }, + "meow": { + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", + "dev": true, + "requires": { + "camelcase-keys": "^2.0.0", + "decamelize": "^1.1.2", + "loud-rejection": "^1.0.0", + "map-obj": "^1.0.1", + "minimist": "^1.1.3", + "normalize-package-data": "^2.3.4", + "object-assign": "^4.0.1", + "read-pkg-up": "^1.0.1", + "redent": "^1.0.0", + "trim-newlines": "^1.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": "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" + } + }, + "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" + } + }, + "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" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "read-pkg": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz", + "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=", + "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" + } + }, + "redent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz", + "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=", + "dev": true, + "requires": { + "indent-string": "^2.1.0", + "strip-indent": "^1.0.1" + } + }, + "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-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", + "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=", + "dev": true, + "requires": { + "get-stdin": "^4.0.1" + } + }, + "trim-newlines": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true + } + } + }, + "get-port": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/get-port/-/get-port-3.2.0.tgz", + "integrity": "sha1-3Xzn3hh8Bsi/NTeWrHHgmfCYDrw=", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "getpass": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", + "integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=", + "dev": true, + "requires": { + "assert-plus": "^1.0.0" + } + }, + "git-raw-commits": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-2.0.0.tgz", + "integrity": "sha512-w4jFEJFgKXMQJ0H0ikBk2S+4KP2VEjhCvLCNqbNRQC8BgGWgLKNCO7a9K9LI+TVT7Gfoloje502sEnctibffgg==", + "dev": true, + "requires": { + "dargs": "^4.0.1", + "lodash.template": "^4.0.2", + "meow": "^4.0.0", + "split2": "^2.0.0", + "through2": "^2.0.0" + } + }, + "git-remote-origin-url": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/git-remote-origin-url/-/git-remote-origin-url-2.0.0.tgz", + "integrity": "sha1-UoJlna4hBxRaERJhEq0yFuxfpl8=", + "dev": true, + "requires": { + "gitconfiglocal": "^1.0.0", + "pify": "^2.3.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "git-semver-tags": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/git-semver-tags/-/git-semver-tags-2.0.2.tgz", + "integrity": "sha512-34lMF7Yo1xEmsK2EkbArdoU79umpvm0MfzaDkSNYSJqtM5QLAVTPWgpiXSVI5o/O9EvZPSrP4Zvnec/CqhSd5w==", + "dev": true, + "requires": { + "meow": "^4.0.0", + "semver": "^5.5.0" + } + }, + "gitconfiglocal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/gitconfiglocal/-/gitconfiglocal-1.0.0.tgz", + "integrity": "sha1-QdBF84UaXqiPA/JMocYXgRRGS5s=", + "dev": true, + "requires": { + "ini": "^1.3.2" + } + }, + "glob": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", + "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-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" + } + }, + "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 + }, + "globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "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" + }, + "dependencies": { + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "handlebars": { + "version": "4.0.12", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.12.tgz", + "integrity": "sha512-RhmTekP+FZL+XNhwS1Wf+bTTZpdLougwt5pcgA1tuz6Jcx0fpH/7z0qd71RKnZHBCxIRBHfBOnio4gViPemNzA==", + "dev": true, + "requires": { + "async": "^2.5.0", + "optimist": "^0.6.1", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4" + }, + "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 + } + } + }, + "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.1.3", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz", + "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==", + "dev": true, + "requires": { + "ajv": "^6.5.5", + "har-schema": "^2.0.0" + } + }, + "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-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "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" + } + } + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "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-proxy-agent": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz", + "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==", + "dev": true, + "requires": { + "agent-base": "4", + "debug": "3.1.0" + } + }, + "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-proxy-agent": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz", + "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==", + "dev": true, + "requires": { + "agent-base": "^4.1.0", + "debug": "^3.1.0" + } + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "husky": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/husky/-/husky-1.3.1.tgz", + "integrity": "sha512-86U6sVVVf4b5NYSZ0yvv88dRgBSSXXmHaiq5pP4KDj5JVzdwKgBjEtUPOm8hcoytezFwbU+7gotXNhpHdystlg==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.7", + "execa": "^1.0.0", + "find-up": "^3.0.0", + "get-stdin": "^6.0.0", + "is-ci": "^2.0.0", + "pkg-dir": "^3.0.0", + "please-upgrade-node": "^3.1.1", + "read-pkg": "^4.0.1", + "run-node": "^1.0.0", + "slash": "^2.0.0" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "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.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "ignore-walk": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ignore-walk/-/ignore-walk-3.0.1.tgz", + "integrity": "sha512-DTVlMx3IYPe0/JJcYP7Gxg7ttZZu3IInhuEhbchuqneY9wWe5Ojy2mXLBaQFUQmo0AW2r3qG7m1mg86js+gnlQ==", + "dev": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz", + "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==", + "dev": true, + "requires": { + "pkg-dir": "^2.0.0", + "resolve-cwd": "^2.0.0" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + } + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=", + "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=", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "init-package-json": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/init-package-json/-/init-package-json-1.10.3.tgz", + "integrity": "sha512-zKSiXKhQveNteyhcj1CoOP8tqp1QuxPIPBl8Bid99DGLFqA1p87M6lNgfjJHSBoWJJlidGOv5rWjyYKEB3g2Jw==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "npm-package-arg": "^4.0.0 || ^5.0.0 || ^6.0.0", + "promzard": "^0.3.0", + "read": "~1.0.1", + "read-package-json": "1 || 2", + "semver": "2.x || 3.x || 4 || 5", + "validate-npm-package-license": "^3.0.1", + "validate-npm-package-name": "^3.0.0" + } + }, + "inquirer": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.2.2.tgz", + "integrity": "sha512-Z2rREiXA6cHRR9KBOarR3WuLlFzlIfAEIiB45ll5SSadMg7WqOh1MKEjjndfuH5ewXdixWCxqnVfGOQzPeiztA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.0.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "strip-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.0.0.tgz", + "integrity": "sha512-Uu7gQyZI7J7gn5qLn1Np3G9vcYGTVqB+lFTytnDJv83dd8T22aGH451P3jueT2/QemInJDfxHB5Tde5OzgG1Ow==", + "dev": true, + "requires": { + "ansi-regex": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.0.0.tgz", + "integrity": "sha512-iB5Dda8t/UqpPI/IjsejXu5jOGDrzn41wJyljwPH65VCIbk6+1BzFIMJGFwTNrYXT1CrD+B4l19U7awiQ8rk7w==", + "dev": true + } + } + } + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "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" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "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-ci": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz", + "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==", + "dev": true, + "requires": { + "ci-info": "^2.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" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-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-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-finite": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", + "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "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" + } + }, + "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-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "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" + } + }, + "is-path-cwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz", + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true + }, + "is-path-in-cwd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz", + "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==", + "dev": true, + "requires": { + "is-path-inside": "^1.0.0" + } + }, + "is-path-inside": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz", + "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=", + "dev": true, + "requires": { + "path-is-inside": "^1.0.1" + } + }, + "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-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-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true + }, + "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-subset": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-subset/-/is-subset-0.1.1.tgz", + "integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=", + "dev": true + }, + "is-text-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-1.0.1.tgz", + "integrity": "sha1-Thqg+1G/vLPpJogAE5cgLBd1tm4=", + "dev": true, + "requires": { + "text-extensions": "^1.0.0" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "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 + }, + "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 + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "js-yaml": { + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.12.1.tgz", + "integrity": "sha512-um46hB9wNOKlwkHgiuyEVAybXBjwFUV0Z/RaHJblRd9DXltue9FTYvzCr9ErQrK9Adz5MU4gHWVaNUfdmrC8qA==", + "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 + }, + "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.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stringify-safe": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", + "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" + } + }, + "jsonparse": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz", + "integrity": "sha1-P02uSpH6wxX3EGL4UhzCOfE2YoA=", + "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" + } + }, + "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 + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "lerna": { + "version": "3.10.8", + "resolved": "https://registry.npmjs.org/lerna/-/lerna-3.10.8.tgz", + "integrity": "sha512-Ua5SkZnVk+gtplaw/IiXOckk9TEvNwNyTXJke5gkf0vxku809iRmI7RlI0mKFUjeweBs7AJDgBoD/A+vHst/UQ==", + "dev": true, + "requires": { + "@lerna/add": "3.10.6", + "@lerna/bootstrap": "3.10.6", + "@lerna/changed": "3.10.8", + "@lerna/clean": "3.10.6", + "@lerna/cli": "3.10.7", + "@lerna/create": "3.10.6", + "@lerna/diff": "3.10.6", + "@lerna/exec": "3.10.6", + "@lerna/import": "3.10.6", + "@lerna/init": "3.10.6", + "@lerna/link": "3.10.6", + "@lerna/list": "3.10.6", + "@lerna/publish": "3.10.8", + "@lerna/run": "3.10.6", + "@lerna/version": "3.10.8", + "import-local": "^1.0.0", + "libnpm": "^2.0.1" + } + }, + "libnpm": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/libnpm/-/libnpm-2.0.1.tgz", + "integrity": "sha512-qTKoxyJvpBxHZQB6k0AhSLajyXq9ZE/lUsZzuHAplr2Bpv9G+k4YuYlExYdUCeVRRGqcJt8hvkPh4tBwKoV98w==", + "dev": true, + "requires": { + "bin-links": "^1.1.2", + "bluebird": "^3.5.3", + "find-npm-prefix": "^1.0.2", + "libnpmaccess": "^3.0.1", + "libnpmconfig": "^1.2.1", + "libnpmhook": "^5.0.2", + "libnpmorg": "^1.0.0", + "libnpmpublish": "^1.1.0", + "libnpmsearch": "^2.0.0", + "libnpmteam": "^1.0.1", + "lock-verify": "^2.0.2", + "npm-lifecycle": "^2.1.0", + "npm-logical-tree": "^1.2.1", + "npm-package-arg": "^6.1.0", + "npm-profile": "^4.0.1", + "npm-registry-fetch": "^3.8.0", + "npmlog": "^4.1.2", + "pacote": "^9.2.3", + "read-package-json": "^2.0.13", + "stringify-package": "^1.0.0" + } + }, + "libnpmaccess": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/libnpmaccess/-/libnpmaccess-3.0.1.tgz", + "integrity": "sha512-RlZ7PNarCBt+XbnP7R6PoVgOq9t+kou5rvhaInoNibhPO7eMlRfS0B8yjatgn2yaHIwWNyoJDolC/6Lc5L/IQA==", + "dev": true, + "requires": { + "aproba": "^2.0.0", + "get-stream": "^4.0.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^3.8.0" + }, + "dependencies": { + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + } + } + }, + "libnpmconfig": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/libnpmconfig/-/libnpmconfig-1.2.1.tgz", + "integrity": "sha512-9esX8rTQAHqarx6qeZqmGQKBNZR5OIbl/Ayr0qQDy3oXja2iFVQQI81R6GZ2a02bSNZ9p3YOGX1O6HHCb1X7kA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "find-up": "^3.0.0", + "ini": "^1.3.5" + } + }, + "libnpmhook": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/libnpmhook/-/libnpmhook-5.0.2.tgz", + "integrity": "sha512-vLenmdFWhRfnnZiNFPNMog6CK7Ujofy2TWiM2CrpZUjBRIhHkJeDaAbJdYCT6W4lcHtyrJR8yXW8KFyq6UAp1g==", + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^3.8.0" + }, + "dependencies": { + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + } + } + }, + "libnpmorg": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/libnpmorg/-/libnpmorg-1.0.0.tgz", + "integrity": "sha512-o+4eVJBoDGMgRwh2lJY0a8pRV2c/tQM/SxlqXezjcAg26Qe9jigYVs+Xk0vvlYDWCDhP0g74J8UwWeAgsB7gGw==", + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^3.8.0" + }, + "dependencies": { + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + } + } + }, + "libnpmpublish": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/libnpmpublish/-/libnpmpublish-1.1.1.tgz", + "integrity": "sha512-nefbvJd/wY38zdt+b9SHL6171vqBrMtZ56Gsgfd0duEKb/pB8rDT4/ObUQLrHz1tOfht1flt2zM+UGaemzAG5g==", + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "lodash.clonedeep": "^4.5.0", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-registry-fetch": "^3.8.0", + "semver": "^5.5.1", + "ssri": "^6.0.1" + }, + "dependencies": { + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + } + } + }, + "libnpmsearch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/libnpmsearch/-/libnpmsearch-2.0.0.tgz", + "integrity": "sha512-vd+JWbTGzOSfiOc+72MU6y7WqmBXn49egCCrIXp27iE/88bX8EpG64ST1blWQI1bSMUr9l1AKPMVsqa2tS5KWA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^3.8.0" + } + }, + "libnpmteam": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/libnpmteam/-/libnpmteam-1.0.1.tgz", + "integrity": "sha512-gDdrflKFCX7TNwOMX1snWojCoDE5LoRWcfOC0C/fqF7mBq8Uz9zWAX4B2RllYETNO7pBupBaSyBDkTAC15cAMg==", + "dev": true, + "requires": { + "aproba": "^2.0.0", + "figgy-pudding": "^3.4.1", + "get-stream": "^4.0.0", + "npm-registry-fetch": "^3.8.0" + }, + "dependencies": { + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + } + } + }, + "lint-staged": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-8.1.3.tgz", + "integrity": "sha512-6TGkikL1B+6mIOuSNq2TV6oP21IhPMnV8q0cf9oYZ296ArTVNcbFh1l1pfVOHHbBIYLlziWNsQ2q45/ffmJ4AA==", + "dev": true, + "requires": { + "@iamstarkov/listr-update-renderer": "0.4.1", + "chalk": "^2.3.1", + "commander": "^2.14.1", + "cosmiconfig": "^5.0.2", + "debug": "^3.1.0", + "dedent": "^0.7.0", + "del": "^3.0.0", + "execa": "^1.0.0", + "find-parent-dir": "^0.3.0", + "g-status": "^2.0.2", + "is-glob": "^4.0.0", + "is-windows": "^1.0.2", + "listr": "^0.14.2", + "lodash": "^4.17.5", + "log-symbols": "^2.2.0", + "micromatch": "^3.1.8", + "npm-which": "^3.0.1", + "p-map": "^1.1.1", + "path-is-inside": "^1.0.2", + "pify": "^3.0.0", + "please-upgrade-node": "^3.0.2", + "staged-git-files": "1.1.2", + "string-argv": "^0.0.2", + "stringify-object": "^3.2.2", + "yup": "^0.26.10" + }, + "dependencies": { + "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" + } + } + } + }, + "listr": { + "version": "0.14.3", + "resolved": "https://registry.npmjs.org/listr/-/listr-0.14.3.tgz", + "integrity": "sha512-RmAl7su35BFd/xoMamRjpIE4j3v+L28o8CT5YhAXQJm1fD+1l9ngXY8JAQRJ+tFK2i5njvi0iRUKV09vPwA0iA==", + "dev": true, + "requires": { + "@samverschueren/stream-to-observable": "^0.3.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.5.0", + "listr-verbose-renderer": "^0.5.0", + "p-map": "^2.0.0", + "rxjs": "^6.3.3" + }, + "dependencies": { + "p-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.0.0.tgz", + "integrity": "sha512-GO107XdrSUmtHxVoi60qc9tUl/KkNKm+X2CF4P9amalpGxv5YqVPJNfSb0wcA+syCopkZvYYIzW8OVTQW59x/w==", + "dev": true + } + } + }, + "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.5.0", + "resolved": "https://registry.npmjs.org/listr-update-renderer/-/listr-update-renderer-0.5.0.tgz", + "integrity": "sha512-tKRsZpKz8GSGqoI/+caPmfrypiaq+OQCbd+CovEC24uk1h952lVj5sC7SqyFUm+OaJ5HN/a1YLt5cit2FMNsFA==", + "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": "^2.3.0", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "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" + } + }, + "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" + } + }, + "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 + } + } + }, + "listr-verbose-renderer": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/listr-verbose-renderer/-/listr-verbose-renderer-0.5.0.tgz", + "integrity": "sha512-04PDPqSlsqIOaaaGZ+41vq5FejI9auqTInicFRndCBgE3bXG8D6W1I+mWhk+1nqbHmyhla/6BUrd5OSiHwKRXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "cli-cursor": "^2.1.0", + "date-fns": "^1.27.2", + "figures": "^2.0.0" + } + }, + "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" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "lock-verify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lock-verify/-/lock-verify-2.0.2.tgz", + "integrity": "sha512-QNVwK0EGZBS4R3YQ7F1Ox8p41Po9VGl2QG/2GsuvTbkJZYSsPeWHKMbbH6iZMCHWSMww5nrJroZYnGzI4cePuw==", + "dev": true, + "requires": { + "npm-package-arg": "^5.1.2 || 6", + "semver": "^5.4.1" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "lodash._reinterpolate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true + }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "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 + }, + "lodash.template": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-4.4.0.tgz", + "integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0", + "lodash.templatesettings": "^4.0.0" + } + }, + "lodash.templatesettings": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-4.1.0.tgz", + "integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=", + "dev": true, + "requires": { + "lodash._reinterpolate": "~3.0.0" + } + }, + "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" + } + }, + "log-update": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-2.3.0.tgz", + "integrity": "sha1-iDKP19HOeTiykoN0bwsbwSayRwg=", + "dev": true, + "requires": { + "ansi-escapes": "^3.0.0", + "cli-cursor": "^2.0.0", + "wrap-ansi": "^3.0.1" + }, + "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 + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-3.0.1.tgz", + "integrity": "sha1-KIoE2H7aXChuBg3+jxNc6NAH+Lo=", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0" + } + } + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "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" + } + }, + "make-fetch-happen": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-4.0.1.tgz", + "integrity": "sha512-7R5ivfy9ilRJ1EMKIOziwrns9fGeAD4bAha8EB7BIiBBLHm2KeTUGCrICFt2rbHfzheTLynv50GnNTK1zDTrcQ==", + "dev": true, + "requires": { + "agentkeepalive": "^3.4.1", + "cacache": "^11.0.1", + "http-cache-semantics": "^3.8.1", + "http-proxy-agent": "^2.1.0", + "https-proxy-agent": "^2.2.1", + "lru-cache": "^4.1.2", + "mississippi": "^3.0.0", + "node-fetch-npm": "^2.0.2", + "promise-retry": "^1.1.1", + "socks-proxy-agent": "^4.0.0", + "ssri": "^6.0.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "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" + } + }, + "matcher": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-1.1.1.tgz", + "integrity": "sha512-+BmqxWIubKTRKNWx/ahnCkk3mG8m7OturVlqq6HiojGJTd5hVYbgZm6WzcYPCoB+KBT4Vd6R7WSRG2OADNaCjg==", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.4" + } + }, + "mem": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.1.0.tgz", + "integrity": "sha512-I5u6Q1x7wxO0kdOpYBB28xueHADYps5uty/zg936CiG8NTe5sJL8EjrCuLneuDW3PlMdZBGDIn8BirEVdovZvg==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^1.0.0", + "p-is-promise": "^2.0.0" + } + }, + "meow": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-4.0.1.tgz", + "integrity": "sha512-xcSBHD5Z86zaOc+781KrupuHAzeGXSLtiAOmBsiLDiPSaYSB6hdew2ng9EBAnZ62jagG9MHAOdxpDi/lWBFJ/A==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist": "^1.1.3", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "merge2": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz", + "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==", + "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" + } + }, + "mime-db": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.37.0.tgz", + "integrity": "sha512-R3C4db6bgQhlIhPU48fUtdVmKnflq+hRdad7IyKhtFj06VPNVdk2RhiYL3UjQIlso8L+YxAtFkobT0VK+S/ybg==", + "dev": true + }, + "mime-types": { + "version": "2.1.21", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.21.tgz", + "integrity": "sha512-3iL6DbwpyLzjR3xHSFNFeb9Nz/M8WDkX33t1GFQnFOllWk8pOrh/LSrB5OXlnlW5P9LH73X6loW/eogc+F5lJg==", + "dev": true, + "requires": { + "mime-db": "~1.37.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 + }, + "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 + }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + } + }, + "minipass": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-2.3.5.tgz", + "integrity": "sha512-Gi1W4k059gyRbyVUZQ4mEqLm0YIUiGYfvxhF6SIlk3ui1WVxMTGfGdQ2SInh3PDrRTVvPKgULkpJtT4RH10+VA==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + }, + "dependencies": { + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "dev": true + } + } + }, + "minizlib": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-1.2.1.tgz", + "integrity": "sha512-7+4oTUOWKg7AuL3vloEWekXY2/D20cevzsrNT2kGWm+39J9hGTCBv8VI5Pm5lXZ/o3/mdR4f8rflAPhnQb8mPA==", + "dev": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "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": "^3.0.0", + "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" + } + }, + "modify-values": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", + "integrity": "sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==", + "dev": true + }, + "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.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "multimatch": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-2.1.0.tgz", + "integrity": "sha1-nHkGoi+0wCkZ4vX3UWG0zb1LKis=", + "dev": true, + "requires": { + "array-differ": "^1.0.0", + "array-union": "^1.0.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 + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-fetch-npm": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz", + "integrity": "sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==", + "dev": true, + "requires": { + "encoding": "^0.1.11", + "json-parse-better-errors": "^1.0.0", + "safe-buffer": "^5.1.1" + } + }, + "node-gyp": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.8.0.tgz", + "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", + "dev": true, + "requires": { + "fstream": "^1.0.0", + "glob": "^7.0.3", + "graceful-fs": "^4.1.2", + "mkdirp": "^0.5.0", + "nopt": "2 || 3", + "npmlog": "0 || 1 || 2 || 3 || 4", + "osenv": "0", + "request": "^2.87.0", + "rimraf": "2", + "semver": "~5.3.0", + "tar": "^2.0.0", + "which": "1" + }, + "dependencies": { + "semver": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true + } + } + }, + "nopt": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", + "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", + "dev": true, + "requires": { + "abbrev": "1" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "npm-bundled": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/npm-bundled/-/npm-bundled-1.0.6.tgz", + "integrity": "sha512-8/JCaftHwbd//k6y2rEWp6k1wxVfpFzB6t1p825+cUb7Ym2XQfhwIC5KwhrvzZRJu+LtDE585zVaS32+CGtf0g==", + "dev": true + }, + "npm-lifecycle": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/npm-lifecycle/-/npm-lifecycle-2.1.0.tgz", + "integrity": "sha512-QbBfLlGBKsktwBZLj6AviHC6Q9Y3R/AY4a2PYSIRhSKSS0/CxRyD/PfxEX6tPeOCXQgMSNdwGeECacstgptc+g==", + "dev": true, + "requires": { + "byline": "^5.0.0", + "graceful-fs": "^4.1.11", + "node-gyp": "^3.8.0", + "resolve-from": "^4.0.0", + "slide": "^1.1.6", + "uid-number": "0.0.6", + "umask": "^1.1.0", + "which": "^1.3.1" + }, + "dependencies": { + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + } + } + }, + "npm-logical-tree": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/npm-logical-tree/-/npm-logical-tree-1.2.1.tgz", + "integrity": "sha512-AJI/qxDB2PWI4LG1CYN579AY1vCiNyWfkiquCsJWqntRu/WwimVrC8yXeILBFHDwxfOejxewlmnvW9XXjMlYIg==", + "dev": true + }, + "npm-package-arg": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-6.1.0.tgz", + "integrity": "sha512-zYbhP2k9DbJhA0Z3HKUePUgdB1x7MfIfKssC+WLPFMKTBZKpZh5m13PgexJjCq6KW7j17r0jHWcCpxEqnnncSA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.6.0", + "osenv": "^0.1.5", + "semver": "^5.5.0", + "validate-npm-package-name": "^3.0.0" + } + }, + "npm-packlist": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/npm-packlist/-/npm-packlist-1.3.0.tgz", + "integrity": "sha512-qPBc6CnxEzpOcc4bjoIBJbYdy0D/LFFPUdxvfwor4/w3vxeE0h6TiOVurCEPpQ6trjN77u/ShyfeJGsbAfB3dA==", + "dev": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npm-path": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/npm-path/-/npm-path-2.0.4.tgz", + "integrity": "sha512-IFsj0R9C7ZdR5cP+ET342q77uSRdtWOlWpih5eC+lu29tIDbNEgDbzgVJ5UFvYHWhxDZ5TFkJafFioO0pPQjCw==", + "dev": true, + "requires": { + "which": "^1.2.10" + } + }, + "npm-pick-manifest": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/npm-pick-manifest/-/npm-pick-manifest-2.2.3.tgz", + "integrity": "sha512-+IluBC5K201+gRU85vFlUwX3PFShZAbAgDNp2ewJdWMVSppdo/Zih0ul2Ecky/X7b51J7LrrUAP+XOmOCvYZqA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "npm-package-arg": "^6.0.0", + "semver": "^5.4.1" + } + }, + "npm-profile": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-profile/-/npm-profile-4.0.1.tgz", + "integrity": "sha512-NQ1I/1Q7YRtHZXkcuU1/IyHeLy6pd+ScKg4+DQHdfsm769TGq6HPrkbuNJVJS4zwE+0mvvmeULzQdWn2L2EsVA==", + "dev": true, + "requires": { + "aproba": "^1.1.2 || 2", + "figgy-pudding": "^3.4.1", + "npm-registry-fetch": "^3.8.0" + } + }, + "npm-registry-fetch": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/npm-registry-fetch/-/npm-registry-fetch-3.9.0.tgz", + "integrity": "sha512-srwmt8YhNajAoSAaDWndmZgx89lJwIZ1GWxOuckH4Coek4uHv5S+o/l9FLQe/awA+JwTnj4FJHldxhlXdZEBmw==", + "dev": true, + "requires": { + "JSONStream": "^1.3.4", + "bluebird": "^3.5.1", + "figgy-pudding": "^3.4.1", + "lru-cache": "^4.1.3", + "make-fetch-happen": "^4.0.1", + "npm-package-arg": "^6.1.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" + } + }, + "npm-which": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-which/-/npm-which-3.0.1.tgz", + "integrity": "sha1-kiXybsOihcIJyuZ8OxGmtKtxQKo=", + "dev": true, + "requires": { + "commander": "^2.9.0", + "npm-path": "^2.0.2", + "which": "^1.2.10" + } + }, + "npmlog": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz", + "integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==", + "dev": 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", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "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" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-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.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" + } + }, + "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": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "osenv": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz", + "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==", + "dev": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "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": "2.0.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.0.0.tgz", + "integrity": "sha512-pzQPhYMCAgLAKPWD2jC3Se9fEfrD9npNos0y150EeqZll7akhEgGhTW/slB6lHku8AvYGiJ+YJ5hfHKePPgFWg==", + "dev": true + }, + "p-limit": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.1.0.tgz", + "integrity": "sha512-NhURkNcrVB+8hNfLuysU8enY5xn2KXphsHBaC2YmRNTZRc7RWusw6apSpdEj3jo4CMb6W9nrF6tTnsJsJeyu6g==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.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-map-series": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-map-series/-/p-map-series-1.0.0.tgz", + "integrity": "sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco=", + "dev": true, + "requires": { + "p-reduce": "^1.0.0" + } + }, + "p-pipe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-1.2.0.tgz", + "integrity": "sha1-SxoROZoRUgpneQ7loMHViB1r7+k=", + "dev": true + }, + "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-try": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.0.0.tgz", + "integrity": "sha512-hMp0onDKIajHfIkdRk3P4CdCmErkYAxxDtP3Wx/4nZ3aGlau2VKh3mZpcuFkH27WQkL/3WBCPOktzA9ZOAnMQQ==", + "dev": true + }, + "p-waterfall": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-waterfall/-/p-waterfall-1.0.0.tgz", + "integrity": "sha1-ftlLPOszMngjU69qrhGqn8I1uwA=", + "dev": true, + "requires": { + "p-reduce": "^1.0.0" + } + }, + "pacote": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/pacote/-/pacote-9.4.1.tgz", + "integrity": "sha512-YKSRsQqmeHxgra0KCdWA2FtVxDPUlBiCdmew+mSe44pzlx5t1ViRMWiQg18T+DREA+vSqYfKzynaToFR4hcKHw==", + "dev": true, + "requires": { + "bluebird": "^3.5.3", + "cacache": "^11.3.2", + "figgy-pudding": "^3.5.1", + "get-stream": "^4.1.0", + "glob": "^7.1.3", + "lru-cache": "^5.1.1", + "make-fetch-happen": "^4.0.1", + "minimatch": "^3.0.4", + "minipass": "^2.3.5", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "normalize-package-data": "^2.4.0", + "npm-package-arg": "^6.1.0", + "npm-packlist": "^1.1.12", + "npm-pick-manifest": "^2.2.3", + "npm-registry-fetch": "^3.8.0", + "osenv": "^0.1.5", + "promise-inflight": "^1.0.1", + "promise-retry": "^1.1.1", + "protoduck": "^5.0.1", + "rimraf": "^2.6.2", + "safe-buffer": "^5.1.2", + "semver": "^5.6.0", + "ssri": "^6.0.1", + "tar": "^4.4.8", + "unique-filename": "^1.1.1", + "which": "^1.3.1" + }, + "dependencies": { + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + } + }, + "tar": { + "version": "4.4.8", + "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.8.tgz", + "integrity": "sha512-LzHF64s5chPQQS0IYBn9IN5h3i98c12bo4NCO7e0sGM2llXQ3p2FGC5sdENN4cTW48O915Sh+x+EXx7XW96xYQ==", + "dev": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "yallist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", + "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", + "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-github-repo-url": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/parse-github-repo-url/-/parse-github-repo-url-1.4.1.tgz", + "integrity": "sha1-nn2LslKmy2ukJZUGC3v23z28H1A=", + "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" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "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-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + } + }, + "please-upgrade-node": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.1.1.tgz", + "integrity": "sha512-KY1uHnQ2NlQHqIJQpnh/i54rKkuxCEBx+voJIS/Mvb+L2iYd2NMotwduhKTMjfC1uKoX3VXOxLjIYG66dfJTVQ==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, + "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 + }, + "prettier": { + "version": "1.16.4", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.16.4.tgz", + "integrity": "sha512-ZzWuos7TI5CKUeQAtFd6Zhm2s6EpAD/ZLApIhsF9pRvRtM1RFo61dM/4MSRUA0SuLugA/zgrZD8m0BaY46Og7g==", + "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 + }, + "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-retry": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-1.1.1.tgz", + "integrity": "sha1-ZznpaOMFHaIM5kl/srUPaRHfPW0=", + "dev": true, + "requires": { + "err-code": "^1.0.0", + "retry": "^0.10.0" + } + }, + "promzard": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promzard/-/promzard-0.3.0.tgz", + "integrity": "sha1-JqXW7ox97kyxIggwWs+5O6OCqe4=", + "dev": true, + "requires": { + "read": "1" + } + }, + "property-expr": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-1.5.1.tgz", + "integrity": "sha512-CGuc0VUTGthpJXL36ydB6jnbyOf/rAHFvmVrJlH+Rg0DqqLFQGAP6hIaxD/G0OAmBJPhXDHuEJigrp0e0wFV6g==", + "dev": true + }, + "proto-list": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", + "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", + "dev": true + }, + "protoduck": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/protoduck/-/protoduck-5.0.1.tgz", + "integrity": "sha512-WxoCeDCoCBY55BMvj4cAEjdVUFGRWed9ZxPlqTKYyw1nDDTQ4pqmnIMAGfJlg7Dx35uB/M+PHJPTmGOvaCaPTg==", + "dev": true, + "requires": { + "genfun": "^5.0.0" + } + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "psl": { + "version": "1.1.31", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.31.tgz", + "integrity": "sha512-/6pt4+C+T+wZUieKR620OpzN/LlnNKuWjy1iFLQ/UG35JqHlR/89MP1d96dUfkf6Dne3TuLQzOYEYshJ+Hx8mw==", + "dev": true + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "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" + }, + "dependencies": { + "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" + } + } + } + }, + "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 + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "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 + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=", + "dev": true + }, + "read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha1-s9oZvQUkMal2cdRKQmNK33ELQMQ=", + "dev": true, + "requires": { + "mute-stream": "~0.0.4" + } + }, + "read-cmd-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/read-cmd-shim/-/read-cmd-shim-1.0.1.tgz", + "integrity": "sha1-LV0Vd4ajfAVdIgd8MsU/gynpHHs=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2" + } + }, + "read-package-json": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/read-package-json/-/read-package-json-2.0.13.tgz", + "integrity": "sha512-/1dZ7TRZvGrYqE0UAfN6qQb5GYBsNcqS1C0tNK601CFOJmtHI7NIGXwetEPU/OtoFHZL3hDxm4rolFFVE9Bnmg==", + "dev": true, + "requires": { + "glob": "^7.1.1", + "graceful-fs": "^4.1.2", + "json-parse-better-errors": "^1.0.1", + "normalize-package-data": "^2.0.0", + "slash": "^1.0.0" + }, + "dependencies": { + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + } + } + }, + "read-package-tree": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/read-package-tree/-/read-package-tree-5.2.1.tgz", + "integrity": "sha512-2CNoRoh95LxY47LvqrehIAfUVda2JbuFE/HaGYs42bNrGG+ojbw1h3zOcPcQ+1GQ3+rkzNndZn85u1XyZ3UsIA==", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "once": "^1.3.0", + "read-package-json": "^2.0.0", + "readdir-scoped-modules": "^1.0.0" + } + }, + "read-pkg": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-4.0.1.tgz", + "integrity": "sha1-ljYlN48+HE1IyFhytabsfV0JMjc=", + "dev": true, + "requires": { + "normalize-package-data": "^2.3.2", + "parse-json": "^4.0.0", + "pify": "^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" + }, + "dependencies": { + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "read-pkg": { + "version": "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" + } + } + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "http://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" + } + }, + "readdir-scoped-modules": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/readdir-scoped-modules/-/readdir-scoped-modules-1.0.2.tgz", + "integrity": "sha1-n6+jfShr5dksuuve4DDcm19AZ0c=", + "dev": true, + "requires": { + "debuglog": "^1.0.1", + "dezalgo": "^1.0.0", + "graceful-fs": "^4.1.2", + "once": "^1.3.0" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, + "regenerator-runtime": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz", + "integrity": "sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg==", + "dev": true + }, + "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" + } + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "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" + } + }, + "request": { + "version": "2.88.0", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", + "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "dev": true, + "requires": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.0", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "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.10.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.0.tgz", + "integrity": "sha512-3sUr9aq5OfSg2S9pNtPA9hL1FVEAjvfOC4leW0SNf/mpnaakz2a9femSd6LqAww2RaFctwyf1lCqnTHuF1rxDg==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "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-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 + }, + "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 + }, + "retry": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.10.1.tgz", + "integrity": "sha1-52OI0heZLCUnUCQdPTlW/tmNj/Q=", + "dev": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "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-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/run-node/-/run-node-1.0.0.tgz", + "integrity": "sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==", + "dev": true + }, + "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": "6.4.0", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.4.0.tgz", + "integrity": "sha512-Z9Yfa11F6B9Sg/BK9MnqnQ+aQYicPLtilXBp2yUtDt2JRCE0h26d33EnfO3ZxoNxG0T92OUucP3Ct7cpfkdFfw==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "semver": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.6.0.tgz", + "integrity": "sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==", + "dev": true + }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "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-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" + } + } + } + }, + "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 + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "simple-git": { + "version": "1.107.0", + "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.107.0.tgz", + "integrity": "sha512-t4OK1JRlp4ayKRfcW6owrWcRVLyHRUlhGd0uN6ZZTqfDq8a5XpcUdOKiGRNobHEuMtNqzp0vcJNvhYWwh5PsQA==", + "dev": true, + "requires": { + "debug": "^4.0.1" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "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 + }, + "smart-buffer": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.0.2.tgz", + "integrity": "sha512-JDhEpTKzXusOqXZ0BUIdH+CjFdO/CR3tLlf5CN34IypI+xMmXW1uB16OOY8z3cICbJlDAVJzNbwBhNO0wt9OAw==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.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" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "socks": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.2.3.tgz", + "integrity": "sha512-+2r83WaRT3PXYoO/1z+RDEBE7Z2f9YcdQnJ0K/ncXXbV5gJ6wYfNAebYFYiiUjM6E4JyXnPY8cimwyvFYHVUUA==", + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "4.0.2" + } + }, + "socks-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-4.0.1.tgz", + "integrity": "sha512-Kezx6/VBguXOsEe5oU3lXYyKMi4+gva72TwJ7pQY5JfqUx2nMk7NXA6z/mpNqIlfQjWYVfeuNvQjexiTaTn6Nw==", + "dev": true, + "requires": { + "agent-base": "~4.2.0", + "socks": "~2.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-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "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.3", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.3.tgz", + "integrity": "sha512-uBIcIl3Ih6Phe3XHK1NqboJLdGfwr1UN3k6wSD1dZpmPsIkb8AGNbZYJ1fOBk834+Gxy8rpfDxrS6XLEMZMY2g==", + "dev": true + }, + "split": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz", + "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==", + "dev": true, + "requires": { + "through": "2" + } + }, + "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" + } + }, + "split2": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz", + "integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==", + "dev": true, + "requires": { + "through2": "^2.0.2" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "sshpk": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz", + "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==", + "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", + "safer-buffer": "^2.0.2", + "tweetnacl": "~0.14.0" + }, + "dependencies": { + "tweetnacl": { + "version": "0.14.5", + "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", + "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", + "dev": true + } + } + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "staged-git-files": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/staged-git-files/-/staged-git-files-1.1.2.tgz", + "integrity": "sha512-0Eyrk6uXW6tg9PYkhi/V/J4zHp33aNyi2hOCmhFLqLTIhbgqWn5jlSzI+IU0VqrZq6+DbHcabQl/WP6P3BG0QA==", + "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" + } + } + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.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 + }, + "string-argv": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.0.2.tgz", + "integrity": "sha1-2sMECGkMIfPDYwo/86BYd73L1zY=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "stringify-object": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.3.0.tgz", + "integrity": "sha512-rHqiFh1elqCQ9WPLIC8I0Q/g/wj5J1eMkyoiD6eoQApWHP0FtlK7rqnhmabL5VUY9JQCcqwwvlOaSuutekgyrw==", + "dev": true, + "requires": { + "get-own-enumerable-property-symbols": "^3.0.0", + "is-obj": "^1.0.1", + "is-regexp": "^1.0.0" + } + }, + "stringify-package": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stringify-package/-/stringify-package-1.0.0.tgz", + "integrity": "sha512-JIQqiWmLiEozOC0b0BtxZ/AOUtdUZHCBPgqIZ2kSJJqGwgb9neo44XdTHUC4HZSGqi03hOeB7W/E8rAlKnGe9g==", + "dev": true + }, + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "strong-log-transformer": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", + "integrity": "sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "minimist": "^1.2.0", + "through": "^2.3.4" + }, + "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": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "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 + }, + "synchronous-promise": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/synchronous-promise/-/synchronous-promise-2.0.6.tgz", + "integrity": "sha512-TyOuWLwkmtPL49LHCX1caIwHjRzcVd62+GF6h8W/jHOeZUFHpnd2XJDVuUlaTaLPH1nuu2M69mfHr5XbQJnf/g==", + "dev": true + }, + "tar": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, + "requires": { + "block-stream": "*", + "fstream": "^1.0.2", + "inherits": "2" + } + }, + "temp-dir": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz", + "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=", + "dev": true + }, + "temp-write": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-write/-/temp-write-3.4.0.tgz", + "integrity": "sha1-jP9jD7fp2gXwR8dM5M5NaFRX1JI=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "is-stream": "^1.1.0", + "make-dir": "^1.0.0", + "pify": "^3.0.0", + "temp-dir": "^1.0.0", + "uuid": "^3.0.1" + } + }, + "text-extensions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-1.9.0.tgz", + "integrity": "sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==", + "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.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha1-riF2gXXRVZ1IvvNUILL0li8JwzA=", + "dev": true + }, + "tough-cookie": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", + "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, + "requires": { + "psl": "^1.1.24", + "punycode": "^1.4.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "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-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "dev": true + }, + "trim-off-newlines": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-off-newlines/-/trim-off-newlines-1.0.1.tgz", + "integrity": "sha1-n5up2e+odkw4dpi8v+sshI8RrbM=", + "dev": true + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "tslint": { + "version": "5.12.1", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-5.12.1.tgz", + "integrity": "sha512-sfodBHOucFg6egff8d1BvuofoOQ/nOeYNfbp7LDlKBcLNrL3lmS5zoiDGyOMdT7YsEXAwWpTdAHwOGOc8eRZAw==", + "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.27.2" + } + }, + "tslint-config-prettier": { + "version": "1.18.0", + "resolved": "https://registry.npmjs.org/tslint-config-prettier/-/tslint-config-prettier-1.18.0.tgz", + "integrity": "sha512-xPw9PgNPLG3iKRxmK7DWr+Ea/SzrvfHtjFt5LBl61gk2UBG/DB9kCXRjv+xyIU1rUtnayLeMUVJBcMX8Z17nDg==", + "dev": true + }, + "tslint-immutable": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/tslint-immutable/-/tslint-immutable-5.1.2.tgz", + "integrity": "sha512-MVxtN0E90q3EJvBrA/B9ojsA2KNYiRqZA/8vQeSjAHgzbwGgx9kpNHssDel+Bi6DmqSGC8J+0Jy1fCNPJxEdZw==", + "dev": true, + "requires": { + "tsutils": "^2.28.0 || ^3.0.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "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" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typescript": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.3.1.tgz", + "integrity": "sha512-cTmIDFW7O0IHbn1DPYjkiebHxwtCMU+eTy30ZtJNBPF9j2O1ITu5XH2YnBeVRKWHqF+3JQwWJv0Q0aUgX8W7IA==", + "dev": true + }, + "uglify-js": { + "version": "3.4.9", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.9.tgz", + "integrity": "sha512-8CJsbKOtEbnJsTyv6LE6m6ZKniqMiFWmm9sRbopbkGs3gMPPfd3Fh8iIA4Ykv5MgaTbqHr4BaoGLJLZNhsrW1Q==", + "dev": true, + "optional": true, + "requires": { + "commander": "~2.17.1", + "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, + "optional": true + } + } + }, + "uid-number": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/uid-number/-/uid-number-0.0.6.tgz", + "integrity": "sha1-DqEOgDXo61uOREnwbaHHMGY7qoE=", + "dev": true + }, + "umask": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/umask/-/umask-1.1.0.tgz", + "integrity": "sha1-8pzr8B31F5ErtY/5xOUP3o4zMg0=", + "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.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.1.tgz", + "integrity": "sha512-n9cU6+gITaVu7VGj1Z8feKMmfAjEAQGhwD9fE3zvpRRa0wEIx8ODYkVGfSc94M2OX00tUFV8wH3zYbm1I8mxFg==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "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 + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "uuid": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", + "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", + "dev": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "validate-npm-package-name": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-3.0.0.tgz", + "integrity": "sha1-X6kS2B630MdK/BQN5zF/DKffQ34=", + "dev": true, + "requires": { + "builtins": "^1.0.3" + } + }, + "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" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "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 + }, + "whatwg-url": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz", + "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==", + "dev": true, + "requires": { + "lodash.sortby": "^4.7.0", + "tr46": "^1.0.1", + "webidl-conversions": "^4.0.2" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=", + "dev": true + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + } + }, + "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.4.2", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-2.4.2.tgz", + "integrity": "sha512-s0b6vB3xIVRLWywa6X9TOMA7k9zio0TMOsl9ZnDkliA/cfJlpHXAscj0gbHVJiTdIuAYpIyqS5GW91fqm6gG5g==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.2" + } + }, + "write-json-file": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/write-json-file/-/write-json-file-2.3.0.tgz", + "integrity": "sha1-K2TIozAE1UuGmMdtWFp3zrYdoy8=", + "dev": true, + "requires": { + "detect-indent": "^5.0.0", + "graceful-fs": "^4.1.2", + "make-dir": "^1.0.0", + "pify": "^3.0.0", + "sort-keys": "^2.0.0", + "write-file-atomic": "^2.0.0" + } + }, + "write-pkg": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/write-pkg/-/write-pkg-3.2.0.tgz", + "integrity": "sha512-tX2ifZ0YqEFOF1wjRW2Pk93NLsj02+n1UP5RvO6rCs0K6R2g1padvf006cY74PQJKMGS2r42NK7FD0dG6Y6paw==", + "dev": true, + "requires": { + "sort-keys": "^2.0.0", + "write-json-file": "^2.2.0" + } + }, + "xtend": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz", + "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=", + "dev": true + }, + "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 + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + }, + "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 + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + } + } + }, + "yup": { + "version": "0.26.10", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.26.10.tgz", + "integrity": "sha512-keuNEbNSnsOTOuGCt3UJW69jDE3O4P+UHAakO7vSeFMnjaitcmlbij/a3oNb9g1Y1KvSKH/7O1R2PQ4m4TRylw==", + "dev": true, + "requires": { + "@babel/runtime": "7.0.0", + "fn-name": "~2.0.1", + "lodash": "^4.17.10", + "property-expr": "^1.5.0", + "synchronous-promise": "^2.0.5", + "toposort": "^2.0.2" + } + } + } +} diff --git a/package.json b/package.json new file mode 100644 index 00000000000..31729214657 --- /dev/null +++ b/package.json @@ -0,0 +1,57 @@ +{ + "name": "lisk-elements-monorepo", + "private": true, + "version": "1.0.0", + "description": "Reusable packages for use with the Lisk ecosystem", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=3 <=6" + }, + "scripts": { + "bootstrap": "lerna bootstrap --hoist", + "clean": "lerna run clean", + "clean:node_modules": "lerna clean --yes", + "format": "npm run format:root && lerna run format", + "format:root": "prettier types/**/*.ts --write", + "lint": "npm run lint:root && lerna run lint", + "lint:fix": "npm run lint:root -- --fix && lerna run lint:fix", + "lint:root": "tslint -p tsconfig.json types/**/*.ts", + "test": "lerna run test", + "test:node": "lerna run test:node", + "test:browser": "lerna run test:browser", + "build": "lerna run build", + "build:browsertest": "lerna run build:browsertest", + "cover": "lerna run cover", + "init": "./scripts/init.sh", + "postinstall": "npm run bootstrap", + "precommit": "lint-staged && npm run lint", + "prepush": "npm run lint && npm test" + }, + "devDependencies": { + "@types/node": "10.12.21", + "@types/sinon": "7.0.5", + "husky": "1.3.1", + "lerna": "3.10.8", + "lint-staged": "8.1.3", + "prettier": "1.16.4", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1" + }, + "dependencies": {} +} diff --git a/scripts/init.sh b/scripts/init.sh new file mode 100755 index 00000000000..6b2836ae42c --- /dev/null +++ b/scripts/init.sh @@ -0,0 +1,62 @@ +#!/bin/bash + +# Unofficial strict mode +set -euo pipefail +IFS=$'\n\t' + +packageName=${1:-} + +ROOT_PACKAGE_NAME=$(jq --raw-output '.name' package.json) +if [ "$ROOT_PACKAGE_NAME" != "lisk-elements-monorepo" ]; then + echo "Please use the command in the project root directory." + exit 1 +fi + +if [ -z "$packageName" ] || [[ "$packageName" =~ [^a-zA-Z0-9-] ]]; then + echo "Usage: npm run init -- PACKAGE_NAME" + exit 1 +fi + +packageDir="./packages/$packageName" +# Just in case package folder doesn't exist yet. +mkdir -p "$packageDir" +mkdir -p "$packageDir/src" +mkdir -p "$packageDir/test" + +cp "./templates/package.json.tmpl" "$packageDir/package.json" + +templatesRoot=( + "browsertest" + "cypress" + "scripts" + "test" + ".npmignore" + ".npmrc" + ".nycrc" + ".prettierignore" + ".prettierrc.json" + "cypress.json" + "tslint.json" + "tsconfig.json" + "tsconfig.browsertest.json" +) + +for i in "${templatesRoot[@]}" +do + if [ ! -e "$packageDir/${i}" ]; then + ln -vs "../../templates/$i.tmpl" "$packageDir/$i" + fi +done + +templatesTest=( + "tslint.json" + "tsconfig.json" + "mocha.opts" +) + +for i in "${templatesTest[@]}" +do + if [ ! -e "$packageDir/test/${i}" ]; then + ln -vs "../../../templates/test/$i.tmpl" "$packageDir/test/$i" + fi +done diff --git a/templates/.npmignore.tmpl b/templates/.npmignore.tmpl new file mode 100644 index 00000000000..65a1b960c92 --- /dev/null +++ b/templates/.npmignore.tmpl @@ -0,0 +1,18 @@ +.babelrc +.eslintignore +.eslintrc.json +.gitignore +.lintstagedrc.json +.nycrc +.prettierrc.json +cypress.json +index.html +Jenkinsfile* + +.nyc_output/ +coverage/ +cypress/ +fixtures/ +src/ +test/ +browsertest/ diff --git a/templates/.npmrc.tmpl b/templates/.npmrc.tmpl new file mode 100644 index 00000000000..cac71fa6f26 --- /dev/null +++ b/templates/.npmrc.tmpl @@ -0,0 +1,2 @@ +message = ":arrow_up: Version %s" +save-exact = true diff --git a/templates/.nycrc.tmpl b/templates/.nycrc.tmpl new file mode 100644 index 00000000000..c47f12ce6df --- /dev/null +++ b/templates/.nycrc.tmpl @@ -0,0 +1,4 @@ +{ + "exclude": ["test/**", "**/*.d.ts"], + "extension": [".ts"] +} diff --git a/templates/.prettierignore.tmpl b/templates/.prettierignore.tmpl new file mode 100644 index 00000000000..61d81dbe240 --- /dev/null +++ b/templates/.prettierignore.tmpl @@ -0,0 +1,11 @@ +package.json + +.nyc_output/ +coverage/ +dist-node/ +dist-browser/ +browsertest.build/ +node_modules/ + +# BUG: See https://github.com/prettier/prettier/issues/3223 +docs/CONTRIBUTING.md diff --git a/templates/.prettierrc.json.tmpl b/templates/.prettierrc.json.tmpl new file mode 100644 index 00000000000..df996112c05 --- /dev/null +++ b/templates/.prettierrc.json.tmpl @@ -0,0 +1,5 @@ +{ + "singleQuote": true, + "trailingComma": "all", + "useTabs": true +} diff --git a/templates/browsertest.tmpl/browsertest.html b/templates/browsertest.tmpl/browsertest.html new file mode 100644 index 00000000000..6bb184a18e9 --- /dev/null +++ b/templates/browsertest.tmpl/browsertest.html @@ -0,0 +1,25 @@ + + + + + + Browser tests + + + + + +
+
+
+ + + + + + + + + + + diff --git a/templates/browsertest.tmpl/browsertest.min.html b/templates/browsertest.tmpl/browsertest.min.html new file mode 100644 index 00000000000..399e82813c4 --- /dev/null +++ b/templates/browsertest.tmpl/browsertest.min.html @@ -0,0 +1,25 @@ + + + + + + Browser tests + + + + + +
+
+
+ + + + + + + + + + + diff --git a/templates/browsertest.tmpl/run_tests.js b/templates/browsertest.tmpl/run_tests.js new file mode 100644 index 00000000000..ed0ae5458c7 --- /dev/null +++ b/templates/browsertest.tmpl/run_tests.js @@ -0,0 +1,19 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +mocha.checkLeaks(); +mocha.run(failures => { + document.getElementById('failures').innerText = failures; + document.getElementById('done').innerText = 'DONE'; +}); diff --git a/templates/browsertest.tmpl/setup.js b/templates/browsertest.tmpl/setup.js new file mode 100644 index 00000000000..ebee9f83f79 --- /dev/null +++ b/templates/browsertest.tmpl/setup.js @@ -0,0 +1,21 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +mocha.setup({ + ui: 'bdd', + timeout: 5000, + globals: ['__$$GLOBAL_REWIRE_NEXT_MODULE_ID__'], + fgrep: '@node-only', + invert: true, +}); diff --git a/templates/cypress.json.tmpl b/templates/cypress.json.tmpl new file mode 100644 index 00000000000..26e2979d8d3 --- /dev/null +++ b/templates/cypress.json.tmpl @@ -0,0 +1,5 @@ +{ + "video": false, + "pluginsFile": false, + "supportFile": false +} diff --git a/templates/cypress.tmpl/integration/index.js b/templates/cypress.tmpl/integration/index.js new file mode 100644 index 00000000000..dd98d245dc2 --- /dev/null +++ b/templates/cypress.tmpl/integration/index.js @@ -0,0 +1,45 @@ +/* + * Copyright © 2018 Lisk Foundation + * + * See the LICENSE file at the top-level directory of this distribution + * for licensing information. + * + * Unless otherwise agreed in a custom licensing agreement with the Lisk Foundation, + * no part of this software, including this file, may be copied, modified, + * propagated, or distributed except according to the terms contained in the + * LICENSE file. + * + * Removal or modification of this copyright notice is prohibited. + * + */ +const ROOT_DIR = Cypress.env('ROOT_DIR'); +const FORCE_RELOAD = true; + +const throwFailuresInWindow = win => { + const failures = win.parent.document + .getElementById(`Your App: '${ROOT_DIR}'`) + .contentDocument.getElementsByClassName('fail'); + + if (failures.length) { + const failuresHTML = Array.from(failures).map(el => el.outerHTML); + let errorString; + try { + errorString = failuresHTML.map(decodeURIComponent).join('\n'); + } catch (error) { + errorString = failuresHTML.join('\n'); + } + throw new Error(errorString); + } +}; + +const testPage = page => () => { + cy.visit(page); + cy.reload(FORCE_RELOAD); + cy.get('#done').should('contain', 'DONE'); + cy.window().then(throwFailuresInWindow); +}; + +describe('Browser tests', () => { + it('should pass without minification', testPage('/browsertest.html')); + it('should pass with minification', testPage('/browsertest.min.html')); +}); diff --git a/templates/package.json.tmpl b/templates/package.json.tmpl new file mode 100644 index 00000000000..d6b2c5731d1 --- /dev/null +++ b/templates/package.json.tmpl @@ -0,0 +1,89 @@ +{ + "name": "@liskhq/lisk-template", + "version": "0.1.0", + "description": "Library according to the Lisk protocol", + "author": "Lisk Foundation , lightcurve GmbH ", + "license": "GPL-3.0", + "keywords": [ + "lisk", + "blockchain" + ], + "homepage": "https://github.com/LiskHQ/lisk-elements/tree/master/packages/lisk-transactions#readme", + "repository": { + "type": "git", + "url": "git+https://github.com/LiskHQ/lisk-elements.git" + }, + "bugs": { + "url": "https://github.com/LiskHQ/lisk-elements/issues" + }, + "engines": { + "node": ">=8.10 <=10", + "npm": ">=5" + }, + "main": "dist-node/index.js", + "scripts": { + "transpile": "tsc", + "transpile:browsertest": "tsc -p tsconfig.browsertest.json", + "browserify": "browserify ./dist-node/index.js -o ./dist-browser/index.js -s liskTransactions", + "browserify:browsertest": "browserify ./browsertest.build/test/*.js -o ./browsertest.build/browsertest.js -s liskTransactions", + "uglify": "uglifyjs -nm -o ./dist-browser/index.min.js ./dist-browser/index.js", + "uglify:browsertest": "uglifyjs -o ./browsertest.build/browsertest.min.js ./browsertest.build/browsertest.js", + "clean": "./scripts/clean.sh", + "format": "prettier --write \"*.{ts,js,json}\" \"{src,test}/**/*.{ts,js,json}\"", + "lint": "tslint --format verbose --project .", + "lint:fix": "npm run lint -- --fix", + "test": "TS_NODE_PROJECT=./test/tsconfig.json nyc mocha test/{,/**/,/**/**/}/*.ts", + "test:watch": "npm test -- --watch", + "test:watch:min": "npm run test:watch -- --reporter=min", + "test:node": "npm run build:check", + "serve:start": "http-server -p {PORT_HERE} ./browsertest &", + "serve:stop": "kill $(lsof -t -i:{PORT_HERE}) || true", + "pretest:browser": "npm run serve:stop && npm run build:browsertest && npm run serve:start", + "test:browser": "wait-on http://localhost:{PORT_HERE} && cypress run --config baseUrl=http://localhost:{PORT_HERE} --env ROOT_DIR=\"${PWD##*/}\"", + "posttest:browser": "npm run serve:stop", + "cover": "if [ -z $JENKINS_HOME ]; then npm run cover:local; else npm run cover:ci; fi", + "cover:base": "NODE_ENV=test nyc report", + "cover:local": "npm run cover:base -- --reporter=html --reporter=text", + "cover:ci": "npm run cover:base -- --reporter=text", + "build:browsertest": "npm run transpile:browsertest && npm run browserify:browsertest && npm run uglify:browsertest", + "postbuild:browsertest": "rm -r browsertest.build/src browsertest.build/test", + "prebuild:node": "rm -r dist-node/* || mkdir dist-node || true", + "build:node": "npm run transpile", + "prebuild:browser": "rm ./dist-browser/index.js ./dist-browser/index.min.js || true", + "build:browser": "npm run build:node && npm run browserify && npm run uglify", + "prebuild": "npm run prebuild:browser", + "build": "npm run build:browser", + "build:check": "node -e \"require('./dist-node')\"", + "prepublishOnly": "npm run lint && npm test && npm run build && npm run build:check" + }, + "dependencies": { + "@types/node": "10.12.21", + "verror": "1.10.0" + }, + "devDependencies": { + "@types/chai": "4.1.7", + "@types/expect": "1.20.3", + "@types/jquery": "3.3.29", + "@types/mocha": "5.2.5", + "@types/node": "10.10.1", + "@types/verror": "1.10.3", + "browserify": "16.2.3", + "chai": "4.2.0", + "cypress": "3.1.5", + "http-server": "0.11.1", + "mocha": "5.2.0", + "nyc": "13.2.0", + "prettier": "1.16.4", + "sinon": "7.2.3", + "sinon-chai": "3.3.0", + "source-map-support": "0.5.10", + "ts-node": "8.0.2", + "tsconfig-paths": "3.8.0", + "tslint": "5.12.1", + "tslint-config-prettier": "1.18.0", + "tslint-immutable": "5.1.2", + "typescript": "3.3.1", + "uglify-es": "3.3.9", + "wait-on": "3.2.0" + } +} diff --git a/templates/scripts.tmpl/clean.sh b/templates/scripts.tmpl/clean.sh new file mode 100755 index 00000000000..c55c421a908 --- /dev/null +++ b/templates/scripts.tmpl/clean.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +# Unofficial strict mode +set -euo pipefail +IFS=$'\n\t' + +# Usage +# npm run clean + +rm -rf .nyc_output/ +rm -rf browsertest.build/ +rm -rf coverage/ +rm -rf dist-browser/ +rm -rf dist-node/ +rm -rf lerna-debug.log +rm -rf npm-debug.log diff --git a/templates/scripts.tmpl/prestart.sh b/templates/scripts.tmpl/prestart.sh new file mode 100755 index 00000000000..1d537e17464 --- /dev/null +++ b/templates/scripts.tmpl/prestart.sh @@ -0,0 +1,5 @@ +read -r -p $'\e[96mDo you want to build library first? [y/N]\e[0m ' should_build +if [[ $should_build =~ ^[Yy]$ ]] +then + npm run build:node +fi diff --git a/templates/scripts.tmpl/start.sh b/templates/scripts.tmpl/start.sh new file mode 100755 index 00000000000..2fd6db1def7 --- /dev/null +++ b/templates/scripts.tmpl/start.sh @@ -0,0 +1 @@ +node -i -e "global.library = require('./dist-node'); console.log('\\x1b[34m', 'The global \`library\` was initialised', '\\x1b[0m')" diff --git a/templates/test/mocha.opts.tmpl b/templates/test/mocha.opts.tmpl new file mode 100644 index 00000000000..225b81f721a --- /dev/null +++ b/templates/test/mocha.opts.tmpl @@ -0,0 +1,6 @@ +--recursive +--require ts-node/register +--require tsconfig-paths/register +--require source-map-support/register +--require ./test/_setup.ts +--watch-extensions ts diff --git a/templates/test/tsconfig.json.tmpl b/templates/test/tsconfig.json.tmpl new file mode 100644 index 00000000000..709a83e049c --- /dev/null +++ b/templates/test/tsconfig.json.tmpl @@ -0,0 +1,15 @@ +{ + "extends": "../tsconfig", + "compilerOptions": { + "baseUrl": ".", + "declaration": false, + "target": "es2017", + "typeRoots": [ + "../types", + "../../../types", + "../node_modules/@types", + "../../../node_modules/@types" + ] + }, + "include": ["../types/**/*", "../../../types/**/*", "./**/*"] +} diff --git a/templates/test/tslint.json.tmpl b/templates/test/tslint.json.tmpl new file mode 100644 index 00000000000..cf9eceecc02 --- /dev/null +++ b/templates/test/tslint.json.tmpl @@ -0,0 +1,3 @@ +{ + "extends": ["../../../tslint.test.json"] +} diff --git a/templates/tsconfig.browsertest.json.tmpl b/templates/tsconfig.browsertest.json.tmpl new file mode 100644 index 00000000000..6778c9d4aea --- /dev/null +++ b/templates/tsconfig.browsertest.json.tmpl @@ -0,0 +1,16 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "declaration": false, + "outDir": "browsertest.build", + "baseUrl": ".", + "rootDir": ".", + "typeRoots": [ + "types", + "../../types", + "./node_modules/@types", + "../../node_modules/@types" + ] + }, + "include": ["../../types/**/*", "src/**/*", "test/**/*"] +} diff --git a/templates/tsconfig.json.tmpl b/templates/tsconfig.json.tmpl new file mode 100644 index 00000000000..63275f554ec --- /dev/null +++ b/templates/tsconfig.json.tmpl @@ -0,0 +1,9 @@ +{ + "extends": "../../tsconfig", + "compilerOptions": { + "declaration": true, + "outDir": "dist-node", + "rootDir": "./src" + }, + "include": ["src/**/*", "types/**/*"] +} diff --git a/templates/tslint.json.tmpl b/templates/tslint.json.tmpl new file mode 100644 index 00000000000..f43f8daec44 --- /dev/null +++ b/templates/tslint.json.tmpl @@ -0,0 +1,3 @@ +{ + "extends": "../../tslint.json" +} diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 00000000000..a09fe467e5d --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "forceConsistentCasingInFileNames": true, + "target": "es2017", + "module": "commonjs", + "moduleResolution": "node", + "newLine": "lf", + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "pretty": true, + "removeComments": true, + "resolveJsonModule": true, + "sourceMap": true, + "strict": true + } +} diff --git a/tslint.json b/tslint.json new file mode 100644 index 00000000000..4b41eb70dae --- /dev/null +++ b/tslint.json @@ -0,0 +1,36 @@ +{ + "defaultSeverity": "error", + "extends": [ + "tslint:all", + "tslint-immutable/all", + "tslint-config-prettier" + ], + "rules": { + "completed-docs": false, + "file-name-casing": false, + "interface-name": [true, "never-prefix"], + // Better to have functionally similar items be close together. + "member-ordering": false, + "no-class": false, + "no-delete": true, + "no-expression-statement": false, + "no-if-statement": false, + "no-let": true, + "no-loop-statement": true, + "no-method-signature": false, + "no-mixed-interface": true, + "no-object-mutation": false, + "no-parameter-reassignment": true, + "no-this": false, + "no-unsafe-any": false, + "no-var-keyword": true, + "object-literal-sort-keys": false, + "prefer-method-signature": false, + "readonly-array": false, + "readonly-keyword": [true, "ignore-class"], + "strict-boolean-expressions": false, + "strict-type-predicates": false, + // We need private class properties to start with an underscore. + "variable-name": [true, "allow-leading-underscore"] + } +} diff --git a/tslint.test.json b/tslint.test.json new file mode 100644 index 00000000000..ee491a33df1 --- /dev/null +++ b/tslint.test.json @@ -0,0 +1,6 @@ +{ + "rules": { + "arrow-return-shorthand": "off", + "no-expression-statement": "off" + } +} diff --git a/types/chai/index.d.ts b/types/chai/index.d.ts index 4c7d3e82d77..f7787f58277 100644 --- a/types/chai/index.d.ts +++ b/types/chai/index.d.ts @@ -16,6 +16,8 @@ declare module 'chai' { export interface TypeComparison { customError: (obj?: Error | typeof Error | string) => Assertion; matchAny: Assertion; + hexString: Assertion; + integer: Assertion; } } } diff --git a/types/globals/index.d.ts b/types/globals/index.d.ts index dfa12677ba2..24bbcb27199 100644 --- a/types/globals/index.d.ts +++ b/types/globals/index.d.ts @@ -10,4 +10,4 @@ declare global { var sandbox: sinon.SinonSandbox; } -export {}; \ No newline at end of file +export {}; diff --git a/types/json/index.d.ts b/types/json/index.d.ts index 6614cf24952..30e8f488980 100644 --- a/types/json/index.d.ts +++ b/types/json/index.d.ts @@ -2,4 +2,4 @@ declare module '*.json' { const value: any; export default value; -} \ No newline at end of file +}