From f9aa5a70defdad3ce13a257dc689add1d4b7d736 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 30 Jul 2018 23:58:05 -0230 Subject: [PATCH 01/64] Adds new gas customization modal container (without content) --- app/_locales/en/messages.json | 18 ++ .../gas-modal-page-container.component.js | 79 +++++++++ .../gas-modal-page-container.container.js | 11 ++ .../gas-modal-page-container/index.js | 1 + .../gas-modal-page-container/index.scss | 50 ++++++ ...gas-modal-page-container-component.test.js | 156 ++++++++++++++++++ ...gas-modal-page-container-container.test.js | 44 +++++ ui/app/components/index.scss | 2 + ui/app/components/modals/modal.js | 36 +--- .../confirm-transaction-base.container.js | 2 +- ui/app/css/itcss/settings/variables.scss | 1 + 11 files changed, 371 insertions(+), 29 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 0fe8e81cdb2f..6e7df3aa82e2 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -80,12 +80,18 @@ "addAcquiredTokens": { "message": "Add the tokens you've acquired using MetaMask" }, + "advanced": { + "message": "Advanced" + }, "amount": { "message": "Amount" }, "amountPlusGas": { "message": "Amount + Gas" }, + "amountPlusTxFee": { + "message": "Amount + TX Fee" + }, "appDescription": { "message": "Ethereum Browser Extension", "description": "The description of the application" @@ -127,6 +133,9 @@ "balanceIsInsufficientGas": { "message": "Insufficient balance for current gas total" }, + "basic": { + "message": "Basic" + }, "beta": { "message": "BETA" }, @@ -303,6 +312,9 @@ "customGas": { "message": "Customize Gas" }, + "customGasSubTitle": { + "message": "Increasing fee may decrease processing times, but it is not guaranteed." + }, "customToken": { "message": "Custom Token" }, @@ -755,6 +767,9 @@ "optionalNickname": { "message": "Nickname (optional)" }, + "newTotal": { + "message": "New Total" + }, "next": { "message": "Next" }, @@ -820,6 +835,9 @@ "parameters": { "message": "Parameters" }, + "originalTotal": { + "message": "Original Total" + }, "password": { "message": "Password" }, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js new file mode 100644 index 000000000000..dfc011c1e852 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -0,0 +1,79 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import PageContainer from '../../page-container' +import { Tabs, Tab } from '../../tabs' + +export default class GasModalPageContainer extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + hideModal: PropTypes.func, + } + + state = {} + + renderBasicTabContent () { + return ( +
+ ) + } + + renderAdvancedTabContent () { + return ( +
+ ) + } + + renderInfoRow (className, totalLabelKey, fiatTotal, cryptoTotal) { + return ( +
+
+ {`${this.context.t(totalLabelKey)}:`}{fiatTotal} +
+
+ {`${this.context.t('amountPlusTxFee')}`}{cryptoTotal} +
+
+ ) + } + + renderTabContent (mainTabContent) { + return ( +
+ { mainTabContent() } + { this.renderInfoRow('info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } + { this.renderInfoRow('info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') } +
+ ) + } + + renderTabs () { + return ( + + + { this.renderTabContent(this.renderBasicTabContent) } + + + { this.renderTabContent(this.renderAdvancedTabContent) } + + + ) + } + + render () { + const { hideModal } = this.props + + return ( + hideModal()} + onClose={() => hideModal()} + /> + ) + } +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js new file mode 100644 index 000000000000..71c700507670 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -0,0 +1,11 @@ +import { connect } from 'react-redux' +import GasModalPageContainer from './gas-modal-page-container.component' +import { hideModal } from '../../../actions' + +const mapDispatchToProps = dispatch => { + return { + hideModal: () => dispatch(hideModal()), + } +} + +export default connect(null, mapDispatchToProps)(GasModalPageContainer) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.js b/ui/app/components/gas-customization/gas-modal-page-container/index.js new file mode 100644 index 000000000000..ec0ebad22b65 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.js @@ -0,0 +1 @@ +export { default } from './gas-modal-page-container.container' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss new file mode 100644 index 000000000000..2d2250212324 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -0,0 +1,50 @@ +.gas-modal-content { + .basic-tab { + height: 219px; + } + + .advanced-tab { + height: 475px; + } + + .info-row, .info-row--fade { + width: 100%; + background: $polar; + padding: 15px 21px; + display: flex; + flex-flow: column; + color: $scorpion; + + .total-info, .sum-info { + display: flex; + flex-flow: row; + justify-content: space-between; + } + + .total-info { + .total-label { + font-size: 16px; + } + + .total-value { + font-size: 16px; + font-weight: bold; + } + } + + .sum-info { + .sum-label { + font-size: 12px; + } + + .sum-value { + font-size: 14px; + } + } + } + + .info-row--fade { + background: white; + color: $dusty-gray; + } +} \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js new file mode 100644 index 000000000000..ffe242de2685 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -0,0 +1,156 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import sinon from 'sinon' +import GasModalPageContainer from '../gas-modal-page-container.component.js' + +import PageContainer from '../../../page-container' +import { Tab } from '../../../tabs' + +const propsMethodSpies = { + hideModal: sinon.spy(), +} + +describe('GasModalPageContainer Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + }) + + afterEach(() => { + propsMethodSpies.hideModal.resetHistory() + }) + + describe('render', () => { + it('should render a PageContainer compenent', () => { + assert.equal(wrapper.find(PageContainer).length, 1) + }) + + it('should pass correct props to PageContainer', () => { + const { + title, + subtitle, + disabled, + } = wrapper.find(PageContainer).props() + assert.equal(title, 'customGas') + assert.equal(subtitle, 'customGasSpeedUp') + assert.equal(disabled, false) + }) + + it('should pass the correct onCancel and onClose methods to PageContainer', () => { + const { + onCancel, + onClose, + } = wrapper.find(PageContainer).props() + assert.equal(propsMethodSpies.hideModal.callCount, 0) + onCancel() + assert.equal(propsMethodSpies.hideModal.callCount, 1) + onClose() + assert.equal(propsMethodSpies.hideModal.callCount, 2) + }) + + it('should pass the correct renderTabs property to PageContainer', () => { + sinon.stub(GasModalPageContainer.prototype, 'renderTabs').returns('mockTabs') + const renderTabsWrapperTester = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props() + assert.equal(tabsComponent, 'mockTabs') + GasModalPageContainer.prototype.renderTabs.restore() + }) + }) + + describe('renderTabs', () => { + it('should render a Tabs component with "Basic" and "Advanced" tabs', () => { + const renderTabsResult = wrapper.instance().renderTabs() + const renderedTabs = shallow(renderTabsResult) + assert.equal(renderedTabs.props().className, 'tabs') + + const tabs = renderedTabs.find(Tab) + assert.equal(tabs.length, 2) + + assert.equal(tabs.at(0).props().name, 'basic') + assert.equal(tabs.at(1).props().name, 'advanced') + + assert.equal(tabs.at(0).childAt(0).props().className, 'gas-modal-content') + assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content') + }) + + it('should render the expected children of each tab', () => { + const GP = GasModalPageContainer.prototype + sinon.spy(GP, 'renderTabContent') + assert.equal(GP.renderTabContent.callCount, 0) + + wrapper.instance().renderTabs() + + assert.equal(GP.renderTabContent.callCount, 2) + + assert.deepEqual(GP.renderTabContent.firstCall.args, [wrapper.instance().renderBasicTabContent]) + assert.deepEqual(GP.renderTabContent.secondCall.args, [wrapper.instance().renderAdvancedTabContent]) + + GP.renderTabContent.restore() + }) + }) + + describe('renderTabContent', () => { + it('should render a root gas-modal-content div', () => { + const renderTabContentResult = wrapper.instance().renderTabContent(() => {}) + const renderedTabContent = shallow(renderTabContentResult) + assert.equal(renderedTabContent.props().className, 'gas-modal-content') + }) + + it('should render the element returned by the passed func as its first child', () => { + const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) + const renderedTabContent = shallow(renderTabContentResult) + assert(renderedTabContent.childAt(0).equals(Mock content)) + }) + + it('should render the element results of renderInfoRow calls as second and third childs', () => { + const GP = GasModalPageContainer.prototype + sinon.stub(GP, 'renderInfoRow').callsFake((...args) => args.join(',')) + + const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) + const renderedTabContent = shallow(renderTabContentResult) + assert.equal(renderedTabContent.childAt(1).text(), 'info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') + assert.equal(renderedTabContent.childAt(2).text(), 'info-row,newTotal,$20.02 USD,0.06685 ETH') + + GP.renderInfoRow.restore() + }) + }) + + describe('renderInfoRow', () => { + it('should render a div with the passed className and two children, each with the expected text', () => { + const renderInfoRowResult = wrapper.instance().renderInfoRow('mockClassName', 'mockLabelKey', 'mockFiatAmount', 'mockCryptoAmount') + const renderedInfoRow = shallow(renderInfoRowResult) + assert.equal(renderedInfoRow.props().className, 'mockClassName') + + const firstChild = renderedInfoRow.childAt(0) + const secondhild = renderedInfoRow.childAt(1) + + assert.equal(firstChild.props().className, 'total-info') + assert.equal(secondhild.props().className, 'sum-info') + + assert.equal(firstChild.childAt(0).text(), 'mockLabelKey:') + assert.equal(firstChild.childAt(1).text(), 'mockFiatAmount') + assert.equal(secondhild.childAt(0).text(), 'amountPlusTxFee') + assert.equal(secondhild.childAt(1).text(), 'mockCryptoAmount') + }) + }) + + describe('renderBasicTabContent', () => { + it('should render', () => { + const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() + const renderedBasicTabContent = shallow(renderBasicTabContentResult) + assert.equal(renderedBasicTabContent.props().className, 'basic-tab') + }) + }) + + describe('renderAdvancedTabContent', () => { + it('should render', () => { + const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() + const renderedAdvancedTabContent = shallow(renderAdvancedTabContentResult) + assert.equal(renderedAdvancedTabContent.props().className, 'advanced-tab') + }) + }) +}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js new file mode 100644 index 000000000000..5b133fbe24f2 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -0,0 +1,44 @@ +import assert from 'assert' +import proxyquire from 'proxyquire' +import sinon from 'sinon' + +// let mapStateToProps +let mapDispatchToProps + +const actionSpies = { + hideModal: sinon.spy(), +} + +proxyquire('../gas-modal-page-container.container.js', { + 'react-redux': { + connect: (ms, md) => { + // mapStateToProps = ms + mapDispatchToProps = md + return () => ({}) + }, + }, + '../../../actions': actionSpies, +}) + +describe('gas-modal-page-container container', () => { + + describe('mapDispatchToProps()', () => { + let dispatchSpy + let mapDispatchToPropsObject + + beforeEach(() => { + dispatchSpy = sinon.spy() + mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) + }) + + describe('hideModal()', () => { + it('should dispatch a hideModal action', () => { + mapDispatchToPropsObject.hideModal() + assert(dispatchSpy.calledOnce) + assert(actionSpies.hideModal.calledOnce) + }) + }) + + }) + +}) diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss index f901aed7d74c..48c6496d94e6 100644 --- a/ui/app/components/index.scss +++ b/ui/app/components/index.scss @@ -63,3 +63,5 @@ @import './sidebars/index'; @import './unit-input/index'; + +@import './gas-customization/gas-modal-page-container/index' diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 5aff4f5e12d4..46347312cd11 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -17,18 +17,17 @@ const ExportPrivateKeyModal = require('./export-private-key-modal') const NewAccountModal = require('./new-account-modal') const ShapeshiftDepositTxModal = require('./shapeshift-deposit-tx-modal.js') const HideTokenConfirmationModal = require('./hide-token-confirmation-modal') -const CustomizeGasModal = require('../customize-gas-modal') const NotifcationModal = require('./notification-modal') const QRScanner = require('./qr-scanner') import ConfirmRemoveAccount from './confirm-remove-account' import ConfirmResetAccount from './confirm-reset-account' import TransactionConfirmed from './transaction-confirmed' -import ConfirmCustomizeGasModal from './customize-gas' import CancelTransaction from './cancel-transaction' import WelcomeBeta from './welcome-beta' import RejectTransactions from './reject-transactions' import ClearApprovedOrigins from './clear-approved-origins' +import ConfirmCustomizeGasModal from '../gas-customization/gas-modal-page-container' const modalContainerBaseStyle = { transform: 'translate3d(-50%, 0, 0px)', @@ -295,7 +294,7 @@ const MODALS = { CUSTOMIZE_GAS: { contents: [ - h(CustomizeGasModal), + h(ConfirmCustomizeGasModal), ], mobileModalStyle: { width: '100vw', @@ -307,35 +306,16 @@ const MODALS = { margin: '0 auto', }, laptopModalStyle: { - width: '720px', - height: '377px', + width: 'auto', + height: '0px', top: '80px', + left: '0px', transform: 'none', - left: '0', - right: '0', margin: '0 auto', + position: 'relative', }, - }, - - CONFIRM_CUSTOMIZE_GAS: { - contents: h(ConfirmCustomizeGasModal), - mobileModalStyle: { - width: '100vw', - height: '100vh', - top: '0', - transform: 'none', - left: '0', - right: '0', - margin: '0 auto', - }, - laptopModalStyle: { - width: '720px', - height: '377px', - top: '80px', - transform: 'none', - left: '0', - right: '0', - margin: '0 auto', + contentStyle: { + borderRadius: '8px', }, }, diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index 626143ac762b..a3ec82863833 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -117,7 +117,7 @@ const mapDispatchToProps = dispatch => { return dispatch(showModal({ name: 'TRANSACTION_CONFIRMED', onSubmit })) }, showCustomizeGasModal: ({ txData, onSubmit, validate }) => { - return dispatch(showModal({ name: 'CONFIRM_CUSTOMIZE_GAS', txData, onSubmit, validate })) + return dispatch(showModal({ name: 'CUSTOMIZE_GAS', txData, onSubmit, validate })) }, updateGasAndCalculate: ({ gasLimit, gasPrice }) => { return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss index f90c8edc3ef2..6c2b82f39e4a 100644 --- a/ui/app/css/itcss/settings/variables.scss +++ b/ui/app/css/itcss/settings/variables.scss @@ -56,6 +56,7 @@ $zumthor: #edf7ff; $ecstasy: #f7861c; $linen: #fdf4f4; $oslo-gray: #8C8E94; +$polar: #fafcfe; /* Z-Indicies From 88d8eb289edd7bec86993aac946ac85e4e5219ec Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 6 Aug 2018 11:47:58 -0230 Subject: [PATCH 02/64] Use correct message key in gas-modal-page-container.component.js --- .../gas-modal-page-container.component.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index dfc011c1e852..51a202df1c99 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -68,7 +68,7 @@ export default class GasModalPageContainer extends Component { return ( hideModal()} From 5e7409482b6fc55eafc330e4bc119f7485f068bb Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 6 Aug 2018 12:04:06 -0230 Subject: [PATCH 03/64] Use BEM for css in gas-modal-page-container --- .../gas-modal-page-container.component.js | 18 ++++++++------- .../gas-modal-page-container/index.scss | 22 +++++++++---------- ...gas-modal-page-container-component.test.js | 14 ++++++------ 3 files changed, 28 insertions(+), 26 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 51a202df1c99..697594ec9cc5 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -16,24 +16,26 @@ export default class GasModalPageContainer extends Component { renderBasicTabContent () { return ( -
+
) } renderAdvancedTabContent () { return ( -
+
) } renderInfoRow (className, totalLabelKey, fiatTotal, cryptoTotal) { return (
-
- {`${this.context.t(totalLabelKey)}:`}{fiatTotal} +
+ {`${this.context.t(totalLabelKey)}:`} + {fiatTotal}
-
- {`${this.context.t('amountPlusTxFee')}`}{cryptoTotal} +
+ {`${this.context.t('amountPlusTxFee')}`} + {cryptoTotal}
) @@ -43,8 +45,8 @@ export default class GasModalPageContainer extends Component { return (
{ mainTabContent() } - { this.renderInfoRow('info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } - { this.renderInfoRow('info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') } + { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } + { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index 2d2250212324..a6609a385222 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -1,13 +1,13 @@ .gas-modal-content { - .basic-tab { + &__basic-tab { height: 219px; } - .advanced-tab { + &__advanced-tab { height: 475px; } - .info-row, .info-row--fade { + &__info-row, &__info-row--fade { width: 100%; background: $polar; padding: 15px 21px; @@ -15,35 +15,35 @@ flex-flow: column; color: $scorpion; - .total-info, .sum-info { + &__total-info, &__sum-info { display: flex; flex-flow: row; justify-content: space-between; } - .total-info { - .total-label { + &__total-info { + &__total-label { font-size: 16px; } - .total-value { + &__total-value { font-size: 16px; font-weight: bold; } } - .sum-info { - .sum-label { + &__sum-info { + &__sum-label { font-size: 12px; } - .sum-value { + &__sum-value { font-size: 14px; } } } - .info-row--fade { + &__info-row--fade { background: white; color: $dusty-gray; } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index ffe242de2685..32f6447651b8 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -36,7 +36,7 @@ describe('GasModalPageContainer Component', function () { disabled, } = wrapper.find(PageContainer).props() assert.equal(title, 'customGas') - assert.equal(subtitle, 'customGasSpeedUp') + assert.equal(subtitle, 'customGasSubTitle') assert.equal(disabled, false) }) @@ -112,8 +112,8 @@ describe('GasModalPageContainer Component', function () { const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) const renderedTabContent = shallow(renderTabContentResult) - assert.equal(renderedTabContent.childAt(1).text(), 'info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') - assert.equal(renderedTabContent.childAt(2).text(), 'info-row,newTotal,$20.02 USD,0.06685 ETH') + assert.equal(renderedTabContent.childAt(1).text(), 'gas-modal-content__info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') + assert.equal(renderedTabContent.childAt(2).text(), 'gas-modal-content__info-row,newTotal,$20.02 USD,0.06685 ETH') GP.renderInfoRow.restore() }) @@ -128,8 +128,8 @@ describe('GasModalPageContainer Component', function () { const firstChild = renderedInfoRow.childAt(0) const secondhild = renderedInfoRow.childAt(1) - assert.equal(firstChild.props().className, 'total-info') - assert.equal(secondhild.props().className, 'sum-info') + assert.equal(firstChild.props().className, 'mockClassName__total-info') + assert.equal(secondhild.props().className, 'mockClassName__sum-info') assert.equal(firstChild.childAt(0).text(), 'mockLabelKey:') assert.equal(firstChild.childAt(1).text(), 'mockFiatAmount') @@ -142,7 +142,7 @@ describe('GasModalPageContainer Component', function () { it('should render', () => { const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() const renderedBasicTabContent = shallow(renderBasicTabContentResult) - assert.equal(renderedBasicTabContent.props().className, 'basic-tab') + assert.equal(renderedBasicTabContent.props().className, 'gas-modal-content__basic-tab') }) }) @@ -150,7 +150,7 @@ describe('GasModalPageContainer Component', function () { it('should render', () => { const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() const renderedAdvancedTabContent = shallow(renderAdvancedTabContentResult) - assert.equal(renderedAdvancedTabContent.props().className, 'advanced-tab') + assert.equal(renderedAdvancedTabContent.props().className, 'gas-modal-content__advanced-tab') }) }) }) From 342dc95410b10f042b3f8ee4135f5fef1fd6fe93 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 2 Aug 2018 13:32:22 -0230 Subject: [PATCH 04/64] Adds the content of the advanced tab - w/o chart or dynamic content - to gas customize modal. --- app/_locales/en/messages.json | 6 + .../advanced-tab-content.component.js | 105 +++++++++++++++++ .../advanced-tab-content/index.js | 1 + .../advanced-tab-content/index.scss | 109 ++++++++++++++++++ .../time-remaining/index.js | 1 + .../time-remaining/index.scss | 13 +++ .../time-remaining.component.js | 33 ++++++ .../time-remaining/time-remaining.utils.js | 11 ++ .../gas-modal-page-container.component.js | 40 +++++-- .../gas-modal-page-container.container.js | 19 ++- .../gas-modal-page-container/index.scss | 8 ++ .../gas-slider/gas-slider.component.js | 48 ++++++++ .../gas-customization/gas-slider/index.js | 1 + .../gas-customization/gas-slider/index.scss | 54 +++++++++ .../components/gas-customization/index.scss | 3 + ui/app/components/index.scss | 8 +- ui/app/css/itcss/components/gas-slider.scss | 51 -------- ui/app/css/itcss/settings/variables.scss | 1 + ui/app/ducks/custom-gas.js | 67 +++++++++++ ui/app/reducers.js | 3 + ui/app/selectors/custom-gas.js | 19 +++ 21 files changed, 538 insertions(+), 63 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js create mode 100644 ui/app/components/gas-customization/gas-slider/gas-slider.component.js create mode 100644 ui/app/components/gas-customization/gas-slider/index.js create mode 100644 ui/app/components/gas-customization/gas-slider/index.scss create mode 100644 ui/app/components/gas-customization/index.scss create mode 100644 ui/app/ducks/custom-gas.js create mode 100644 ui/app/selectors/custom-gas.js diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 6e7df3aa82e2..103d8534f1a6 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -701,6 +701,9 @@ "missingYourTokens": { "message": "Don't see your tokens?" }, + "minutesShorthand": { + "message": "Min" + }, "myAccounts": { "message": "My Accounts" }, @@ -1036,6 +1039,9 @@ "secretPhrase": { "message": "Enter your secret twelve word phrase here to restore your vault." }, + "secondsShorthand": { + "message": "Sec" + }, "seedPhraseReq": { "message": "Seed phrases are 12 words long" }, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js new file mode 100644 index 000000000000..7ddf13e51217 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -0,0 +1,105 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { + MIN_GAS_PRICE_DEC, + MIN_GAS_LIMIT_DEC, +} from '../../../send/send.constants' +import GasSlider from '../../gas-slider' +import TimeRemaining from './time-remaining' + +export default class AdvancedTabContent extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + updateCustomGasPrice: PropTypes.func, + updateCustomGasLimit: PropTypes.func, + customGasPrice: PropTypes.number, + customGasLimit: PropTypes.number, + millisecondsRemaining: PropTypes.number, + } + + gasInput (value, onChange, min, precision, showGWEI) { + return ( +
+ onChange(Number(event.target.value))} + /> + {showGWEI + ? GWEI + : null} +
+ ) + } + + infoButton (onClick) { + return + } + + render () { + const { + updateCustomGasPrice, + updateCustomGasLimit, + millisecondsRemaining, + customGasPrice, + customGasLimit, + } = this.props + + return ( +
+
+
+ New Transaction Fee + ~Transaction Time +
+
+
+ $0.30 +
+ +
+
+
+ Live Transaction Fee Predictions +
+
+
+ { + updateCustomGasPrice(Number(value)) + }} + lowLabel={'Cheaper'} + highLabel={'Faster'} + value={customGasPrice} + step={0.1} + max={200} + min={0} + coloredStart={{}} + /> +
+
+
+
+ Gas Price + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } +
+
+
+ Gas Limit + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } +
+
+
+ ) + } +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js new file mode 100644 index 000000000000..492037f250c0 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.js @@ -0,0 +1 @@ +export { default } from './advanced-tab-content.component' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss new file mode 100644 index 000000000000..5dc30e061641 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -0,0 +1,109 @@ +@import './time-remaining/index'; + +.advanced-tab { + display: flex; + flex-flow: column; + border-bottom: 1px solid $alto; + + &__transaction-data-summary, + &__fee-chart-title, + &__gas-edit-row { + padding-left: 24px; + padding-right: 24px; + } + + &__transaction-data-summary { + display: flex; + flex-flow: column; + color: $mid-gray; + margin-top: 12px; + + &__titles, + &__container { + display: flex; + flex-flow: row; + justify-content: space-between; + font-size: 12px; + } + + &__container { + font-size: 26px; + margin-top: 6px; + } + } + + &__fee-chart-title { + font-size: 14px; + color: $scorpion; + margin-top: 22px; + } + + &__fee-chart { + padding-left: 10px; + margin-top: 24px; + height: 134px; + } + + &__slider-container { + padding-left: 27px; + padding-right: 27px; + } + + &__gas-edit-rows { + margin-top: 44px; + height: 87px; + display: flex; + flex-flow: column; + justify-content: space-between; + } + + &__gas-edit-row { + display: flex; + flex-flow: row; + justify-content: space-between; + + &__label { + color: $mid-gray; + font-size: 16px; + + .info-circle { + color: $silver; + margin-left: 10px; + } + } + + + &__input-wrapper { + position: relative; + } + + &__input { + border: 1px solid $dusty-gray; + border-radius: 4px; + color: $mid-gray; + font-size: 16px; + height: 37px; + width: 163px; + padding: 8px 10px 10px 10px; + } + + input[type="number"]::-webkit-inner-spin-button { + -webkit-appearance: none; + -moz-appearance: none; + display: none; + } + + input[type="number"]:hover::-webkit-inner-spin-button { + -webkit-appearance: none; + -moz-appearance: none; + display: none; + } + + &__gwei-symbol { + position: absolute; + top: 8px; + right: 10px; + color: $dusty-gray; + } + } +} \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js new file mode 100644 index 000000000000..61b681e1a1e7 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.js @@ -0,0 +1 @@ +export { default } from './time-remaining.component' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss new file mode 100644 index 000000000000..01bb06268155 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss @@ -0,0 +1,13 @@ +.time-remaining { + .minutes-num, .seconds-num { + font-size: 26px; + } + + .seconds-num { + margin-left: 7px; + } + + .minutes-label, .seconds-label { + font-size: 14px; + } +} \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js new file mode 100644 index 000000000000..826d41f9c174 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.component.js @@ -0,0 +1,33 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import { getTimeBreakdown } from './time-remaining.utils' + +export default class TimeRemaining extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + milliseconds: PropTypes.number, + } + + render () { + const { + milliseconds, + } = this.props + + const { + minutes, + seconds, + } = getTimeBreakdown(milliseconds) + + return ( +
+ {minutes} + {this.context.t('minutesShorthand')} + {seconds} + {this.context.t('secondsShorthand')} +
+ ) + } +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js new file mode 100644 index 000000000000..cf43e0acb9f3 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/time-remaining.utils.js @@ -0,0 +1,11 @@ +function getTimeBreakdown (milliseconds) { + return { + hours: Math.floor(milliseconds / 3600000), + minutes: Math.floor((milliseconds % 3600000) / 60000), + seconds: Math.floor((milliseconds % 60000) / 1000), + } +} + +module.exports = { + getTimeBreakdown, +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 697594ec9cc5..1d7a9d986aec 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -2,6 +2,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import PageContainer from '../../page-container' import { Tabs, Tab } from '../../tabs' +import AdvancedTabContent from './advanced-tab-content' export default class GasModalPageContainer extends Component { static contextTypes = { @@ -10,6 +11,10 @@ export default class GasModalPageContainer extends Component { static propTypes = { hideModal: PropTypes.func, + updateCustomGasPrice: PropTypes.func, + updateCustomGasLimit: PropTypes.func, + customGasPrice: PropTypes.number, + customGasLimit: PropTypes.number, } state = {} @@ -20,9 +25,22 @@ export default class GasModalPageContainer extends Component { ) } - renderAdvancedTabContent () { + renderAdvancedTabContent = () => { + const { + updateCustomGasPrice, + updateCustomGasLimit, + customGasPrice, + customGasLimit, + } = this.props + return ( -
+ ) } @@ -68,14 +86,16 @@ export default class GasModalPageContainer extends Component { const { hideModal } = this.props return ( - hideModal()} - onClose={() => hideModal()} - /> +
+ hideModal()} + onClose={() => hideModal()} + /> +
) } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 71c700507670..f7ac91a3811d 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -1,11 +1,28 @@ import { connect } from 'react-redux' import GasModalPageContainer from './gas-modal-page-container.component' import { hideModal } from '../../../actions' +import { + setCustomGasPrice, + setCustomGasLimit, +} from '../../../ducks/custom-gas' +import { + getCustomGasPrice, + getCustomGasLimit, +} from '../../../selectors/custom-gas' + +const mapStateToProps = state => { + return { + customGasPrice: getCustomGasPrice(state), + customGasLimit: getCustomGasLimit(state), + } +} const mapDispatchToProps = dispatch => { return { hideModal: () => dispatch(hideModal()), + updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)), + updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)), } } -export default connect(null, mapDispatchToProps)(GasModalPageContainer) +export default connect(mapStateToProps, mapDispatchToProps)(GasModalPageContainer) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index a6609a385222..027165b4834d 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -1,3 +1,11 @@ +@import './advanced-tab-content/index'; + +.gas-modal-page-container { + .page-container { + width: 391px; + } +} + .gas-modal-content { &__basic-tab { height: 219px; diff --git a/ui/app/components/gas-customization/gas-slider/gas-slider.component.js b/ui/app/components/gas-customization/gas-slider/gas-slider.component.js new file mode 100644 index 000000000000..5836e7dfca2d --- /dev/null +++ b/ui/app/components/gas-customization/gas-slider/gas-slider.component.js @@ -0,0 +1,48 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +export default class AdvancedTabContent extends Component { + static propTypes = { + onChange: PropTypes.func, + lowLabel: PropTypes.string, + highLabel: PropTypes.string, + value: PropTypes.number, + step: PropTypes.number, + max: PropTypes.number, + min: PropTypes.number, + } + + render () { + const { + onChange, + lowLabel, + highLabel, + value, + step, + max, + min, + } = this.props + + return ( +
+ onChange(event.target.value)} + /> +
+
+
+
+ {lowLabel} + {highLabel} +
+
+ ) + } +} diff --git a/ui/app/components/gas-customization/gas-slider/index.js b/ui/app/components/gas-customization/gas-slider/index.js new file mode 100644 index 000000000000..f1752c93f9d0 --- /dev/null +++ b/ui/app/components/gas-customization/gas-slider/index.js @@ -0,0 +1 @@ +export { default } from './gas-slider.component' diff --git a/ui/app/components/gas-customization/gas-slider/index.scss b/ui/app/components/gas-customization/gas-slider/index.scss new file mode 100644 index 000000000000..e6c73436753c --- /dev/null +++ b/ui/app/components/gas-customization/gas-slider/index.scss @@ -0,0 +1,54 @@ +.gas-slider { + position: relative; + width: 322px; + + &__input { + width: 322px; + margin-left: -2px; + z-index: 2; + } + + input[type=range] { + -webkit-appearance: none !important; + } + + input[type=range]::-webkit-slider-thumb { + -webkit-appearance: none !important; + height: 34px; + width: 34px; + background-color: $curious-blue; + box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08); + border-radius: 50%; + position: relative; + z-index: 10; + } + + &__bar { + height: 6px; + width: 322px; + background: $alto; + display: flex; + justify-content: space-between; + position: absolute; + top: 16px; + z-index: 0; + border-radius: 4px; + } + + &__colored { + height: 6px; + border-radius: 4px; + margin-left: 102px; + width: 322px; + z-index: 1; + background-color: $blizzard-blue; + } + + &__labels { + display: flex; + justify-content: space-between; + font-size: 12px; + margin-top: -6px; + color: $mid-gray; + } +} \ No newline at end of file diff --git a/ui/app/components/gas-customization/index.scss b/ui/app/components/gas-customization/index.scss new file mode 100644 index 000000000000..91ca5004e3cd --- /dev/null +++ b/ui/app/components/gas-customization/index.scss @@ -0,0 +1,3 @@ +@import './gas-slider/index'; + +@import './gas-modal-page-container/index'; diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss index 48c6496d94e6..156b1b9f6c1a 100644 --- a/ui/app/components/index.scss +++ b/ui/app/components/index.scss @@ -64,4 +64,10 @@ @import './unit-input/index'; -@import './gas-customization/gas-modal-page-container/index' +@import './gas-customization/gas-modal-page-container/index'; + +@import './gas-customization/gas-modal-page-container/index'; + +@import './gas-customization/gas-modal-page-container/index'; + +@import './gas-customization/index'; diff --git a/ui/app/css/itcss/components/gas-slider.scss b/ui/app/css/itcss/components/gas-slider.scss index c27a560bdd16..e69de29bb2d1 100644 --- a/ui/app/css/itcss/components/gas-slider.scss +++ b/ui/app/css/itcss/components/gas-slider.scss @@ -1,51 +0,0 @@ -.gas-slider { - position: relative; - width: 313px; - - &__input { - width: 317px; - margin-left: -2px; - z-index: 2; - } - - input[type=range] { - -webkit-appearance: none !important; - } - - input[type=range]::-webkit-slider-thumb { - -webkit-appearance: none !important; - height: 26px; - width: 26px; - border: 2px solid #B8B8B8; - background-color: #FFFFFF; - box-shadow: 0 2px 4px 0 rgba(0,0,0,0.08); - border-radius: 50%; - position: relative; - z-index: 10; - } - - &__bar { - height: 6px; - width: 313px; - background: $alto; - display: flex; - justify-content: space-between; - position: absolute; - top: 11px; - z-index: 0; - } - - &__low, &__high { - height: 6px; - width: 49px; - z-index: 1; - } - - &__low { - background-color: $crimson; - } - - &__high { - background-color: $caribbean-green; - } -} \ No newline at end of file diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss index 6c2b82f39e4a..1c95f06a03d1 100644 --- a/ui/app/css/itcss/settings/variables.scss +++ b/ui/app/css/itcss/settings/variables.scss @@ -57,6 +57,7 @@ $ecstasy: #f7861c; $linen: #fdf4f4; $oslo-gray: #8C8E94; $polar: #fafcfe; +$blizzard-blue: #bfdef3; /* Z-Indicies diff --git a/ui/app/ducks/custom-gas.js b/ui/app/ducks/custom-gas.js new file mode 100644 index 000000000000..f1f483e9304e --- /dev/null +++ b/ui/app/ducks/custom-gas.js @@ -0,0 +1,67 @@ +import extend from 'xtend' + +// Actions +const SET_CUSTOM_GAS_PRICE = 'metamask/custom-gas/SET_CUSTOM_GAS_PRICE' +const SET_CUSTOM_GAS_LIMIT = 'metamask/custom-gas/SET_CUSTOM_GAS_LIMIT' +const SET_CUSTOM_GAS_ERRORS = 'metamask/custom-gas/SET_CUSTOM_GAS_ERRORS' +const RESET_CUSTOM_GAS_STATE = 'metamask/custom-gas/RESET_CUSTOM_GAS_STATE' + +// TODO: determine if this approach to initState is consistent with conventional ducks pattern +const initState = { + price: 0, + limit: 21000, + errors: {}, +} + +// Reducer +export default function reducer ({ customGas: customGasState = initState }, action = {}) { + const newState = extend({}, customGasState) + + switch (action.type) { + case SET_CUSTOM_GAS_PRICE: + return extend(newState, { + price: action.value, + }) + case SET_CUSTOM_GAS_LIMIT: + return extend(newState, { + limit: action.value, + }) + case SET_CUSTOM_GAS_ERRORS: + return extend(newState, { + errors: { + ...newState.errors, + ...action.value, + }, + }) + case RESET_CUSTOM_GAS_STATE: + return extend({}, initState) + default: + return newState + } +} + +// Action Creators +export function setCustomGasPrice (newPrice) { + return { + type: SET_CUSTOM_GAS_PRICE, + value: newPrice, + } +} + +export function setCustomGasLimit (newLimit) { + return { + type: SET_CUSTOM_GAS_LIMIT, + value: newLimit, + } +} + +export function setCustomGasErrors (newErrors) { + return { + type: SET_CUSTOM_GAS_ERRORS, + value: newErrors, + } +} + +export function resetCustomGasState () { + return { type: RESET_CUSTOM_GAS_STATE } +} diff --git a/ui/app/reducers.js b/ui/app/reducers.js index e1a982f93909..7234c3c02c10 100644 --- a/ui/app/reducers.js +++ b/ui/app/reducers.js @@ -10,6 +10,7 @@ const reduceApp = require('./reducers/app') const reduceLocale = require('./reducers/locale') const reduceSend = require('./ducks/send.duck').default import reduceConfirmTransaction from './ducks/confirm-transaction.duck' +import reduceCustomGas from './ducks/custom-gas' window.METAMASK_CACHED_LOG_STATE = null @@ -49,6 +50,8 @@ function rootReducer (state, action) { state.confirmTransaction = reduceConfirmTransaction(state, action) + state.customGas = reduceCustomGas(state, action) + window.METAMASK_CACHED_LOG_STATE = state return state } diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js new file mode 100644 index 000000000000..97280190fbe4 --- /dev/null +++ b/ui/app/selectors/custom-gas.js @@ -0,0 +1,19 @@ +const selectors = { + getCustomGasPrice, + getCustomGasLimit, + getCustomGasErrors, +} + +module.exports = selectors + +function getCustomGasPrice (state) { + return state.customGas.price +} + +function getCustomGasLimit (state) { + return state.customGas.limit +} + +function getCustomGasErrors (state) { + return state.customGas.errors +} From d55a2615a4af1a0e4d589d0b82904f46cfbff6f7 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 7 Aug 2018 12:27:42 -0230 Subject: [PATCH 05/64] Split advanced-tab-content.component.js render() method into smaller pieces; add translations to the same file. --- app/_locales/en/messages.json | 12 +++ .../advanced-tab-content.component.js | 81 ++++++++++++------- .../gas-modal-page-container.component.js | 1 + 3 files changed, 63 insertions(+), 31 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 103d8534f1a6..017a8a38047a 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -439,6 +439,9 @@ "failed": { "message": "Failed" }, + "feeChartTitle": { + "message": "Live Transaction Fee Predictions" + }, "fiat": { "message": "Fiat", "description": "Exchange type" @@ -493,6 +496,9 @@ "gasPrice": { "message": "Gas Price (GWEI)" }, + "gasPriceNoDenom": { + "message": "Gas Price" + }, "gasPriceCalculation": { "message": "We calculate the suggested gas prices based on network success rates." }, @@ -773,6 +779,9 @@ "newTotal": { "message": "New Total" }, + "newTransactionFee": { + "message": "New Transaction Fee" + }, "next": { "message": "Next" }, @@ -1274,6 +1283,9 @@ "transactionNumber": { "message": "Transaction Number" }, + "transactionTime": { + "message": "Transaction Time" + }, "transfer": { "message": "Transfer" }, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 7ddf13e51217..8e593f029902 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -18,6 +18,7 @@ export default class AdvancedTabContent extends Component { customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, millisecondsRemaining: PropTypes.number, + totalFee: PropTypes.string, } gasInput (value, onChange, min, precision, showGWEI) { @@ -40,6 +41,46 @@ export default class AdvancedTabContent extends Component { return } + renderDataSummary (totalFee, millisecondsRemaining) { + return ( +
+
+ { this.context.t('newTransactionFee') } + ~{ this.context.t('transactionTime') } +
+
+
+ {totalFee} +
+ +
+
+ ) + } + + renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { + return ( +
+
+
+ { this.context.t('gasPriceNoDenom') } + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } +
+
+
+ { this.context.t('gasLimit') } + { this.infoButton(() => {}) } +
+ { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } +
+
+ ) + } + render () { const { updateCustomGasPrice, @@ -47,26 +88,14 @@ export default class AdvancedTabContent extends Component { millisecondsRemaining, customGasPrice, customGasLimit, + totalFee, } = this.props return (
-
-
- New Transaction Fee - ~Transaction Time -
-
-
- $0.30 -
- -
-
+ { this.renderDataSummary(totalFee, millisecondsRemaining) }
- Live Transaction Fee Predictions + { this.context.t('feeChartTitle') }
@@ -83,22 +112,12 @@ export default class AdvancedTabContent extends Component { coloredStart={{}} />
-
-
-
- Gas Price - { this.infoButton(() => {}) } -
- { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } -
-
-
- Gas Limit - { this.infoButton(() => {}) } -
- { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } -
-
+ { this.renderGasEditRows( + customGasPrice, + updateCustomGasPrice, + customGasLimit, + updateCustomGasLimit + ) }
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 1d7a9d986aec..e47ebaf6575c 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -40,6 +40,7 @@ export default class GasModalPageContainer extends Component { customGasPrice={customGasPrice} customGasLimit={customGasLimit} millisecondsRemaining={91000} + totalFee={'$0.30'} /> ) } From 3b9ec8e1bc8f3db9cfd645b10e4908f06096c70c Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 7 Aug 2018 12:29:14 -0230 Subject: [PATCH 06/64] Remove gas slider from advance-tab-content.component --- .../advanced-tab-content.component.js | 15 --------------- .../advanced-tab-content/index.scss | 1 + .../gas-modal-page-container/index.scss | 5 +---- 3 files changed, 2 insertions(+), 19 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 8e593f029902..a09869a46357 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -4,7 +4,6 @@ import { MIN_GAS_PRICE_DEC, MIN_GAS_LIMIT_DEC, } from '../../../send/send.constants' -import GasSlider from '../../gas-slider' import TimeRemaining from './time-remaining' export default class AdvancedTabContent extends Component { @@ -98,20 +97,6 @@ export default class AdvancedTabContent extends Component { { this.context.t('feeChartTitle') }
-
- { - updateCustomGasPrice(Number(value)) - }} - lowLabel={'Cheaper'} - highLabel={'Faster'} - value={customGasPrice} - step={0.1} - max={200} - min={0} - coloredStart={{}} - /> -
{ this.renderGasEditRows( customGasPrice, updateCustomGasPrice, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index 5dc30e061641..0c95afc4830f 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -4,6 +4,7 @@ display: flex; flex-flow: column; border-bottom: 1px solid $alto; + height: 430px; &__transaction-data-summary, &__fee-chart-title, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index 027165b4834d..ff512537e386 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -11,11 +11,8 @@ height: 219px; } - &__advanced-tab { - height: 475px; - } - &__info-row, &__info-row--fade { + .info-row, .info-row--fade { width: 100%; background: $polar; padding: 15px 21px; From 99c8804eeb8c3e407fa9f2d806c145113ec6ec2c Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 8 Aug 2018 11:21:06 -0230 Subject: [PATCH 07/64] Add tests for advanced-tab-component.js and subcomponents. --- .../advanced-tab-content.component.js | 30 +-- .../advanced-tab-content-component.test.js | 215 ++++++++++++++++++ .../tests/time-remaining-component.test.js | 30 +++ ...gas-modal-page-container-component.test.js | 18 +- ui/lib/shallow-with-context.js | 7 + 5 files changed, 282 insertions(+), 18 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js create mode 100644 ui/lib/shallow-with-context.js diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index a09869a46357..69cd06cde7d0 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -27,6 +27,8 @@ export default class AdvancedTabContent extends Component { className="advanced-tab__gas-edit-row__input" type="number" value={value} + min={min} + precision={precision} onChange={event => onChange(Number(event.target.value))} /> {showGWEI @@ -59,23 +61,23 @@ export default class AdvancedTabContent extends Component { ) } + renderGasEditRow (labelKey, ...gasInputArgs) { + return ( +
+
+ { this.context.t(labelKey) } + { this.infoButton(() => {}) } +
+ { this.gasInput(...gasInputArgs) } +
+ ) + } + renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { return (
-
-
- { this.context.t('gasPriceNoDenom') } - { this.infoButton(() => {}) } -
- { this.gasInput(customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } -
-
-
- { this.context.t('gasLimit') } - { this.infoButton(() => {}) } -
- { this.gasInput(customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } -
+ { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } + { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) }
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js new file mode 100644 index 000000000000..3efe1d2a9da0 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -0,0 +1,215 @@ +import React from 'react' +import assert from 'assert' +import shallow from '../../../../../../lib/shallow-with-context' +import sinon from 'sinon' +import AdvancedTabContent from '../advanced-tab-content.component.js' + +import TimeRemaining from '../time-remaining' + +const propsMethodSpies = { + updateCustomGasPrice: sinon.spy(), + updateCustomGasLimit: sinon.spy(), +} + +sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRow') +sinon.spy(AdvancedTabContent.prototype, 'gasInput') + +describe('AdvancedTabContent Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + }) + + afterEach(() => { + propsMethodSpies.updateCustomGasPrice.resetHistory() + propsMethodSpies.updateCustomGasLimit.resetHistory() + }) + + describe('render()', () => { + it('should render the advanced-tab root node', () => { + assert(wrapper.hasClass('advanced-tab')) + }) + + it('should render the expected four children of the advanced-tab div', () => { + const advancedTabChildren = wrapper.children() + assert.equal(advancedTabChildren.length, 4) + + assert(advancedTabChildren.at(0).hasClass('advanced-tab__transaction-data-summary')) + assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart-title')) + assert(advancedTabChildren.at(2).hasClass('advanced-tab__fee-chart')) + assert(advancedTabChildren.at(3).hasClass('advanced-tab__gas-edit-rows')) + }) + }) + + describe('renderDataSummary()', () => { + let dataSummary + + beforeEach(() => { + dataSummary = shallow(wrapper.instance().renderDataSummary('mockTotalFee', 'mockMsRemaining')) + }) + + it('should render the transaction-data-summary root node', () => { + assert(dataSummary.hasClass('advanced-tab__transaction-data-summary')) + }) + + it('should render titles of the data', () => { + const titlesNode = dataSummary.children().at(0) + assert(titlesNode.hasClass('advanced-tab__transaction-data-summary__titles')) + assert.equal(titlesNode.children().at(0).text(), 'newTransactionFee') + assert.equal(titlesNode.children().at(1).text(), '~transactionTime') + }) + + it('should render the data', () => { + const dataNode = dataSummary.children().at(1) + assert(dataNode.hasClass('advanced-tab__transaction-data-summary__container')) + assert.equal(dataNode.children().at(0).text(), 'mockTotalFee') + assert(dataNode.children().at(1).is(TimeRemaining)) + assert.equal(dataNode.children().at(1).props().milliseconds, 'mockMsRemaining') + }) + }) + + describe('renderGasEditRow()', () => { + let gasEditRow + + beforeEach(() => { + AdvancedTabContent.prototype.gasInput.resetHistory() + gasEditRow = shallow(wrapper.instance().renderGasEditRow( + 'mockLabelKey', 'argA', 'argB' + )) + }) + + it('should render the gas-edit-row root node', () => { + assert(gasEditRow.hasClass('advanced-tab__gas-edit-row')) + }) + + it('should render a label and an input', () => { + const gasEditRowChildren = gasEditRow.children() + assert.equal(gasEditRowChildren.length, 2) + assert(gasEditRowChildren.at(0).hasClass('advanced-tab__gas-edit-row__label')) + assert(gasEditRowChildren.at(1).hasClass('advanced-tab__gas-edit-row__input-wrapper')) + }) + + it('should render the label key and info button', () => { + const gasRowLabelChildren = gasEditRow.children().at(0).children() + assert.equal(gasRowLabelChildren.length, 2) + assert(gasRowLabelChildren.at(0), 'mockLabelKey') + assert(gasRowLabelChildren.at(1).hasClass('info-circle')) + }) + + it('should call this.gasInput with the correct args', () => { + const gasInputSpyArgs = AdvancedTabContent.prototype.gasInput.args + assert.deepEqual(gasInputSpyArgs[0], [ 'argA', 'argB' ]) + }) + }) + + describe('renderGasEditRows()', () => { + let gasEditRows + + beforeEach(() => { + AdvancedTabContent.prototype.renderGasEditRow.resetHistory() + gasEditRows = shallow(wrapper.instance().renderGasEditRows( + 'mockGasPrice', + () => 'mockUpdateCustomGasPriceReturn', + 'mockGasLimit', + () => 'mockUpdateCustomGasLimitReturn' + )) + }) + + it('should render the gas-edit-rows root node', () => { + assert(gasEditRows.hasClass('advanced-tab__gas-edit-rows')) + }) + + it('should render two rows', () => { + const gasEditRowsChildren = gasEditRows.children() + assert.equal(gasEditRowsChildren.length, 2) + assert(gasEditRowsChildren.at(0).hasClass('advanced-tab__gas-edit-row')) + assert(gasEditRowsChildren.at(1).hasClass('advanced-tab__gas-edit-row')) + }) + + it('should call this.renderGasEditRow twice, with the expected args', () => { + const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args + assert.equal(renderGasEditRowSpyArgs.length, 2) + assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ + 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', '0', 9, true, + ].map(String)) + assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ + 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 21000, '0', + ].map(String)) + }) + }) + + describe('infoButton()', () => { + let infoButton + + beforeEach(() => { + AdvancedTabContent.prototype.renderGasEditRow.resetHistory() + infoButton = shallow(wrapper.instance().infoButton(() => 'mockOnClickReturn')) + }) + + it('should render the i element', () => { + assert(infoButton.hasClass('info-circle')) + }) + + it('should pass the onClick argument to the i tag onClick prop', () => { + assert(infoButton.props().onClick(), 'mockOnClickReturn') + }) + }) + + describe('gasInput()', () => { + let gasInput + + beforeEach(() => { + AdvancedTabContent.prototype.renderGasEditRow.resetHistory() + gasInput = shallow(wrapper.instance().gasInput( + 321, + value => value + 7, + 0, + 8, + false + )) + }) + + it('should render the input-wrapper root node', () => { + assert(gasInput.hasClass('advanced-tab__gas-edit-row__input-wrapper')) + }) + + it('should render an input, but not a GWEI symbol', () => { + assert.equal(gasInput.children().length, 1) + assert(gasInput.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) + }) + + it('should show GWEI if the showGWEI prop is truthy', () => { + const gasInputWithGWEI = shallow(wrapper.instance().gasInput( + 321, + value => value + 7, + 0, + 8, + true + )) + assert.equal(gasInputWithGWEI.children().length, 2) + assert(gasInputWithGWEI.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) + assert(gasInputWithGWEI.children().at(1).hasClass('advanced-tab__gas-edit-row__gwei-symbol')) + }) + + it('should pass the correct value min and precision props to the input', () => { + const inputProps = gasInput.find('input').props() + assert.equal(inputProps.min, 0) + assert.equal(inputProps.value, 321) + assert.equal(inputProps.precision, 8) + }) + + it('should call the passed onChange method with the value of the input onChange event', () => { + const inputOnChange = gasInput.find('input').props().onChange + assert.equal(inputOnChange({ target: { value: 8} }), 15) + }) + }) + +}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js new file mode 100644 index 000000000000..d8490272ff76 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/tests/time-remaining-component.test.js @@ -0,0 +1,30 @@ +import React from 'react' +import assert from 'assert' +import shallow from '../../../../../../../lib/shallow-with-context' +import TimeRemaining from '../time-remaining.component.js' + +describe('TimeRemaining Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow() + }) + + describe('render()', () => { + it('should render the time-remaining root node', () => { + assert(wrapper.hasClass('time-remaining')) + }) + + it('should render minutes and seconds numbers and labels', () => { + const timeRemainingChildren = wrapper.children() + assert.equal(timeRemainingChildren.length, 4) + assert.equal(timeRemainingChildren.at(0).text(), 8) + assert.equal(timeRemainingChildren.at(1).text(), 'minutesShorthand') + assert.equal(timeRemainingChildren.at(2).text(), 15) + assert.equal(timeRemainingChildren.at(3).text(), 'secondsShorthand') + }) + }) + +}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 32f6447651b8..8bf72647afb4 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -1,6 +1,6 @@ import React from 'react' import assert from 'assert' -import { shallow } from 'enzyme' +import shallow from '../../../../../lib/shallow-with-context' import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' @@ -17,6 +17,10 @@ describe('GasModalPageContainer Component', function () { beforeEach(() => { wrapper = shallow( 'mockupdateCustomGasPrice'} + updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} + customGasPrice={21} + customGasLimit={54321} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -147,10 +151,16 @@ describe('GasModalPageContainer Component', function () { }) describe('renderAdvancedTabContent', () => { - it('should render', () => { + it('should render with the correct props', () => { const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() - const renderedAdvancedTabContent = shallow(renderAdvancedTabContentResult) - assert.equal(renderedAdvancedTabContent.props().className, 'gas-modal-content__advanced-tab') + const advancedTabContentProps = renderAdvancedTabContentResult.props + assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockupdateCustomGasPrice') + assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockupdateCustomGasLimit') + assert.equal(advancedTabContentProps.customGasPrice, 21) + assert.equal(advancedTabContentProps.customGasLimit, 54321) + assert.equal(advancedTabContentProps.millisecondsRemaining, 91000) + assert.equal(advancedTabContentProps.totalFee, '$0.30') + assert(shallow(renderAdvancedTabContentResult).hasClass('advanced-tab')) }) }) }) diff --git a/ui/lib/shallow-with-context.js b/ui/lib/shallow-with-context.js new file mode 100644 index 000000000000..cf83dd76e86d --- /dev/null +++ b/ui/lib/shallow-with-context.js @@ -0,0 +1,7 @@ +import { shallow } from 'enzyme' + +export default function (jsxComponent) { + return shallow(jsxComponent, { + context: { t: (str1, str2) => str2 ? str1 + str2 : str1 }, + }) +} From 57cd721800aff67cd18e9e530d92eb94ff75d473 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 8 Aug 2018 11:40:17 -0230 Subject: [PATCH 08/64] Improve styling of advanced-tab-content gasInput row --- .../advanced-tab-content.component.js | 2 +- .../advanced-tab-content/index.scss | 10 ++++++++-- .../tests/advanced-tab-content-component.test.js | 4 ++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 69cd06cde7d0..cd5ca7d35458 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -39,7 +39,7 @@ export default class AdvancedTabContent extends Component { } infoButton (onClick) { - return + return } renderDataSummary (totalFee, millisecondsRemaining) { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index 0c95afc4830f..28e2fde9b79d 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -67,9 +67,14 @@ color: $mid-gray; font-size: 16px; - .info-circle { + .fa-info-circle { color: $silver; margin-left: 10px; + cursor: pointer; + } + + .fa-info-circle:hover { + color: $mid-gray; } } @@ -85,7 +90,8 @@ font-size: 16px; height: 37px; width: 163px; - padding: 8px 10px 10px 10px; + padding-left: 8px; + padding-top: 2px; } input[type="number"]::-webkit-inner-spin-button { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 3efe1d2a9da0..5cdcf687e076 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -101,7 +101,7 @@ describe('AdvancedTabContent Component', function () { const gasRowLabelChildren = gasEditRow.children().at(0).children() assert.equal(gasRowLabelChildren.length, 2) assert(gasRowLabelChildren.at(0), 'mockLabelKey') - assert(gasRowLabelChildren.at(1).hasClass('info-circle')) + assert(gasRowLabelChildren.at(1).hasClass('fa-info-circle')) }) it('should call this.gasInput with the correct args', () => { @@ -155,7 +155,7 @@ describe('AdvancedTabContent Component', function () { }) it('should render the i element', () => { - assert(infoButton.hasClass('info-circle')) + assert(infoButton.hasClass('fa-info-circle')) }) it('should pass the onClick argument to the i tag onClick prop', () => { From 112d18e316df312a648b8c8ac17c201314fc9ed6 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 9 Aug 2018 13:44:03 -0230 Subject: [PATCH 09/64] Adds basic tab content to gas customizer, with styled button group (static, for now). --- ui/app/components/button/button.component.js | 6 +- .../basic-tab-content.component.js | 22 ++ .../basic-tab-content/index.js | 1 + .../basic-tab-content/index.scss | 11 + .../tests/basic-tab-content-component.test.js | 71 ++++++ .../gas-modal-page-container.component.js | 10 +- .../gas-modal-page-container.container.js | 29 +++ .../gas-modal-page-container/index.scss | 7 +- ...gas-modal-page-container-component.test.js | 47 +++- ...gas-modal-page-container-container.test.js | 39 ++- .../gas-price-button-group.component.js | 85 +++++++ .../gas-price-button-group/index.js | 1 + .../gas-price-button-group/index.scss | 60 +++++ .../gas-price-button-group-component.test.js | 238 ++++++++++++++++++ ui/app/components/index.scss | 2 + ui/app/css/itcss/settings/variables.scss | 1 + 16 files changed, 615 insertions(+), 15 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss create mode 100644 ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js create mode 100644 ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js create mode 100644 ui/app/components/gas-customization/gas-price-button-group/index.js create mode 100644 ui/app/components/gas-customization/gas-price-button-group/index.scss create mode 100644 ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js diff --git a/ui/app/components/button/button.component.js b/ui/app/components/button/button.component.js index 4a06333e76b9..5c617585d95b 100644 --- a/ui/app/components/button/button.component.js +++ b/ui/app/components/button/button.component.js @@ -22,7 +22,11 @@ export default class Button extends Component { type: PropTypes.string, large: PropTypes.bool, className: PropTypes.string, - children: PropTypes.oneOfType([PropTypes.string, PropTypes.node]), + children: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.array, + PropTypes.element, + ]), } render () { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js new file mode 100644 index 000000000000..7510428719e0 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -0,0 +1,22 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import GasPriceButtonGroup from '../../gas-price-button-group' + +export default class BasicTabContent extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + gasPriceButtonGroupProps: PropTypes.object, + } + + render () { + return ( +
+
Suggest gas fee increases
+ +
+ ) + } +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js new file mode 100644 index 000000000000..078d50fce1b8 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.js @@ -0,0 +1 @@ +export { default } from './basic-tab-content.component' diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss new file mode 100644 index 000000000000..ba665716cbc8 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss @@ -0,0 +1,11 @@ +.basic-tab-content { + display: flex; + flex-direction: column; + align-items: center; + + &__title { + margin-top: 19px; + font-size: 20px; + color: $scorpion; + } +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js new file mode 100644 index 000000000000..0c9c6ac63383 --- /dev/null +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -0,0 +1,71 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import BasicTabContent from '../basic-tab-content.component' + +import GasPriceButtonGroup from '../../../gas-price-button-group/' + +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), + noButtonActiveByDefault: true, + showCheck: true, +} + +describe('BasicTabContent Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow() + }) + + describe('render', () => { + it('should have a title', () => { + assert(wrapper.find('.basic-tab-content').childAt(0).hasClass('basic-tab-content__title')) + }) + + it('should render a GasPriceButtonGroup compenent', () => { + assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) + }) + + it('should pass correct props to GasPriceButtonGroup', () => { + const { + buttonDataLoading, + className, + gasButtonInfo, + handleGasPriceSelection, + noButtonActiveByDefault, + showCheck, + } = wrapper.find(GasPriceButtonGroup).props() + assert.equal(buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading) + assert.equal(className, mockGasPriceButtonGroupProps.className) + assert.equal(noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault) + assert.equal(showCheck, mockGasPriceButtonGroupProps.showCheck) + assert.deepEqual(gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo) + assert.equal(JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection)) + }) + }) +}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index e47ebaf6575c..9a0070b2a115 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import PageContainer from '../../page-container' import { Tabs, Tab } from '../../tabs' import AdvancedTabContent from './advanced-tab-content' +import BasicTabContent from './basic-tab-content' export default class GasModalPageContainer extends Component { static contextTypes = { @@ -15,13 +16,14 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit: PropTypes.func, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + gasPriceButtonGroupProps: PropTypes.object, } state = {} renderBasicTabContent () { return ( -
+ ) } @@ -63,7 +65,7 @@ export default class GasModalPageContainer extends Component { renderTabContent (mainTabContent) { return (
- { mainTabContent() } + { mainTabContent } { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') }
@@ -74,10 +76,10 @@ export default class GasModalPageContainer extends Component { return ( - { this.renderTabContent(this.renderBasicTabContent) } + { this.renderTabContent(this.renderBasicTabContent()) } - { this.renderTabContent(this.renderAdvancedTabContent) } + { this.renderTabContent(this.renderAdvancedTabContent()) } ) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index f7ac91a3811d..2354d578cbb6 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -10,10 +10,39 @@ import { getCustomGasLimit, } from '../../../selectors/custom-gas' +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), + noButtonActiveByDefault: true, + showCheck: true, +} + const mapStateToProps = state => { return { customGasPrice: getCustomGasPrice(state), customGasLimit: getCustomGasLimit(state), + gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index ff512537e386..427b58888ad9 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -1,4 +1,5 @@ @import './advanced-tab-content/index'; +@import './basic-tab-content/index'; .gas-modal-page-container { .page-container { @@ -12,7 +13,7 @@ } - .info-row, .info-row--fade { + &__info-row, &__info-row--fade { width: 100%; background: $polar; padding: 15px 21px; @@ -51,5 +52,7 @@ &__info-row--fade { background: white; color: $dusty-gray; + border-top: 1px solid $mischka; + margin-top: 22px; } -} \ No newline at end of file +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 8bf72647afb4..86286b615ab4 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -5,12 +5,43 @@ import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' import PageContainer from '../../../page-container' +import BasicTabContent from '../basic-tab-content' +import AdvancedTabContent from '../advanced-tab-content' + import { Tab } from '../../../tabs' const propsMethodSpies = { hideModal: sinon.spy(), } +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: 'mockSelectionFunction', + noButtonActiveByDefault: true, + showCheck: true, +} + describe('GasModalPageContainer Component', function () { let wrapper @@ -21,6 +52,7 @@ describe('GasModalPageContainer Component', function () { updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} customGasPrice={21} customGasLimit={54321} + gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -90,8 +122,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(GP.renderTabContent.callCount, 2) - assert.deepEqual(GP.renderTabContent.firstCall.args, [wrapper.instance().renderBasicTabContent]) - assert.deepEqual(GP.renderTabContent.secondCall.args, [wrapper.instance().renderAdvancedTabContent]) + assert.equal(GP.renderTabContent.firstCall.args.type, BasicTabContent.type) + assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type) GP.renderTabContent.restore() }) @@ -104,8 +136,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(renderedTabContent.props().className, 'gas-modal-content') }) - it('should render the element returned by the passed func as its first child', () => { - const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) + it('should render the passed element as its first child', () => { + const renderTabContentResult = wrapper.instance().renderTabContent(Mock content) const renderedTabContent = shallow(renderTabContentResult) assert(renderedTabContent.childAt(0).equals(Mock content)) }) @@ -145,8 +177,11 @@ describe('GasModalPageContainer Component', function () { describe('renderBasicTabContent', () => { it('should render', () => { const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() - const renderedBasicTabContent = shallow(renderBasicTabContentResult) - assert.equal(renderedBasicTabContent.props().className, 'gas-modal-content__basic-tab') + + assert.deepEqual( + renderBasicTabContentResult.props.gasPriceButtonGroupProps, + mockGasPriceButtonGroupProps + ) }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 5b133fbe24f2..119ae640b3c5 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -2,26 +2,45 @@ import assert from 'assert' import proxyquire from 'proxyquire' import sinon from 'sinon' -// let mapStateToProps +let mapStateToProps let mapDispatchToProps const actionSpies = { hideModal: sinon.spy(), } +const customGasActionSpies = { + setCustomGasPrice: sinon.spy(), + setCustomGasLimit: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { connect: (ms, md) => { - // mapStateToProps = ms + mapStateToProps = ms mapDispatchToProps = md return () => ({}) }, }, + '../../../selectors/custom-gas': { + getCustomGasPrice: (s) => `mockGasPrice:${s}`, + getCustomGasLimit: (s) => `mockGasLimit:${s}`, + }, '../../../actions': actionSpies, + '../../../ducks/custom-gas': customGasActionSpies, }) describe('gas-modal-page-container container', () => { + describe('mapStateToProps()', () => { + + it('should map the correct properties to props', () => { + assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState') + assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState') + }) + + }) + describe('mapDispatchToProps()', () => { let dispatchSpy let mapDispatchToPropsObject @@ -39,6 +58,22 @@ describe('gas-modal-page-container container', () => { }) }) + describe('updateCustomGasPrice()', () => { + it('should dispatch a setCustomGasPrice action', () => { + mapDispatchToPropsObject.updateCustomGasPrice() + assert(dispatchSpy.calledOnce) + assert(customGasActionSpies.setCustomGasPrice.calledOnce) + }) + }) + + describe('updateCustomGasLimit()', () => { + it('should dispatch a setCustomGasLimit action', () => { + mapDispatchToPropsObject.updateCustomGasLimit() + assert(dispatchSpy.calledOnce) + assert(customGasActionSpies.setCustomGasLimit.calledOnce) + }) + }) + }) }) diff --git a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js new file mode 100644 index 000000000000..3873f54bc030 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js @@ -0,0 +1,85 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' +import ButtonGroup from '../../button-group' +import Button from '../../button' + +const GAS_OBJECT_PROPTYPES_SHAPE = { + label: PropTypes.string, + feeInPrimaryCurrency: PropTypes.string, + feeInSecondaryCurrency: PropTypes.string, + timeEstimate: PropTypes.string, + priceInHexWei: PropTypes.string, +} + +export default class GasPriceButtonGroup extends Component { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + buttonDataLoading: PropTypes.bool, + className: PropTypes.string, + defaultActiveButtonIndex: PropTypes.number, + gasButtonInfo: PropTypes.arrayOf(PropTypes.shape(GAS_OBJECT_PROPTYPES_SHAPE)), + handleGasPriceSelection: PropTypes.func, + noButtonActiveByDefault: PropTypes.bool, + showCheck: PropTypes.bool, + } + + renderButtonContent ({ + label, + feeInPrimaryCurrency, + feeInSecondaryCurrency, + timeEstimate, + }, { + className, + showCheck, + }) { + return (
+ { label &&
{ label }
} + { feeInPrimaryCurrency &&
{ feeInPrimaryCurrency }
} + { feeInSecondaryCurrency &&
{ feeInSecondaryCurrency }
} + { timeEstimate &&
{ timeEstimate }
} + { showCheck && } +
) + } + + renderButton ({ + priceInHexWei, + ...renderableGasInfo + }, { + buttonDataLoading, + handleGasPriceSelection, + ...buttonContentPropsAndFlags + }, index) { + return ( + + ) + } + + render () { + const { + gasButtonInfo, + defaultActiveButtonIndex = 1, + noButtonActiveByDefault = false, + ...buttonPropsAndFlags + } = this.props + + return ( + + { gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } + + ) + } +} diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.js b/ui/app/components/gas-customization/gas-price-button-group/index.js new file mode 100644 index 000000000000..77564833036b --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/index.js @@ -0,0 +1 @@ +export { default } from './gas-price-button-group.component' diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.scss b/ui/app/components/gas-customization/gas-price-button-group/index.scss new file mode 100644 index 000000000000..e2670edd53d1 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/index.scss @@ -0,0 +1,60 @@ +.gas-price-button-group { + margin-top: 22px; + display: flex; + justify-content: space-evenly; + width: 100%; + padding-left: 20px; + padding-right: 20px; + + &__primary-currency { + font-size: 18px; + height: 20.5px; + margin-bottom: 7.5px; + } + + &__time-estimate { + margin-top: 5.5px; + color: $silver-chalice; + height: 15.4px; + } + + + .button-group__button, .button-group__button--active { + height: 130px; + max-width: 108px; + font-size: 12px; + flex-direction: column; + align-items: center; + display: flex; + padding-top: 17px; + border-radius: 4px; + border: 2px solid $spindle; + background: $white; + color: $scorpion; + + div { + display: flex; + flex-direction: column; + align-items: center; + } + + i { + &:last-child { + display: none; + } + } + } + + .button-group__button--active { + border: 2px solid $curious-blue; + color: $scorpion; + + i { + &:last-child { + display: flex; + color: $curious-blue; + margin-top: 8px + } + } + } +} diff --git a/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js new file mode 100644 index 000000000000..e1458188d087 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js @@ -0,0 +1,238 @@ +import React from 'react' +import assert from 'assert' +import { shallow } from 'enzyme' +import sinon from 'sinon' +import GasPriceButtonGroup from '../gas-price-button-group.component' + +import ButtonGroup from '../../../button-group/' + +const mockGasPriceButtonGroupProps = { + buttonDataLoading: false, + className: 'gas-price-button-group', + gasButtonInfo: [ + { + feeInPrimaryCurrency: '$0.52', + feeInSecondaryCurrency: '0.0048 ETH', + timeEstimate: '~ 1 min 0 sec', + priceInHexWei: '0xa1b2c3f', + }, + { + feeInPrimaryCurrency: '$0.39', + feeInSecondaryCurrency: '0.004 ETH', + timeEstimate: '~ 1 min 30 sec', + priceInHexWei: '0xa1b2c39', + }, + { + feeInPrimaryCurrency: '$0.30', + feeInSecondaryCurrency: '0.00354 ETH', + timeEstimate: '~ 2 min 1 sec', + priceInHexWei: '0xa1b2c30', + }, + ], + handleGasPriceSelection: sinon.spy(), + noButtonActiveByDefault: true, + defaultActiveButtonIndex: 2, + showCheck: true, +} + +const mockButtonPropsAndFlags = Object.assign({}, { + buttonDataLoading: mockGasPriceButtonGroupProps.buttonDataLoading, + className: mockGasPriceButtonGroupProps.className, + handleGasPriceSelection: mockGasPriceButtonGroupProps.handleGasPriceSelection, + showCheck: mockGasPriceButtonGroupProps.showCheck, +}) + +sinon.spy(GasPriceButtonGroup.prototype, 'renderButton') +sinon.spy(GasPriceButtonGroup.prototype, 'renderButtonContent') + +describe('GasPriceButtonGroup Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow() + }) + + afterEach(() => { + GasPriceButtonGroup.prototype.renderButton.resetHistory() + GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() + mockGasPriceButtonGroupProps.handleGasPriceSelection.resetHistory() + }) + + describe('render', () => { + it('should render a ButtonGroup', () => { + assert(wrapper.is(ButtonGroup)) + }) + + it('should render the correct props on the ButtonGroup', () => { + const { + className, + defaultActiveButtonIndex, + noButtonActiveByDefault, + } = wrapper.props() + assert.equal(className, 'gas-price-button-group') + assert.equal(defaultActiveButtonIndex, 2) + assert.equal(noButtonActiveByDefault, true) + }) + + function renderButtonArgsTest (i, mockButtonPropsAndFlags) { + assert.deepEqual( + GasPriceButtonGroup.prototype.renderButton.getCall(i).args, + [ + Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[i]), + mockButtonPropsAndFlags, + i, + ] + ) + } + + it('should called this.renderButton 3 times, with the correct args', () => { + assert.equal(GasPriceButtonGroup.prototype.renderButton.callCount, 3) + renderButtonArgsTest(0, mockButtonPropsAndFlags) + renderButtonArgsTest(1, mockButtonPropsAndFlags) + renderButtonArgsTest(2, mockButtonPropsAndFlags) + }) + }) + + describe('renderButton', () => { + let wrappedRenderButtonResult + + beforeEach(() => { + GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() + const renderButtonResult = GasPriceButtonGroup.prototype.renderButton( + Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[0]), + mockButtonPropsAndFlags + ) + wrappedRenderButtonResult = shallow(renderButtonResult) + }) + + it('should render a button', () => { + assert.equal(wrappedRenderButtonResult.type(), 'button') + }) + + it('should call the correct method when clicked', () => { + assert.equal(mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 0) + wrappedRenderButtonResult.props().onClick() + assert.equal(mockGasPriceButtonGroupProps.handleGasPriceSelection.callCount, 1) + assert.deepEqual( + mockGasPriceButtonGroupProps.handleGasPriceSelection.getCall(0).args, + [mockGasPriceButtonGroupProps.gasButtonInfo[0].priceInHexWei] + ) + }) + + it('should call this.renderButtonContent with the correct args', () => { + assert.equal(GasPriceButtonGroup.prototype.renderButtonContent.callCount, 1) + const { + feeInPrimaryCurrency, + feeInSecondaryCurrency, + timeEstimate, + } = mockGasPriceButtonGroupProps.gasButtonInfo[0] + const { + showCheck, + className, + } = mockGasPriceButtonGroupProps + assert.deepEqual( + GasPriceButtonGroup.prototype.renderButtonContent.getCall(0).args, + [ + { + feeInPrimaryCurrency, + feeInSecondaryCurrency, + timeEstimate, + }, + { + showCheck, + className, + }, + ] + ) + }) + + it('should not call renderButtonContent if buttonDataLoading is true and should show a loading indicator', () => { + GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() + const renderButtonResult = GasPriceButtonGroup.prototype.renderButton( + Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[0]), + Object.assign({}, mockButtonPropsAndFlags, {buttonDataLoading: true}) + ) + wrappedRenderButtonResult = shallow(renderButtonResult) + assert.equal(GasPriceButtonGroup.prototype.renderButtonContent.callCount, 0) + assert.equal(wrappedRenderButtonResult.childAt(0).text(), 'Loading...') + }) + }) + + describe('renderButtonContent', () => { + it('should render a label if passed a label', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + label: 'mockLabel', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabel') + }) + + it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__primary-currency').text(), 'mockFeeInPrimaryCurrency') + }) + + it('should render a feeInSecondaryCurrency if passed a feeInSecondaryCurrency', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__secondary-currency').text(), 'mockFeeInSecondaryCurrency') + }) + + it('should render a timeEstimate if passed a timeEstimate', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + timeEstimate: 'mockTimeEstimate', + }, { + className: 'someClass', + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) + assert.equal(wrappedRenderButtonContentResult.find('.someClass__time-estimate').text(), 'mockTimeEstimate') + }) + + it('should render a check if showCheck is true', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({}, { + className: 'someClass', + showCheck: true, + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.find('.fa-check').length, 1) + }) + + it('should render all elements if all args passed', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ + label: 'mockLabel', + feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', + feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', + timeEstimate: 'mockTimeEstimate', + }, { + className: 'someClass', + showCheck: true, + }) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.children().length, 5) + }) + + + it('should render no elements if all args passed', () => { + const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({}, {}) + const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) + assert.equal(wrappedRenderButtonContentResult.children().length, 0) + }) + }) +}) diff --git a/ui/app/components/index.scss b/ui/app/components/index.scss index 156b1b9f6c1a..78c1216f7c2f 100644 --- a/ui/app/components/index.scss +++ b/ui/app/components/index.scss @@ -71,3 +71,5 @@ @import './gas-customization/gas-modal-page-container/index'; @import './gas-customization/index'; + +@import './gas-customization/gas-price-button-group/index'; diff --git a/ui/app/css/itcss/settings/variables.scss b/ui/app/css/itcss/settings/variables.scss index 1c95f06a03d1..42a8655df15f 100644 --- a/ui/app/css/itcss/settings/variables.scss +++ b/ui/app/css/itcss/settings/variables.scss @@ -58,6 +58,7 @@ $linen: #fdf4f4; $oslo-gray: #8C8E94; $polar: #fafcfe; $blizzard-blue: #bfdef3; +$mischka: #dddee9; /* Z-Indicies From 0a7dfcd55d02a7204d8f0773ff9d91f325aabea8 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 16 Aug 2018 09:58:27 -0230 Subject: [PATCH 10/64] Connect the gas-button-group component to redux and a live api. --- .../button-group/button-group.component.js | 5 +- .../basic-tab-content.component.js | 8 +- .../gas-modal-page-container.component.js | 4 +- .../gas-modal-page-container.container.js | 39 +--- ...gas-modal-page-container-container.test.js | 6 +- .../gas-customization/gas.selectors.js | 14 ++ ui/app/components/send/send.component.js | 4 + ui/app/components/send/send.container.js | 4 + .../send/tests/send-component.test.js | 12 ++ ui/app/ducks/custom-gas.js | 67 ------- ui/app/ducks/gas.duck.js | 189 ++++++++++++++++++ ui/app/helpers/confirm-transaction/util.js | 2 +- ui/app/reducers.js | 4 +- ui/app/selectors/custom-gas.js | 186 ++++++++++++++++- ui/app/selectors/tests/custom-gas.test.js | 140 +++++++++++++ 15 files changed, 573 insertions(+), 111 deletions(-) create mode 100644 ui/app/components/gas-customization/gas.selectors.js delete mode 100644 ui/app/ducks/custom-gas.js create mode 100644 ui/app/ducks/gas.duck.js create mode 100644 ui/app/selectors/tests/custom-gas.test.js diff --git a/ui/app/components/button-group/button-group.component.js b/ui/app/components/button-group/button-group.component.js index f99f710ce1b3..905bbe9d2691 100644 --- a/ui/app/components/button-group/button-group.component.js +++ b/ui/app/components/button-group/button-group.component.js @@ -5,6 +5,7 @@ import classnames from 'classnames' export default class ButtonGroup extends PureComponent { static propTypes = { defaultActiveButtonIndex: PropTypes.number, + noButtonActiveByDefault: PropTypes.bool, disabled: PropTypes.bool, children: PropTypes.array, className: PropTypes.string, @@ -16,7 +17,9 @@ export default class ButtonGroup extends PureComponent { } state = { - activeButtonIndex: this.props.defaultActiveButtonIndex || 0, + activeButtonIndex: this.props.noButtonActiveByDefault + ? null + : this.props.defaultActiveButtonIndex || 0, } handleButtonClick (activeButtonIndex) { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js index 7510428719e0..99ef28b5ed8a 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -15,7 +15,13 @@ export default class BasicTabContent extends Component { return (
Suggest gas fee increases
- + console.log('New Price:', newPrice)} + />
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 9a0070b2a115..399520baf51b 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -23,7 +23,9 @@ export default class GasModalPageContainer extends Component { renderBasicTabContent () { return ( - + ) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 2354d578cbb6..ebdd035ea912 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -4,45 +4,23 @@ import { hideModal } from '../../../actions' import { setCustomGasPrice, setCustomGasLimit, -} from '../../../ducks/custom-gas' +} from '../../../ducks/gas.duck' import { getCustomGasPrice, getCustomGasLimit, + getRenderableBasicEstimateData, + getBasicGasEstimateLoadingStatus, } from '../../../selectors/custom-gas' -const mockGasPriceButtonGroupProps = { - buttonDataLoading: false, - className: 'gas-price-button-group', - gasButtonInfo: [ - { - feeInPrimaryCurrency: '$0.52', - feeInSecondaryCurrency: '0.0048 ETH', - timeEstimate: '~ 1 min 0 sec', - priceInHexWei: '0xa1b2c3f', - }, - { - feeInPrimaryCurrency: '$0.39', - feeInSecondaryCurrency: '0.004 ETH', - timeEstimate: '~ 1 min 30 sec', - priceInHexWei: '0xa1b2c39', - }, - { - feeInPrimaryCurrency: '$0.30', - feeInSecondaryCurrency: '0.00354 ETH', - timeEstimate: '~ 2 min 1 sec', - priceInHexWei: '0xa1b2c30', - }, - ], - handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), - noButtonActiveByDefault: true, - showCheck: true, -} - const mapStateToProps = state => { + const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) return { customGasPrice: getCustomGasPrice(state), customGasLimit: getCustomGasLimit(state), - gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, + gasPriceButtonGroupProps: { + buttonDataLoading, + gasButtonInfo: getRenderableBasicEstimateData(state), + }, } } @@ -51,6 +29,7 @@ const mapDispatchToProps = dispatch => { hideModal: () => dispatch(hideModal()), updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)), updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)), + handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 119ae640b3c5..4067265b5247 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -25,9 +25,11 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../selectors/custom-gas': { getCustomGasPrice: (s) => `mockGasPrice:${s}`, getCustomGasLimit: (s) => `mockGasLimit:${s}`, + getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`, + getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${s}`, }, '../../../actions': actionSpies, - '../../../ducks/custom-gas': customGasActionSpies, + '../../../ducks/gas.duck': customGasActionSpies, }) describe('gas-modal-page-container container', () => { @@ -37,6 +39,8 @@ describe('gas-modal-page-container container', () => { it('should map the correct properties to props', () => { assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState') assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState') + assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.buttonDataLoading, 'mockBasicGasEstimateLoadingStatus:mockState') + assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.gasButtonInfo, 'mockRenderableBasicEstimateData:mockState') }) }) diff --git a/ui/app/components/gas-customization/gas.selectors.js b/ui/app/components/gas-customization/gas.selectors.js new file mode 100644 index 000000000000..89374b5f1beb --- /dev/null +++ b/ui/app/components/gas-customization/gas.selectors.js @@ -0,0 +1,14 @@ +const selectors = { + getCurrentBlockTime, + getBasicGasEstimateLoadingStatus, +} + +module.exports = selectors + +function getCurrentBlockTime (state) { + return state.gas.currentBlockTime +} + +function getBasicGasEstimateLoadingStatus (state) { + return state.gas.basicEstimateIsLoading +} diff --git a/ui/app/components/send/send.component.js b/ui/app/components/send/send.component.js index a27401f30b87..a639c24b0e0a 100644 --- a/ui/app/components/send/send.component.js +++ b/ui/app/components/send/send.component.js @@ -162,6 +162,10 @@ export default class SendTransactionScreen extends PersistentForm { } } + componentDidMount () { + this.props.fetchGasEstimates() + } + componentWillMount () { const { from: { address }, diff --git a/ui/app/components/send/send.container.js b/ui/app/components/send/send.container.js index 87056499f491..a00fb3545c04 100644 --- a/ui/app/components/send/send.container.js +++ b/ui/app/components/send/send.container.js @@ -36,6 +36,9 @@ import { resetSendState, updateSendErrors, } from '../../ducks/send.duck' +import { + fetchGasEstimates, +} from '../../ducks/gas.duck' import { calcGasTotal, } from './send.utils.js' @@ -104,5 +107,6 @@ function mapDispatchToProps (dispatch) { scanQrCode: () => dispatch(showQrScanner(SEND_ROUTE)), qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)), + fetchGasEstimates: () => dispatch(fetchGasEstimates()), } } diff --git a/ui/app/components/send/tests/send-component.test.js b/ui/app/components/send/tests/send-component.test.js index bd136a0b8ade..0f3902c07ef6 100644 --- a/ui/app/components/send/tests/send-component.test.js +++ b/ui/app/components/send/tests/send-component.test.js @@ -13,6 +13,7 @@ const propsMethodSpies = { updateSendErrors: sinon.spy(), updateSendTokenBalance: sinon.spy(), resetSendState: sinon.spy(), + fetchGasEstimates: sinon.spy(), } const utilsMethodStubs = { getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }), @@ -37,6 +38,7 @@ describe('Send Component', function () { blockGasLimit={'mockBlockGasLimit'} conversionRate={10} editingTransactionId={'mockEditingTransactionId'} + fetchGasEstimates={propsMethodSpies.fetchGasEstimates} from={ { address: 'mockAddress', balance: 'mockBalance' } } gasLimit={'mockGasLimit'} gasPrice={'mockGasPrice'} @@ -63,6 +65,7 @@ describe('Send Component', function () { utilsMethodStubs.doesAmountErrorRequireUpdate.resetHistory() utilsMethodStubs.getAmountErrorObject.resetHistory() utilsMethodStubs.getGasFeeErrorObject.resetHistory() + propsMethodSpies.fetchGasEstimates.resetHistory() propsMethodSpies.updateAndSetGasTotal.resetHistory() propsMethodSpies.updateSendErrors.resetHistory() propsMethodSpies.updateSendTokenBalance.resetHistory() @@ -82,6 +85,15 @@ describe('Send Component', function () { }) }) + describe('componentDidMount', () => { + it('should call props.fetchGasEstimates', () => { + propsMethodSpies.fetchGasEstimates.resetHistory() + assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0) + wrapper.instance().componentDidMount() + assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1) + }) + }) + describe('componentWillUnmount', () => { it('should call this.props.resetSendState', () => { propsMethodSpies.resetSendState.resetHistory() diff --git a/ui/app/ducks/custom-gas.js b/ui/app/ducks/custom-gas.js deleted file mode 100644 index f1f483e9304e..000000000000 --- a/ui/app/ducks/custom-gas.js +++ /dev/null @@ -1,67 +0,0 @@ -import extend from 'xtend' - -// Actions -const SET_CUSTOM_GAS_PRICE = 'metamask/custom-gas/SET_CUSTOM_GAS_PRICE' -const SET_CUSTOM_GAS_LIMIT = 'metamask/custom-gas/SET_CUSTOM_GAS_LIMIT' -const SET_CUSTOM_GAS_ERRORS = 'metamask/custom-gas/SET_CUSTOM_GAS_ERRORS' -const RESET_CUSTOM_GAS_STATE = 'metamask/custom-gas/RESET_CUSTOM_GAS_STATE' - -// TODO: determine if this approach to initState is consistent with conventional ducks pattern -const initState = { - price: 0, - limit: 21000, - errors: {}, -} - -// Reducer -export default function reducer ({ customGas: customGasState = initState }, action = {}) { - const newState = extend({}, customGasState) - - switch (action.type) { - case SET_CUSTOM_GAS_PRICE: - return extend(newState, { - price: action.value, - }) - case SET_CUSTOM_GAS_LIMIT: - return extend(newState, { - limit: action.value, - }) - case SET_CUSTOM_GAS_ERRORS: - return extend(newState, { - errors: { - ...newState.errors, - ...action.value, - }, - }) - case RESET_CUSTOM_GAS_STATE: - return extend({}, initState) - default: - return newState - } -} - -// Action Creators -export function setCustomGasPrice (newPrice) { - return { - type: SET_CUSTOM_GAS_PRICE, - value: newPrice, - } -} - -export function setCustomGasLimit (newLimit) { - return { - type: SET_CUSTOM_GAS_LIMIT, - value: newLimit, - } -} - -export function setCustomGasErrors (newErrors) { - return { - type: SET_CUSTOM_GAS_ERRORS, - value: newErrors, - } -} - -export function resetCustomGasState () { - return { type: RESET_CUSTOM_GAS_STATE } -} diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js new file mode 100644 index 000000000000..8b2fbcfdbb28 --- /dev/null +++ b/ui/app/ducks/gas.duck.js @@ -0,0 +1,189 @@ +import { clone } from 'ramda' + +// Actions +const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' +const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' +const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' +const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' +const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' +const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' +const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' +const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' + +// TODO: determine if this approach to initState is consistent with conventional ducks pattern +const initState = { + customData: { + price: 0, + limit: 21000, + }, + basicEstimates: { + average: null, + fastestWait: null, + fastWait: null, + fast: null, + safeLowWait: null, + blockNum: null, + avgWait: null, + blockTime: null, + speed: null, + fastest: null, + safeLow: null, + }, + basicEstimateIsLoading: true, + errors: {}, +} + +// Reducer +export default function reducer ({ gas: gasState = initState }, action = {}) { + const newState = clone(gasState) + + switch (action.type) { + case BASIC_GAS_ESTIMATE_LOADING_STARTED: + return { + ...newState, + basicEstimateIsLoading: true, + } + case BASIC_GAS_ESTIMATE_LOADING_FINISHED: + return { + ...newState, + basicEstimateIsLoading: false, + } + case SET_BASIC_GAS_ESTIMATE_DATA: + return { + ...newState, + basicEstimates: action.value, + } + case SET_CUSTOM_GAS_PRICE: + return { + ...newState, + customData: { + ...newState.customData, + price: action.value, + }, + } + case SET_CUSTOM_GAS_LIMIT: + return { + ...newState, + customData: { + ...newState.customData, + limit: action.value, + }, + } + case SET_CUSTOM_GAS_TOTAL: + return { + ...newState, + customData: { + ...newState.customData, + total: action.value, + }, + } + case SET_CUSTOM_GAS_ERRORS: + return { + ...newState, + errors: { + ...newState.errors, + ...action.value, + }, + } + case RESET_CUSTOM_GAS_STATE: + return clone(initState) + default: + return newState + } +} + +// Action Creators +export function basicGasEstimatesLoadingStarted () { + return { + type: BASIC_GAS_ESTIMATE_LOADING_STARTED, + } +} + +export function basicGasEstimatesLoadingFinished () { + return { + type: BASIC_GAS_ESTIMATE_LOADING_FINISHED, + } +} + +export function fetchGasEstimates () { + return (dispatch) => { + dispatch(basicGasEstimatesLoadingStarted()) + + return fetch('https://ethgasstation.info/json/ethgasAPI.json', { + 'headers': {}, + 'referrer': 'http://ethgasstation.info/json/', + 'referrerPolicy': 'no-referrer-when-downgrade', + 'body': null, + 'method': 'GET', + 'mode': 'cors'} + ) + .then(r => r.json()) + .then(({ + average, + avgWait, + block_time: blockTime, + blockNum, + fast, + fastest, + fastestWait, + fastWait, + safeLow, + safeLowWait, + speed, + }) => { + dispatch(setBasicGasEstimateData({ + average, + avgWait, + blockTime, + blockNum, + fast, + fastest, + fastestWait, + fastWait, + safeLow, + safeLowWait, + speed, + })) + dispatch(basicGasEstimatesLoadingFinished()) + }) + } +} + +export function setBasicGasEstimateData (basicGasEstimateData) { + return { + type: SET_BASIC_GAS_ESTIMATE_DATA, + value: basicGasEstimateData, + } +} + +export function setCustomGasPrice (newPrice) { + return { + type: SET_CUSTOM_GAS_PRICE, + value: newPrice, + } +} + +export function setCustomGasLimit (newLimit) { + return { + type: SET_CUSTOM_GAS_LIMIT, + value: newLimit, + } +} + +export function setCustomGasTotal (newTotal) { + return { + type: SET_CUSTOM_GAS_TOTAL, + value: newTotal, + } +} + +export function setCustomGasErrors (newErrors) { + return { + type: SET_CUSTOM_GAS_ERRORS, + value: newErrors, + } +} + +export function resetCustomGasState () { + return { type: RESET_CUSTOM_GAS_STATE } +} diff --git a/ui/app/helpers/confirm-transaction/util.js b/ui/app/helpers/confirm-transaction/util.js index eb334a4b8271..0451824e8bfa 100644 --- a/ui/app/helpers/confirm-transaction/util.js +++ b/ui/app/helpers/confirm-transaction/util.js @@ -95,7 +95,7 @@ export function formatCurrency (value, currencyCode) { const upperCaseCurrencyCode = currencyCode.toUpperCase() return currencies.find(currency => currency.code === upperCaseCurrencyCode) - ? currencyFormatter.format(Number(value), { code: upperCaseCurrencyCode }) + ? currencyFormatter.format(Number(value), { code: upperCaseCurrencyCode, style: 'currency' }) : value } diff --git a/ui/app/reducers.js b/ui/app/reducers.js index 7234c3c02c10..786af853de05 100644 --- a/ui/app/reducers.js +++ b/ui/app/reducers.js @@ -10,7 +10,7 @@ const reduceApp = require('./reducers/app') const reduceLocale = require('./reducers/locale') const reduceSend = require('./ducks/send.duck').default import reduceConfirmTransaction from './ducks/confirm-transaction.duck' -import reduceCustomGas from './ducks/custom-gas' +import reduceGas from './ducks/gas.duck' window.METAMASK_CACHED_LOG_STATE = null @@ -50,7 +50,7 @@ function rootReducer (state, action) { state.confirmTransaction = reduceConfirmTransaction(state, action) - state.customGas = reduceCustomGas(state, action) + state.gas = reduceGas(state, action) window.METAMASK_CACHED_LOG_STATE = state return state diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 97280190fbe4..ff2fd0e0565a 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -1,19 +1,191 @@ +import { pipe, partialRight } from 'ramda' +import { + getConversionRate, + getGasLimit, +} from '../components/send/send.selectors' +import { + conversionUtil, + multiplyCurrencies, +} from '../conversion-util' +import { + getCurrentCurrency, +} from '../selectors' +import { + formatCurrency, +} from '../helpers/confirm-transaction/util' +import { + calcGasTotal, +} from '../components/send/send.utils' +import { addHexPrefix } from 'ethereumjs-util' + const selectors = { - getCustomGasPrice, - getCustomGasLimit, getCustomGasErrors, + getCustomGasLimit, + getCustomGasPrice, + getCustomGasTotal, + getRenderableBasicEstimateData, + getBasicGasEstimateLoadingStatus, } module.exports = selectors -function getCustomGasPrice (state) { - return state.customGas.price +function getCustomGasErrors (state) { + return state.gas.errors } function getCustomGasLimit (state) { - return state.customGas.limit + return state.gas.customData.limit } -function getCustomGasErrors (state) { - return state.customGas.errors +function getCustomGasPrice (state) { + return state.gas.customData.price +} + +function getCustomGasTotal (state) { + return state.gas.customData.total +} + +function getBasicGasEstimateLoadingStatus (state) { + return state.gas.basicEstimateIsLoading +} + + +function apiEstimateModifiedToGWEI (estimate) { + return multiplyCurrencies(estimate, 0.10, { + toNumericBase: 'hex', + multiplicandBase: 10, + multiplierBase: 10, + numberOfDecimals: 9, + }) +} + +function basicPriceEstimateToETHTotal (estimate, gasLimit) { + return conversionUtil(calcGasTotal(gasLimit, estimate), { + fromNumericBase: 'hex', + toNumericBase: 'dec', + fromDenomination: 'GWEI', + numberOfDecimals: 9, + }) +} + +function ethTotalToConvertedCurrency (ethTotal, convertedCurrency, conversionRate) { + return conversionUtil(ethTotal, { + fromNumericBase: 'dec', + toNumericBase: 'dec', + fromCurrency: 'ETH', + toCurrency: convertedCurrency, + numberOfDecimals: 2, + conversionRate, + }) +} + +function formatETHFee (ethFee) { + return ethFee + ' ETH' +} + +function getRenderableEthFee (estimate, gasLimit) { + return pipe( + apiEstimateModifiedToGWEI, + partialRight(basicPriceEstimateToETHTotal, [gasLimit]), + formatETHFee + )(estimate, gasLimit) +} + +function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) { + return pipe( + apiEstimateModifiedToGWEI, + partialRight(basicPriceEstimateToETHTotal, [gasLimit]), + partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]), + partialRight(formatCurrency, [convertedCurrency]) + )(estimate, gasLimit, convertedCurrency, conversionRate) +} + +function getTimeEstimateInSeconds (blockWaitEstimate, currentBlockTime) { + return multiplyCurrencies(blockWaitEstimate, currentBlockTime, { + toNumericBase: 'dec', + multiplicandBase: 10, + multiplierBase: 10, + numberOfDecimals: 1, + }) +} + +function formatTimeEstimate (totalSeconds) { + const minutes = Math.floor(totalSeconds / 60) + const seconds = Math.floor(totalSeconds % 60) + const formattedMin = `${minutes ? minutes + ' min' : ''}` + const formattedSec = `${seconds ? seconds + ' sec' : ''}` + const formattedCombined = formattedMin && formattedSec + ? `~${formattedMin} ${formattedSec}` + : '~' + [formattedMin, formattedSec].find(t => t) + + return formattedCombined +} + +function getRenderableTimeEstimate (blockWaitEstimate, currentBlockTime) { + return pipe( + getTimeEstimateInSeconds, + formatTimeEstimate + )(blockWaitEstimate, currentBlockTime) +} + +function priceEstimateToWei (priceEstimate) { + return conversionUtil(priceEstimate, { + fromNumericBase: 'hex', + toNumericBase: 'hex', + fromDenomination: 'GWEI', + toDenomination: 'WEI', + numberOfDecimals: 9, + }) +} + +function getGasPriceInHexWei (price) { + return pipe( + apiEstimateModifiedToGWEI, + priceEstimateToWei, + addHexPrefix + )(price) +} + +function getRenderableBasicEstimateData (state) { + if (getBasicGasEstimateLoadingStatus(state)) { + return [] + } + + const gasLimit = getGasLimit(state) + const conversionRate = getConversionRate(state) + const currentCurrency = getCurrentCurrency(state) + const { + gas: { + basicEstimates: { + safeLow, + average, + fast, + blockTime, + safeLowWait, + avgWait, + fastWait, + }, + }, + } = state + + return [ + { + feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), + feeInSecondaryCurrency: getRenderableEthFee(fast, gasLimit), + timeEstimate: getRenderableTimeEstimate(fastWait, blockTime), + priceInHexWei: getGasPriceInHexWei(fast), + }, + { + feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate), + feeInSecondaryCurrency: getRenderableEthFee(average, gasLimit), + timeEstimate: getRenderableTimeEstimate(avgWait, blockTime), + priceInHexWei: getGasPriceInHexWei(average), + }, + { + feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), + feeInSecondaryCurrency: getRenderableEthFee(safeLow, gasLimit), + timeEstimate: getRenderableTimeEstimate(safeLowWait, blockTime), + priceInHexWei: getGasPriceInHexWei(safeLow), + }, + ] } diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js new file mode 100644 index 000000000000..d53c1ec9886d --- /dev/null +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -0,0 +1,140 @@ +import assert from 'assert' +import proxyquire from 'proxyquire' + +const { + getCustomGasErrors, + getCustomGasLimit, + getCustomGasPrice, + getCustomGasTotal, + getRenderableBasicEstimateData, +} = proxyquire('../custom-gas', {}) + +describe('custom-gas selectors', () => { + + describe('getCustomGasPrice()', () => { + it('should return gas.customData.price', () => { + const mockState = { gas: { customData: { price: 'mockPrice' } } } + assert.equal(getCustomGasPrice(mockState), 'mockPrice') + }) + }) + + describe('getCustomGasLimit()', () => { + it('should return gas.customData.limit', () => { + const mockState = { gas: { customData: { limit: 'mockLimit' } } } + assert.equal(getCustomGasLimit(mockState), 'mockLimit') + }) + }) + + describe('getCustomGasTotal()', () => { + it('should return gas.customData.total', () => { + const mockState = { gas: { customData: { total: 'mockTotal' } } } + assert.equal(getCustomGasTotal(mockState), 'mockTotal') + }) + }) + + describe('getCustomGasErrors()', () => { + it('should return gas.errors', () => { + const mockState = { gas: { errors: 'mockErrors' } } + assert.equal(getCustomGasErrors(mockState), 'mockErrors') + }) + }) + + describe('getRenderableBasicEstimateData()', () => { + const tests = [ + { + expectedResult: [ + { + feeInPrimaryCurrency: '$0.05', + feeInSecondaryCurrency: '0.00021 ETH', + timeEstimate: '~7 sec', + priceInHexWei: '0x2540be400', + }, + { + feeInPrimaryCurrency: '$0.03', + feeInSecondaryCurrency: '0.000105 ETH', + timeEstimate: '~46 sec', + priceInHexWei: '0x12a05f200', + }, + { + feeInPrimaryCurrency: '$0.01', + feeInSecondaryCurrency: '0.0000525 ETH', + timeEstimate: '~1 min 33 sec', + priceInHexWei: '0x9502f900', + }, + ], + mockState: { + metamask: { + conversionRate: 255.71, + currentCurrency: 'usd', + send: { + gasLimit: '0x5208', + }, + }, + gas: { + basicEstimates: { + blockTime: 14.16326530612245, + safeLow: 25, + safeLowWait: 6.6, + average: 50, + avgWait: 3.3, + fast: 100, + fastWait: 0.5, + }, + }, + }, + }, + { + expectedResult: [ + { + feeInPrimaryCurrency: '$1.07', + feeInSecondaryCurrency: '0.00042 ETH', + timeEstimate: '~14 sec', + priceInHexWei: '0x4a817c800', + }, + { + feeInPrimaryCurrency: '$0.54', + feeInSecondaryCurrency: '0.00021 ETH', + timeEstimate: '~1 min 33 sec', + priceInHexWei: '0x2540be400', + }, + { + feeInPrimaryCurrency: '$0.27', + feeInSecondaryCurrency: '0.000105 ETH', + timeEstimate: '~3 min 7 sec', + priceInHexWei: '0x12a05f200', + }, + ], + mockState: { + metamask: { + conversionRate: 2557.1, + currentCurrency: 'usd', + send: { + gasLimit: '0x5208', + }, + }, + gas: { + basicEstimates: { + blockTime: 14.16326530612245, + safeLow: 50, + safeLowWait: 13.2, + average: 100, + avgWait: 6.6, + fast: 200, + fastWait: 1.0, + }, + }, + }, + }, + ] + it('should return renderable data about basic estimates', () => { + tests.forEach(test => { + assert.deepEqual( + getRenderableBasicEstimateData(test.mockState), + test.expectedResult + ) + }) + }) + + }) + +}) From d07d40cf7cf013bd9b9968fa6bc37bcfd1367cf9 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Sun, 9 Sep 2018 13:48:34 -0230 Subject: [PATCH 11/64] Improvements to propdefaults in button-group.component and basic-tab-content.component --- ui/app/components/button-group/button-group.component.js | 3 ++- .../basic-tab-content/basic-tab-content.component.js | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/ui/app/components/button-group/button-group.component.js b/ui/app/components/button-group/button-group.component.js index 905bbe9d2691..440b3c4f78aa 100644 --- a/ui/app/components/button-group/button-group.component.js +++ b/ui/app/components/button-group/button-group.component.js @@ -14,12 +14,13 @@ export default class ButtonGroup extends PureComponent { static defaultProps = { className: 'button-group', + defaultActiveButtonIndex: 0, } state = { activeButtonIndex: this.props.noButtonActiveByDefault ? null - : this.props.defaultActiveButtonIndex || 0, + : this.props.defaultActiveButtonIndex, } handleButtonClick (activeButtonIndex) { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js index 99ef28b5ed8a..164da4a32db5 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -16,11 +16,11 @@ export default class BasicTabContent extends Component {
Suggest gas fee increases
console.log('New Price:', newPrice)} + {...this.props.gasPriceButtonGroupProps} />
) From 58feb24fa72bac5c79daa96956810dd2233adf02 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Sun, 9 Sep 2018 15:17:49 -0230 Subject: [PATCH 12/64] Styling fixes for gas customization advanced tab content. --- .../advanced-tab-content/advanced-tab-content.component.js | 2 +- .../gas-modal-page-container/advanced-tab-content/index.scss | 1 - .../gas-modal-page-container/basic-tab-content/index.scss | 1 + .../gas-customization/gas-modal-page-container/index.scss | 1 - 4 files changed, 2 insertions(+), 3 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index cd5ca7d35458..38fa117f9682 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -39,7 +39,7 @@ export default class AdvancedTabContent extends Component { } infoButton (onClick) { - return + return } renderDataSummary (totalFee, millisecondsRemaining) { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index 28e2fde9b79d..aced75449959 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -3,7 +3,6 @@ .advanced-tab { display: flex; flex-flow: column; - border-bottom: 1px solid $alto; height: 430px; &__transaction-data-summary, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss index ba665716cbc8..d5eb5d4141c3 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss @@ -2,6 +2,7 @@ display: flex; flex-direction: column; align-items: center; + margin-bottom: 22px; &__title { margin-top: 19px; diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index 427b58888ad9..f02045fe3357 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -53,6 +53,5 @@ background: white; color: $dusty-gray; border-top: 1px solid $mischka; - margin-top: 22px; } } From 6ada9b4a3c02014f8d00b1f45a149afbf47f700d Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Sun, 9 Sep 2018 16:55:54 -0230 Subject: [PATCH 13/64] Adds gas-duck.test.js tests. --- ui/app/ducks/tests/gas-duck.test.js | 300 ++++++++++++++++++++++++++++ 1 file changed, 300 insertions(+) create mode 100644 ui/app/ducks/tests/gas-duck.test.js diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js new file mode 100644 index 000000000000..7fd74f815ccc --- /dev/null +++ b/ui/app/ducks/tests/gas-duck.test.js @@ -0,0 +1,300 @@ +import assert from 'assert' +import sinon from 'sinon' + +import GasReducer, { + basicGasEstimatesLoadingStarted, + basicGasEstimatesLoadingFinished, + setBasicGasEstimateData, + setCustomGasPrice, + setCustomGasLimit, + setCustomGasTotal, + setCustomGasErrors, + resetCustomGasState, + fetchGasEstimates, +} from '../gas.duck.js' + +describe('Gas Duck', () => { + let tempFetch + const fetchStub = sinon.stub().returns(new Promise(resolve => resolve({ + json: () => new Promise(resolve => resolve({ + average: 'mockAverage', + avgWait: 'mockAvgWait', + block_time: 'mockBlock_time', + blockNum: 'mockBlockNum', + fast: 'mockFast', + fastest: 'mockFastest', + fastestWait: 'mockFastestWait', + fastWait: 'mockFastWait', + safeLow: 'mockSafeLow', + safeLowWait: 'mockSafeLowWait', + speed: 'mockSpeed', + })), + }))) + + beforeEach(() => { + tempFetch = global.fetch + global.fetch = fetchStub + }) + + afterEach(() => { + global.fetch = tempFetch + }) + + const mockState = { + gas: { + mockProp: 123, + }, + } + const initState = { + customData: { + price: 0, + limit: 21000, + }, + basicEstimates: { + average: null, + fastestWait: null, + fastWait: null, + fast: null, + safeLowWait: null, + blockNum: null, + avgWait: null, + blockTime: null, + speed: null, + fastest: null, + safeLow: null, + }, + basicEstimateIsLoading: true, + errors: {}, + } + const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' + const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' + const RESET_CUSTOM_GAS_STATE = 'metamask/gas/RESET_CUSTOM_GAS_STATE' + const SET_BASIC_GAS_ESTIMATE_DATA = 'metamask/gas/SET_BASIC_GAS_ESTIMATE_DATA' + const SET_CUSTOM_GAS_ERRORS = 'metamask/gas/SET_CUSTOM_GAS_ERRORS' + const SET_CUSTOM_GAS_LIMIT = 'metamask/gas/SET_CUSTOM_GAS_LIMIT' + const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' + const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' + + describe('GasReducer()', () => { + it('should initialize state', () => { + assert.deepEqual( + GasReducer({}), + initState + ) + }) + + it('should return state unchanged if it does not match a dispatched actions type', () => { + assert.deepEqual( + GasReducer(mockState, { + type: 'someOtherAction', + value: 'someValue', + }), + Object.assign({}, mockState.gas) + ) + }) + + it('should set basicEstimateIsLoading to true when receiving a BASIC_GAS_ESTIMATE_LOADING_STARTED action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: BASIC_GAS_ESTIMATE_LOADING_STARTED, + }), + Object.assign({basicEstimateIsLoading: true}, mockState.gas) + ) + }) + + it('should set basicEstimateIsLoading to false when receiving a BASIC_GAS_ESTIMATE_LOADING_FINISHED action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: BASIC_GAS_ESTIMATE_LOADING_FINISHED, + }), + Object.assign({basicEstimateIsLoading: false}, mockState.gas) + ) + }) + + it('should return a new object (and not just modify the existing state object)', () => { + assert.deepEqual(GasReducer(mockState), mockState.gas) + assert.notEqual(GasReducer(mockState), mockState.gas) + }) + + it('should set basicEstimates when receiving a SET_BASIC_GAS_ESTIMATE_DATA action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: SET_BASIC_GAS_ESTIMATE_DATA, + value: { someProp: 'someData123' }, + }), + Object.assign({basicEstimates: {someProp: 'someData123'} }, mockState.gas) + ) + }) + + it('should set customData.price when receiving a SET_CUSTOM_GAS_PRICE action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: SET_CUSTOM_GAS_PRICE, + value: 4321, + }), + Object.assign({customData: {price: 4321} }, mockState.gas) + ) + }) + + it('should set customData.limit when receiving a SET_CUSTOM_GAS_LIMIT action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: SET_CUSTOM_GAS_LIMIT, + value: 9876, + }), + Object.assign({customData: {limit: 9876} }, mockState.gas) + ) + }) + + it('should set customData.total when receiving a SET_CUSTOM_GAS_TOTAL action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: SET_CUSTOM_GAS_TOTAL, + value: 10000, + }), + Object.assign({customData: {total: 10000} }, mockState.gas) + ) + }) + + it('should set errors when receiving a SET_CUSTOM_GAS_ERRORS action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: SET_CUSTOM_GAS_ERRORS, + value: { someError: 'error_error' }, + }), + Object.assign({errors: {someError: 'error_error'} }, mockState.gas) + ) + }) + + it('should return the initial state in response to a RESET_CUSTOM_GAS_STATE action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: RESET_CUSTOM_GAS_STATE, + }), + Object.assign({}, initState) + ) + }) + }) + + describe('basicGasEstimatesLoadingStarted', () => { + it('should create the correct action', () => { + assert.deepEqual( + basicGasEstimatesLoadingStarted(), + { type: BASIC_GAS_ESTIMATE_LOADING_STARTED } + ) + }) + }) + + describe('basicGasEstimatesLoadingFinished', () => { + it('should create the correct action', () => { + assert.deepEqual( + basicGasEstimatesLoadingFinished(), + { type: BASIC_GAS_ESTIMATE_LOADING_FINISHED } + ) + }) + }) + + describe('fetchGasEstimates', () => { + const mockDistpatch = sinon.spy() + it('should call fetch with the expected params', async () => { + await fetchGasEstimates()(mockDistpatch) + assert.deepEqual( + mockDistpatch.getCall(0).args, + [{ type: BASIC_GAS_ESTIMATE_LOADING_STARTED} ] + ) + assert.deepEqual( + global.fetch.getCall(0).args, + [ + 'https://ethgasstation.info/json/ethgasAPI.json', + { + 'headers': {}, + 'referrer': 'http://ethgasstation.info/json/', + 'referrerPolicy': 'no-referrer-when-downgrade', + 'body': null, + 'method': 'GET', + 'mode': 'cors', + }, + ] + ) + assert.deepEqual( + mockDistpatch.getCall(1).args, + [{ + type: SET_BASIC_GAS_ESTIMATE_DATA, + value: { + average: 'mockAverage', + avgWait: 'mockAvgWait', + blockTime: 'mockBlock_time', + blockNum: 'mockBlockNum', + fast: 'mockFast', + fastest: 'mockFastest', + fastestWait: 'mockFastestWait', + fastWait: 'mockFastWait', + safeLow: 'mockSafeLow', + safeLowWait: 'mockSafeLowWait', + speed: 'mockSpeed', + }, + }] + ) + assert.deepEqual( + mockDistpatch.getCall(2).args, + [{ type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }] + ) + }) + }) + + + describe('setBasicGasEstimateData', () => { + it('should create the correct action', () => { + assert.deepEqual( + setBasicGasEstimateData('mockBasicEstimatData'), + { type: SET_BASIC_GAS_ESTIMATE_DATA, value: 'mockBasicEstimatData' } + ) + }) + }) + + describe('setCustomGasPrice', () => { + it('should create the correct action', () => { + assert.deepEqual( + setCustomGasPrice('mockCustomGasPrice'), + { type: SET_CUSTOM_GAS_PRICE, value: 'mockCustomGasPrice' } + ) + }) + }) + + describe('setCustomGasLimit', () => { + it('should create the correct action', () => { + assert.deepEqual( + setCustomGasLimit('mockCustomGasLimit'), + { type: SET_CUSTOM_GAS_LIMIT, value: 'mockCustomGasLimit' } + ) + }) + }) + + describe('setCustomGasTotal', () => { + it('should create the correct action', () => { + assert.deepEqual( + setCustomGasTotal('mockCustomGasTotal'), + { type: SET_CUSTOM_GAS_TOTAL, value: 'mockCustomGasTotal' } + ) + }) + }) + + describe('setCustomGasErrors', () => { + it('should create the correct action', () => { + assert.deepEqual( + setCustomGasErrors('mockErrorObject'), + { type: SET_CUSTOM_GAS_ERRORS, value: 'mockErrorObject' } + ) + }) + }) + + describe('resetCustomGasState', () => { + it('should create the correct action', () => { + assert.deepEqual( + resetCustomGasState(), + { type: RESET_CUSTOM_GAS_STATE } + ) + }) + }) + +}) From 7de3f22d63748ed5a81e947755db056d4cdef3db Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 13 Sep 2018 06:17:05 -0230 Subject: [PATCH 14/64] Connects remained of the gas customization component to redux. --- ui/app/actions.js | 42 ++---- .../advanced-tab-content.component.js | 8 +- .../advanced-tab-content-component.test.js | 4 +- .../basic-tab-content.component.js | 2 - .../gas-modal-page-container.component.js | 80 +++++++--- .../gas-modal-page-container.container.js | 141 +++++++++++++++++- ...gas-modal-page-container-component.test.js | 97 ++++++------ ...gas-modal-page-container-container.test.js | 122 ++++++++++++--- .../confirm-transaction-base.container.js | 14 +- .../confirm-transaction.component.js | 3 + .../confirm-transaction.container.js | 4 + ui/app/components/send/send.component.js | 9 +- ui/app/components/send/send.container.js | 4 +- ui/app/components/send/send.selectors.js | 10 +- .../send/tests/send-component.test.js | 46 +++--- .../send/tests/send-container.test.js | 10 +- .../send/tests/send-selectors.test.js | 2 +- ui/app/ducks/gas.duck.js | 4 +- ui/app/ducks/tests/gas-duck.test.js | 4 +- ui/app/helpers/conversions.util.js | 39 +++++ ui/app/helpers/formatters.js | 3 + ui/app/selectors/custom-gas.js | 43 +++--- 22 files changed, 497 insertions(+), 194 deletions(-) create mode 100644 ui/app/helpers/formatters.js diff --git a/ui/app/actions.js b/ui/app/actions.js index e3cf57c9e51f..b747a97fbd81 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -3,7 +3,6 @@ const pify = require('pify') const getBuyEthUrl = require('../../app/scripts/lib/buy-eth-url') const { getTokenAddressFromTokenObject } = require('./util') const { - calcGasTotal, calcTokenBalance, estimateGas, } = require('./components/send/send.utils') @@ -12,6 +11,7 @@ const { fetchLocale } = require('../i18n-helper') const log = require('loglevel') const { ENVIRONMENT_TYPE_NOTIFICATION } = require('../../app/scripts/lib/enums') const { hasUnconfirmedTransactions } = require('./helpers/confirm-transaction/util') +const gasDuck = require('./ducks/gas.duck') const WebcamUtils = require('../lib/webcam-utils') var actions = { @@ -921,6 +921,7 @@ function setGasTotal (gasTotal) { } function updateGasData ({ + gasPrice, blockGasLimit, recentBlocks, selectedAddress, @@ -931,34 +932,19 @@ function updateGasData ({ }) { return (dispatch) => { dispatch(actions.gasLoadingStarted()) - return new Promise((resolve, reject) => { - background.getGasPrice((err, data) => { - if (err) return reject(err) - return resolve(data) - }) - }) - .then(estimateGasPrice => { - return Promise.all([ - Promise.resolve(estimateGasPrice), - estimateGas({ - estimateGasMethod: background.estimateGas, - blockGasLimit, - selectedAddress, - selectedToken, - to, - value, - estimateGasPrice, - data, - }), - ]) - }) - .then(([gasPrice, gas]) => { - dispatch(actions.setGasPrice(gasPrice)) + return estimateGas({ + estimateGasMethod: background.estimateGas, + blockGasLimit, + selectedAddress, + selectedToken, + to, + value, + estimateGasPrice: gasPrice, + data, + }) + .then(gas => { dispatch(actions.setGasLimit(gas)) - return calcGasTotal(gas, gasPrice) - }) - .then((gasEstimate) => { - dispatch(actions.setGasTotal(gasEstimate)) + dispatch(gasDuck.setCustomGasLimit(gas)) dispatch(updateSendErrors({ gasLoadingError: null })) dispatch(actions.gasLoadingFinished()) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 38fa117f9682..56d10cc2b852 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,9 +1,5 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import { - MIN_GAS_PRICE_DEC, - MIN_GAS_LIMIT_DEC, -} from '../../../send/send.constants' import TimeRemaining from './time-remaining' export default class AdvancedTabContent extends Component { @@ -76,8 +72,8 @@ export default class AdvancedTabContent extends Component { renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { return (
- { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, MIN_GAS_PRICE_DEC, 9, true) } - { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, MIN_GAS_LIMIT_DEC, 0) } + { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) } + { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, 0) }
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 5cdcf687e076..0ef286b8aad5 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -138,10 +138,10 @@ describe('AdvancedTabContent Component', function () { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', '0', 9, true, + 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true, ].map(String)) assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ - 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 21000, '0', + 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', 0, ].map(String)) }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js index 164da4a32db5..0e5f15519e28 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -17,9 +17,7 @@ export default class BasicTabContent extends Component {
Suggest gas fee increases
console.log('New Price:', newPrice)} {...this.props.gasPriceButtonGroupProps} />
diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 399520baf51b..89065472d39e 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -17,34 +17,42 @@ export default class GasModalPageContainer extends Component { customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, gasPriceButtonGroupProps: PropTypes.object, + infoRowProps: PropTypes.shape({ + originalTotalFiat: PropTypes.string, + originalTotalEth: PropTypes.string, + newTotalFiat: PropTypes.string, + newTotalEth: PropTypes.string, + }), + onSubmit: PropTypes.func, + customGasPriceInHex: PropTypes.string, + customGasLimitInHex: PropTypes.string, } state = {} - renderBasicTabContent () { + renderBasicTabContent (gasPriceButtonGroupProps) { return ( ) } - renderAdvancedTabContent = () => { - const { - updateCustomGasPrice, - updateCustomGasLimit, - customGasPrice, - customGasLimit, - } = this.props - + renderAdvancedTabContent ({ + convertThenUpdateCustomGasPrice, + convertThenUpdateCustomGasLimit, + customGasPrice, + customGasLimit, + newTotalFiat, + }) { return ( ) } @@ -64,41 +72,67 @@ export default class GasModalPageContainer extends Component { ) } - renderTabContent (mainTabContent) { + renderInfoRows (originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) { return ( -
- { mainTabContent } - { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', '$20.02 USD', '0.06685 ETH') } - { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', '$20.02 USD', '0.06685 ETH') } +
+ { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', originalTotalFiat, originalTotalEth) } + { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', newTotalFiat, newTotalEth) }
) } - renderTabs () { + renderTabs ({ + originalTotalFiat, + originalTotalEth, + newTotalFiat, + newTotalEth, + }, + { + gasPriceButtonGroupProps, + ...advancedTabProps + }) { return ( - { this.renderTabContent(this.renderBasicTabContent()) } +
+ { this.renderBasicTabContent(gasPriceButtonGroupProps) } + { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } +
- { this.renderTabContent(this.renderAdvancedTabContent()) } +
+ { this.renderAdvancedTabContent(advancedTabProps) } + { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } +
) } render () { - const { hideModal } = this.props + const { + hideModal, + infoRowProps, + onSubmit, + customGasPriceInHex, + customGasLimitInHex, + ...tabProps + } = this.props return (
hideModal()} onClose={() => hideModal()} + onSubmit={() => { + onSubmit(customGasLimitInHex, customGasPriceInHex) + hideModal() + }} + submitText={this.context.t('save')} />
) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index ebdd035ea912..7e2a7e1442c4 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -1,36 +1,161 @@ import { connect } from 'react-redux' +import { pipe, partialRight } from 'ramda' import GasModalPageContainer from './gas-modal-page-container.component' -import { hideModal } from '../../../actions' +import { + hideModal, + setGasLimit, + setGasPrice, +} from '../../../actions' import { setCustomGasPrice, setCustomGasLimit, } from '../../../ducks/gas.duck' +import { + updateGasAndCalculate, +} from '../../../ducks/confirm-transaction.duck' +import { + getCurrentCurrency, + conversionRateSelector as getConversionRate, + getSelectedToken, +} from '../../../selectors.js' import { getCustomGasPrice, getCustomGasLimit, getRenderableBasicEstimateData, getBasicGasEstimateLoadingStatus, + getAveragePriceEstimateInHexWEI, + getDefaultActiveButtonIndex, } from '../../../selectors/custom-gas' +import { + formatCurrency, +} from '../../../helpers/confirm-transaction/util' +import { + addHexWEIsToDec, + decEthToConvertedCurrency as ethTotalToConvertedCurrency, + decGWEIToHexWEI, + hexWEIToDecGWEI, +} from '../../../helpers/conversions.util' +import { + formatETHFee, +} from '../../../helpers/formatters' +import { + calcGasTotal, +} from '../../send/send.utils' +import { addHexPrefix } from 'ethereumjs-util' const mapStateToProps = state => { const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) + const { gasPrice, gas: gasLimit, value } = getTxParams(state) + const gasTotal = calcGasTotal(gasLimit, gasPrice) + + const customGasPriceInHex = getCustomGasPrice(state) + const customGasLimitInHex = getCustomGasLimit(state) + const customGasTotal = calcGasTotal(customGasLimitInHex || gasLimit, customGasPriceInHex || gasPrice) + + const gasButtonInfo = getRenderableBasicEstimateData(state) + + const currentCurrency = getCurrentCurrency(state) + const conversionRate = getConversionRate(state) + + const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate) + return { - customGasPrice: getCustomGasPrice(state), - customGasLimit: getCustomGasLimit(state), + isConfirm: isConfirm(state), + customGasPriceInHex, + customGasLimitInHex, + customGasPrice: calcCustomGasPrice(customGasPriceInHex, gasPrice), + customGasLimit: calcCustomGasLimit(customGasLimitInHex, gasLimit), + newTotalFiat, gasPriceButtonGroupProps: { buttonDataLoading, - gasButtonInfo: getRenderableBasicEstimateData(state), + defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customGasPriceInHex, gasPrice), + gasButtonInfo, + }, + infoRowProps: { + originalTotalFiat: addHexWEIsToRenderableFiat(value, gasTotal, currentCurrency, conversionRate), + originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal), + newTotalFiat, + newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal), }, } } const mapDispatchToProps = dispatch => { + const updateCustomGasPrice = newPrice => dispatch(setCustomGasPrice(addHexPrefix(newPrice))) + return { hideModal: () => dispatch(hideModal()), - updateCustomGasPrice: (newPrice) => dispatch(setCustomGasPrice(newPrice)), - updateCustomGasLimit: (newLimit) => dispatch(setCustomGasLimit(newLimit)), - handleGasPriceSelection: newPrice => console.log('NewPrice: ', newPrice), + updateCustomGasPrice, + convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)), + convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))), + setGasData: (newLimit, newPrice) => { + dispatch(setGasLimit(newLimit)) + dispatch(setGasPrice(newPrice)) + }, + updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { + return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) + }, } } -export default connect(mapStateToProps, mapDispatchToProps)(GasModalPageContainer) +const mergeProps = (stateProps, dispatchProps, ownProps) => { + const { gasPriceButtonGroupProps, isConfirm } = stateProps + const { + updateCustomGasPrice: dispatchUpdateCustomGasPrice, + setGasData: dispatchSetGasData, + updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, + ...otherDispatchProps + } = dispatchProps + + return { + ...stateProps, + ...otherDispatchProps, + ...ownProps, + onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : dispatchSetGasData, + gasPriceButtonGroupProps: { + ...gasPriceButtonGroupProps, + handleGasPriceSelection: dispatchUpdateCustomGasPrice, + }, + } +} + +export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(GasModalPageContainer) + +function isConfirm (state) { + return Boolean(Object.keys(state.confirmTransaction.txData).length) +} + +function calcCustomGasPrice (customGasPriceInHex, gasPrice) { + return Number(hexWEIToDecGWEI(customGasPriceInHex || gasPrice)) +} + +function calcCustomGasLimit (customGasLimitInHex, gasLimit) { + return parseInt(customGasLimitInHex || gasLimit, 16) +} + +function getTxParams (state) { + const { confirmTransaction: { txData }, metamask: { send } } = state + + return txData.txParams || { + from: send.from, + gas: send.gasLimit, + gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state), + to: send.to, + value: getSelectedToken(state) ? '0x0' : send.amount, + } +} + +function addHexWEIsToRenderableEth (aHexWEI, bHexWEI) { + return pipe( + addHexWEIsToDec, + formatETHFee + )(aHexWEI, bHexWEI) +} + +function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conversionRate) { + return pipe( + addHexWEIsToDec, + partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]), + partialRight(formatCurrency, [convertedCurrency]), + )(aHexWEI, bHexWEI) +} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 86286b615ab4..c41adca83a03 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -5,13 +5,12 @@ import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' import PageContainer from '../../../page-container' -import BasicTabContent from '../basic-tab-content' -import AdvancedTabContent from '../advanced-tab-content' import { Tab } from '../../../tabs' const propsMethodSpies = { hideModal: sinon.spy(), + onSubmit: sinon.spy(), } const mockGasPriceButtonGroupProps = { @@ -41,18 +40,29 @@ const mockGasPriceButtonGroupProps = { noButtonActiveByDefault: true, showCheck: true, } +const mockInfoRowProps = { + originalTotalFiat: 'mockOriginalTotalFiat', + originalTotalEth: 'mockOriginalTotalEth', + newTotalFiat: 'mockNewTotalFiat', + newTotalEth: 'mockNewTotalEth', +} +const GP = GasModalPageContainer.prototype describe('GasModalPageContainer Component', function () { let wrapper beforeEach(() => { wrapper = shallow( 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} customGasPrice={21} customGasLimit={54321} gasPriceButtonGroupProps={mockGasPriceButtonGroupProps} + infoRowProps={mockInfoRowProps} + customGasPriceInHex={'mockCustomGasPriceInHex'} + customGasLimitInHex={'mockCustomGasLimitInHex'} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -89,7 +99,7 @@ describe('GasModalPageContainer Component', function () { }) it('should pass the correct renderTabs property to PageContainer', () => { - sinon.stub(GasModalPageContainer.prototype, 'renderTabs').returns('mockTabs') + sinon.stub(GP, 'renderTabs').returns('mockTabs') const renderTabsWrapperTester = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props() assert.equal(tabsComponent, 'mockTabs') @@ -98,8 +108,23 @@ describe('GasModalPageContainer Component', function () { }) describe('renderTabs', () => { + beforeEach(() => { + sinon.spy(GP, 'renderBasicTabContent') + sinon.spy(GP, 'renderAdvancedTabContent') + sinon.spy(GP, 'renderInfoRows') + }) + + afterEach(() => { + GP.renderBasicTabContent.restore() + GP.renderAdvancedTabContent.restore() + GP.renderInfoRows.restore() + }) + it('should render a Tabs component with "Basic" and "Advanced" tabs', () => { - const renderTabsResult = wrapper.instance().renderTabs() + const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { + gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, + otherProps: 'mockAdvancedTabProps', + }) const renderedTabs = shallow(renderTabsResult) assert.equal(renderedTabs.props().className, 'tabs') @@ -113,45 +138,28 @@ describe('GasModalPageContainer Component', function () { assert.equal(tabs.at(1).childAt(0).props().className, 'gas-modal-content') }) - it('should render the expected children of each tab', () => { - const GP = GasModalPageContainer.prototype - sinon.spy(GP, 'renderTabContent') - assert.equal(GP.renderTabContent.callCount, 0) + it('should call renderBasicTabContent and renderAdvancedTabContent with the expected props', () => { + assert.equal(GP.renderBasicTabContent.callCount, 0) + assert.equal(GP.renderAdvancedTabContent.callCount, 0) - wrapper.instance().renderTabs() + wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) - assert.equal(GP.renderTabContent.callCount, 2) + assert.equal(GP.renderBasicTabContent.callCount, 1) + assert.equal(GP.renderAdvancedTabContent.callCount, 1) - assert.equal(GP.renderTabContent.firstCall.args.type, BasicTabContent.type) - assert.equal(GP.renderTabContent.secondCall.args.type, AdvancedTabContent.type) - - GP.renderTabContent.restore() + assert.deepEqual(GP.renderBasicTabContent.getCall(0).args[0], mockGasPriceButtonGroupProps) + assert.deepEqual(GP.renderAdvancedTabContent.getCall(0).args[0], { otherProps: 'mockAdvancedTabProps' }) }) - }) - describe('renderTabContent', () => { - it('should render a root gas-modal-content div', () => { - const renderTabContentResult = wrapper.instance().renderTabContent(() => {}) - const renderedTabContent = shallow(renderTabContentResult) - assert.equal(renderedTabContent.props().className, 'gas-modal-content') - }) - - it('should render the passed element as its first child', () => { - const renderTabContentResult = wrapper.instance().renderTabContent(Mock content) - const renderedTabContent = shallow(renderTabContentResult) - assert(renderedTabContent.childAt(0).equals(Mock content)) - }) + it('should call renderInfoRows with the expected props', () => { + assert.equal(GP.renderInfoRows.callCount, 0) - it('should render the element results of renderInfoRow calls as second and third childs', () => { - const GP = GasModalPageContainer.prototype - sinon.stub(GP, 'renderInfoRow').callsFake((...args) => args.join(',')) + wrapper.instance().renderTabs(mockInfoRowProps, { gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, otherProps: 'mockAdvancedTabProps' }) - const renderTabContentResult = wrapper.instance().renderTabContent(() => Mock content) - const renderedTabContent = shallow(renderTabContentResult) - assert.equal(renderedTabContent.childAt(1).text(), 'gas-modal-content__info-row--fade,originalTotal,$20.02 USD,0.06685 ETH') - assert.equal(renderedTabContent.childAt(2).text(), 'gas-modal-content__info-row,newTotal,$20.02 USD,0.06685 ETH') + assert.equal(GP.renderInfoRows.callCount, 2) - GP.renderInfoRow.restore() + assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) + assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) }) }) @@ -176,7 +184,7 @@ describe('GasModalPageContainer Component', function () { describe('renderBasicTabContent', () => { it('should render', () => { - const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent() + const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent(mockGasPriceButtonGroupProps) assert.deepEqual( renderBasicTabContentResult.props.gasPriceButtonGroupProps, @@ -187,15 +195,20 @@ describe('GasModalPageContainer Component', function () { describe('renderAdvancedTabContent', () => { it('should render with the correct props', () => { - const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent() + const renderAdvancedTabContentResult = wrapper.instance().renderAdvancedTabContent({ + convertThenUpdateCustomGasPrice: () => 'mockConvertThenUpdateCustomGasPrice', + convertThenUpdateCustomGasLimit: () => 'mockConvertThenUpdateCustomGasLimit', + customGasPrice: 123, + customGasLimit: 456, + newTotalFiat: '$0.30', + }) const advancedTabContentProps = renderAdvancedTabContentResult.props - assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockupdateCustomGasPrice') - assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockupdateCustomGasLimit') - assert.equal(advancedTabContentProps.customGasPrice, 21) - assert.equal(advancedTabContentProps.customGasLimit, 54321) + assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') + assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit') + assert.equal(advancedTabContentProps.customGasPrice, 123) + assert.equal(advancedTabContentProps.customGasLimit, 456) assert.equal(advancedTabContentProps.millisecondsRemaining, 91000) assert.equal(advancedTabContentProps.totalFee, '$0.30') - assert(shallow(renderAdvancedTabContentResult).hasClass('advanced-tab')) }) }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 4067265b5247..e01fd38986cd 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -7,13 +7,19 @@ let mapDispatchToProps const actionSpies = { hideModal: sinon.spy(), + setGasLimit: sinon.spy(), + setGasPrice: sinon.spy(), } -const customGasActionSpies = { +const gasActionSpies = { setCustomGasPrice: sinon.spy(), setCustomGasLimit: sinon.spy(), } +const confirmTransactionActionSpies = { + updateGasAndCalculate: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { connect: (ms, md) => { @@ -23,13 +29,13 @@ proxyquire('../gas-modal-page-container.container.js', { }, }, '../../../selectors/custom-gas': { - getCustomGasPrice: (s) => `mockGasPrice:${s}`, - getCustomGasLimit: (s) => `mockGasLimit:${s}`, - getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`, - getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${s}`, + getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`, + getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`, + getDefaultActiveButtonIndex: (a, b, c) => a + b + c, }, '../../../actions': actionSpies, - '../../../ducks/gas.duck': customGasActionSpies, + '../../../ducks/gas.duck': gasActionSpies, + '../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies, }) describe('gas-modal-page-container container', () => { @@ -37,10 +43,54 @@ describe('gas-modal-page-container container', () => { describe('mapStateToProps()', () => { it('should map the correct properties to props', () => { - assert.equal(mapStateToProps('mockState').customGasPrice, 'mockGasPrice:mockState') - assert.equal(mapStateToProps('mockState').customGasLimit, 'mockGasLimit:mockState') - assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.buttonDataLoading, 'mockBasicGasEstimateLoadingStatus:mockState') - assert.equal(mapStateToProps('mockState').gasPriceButtonGroupProps.gasButtonInfo, 'mockRenderableBasicEstimateData:mockState') + const mockState2 = { + metamask: { + send: { + gasLimit: '16', + gasPrice: '32', + amount: '64', + }, + currentCurrency: 'abc', + conversionRate: 50, + }, + gas: { + customData: { + limit: 'aaaaaaaa', + price: 'ffffffff', + }, + }, + confirmTransaction: { + txData: { + txParams: { + gas: '0x1600000', + gasPrice: '0x3200000', + value: '0x640000000000000', + }, + }, + }, + } + const result2 = mapStateToProps(mockState2) + + assert.deepEqual(result2, { + isConfirm: true, + customGasPriceInHex: 'ffffffff', + customGasLimitInHex: 'aaaaaaaa', + customGasPrice: 4.294967295, + customGasLimit: 2863311530, + newTotalFiat: '637.41', + gasPriceButtonGroupProps: + { + buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:3', + defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:3ffffffff0x3200000', + gasButtonInfo: 'mockRenderableBasicEstimateData:3', + }, + infoRowProps: { + originalTotalFiat: '22.58', + originalTotalEth: '0.451569 ETH', + newTotalFiat: '637.41', + newTotalEth: '12.748189 ETH', + }, + }) }) }) @@ -54,6 +104,12 @@ describe('gas-modal-page-container container', () => { mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) }) + afterEach(() => { + actionSpies.hideModal.resetHistory() + gasActionSpies.setCustomGasPrice.resetHistory() + gasActionSpies.setCustomGasLimit.resetHistory() + }) + describe('hideModal()', () => { it('should dispatch a hideModal action', () => { mapDispatchToPropsObject.hideModal() @@ -63,18 +119,50 @@ describe('gas-modal-page-container container', () => { }) describe('updateCustomGasPrice()', () => { - it('should dispatch a setCustomGasPrice action', () => { - mapDispatchToPropsObject.updateCustomGasPrice() + it('should dispatch a setCustomGasPrice action with the arg passed to updateCustomGasPrice hex prefixed', () => { + mapDispatchToPropsObject.updateCustomGasPrice('ffff') + assert(dispatchSpy.calledOnce) + assert(gasActionSpies.setCustomGasPrice.calledOnce) + assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0xffff') + }) + }) + + describe('convertThenUpdateCustomGasPrice()', () => { + it('should dispatch a setCustomGasPrice action with the arg passed to convertThenUpdateCustomGasPrice converted to WEI', () => { + mapDispatchToPropsObject.convertThenUpdateCustomGasPrice('0xffff') assert(dispatchSpy.calledOnce) - assert(customGasActionSpies.setCustomGasPrice.calledOnce) + assert(gasActionSpies.setCustomGasPrice.calledOnce) + assert.equal(gasActionSpies.setCustomGasPrice.getCall(0).args[0], '0x3b9a8e653600') + }) + }) + + + describe('convertThenUpdateCustomGasLimit()', () => { + it('should dispatch a setCustomGasLimit action with the arg passed to convertThenUpdateCustomGasLimit converted to hex', () => { + mapDispatchToPropsObject.convertThenUpdateCustomGasLimit(16) + assert(dispatchSpy.calledOnce) + assert(gasActionSpies.setCustomGasLimit.calledOnce) + assert.equal(gasActionSpies.setCustomGasLimit.getCall(0).args[0], '0x10') + }) + }) + + describe('setGasData()', () => { + it('should dispatch a setGasPrice and setGasLimit action with the correct props', () => { + mapDispatchToPropsObject.setGasData('ffff', 'aaaa') + assert(dispatchSpy.calledTwice) + assert(actionSpies.setGasPrice.calledOnce) + assert(actionSpies.setGasLimit.calledOnce) + assert.equal(actionSpies.setGasLimit.getCall(0).args[0], 'ffff') + assert.equal(actionSpies.setGasPrice.getCall(0).args[0], 'aaaa') }) }) - describe('updateCustomGasLimit()', () => { - it('should dispatch a setCustomGasLimit action', () => { - mapDispatchToPropsObject.updateCustomGasLimit() + describe('updateConfirmTxGasAndCalculate()', () => { + it('should dispatch a updateGasAndCalculate action with the correct props', () => { + mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa') assert(dispatchSpy.calledOnce) - assert(customGasActionSpies.setCustomGasLimit.calledOnce) + assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce) + assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' }) }) }) diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js index a3ec82863833..1e2270432339 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.container.js @@ -29,7 +29,7 @@ const casedContractMap = Object.keys(contractMap).reduce((acc, base) => { const mapStateToProps = (state, props) => { const { toAddress: propsToAddress } = props - const { confirmTransaction, metamask } = state + const { confirmTransaction, metamask, gas } = state const { ethTransactionAmount, ethTransactionFee, @@ -60,6 +60,12 @@ const mapStateToProps = (state, props) => { unapprovedTxs, } = metamask const assetImage = assetImages[txParamsToAddress] + + const { + customGasLimit, + customGasPrice, + } = gas + const { balance } = accounts[selectedAddress] const { name: fromName } = identities[selectedAddress] const toAddress = propsToAddress || txParamsToAddress @@ -106,6 +112,10 @@ const mapStateToProps = (state, props) => { unapprovedTxs, unapprovedTxCount, currentNetworkUnapprovedTxs, + customGas: { + gasLimit: customGasLimit || txData.gasPrice, + gasPrice: customGasPrice || txData.gasLimit, + }, } } @@ -192,7 +202,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...ownProps, showCustomizeGasModal: () => dispatchShowCustomizeGasModal({ txData, - onSubmit: txData => dispatchUpdateGasAndCalculate(txData), + onSubmit: customGas => dispatchUpdateGasAndCalculate(customGas), validate: validateEditGas, }), cancelAllTransactions: () => dispatchCancelAllTransactions(valuesFor(unapprovedTxs)), diff --git a/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js b/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js index 3ac656d73ddc..614b3e584d97 100644 --- a/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js +++ b/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js @@ -32,6 +32,7 @@ export default class ConfirmTransaction extends Component { setTransactionToConfirm: PropTypes.func, confirmTransaction: PropTypes.object, clearConfirmTransaction: PropTypes.func, + fetchGasEstimates: PropTypes.func, } getParamsTransactionId () { @@ -45,6 +46,7 @@ export default class ConfirmTransaction extends Component { send = {}, history, confirmTransaction: { txData: { id: transactionId } = {} }, + fetchGasEstimates, } = this.props if (!totalUnapprovedCount && !send.to) { @@ -53,6 +55,7 @@ export default class ConfirmTransaction extends Component { } if (!transactionId) { + fetchGasEstimates() this.setTransactionToConfirm() } } diff --git a/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js b/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js index 1bc2f1efbe7b..cb1a737f9c0a 100644 --- a/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js +++ b/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js @@ -5,6 +5,9 @@ import { setTransactionToConfirm, clearConfirmTransaction, } from '../../../ducks/confirm-transaction.duck' +import { + fetchGasEstimates, +} from '../../../ducks/gas.duck' import ConfirmTransaction from './confirm-transaction.component' import { getTotalUnapprovedCount } from '../../../selectors' import { unconfirmedTransactionsListSelector } from '../../../selectors/confirm-transaction' @@ -24,6 +27,7 @@ const mapDispatchToProps = dispatch => { return { setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)), clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), + fetchGasEstimates: () => dispatch(fetchGasEstimates()), } } diff --git a/ui/app/components/send/send.component.js b/ui/app/components/send/send.component.js index a639c24b0e0a..5c12826ea991 100644 --- a/ui/app/components/send/send.component.js +++ b/ui/app/components/send/send.component.js @@ -73,10 +73,10 @@ export default class SendTransactionScreen extends PersistentForm { selectedAddress, selectedToken = {}, to: currentToAddress, - updateAndSetGasTotal, + updateAndSetGasLimit, } = this.props - updateAndSetGasTotal({ + updateAndSetGasLimit({ blockGasLimit, editingTransactionId, gasLimit, @@ -164,6 +164,9 @@ export default class SendTransactionScreen extends PersistentForm { componentDidMount () { this.props.fetchGasEstimates() + .then(() => { + this.updateGas() + }) } componentWillMount () { @@ -173,12 +176,12 @@ export default class SendTransactionScreen extends PersistentForm { tokenContract, updateSendTokenBalance, } = this.props + updateSendTokenBalance({ selectedToken, tokenContract, address, }) - this.updateGas() // Show QR Scanner modal if ?scan=true if (window.location.search === '?scan=true') { diff --git a/ui/app/components/send/send.container.js b/ui/app/components/send/send.container.js index a00fb3545c04..f240774d44de 100644 --- a/ui/app/components/send/send.container.js +++ b/ui/app/components/send/send.container.js @@ -79,7 +79,7 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - updateAndSetGasTotal: ({ + updateAndSetGasLimit: ({ blockGasLimit, editingTransactionId, gasLimit, @@ -92,7 +92,7 @@ function mapDispatchToProps (dispatch) { data, }) => { !editingTransactionId - ? dispatch(updateGasData({ recentBlocks, selectedAddress, selectedToken, blockGasLimit, to, value, data })) + ? dispatch(updateGasData({ gasPrice, recentBlocks, selectedAddress, selectedToken, blockGasLimit, to, value, data })) : dispatch(setGasTotal(calcGasTotal(gasLimit, gasPrice))) }, updateSendTokenBalance: ({ selectedToken, tokenContract, address }) => { diff --git a/ui/app/components/send/send.selectors.js b/ui/app/components/send/send.selectors.js index c217d848e7cc..71eb93d6140c 100644 --- a/ui/app/components/send/send.selectors.js +++ b/ui/app/components/send/send.selectors.js @@ -8,7 +8,11 @@ const { } = require('../../selectors') const { estimateGasPriceFromRecentBlocks, + calcGasTotal, } = require('./send.utils') +import { + getAveragePriceEstimateInHexWEI, +} from '../../selectors/custom-gas' const selectors = { accountsWithSendEtherInfoSelector, @@ -131,11 +135,11 @@ function getForceGasMin (state) { } function getGasLimit (state) { - return state.metamask.send.gasLimit + return state.metamask.send.gasLimit || '0' } function getGasPrice (state) { - return state.metamask.send.gasPrice + return state.metamask.send.gasPrice || getAveragePriceEstimateInHexWEI(state) } function getGasPriceFromRecentBlocks (state) { @@ -143,7 +147,7 @@ function getGasPriceFromRecentBlocks (state) { } function getGasTotal (state) { - return state.metamask.send.gasTotal + return calcGasTotal(getGasLimit(state), getGasPrice(state)) } function getPrimaryCurrency (state) { diff --git a/ui/app/components/send/tests/send-component.test.js b/ui/app/components/send/tests/send-component.test.js index 0f3902c07ef6..82e84de30894 100644 --- a/ui/app/components/send/tests/send-component.test.js +++ b/ui/app/components/send/tests/send-component.test.js @@ -9,11 +9,11 @@ import SendContent from '../send-content/send-content.component' import SendFooter from '../send-footer/send-footer.container' const propsMethodSpies = { - updateAndSetGasTotal: sinon.spy(), + updateAndSetGasLimit: sinon.spy(), updateSendErrors: sinon.spy(), updateSendTokenBalance: sinon.spy(), resetSendState: sinon.spy(), - fetchGasEstimates: sinon.spy(), + fetchGasEstimates: sinon.stub().returns(Promise.resolve()), } const utilsMethodStubs = { getAmountErrorObject: sinon.stub().returns({ amount: 'mockAmountError' }), @@ -52,7 +52,7 @@ describe('Send Component', function () { showHexData={true} tokenBalance={'mockTokenBalance'} tokenContract={'mockTokenContract'} - updateAndSetGasTotal={propsMethodSpies.updateAndSetGasTotal} + updateAndSetGasLimit={propsMethodSpies.updateAndSetGasLimit} updateSendErrors={propsMethodSpies.updateSendErrors} updateSendTokenBalance={propsMethodSpies.updateSendTokenBalance} resetSendState={propsMethodSpies.resetSendState} @@ -66,7 +66,7 @@ describe('Send Component', function () { utilsMethodStubs.getAmountErrorObject.resetHistory() utilsMethodStubs.getGasFeeErrorObject.resetHistory() propsMethodSpies.fetchGasEstimates.resetHistory() - propsMethodSpies.updateAndSetGasTotal.resetHistory() + propsMethodSpies.updateAndSetGasLimit.resetHistory() propsMethodSpies.updateSendErrors.resetHistory() propsMethodSpies.updateSendTokenBalance.resetHistory() }) @@ -75,16 +75,6 @@ describe('Send Component', function () { assert(SendTransactionScreen.prototype.componentDidMount.calledOnce) }) - describe('componentWillMount', () => { - it('should call this.updateGas', () => { - SendTransactionScreen.prototype.updateGas.resetHistory() - propsMethodSpies.updateSendErrors.resetHistory() - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) - wrapper.instance().componentWillMount() - assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1) - }) - }) - describe('componentDidMount', () => { it('should call props.fetchGasEstimates', () => { propsMethodSpies.fetchGasEstimates.resetHistory() @@ -92,6 +82,14 @@ describe('Send Component', function () { wrapper.instance().componentDidMount() assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1) }) + + it('should call this.updateGas', () => { + SendTransactionScreen.prototype.updateGas.resetHistory() + propsMethodSpies.updateSendErrors.resetHistory() + assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 0) + wrapper.instance().componentDidMount() + setTimeout(() => assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1), 250) + }) }) describe('componentWillUnmount', () => { @@ -283,12 +281,12 @@ describe('Send Component', function () { }) describe('updateGas', () => { - it('should call updateAndSetGasTotal with the correct params if no to prop is passed', () => { - propsMethodSpies.updateAndSetGasTotal.resetHistory() + it('should call updateAndSetGasLimit with the correct params if no to prop is passed', () => { + propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.instance().updateGas() - assert.equal(propsMethodSpies.updateAndSetGasTotal.callCount, 1) + assert.equal(propsMethodSpies.updateAndSetGasLimit.callCount, 1) assert.deepEqual( - propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0], + propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0], { blockGasLimit: 'mockBlockGasLimit', editingTransactionId: 'mockEditingTransactionId', @@ -304,20 +302,20 @@ describe('Send Component', function () { ) }) - it('should call updateAndSetGasTotal with the correct params if a to prop is passed', () => { - propsMethodSpies.updateAndSetGasTotal.resetHistory() + it('should call updateAndSetGasLimit with the correct params if a to prop is passed', () => { + propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.setProps({ to: 'someAddress' }) wrapper.instance().updateGas() assert.equal( - propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0].to, + propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, 'someaddress', ) }) - it('should call updateAndSetGasTotal with to set to lowercase if passed', () => { - propsMethodSpies.updateAndSetGasTotal.resetHistory() + it('should call updateAndSetGasLimit with to set to lowercase if passed', () => { + propsMethodSpies.updateAndSetGasLimit.resetHistory() wrapper.instance().updateGas({ to: '0xABC' }) - assert.equal(propsMethodSpies.updateAndSetGasTotal.getCall(0).args[0].to, '0xabc') + assert.equal(propsMethodSpies.updateAndSetGasLimit.getCall(0).args[0].to, '0xabc') }) }) diff --git a/ui/app/components/send/tests/send-container.test.js b/ui/app/components/send/tests/send-container.test.js index 6aa4bf826a34..d8fe85d2252d 100644 --- a/ui/app/components/send/tests/send-container.test.js +++ b/ui/app/components/send/tests/send-container.test.js @@ -94,7 +94,7 @@ describe('send container', () => { mapDispatchToPropsObject = mapDispatchToProps(dispatchSpy) }) - describe('updateAndSetGasTotal()', () => { + describe('updateAndSetGasLimit()', () => { const mockProps = { blockGasLimit: 'mockBlockGasLimit', editingTransactionId: '0x2', @@ -109,7 +109,7 @@ describe('send container', () => { } it('should dispatch a setGasTotal action when editingTransactionId is truthy', () => { - mapDispatchToPropsObject.updateAndSetGasTotal(mockProps) + mapDispatchToPropsObject.updateAndSetGasLimit(mockProps) assert(dispatchSpy.calledOnce) assert.equal( actionSpies.setGasTotal.getCall(0).args[0], @@ -118,14 +118,14 @@ describe('send container', () => { }) it('should dispatch an updateGasData action when editingTransactionId is falsy', () => { - const { selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data } = mockProps - mapDispatchToPropsObject.updateAndSetGasTotal( + const { gasPrice, selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data } = mockProps + mapDispatchToPropsObject.updateAndSetGasLimit( Object.assign({}, mockProps, {editingTransactionId: false}) ) assert(dispatchSpy.calledOnce) assert.deepEqual( actionSpies.updateGasData.getCall(0).args[0], - { selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, data } + { gasPrice, selectedAddress, selectedToken, recentBlocks, blockGasLimit, to, value, } ) }) }) diff --git a/ui/app/components/send/tests/send-selectors.test.js b/ui/app/components/send/tests/send-selectors.test.js index e7e901f0d431..cdc86fe59b49 100644 --- a/ui/app/components/send/tests/send-selectors.test.js +++ b/ui/app/components/send/tests/send-selectors.test.js @@ -237,7 +237,7 @@ describe('send selectors', () => { it('should return the send.gasTotal', () => { assert.equal( getGasTotal(mockState), - '0xb451dc41b578' + 'a9ff56' ) }) }) diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js index 8b2fbcfdbb28..7f18b227251a 100644 --- a/ui/app/ducks/gas.duck.js +++ b/ui/app/ducks/gas.duck.js @@ -13,8 +13,8 @@ const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' // TODO: determine if this approach to initState is consistent with conventional ducks pattern const initState = { customData: { - price: 0, - limit: 21000, + price: null, + limit: '0x5208', }, basicEstimates: { average: null, diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js index 7fd74f815ccc..66cf376a795a 100644 --- a/ui/app/ducks/tests/gas-duck.test.js +++ b/ui/app/ducks/tests/gas-duck.test.js @@ -47,8 +47,8 @@ describe('Gas Duck', () => { } const initState = { customData: { - price: 0, - limit: 21000, + price: null, + limit: '0x5208', }, basicEstimates: { average: null, diff --git a/ui/app/helpers/conversions.util.js b/ui/app/helpers/conversions.util.js index cb5e1b90bf7b..d8e0d87fe021 100644 --- a/ui/app/helpers/conversions.util.js +++ b/ui/app/helpers/conversions.util.js @@ -1,6 +1,7 @@ import ethUtil from 'ethereumjs-util' import { conversionUtil } from '../conversion-util' import { ETH, GWEI, WEI } from '../constants/common' +import { conversionUtil, addCurrencies } from '../conversion-util' export function bnToHex (inputBn) { return ethUtil.addHexPrefix(inputBn.toString(16)) @@ -82,3 +83,41 @@ export function getWeiHexFromDecimalValue ({ toDenomination: WEI, }) } + +export function addHexWEIsToDec (aHexWEI, bHexWEI) { + return addCurrencies(aHexWEI, bHexWEI, { + aBase: 16, + bBase: 16, + fromDenomination: 'WEI', + numberOfDecimals: 6, + }) +} + +export function decEthToConvertedCurrency (ethTotal, convertedCurrency, conversionRate) { + return conversionUtil(ethTotal, { + fromNumericBase: 'dec', + toNumericBase: 'dec', + fromCurrency: 'ETH', + toCurrency: convertedCurrency, + numberOfDecimals: 2, + conversionRate, + }) +} + +export function decGWEIToHexWEI (decGWEI) { + return conversionUtil(decGWEI, { + fromNumericBase: 'dec', + toNumericBase: 'hex', + fromDenomination: 'GWEI', + toDenomination: 'WEI', + }) +} + +export function hexWEIToDecGWEI (decGWEI) { + return conversionUtil(decGWEI, { + fromNumericBase: 'hex', + toNumericBase: 'dec', + fromDenomination: 'WEI', + toDenomination: 'GWEI', + }) +} diff --git a/ui/app/helpers/formatters.js b/ui/app/helpers/formatters.js new file mode 100644 index 000000000000..106a2520dfb2 --- /dev/null +++ b/ui/app/helpers/formatters.js @@ -0,0 +1,3 @@ +export function formatETHFee (ethFee) { + return ethFee + ' ETH' +} diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index ff2fd0e0565a..61c0525df40c 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -1,8 +1,4 @@ import { pipe, partialRight } from 'ramda' -import { - getConversionRate, - getGasLimit, -} from '../components/send/send.selectors' import { conversionUtil, multiplyCurrencies, @@ -13,6 +9,12 @@ import { import { formatCurrency, } from '../helpers/confirm-transaction/util' +import { + decEthToConvertedCurrency as ethTotalToConvertedCurrency, +} from '../helpers/conversions.util' +import { + formatETHFee, +} from '../helpers/formatters' import { calcGasTotal, } from '../components/send/send.utils' @@ -25,6 +27,9 @@ const selectors = { getCustomGasTotal, getRenderableBasicEstimateData, getBasicGasEstimateLoadingStatus, + getAveragePriceEstimateInHexWEI, + getDefaultActiveButtonIndex, + priceEstimateToWei, } module.exports = selectors @@ -49,6 +54,16 @@ function getBasicGasEstimateLoadingStatus (state) { return state.gas.basicEstimateIsLoading } +function getAveragePriceEstimateInHexWEI (state) { + const averagePriceEstimate = state.gas.basicEstimates.average + return getGasPriceInHexWei(averagePriceEstimate || '0x0') +} + +function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { + return gasButtonInfo.findIndex(({ priceInHexWei }) => { + return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice) + }) +} function apiEstimateModifiedToGWEI (estimate) { return multiplyCurrencies(estimate, 0.10, { @@ -68,21 +83,6 @@ function basicPriceEstimateToETHTotal (estimate, gasLimit) { }) } -function ethTotalToConvertedCurrency (ethTotal, convertedCurrency, conversionRate) { - return conversionUtil(ethTotal, { - fromNumericBase: 'dec', - toNumericBase: 'dec', - fromCurrency: 'ETH', - toCurrency: convertedCurrency, - numberOfDecimals: 2, - conversionRate, - }) -} - -function formatETHFee (ethFee) { - return ethFee + ' ETH' -} - function getRenderableEthFee (estimate, gasLimit) { return pipe( apiEstimateModifiedToGWEI, @@ -150,9 +150,8 @@ function getRenderableBasicEstimateData (state) { if (getBasicGasEstimateLoadingStatus(state)) { return [] } - - const gasLimit = getGasLimit(state) - const conversionRate = getConversionRate(state) + const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state) + const conversionRate = state.metamask.conversionRate const currentCurrency = getCurrentCurrency(state) const { gas: { From b567c78bcae73e9c73b69040d22e096e4f876a2b Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 13 Sep 2018 10:05:17 -0230 Subject: [PATCH 15/64] Integrate gas buttons with the send screen. --- app/_locales/en/messages.json | 12 ++++ .../button-group/button-group.component.js | 6 ++ .../gas-modal-page-container.component.js | 16 +++-- .../gas-modal-page-container.container.js | 13 +++- .../gas-price-button-group.component.js | 27 ++++---- .../gas-price-button-group/index.scss | 67 +++++++++++++++++++ .../page-container.component.js | 3 +- .../gas-fee-display.component.js | 7 +- .../send-gas-row/send-gas-row.component.js | 33 ++++++--- .../send-gas-row/send-gas-row.container.js | 47 +++++++++++-- .../send-gas-row/send-gas-row.selectors.js | 5 ++ ui/app/css/itcss/components/send.scss | 30 ++++++++- ui/app/ducks/send.duck.js | 19 ++++++ ui/app/selectors/custom-gas.js | 57 ++++++++++++++-- 14 files changed, 301 insertions(+), 41 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 017a8a38047a..7a79da2bdea2 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -121,6 +121,9 @@ "available": { "message": "Available" }, + "average": { + "message": "Average" + }, "back": { "message": "Back" }, @@ -439,6 +442,9 @@ "failed": { "message": "Failed" }, + "fast": { + "message": "Fast" + }, "feeChartTitle": { "message": "Live Transaction Fee Predictions" }, @@ -1023,6 +1029,9 @@ "save": { "message": "Save" }, + "slow": { + "message": "Slow" + }, "saveAsCsvFile": { "message": "Save as CSV File" }, @@ -1277,6 +1286,9 @@ "transactionErrorNoContract": { "message": "Trying to call a function on a non-contract address." }, + "transactionFee": { + "message": "Transaction Fee" + }, "transactionMemo": { "message": "Transaction memo (optional)" }, diff --git a/ui/app/components/button-group/button-group.component.js b/ui/app/components/button-group/button-group.component.js index 440b3c4f78aa..723f9b526f73 100644 --- a/ui/app/components/button-group/button-group.component.js +++ b/ui/app/components/button-group/button-group.component.js @@ -23,6 +23,12 @@ export default class ButtonGroup extends PureComponent { : this.props.defaultActiveButtonIndex, } + componentDidUpdate (prevProps, prevState) { + if (typeof this.props.newActiveButtonIndex === 'number' && prevState.activeButtonIndex !== this.props.newActiveButtonIndex) { + this.setState({ activeButtonIndex: prevProps.newActiveButtonIndex }) + } + } + handleButtonClick (activeButtonIndex) { this.setState({ activeButtonIndex }) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 89065472d39e..db730458d6ba 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -89,16 +89,20 @@ export default class GasModalPageContainer extends Component { }, { gasPriceButtonGroupProps, + hideBasic, ...advancedTabProps }) { return ( - -
- { this.renderBasicTabContent(gasPriceButtonGroupProps) } - { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } -
-
+ {hideBasic + ? null + : +
+ { this.renderBasicTabContent(gasPriceButtonGroupProps) } + { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } +
+
+ }
{ this.renderAdvancedTabContent(advancedTabProps) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 7e2a7e1442c4..a150e5009c8d 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -10,6 +10,9 @@ import { setCustomGasPrice, setCustomGasLimit, } from '../../../ducks/gas.duck' +import { + hideGasButtonGroup, +} from '../../../ducks/send.duck' import { updateGasAndCalculate, } from '../../../ducks/confirm-transaction.duck' @@ -59,7 +62,10 @@ const mapStateToProps = state => { const newTotalFiat = addHexWEIsToRenderableFiat(value, customGasTotal, currentCurrency, conversionRate) + const hideBasic = state.appState.modal.modalState.props.hideBasic + return { + hideBasic, isConfirm: isConfirm(state), customGasPriceInHex, customGasLimitInHex, @@ -95,6 +101,7 @@ const mapDispatchToProps = dispatch => { updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) }, + hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), } } @@ -102,6 +109,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { const { gasPriceButtonGroupProps, isConfirm } = stateProps const { updateCustomGasPrice: dispatchUpdateCustomGasPrice, + hideGasButtonGroup: dispatchHideGasButtonGroup, setGasData: dispatchSetGasData, updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, ...otherDispatchProps @@ -111,7 +119,10 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...stateProps, ...otherDispatchProps, ...ownProps, - onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : dispatchSetGasData, + onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : (newLimit, newPrice) => { + dispatchSetGasData(newLimit, newPrice) + dispatchHideGasButtonGroup() + }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchUpdateCustomGasPrice, diff --git a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js index 3873f54bc030..8d6675e1866f 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js +++ b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js @@ -27,7 +27,7 @@ export default class GasPriceButtonGroup extends Component { } renderButtonContent ({ - label, + labelKey, feeInPrimaryCurrency, feeInSecondaryCurrency, timeEstimate, @@ -36,7 +36,7 @@ export default class GasPriceButtonGroup extends Component { showCheck, }) { return (
- { label &&
{ label }
} + { labelKey &&
{ this.context.t(labelKey) }
} { feeInPrimaryCurrency &&
{ feeInPrimaryCurrency }
} { feeInSecondaryCurrency &&
{ feeInSecondaryCurrency }
} { timeEstimate &&
{ timeEstimate }
} @@ -57,9 +57,7 @@ export default class GasPriceButtonGroup extends Component { onClick={() => handleGasPriceSelection(priceInHexWei)} key={`gas-price-button-${index}`} > - {buttonDataLoading - ? 'Loading...' - : this.renderButtonContent(renderableGasInfo, buttonContentPropsAndFlags)} + {this.renderButtonContent(renderableGasInfo, buttonContentPropsAndFlags)} ) } @@ -68,18 +66,23 @@ export default class GasPriceButtonGroup extends Component { const { gasButtonInfo, defaultActiveButtonIndex = 1, + newActiveButtonIndex, noButtonActiveByDefault = false, + buttonDataLoading, ...buttonPropsAndFlags } = this.props return ( - - { gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } - + !buttonDataLoading + ? + { gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } + + :
Loading...
) } } diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.scss b/ui/app/components/gas-customization/gas-price-button-group/index.scss index e2670edd53d1..7647c42c06c5 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/index.scss +++ b/ui/app/components/gas-customization/gas-price-button-group/index.scss @@ -18,6 +18,9 @@ height: 15.4px; } + &__loading-container { + height: 130px; + } .button-group__button, .button-group__button--active { height: 130px; @@ -58,3 +61,67 @@ } } } + +.gas-price-button-group--small { + display: flex; + justify-content: stretch; + max-width: 260px; + + &__button-fiat-price { + font-size: 13px; + } + + &__button-label { + font-size: 16px; + } + + &__label { + font-weight: 500; + } + + &__primary-currency { + font-size: 12px; + } + + &__secondary-currency { + font-size: 12px; + } + + &__loading-container { + height: 78px; + } + + .button-group__button, .button-group__button--active { + height: 78px; + background: white; + color: $scorpion; + padding-top: 9px; + padding-left: 8.5px; + + div { + display: flex; + flex-flow: column; + align-items: flex-start; + justify-content: flex-start; + } + + i { + &:last-child { + display: none; + } + } + } + + .button-group__button--active { + color: $white; + background: $dodger-blue; + + i { + &:last-child { + display: flex; + color: $curious-blue; + margin-top: 10px + } + } + } +} diff --git a/ui/app/components/page-container/page-container.component.js b/ui/app/components/page-container/page-container.component.js index 3a2274a29741..672255e272f7 100644 --- a/ui/app/components/page-container/page-container.component.js +++ b/ui/app/components/page-container/page-container.component.js @@ -58,7 +58,8 @@ export default class PageContainer extends PureComponent { renderActiveTabContent () { const { tabsComponent } = this.props - const { children } = tabsComponent.props + let { children } = tabsComponent.props + children = children.filter(child => child) const { activeTabIndex } = this.state return children[activeTabIndex] diff --git a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js index 9bbb67506d82..9962f8028f24 100644 --- a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js +++ b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js @@ -46,11 +46,10 @@ export default class GasFeeDisplay extends Component {
}
) diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js index 6ad4499fff9e..64a5cd603b37 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js @@ -2,6 +2,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import SendRowWrapper from '../send-row-wrapper/' import GasFeeDisplay from './gas-fee-display/gas-fee-display.component' +import GasPriceButtonGroup from '../../../gas-customization/gas-price-button-group' export default class SendGasRow extends Component { @@ -26,21 +27,37 @@ export default class SendGasRow extends Component { gasTotal, gasFeeError, showCustomizeGasModal, + gasPriceButtonGroupProps, + gasButtonGroupShown, + showGasButtonGroup } = this.props return ( - showCustomizeGasModal()} - /> + {gasButtonGroupShown + ?
+ +
showCustomizeGasModal()}> + Advanced Options +
+
+ : showCustomizeGasModal()} + />} +
) } diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js index e44fe4ef173e..19e49b39171c 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js @@ -3,25 +3,64 @@ import { getConversionRate, getCurrentCurrency, getGasTotal, + getGasPrice, } from '../../send.selectors.js' -import { getGasLoadingError, gasFeeIsInError } from './send-gas-row.selectors.js' -import { showModal } from '../../../../actions' +import{ + getBasicGasEstimateLoadingStatus, + getRenderableEstimateDataForSmallButtons, + getDefaultActiveButtonIndex +} from '../../../../selectors/custom-gas' +import{ + showGasButtonGroup +} from '../../../../ducks/send.duck' +import { getGasLoadingError, gasFeeIsInError, getGasButtonGroupShown } from './send-gas-row.selectors.js' +import { showModal, setGasPrice } from '../../../../actions' import SendGasRow from './send-gas-row.component' -export default connect(mapStateToProps, mapDispatchToProps)(SendGasRow) +export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(SendGasRow) function mapStateToProps (state) { + const gasButtonInfo = getRenderableEstimateDataForSmallButtons(state) + const activeButtonIndex = getDefaultActiveButtonIndex(gasButtonInfo, getGasPrice(state)) + return { conversionRate: getConversionRate(state), convertedCurrency: getCurrentCurrency(state), gasTotal: getGasTotal(state), gasFeeError: gasFeeIsInError(state), gasLoadingError: getGasLoadingError(state), + gasPriceButtonGroupProps: { + buttonDataLoading: getBasicGasEstimateLoadingStatus(state), + defaultActiveButtonIndex: 1, + newActiveButtonIndex: activeButtonIndex > -1 ? activeButtonIndex : null, + gasButtonInfo, + }, + gasButtonGroupShown: getGasButtonGroupShown(state), } } function mapDispatchToProps (dispatch) { return { - showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS' })), + showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })), + setGasPrice: newPrice => dispatch(setGasPrice(newPrice)), + showGasButtonGroup: () => dispatch(showGasButtonGroup()) } } + +function mergeProps (stateProps, dispatchProps, ownProps) { + const { gasPriceButtonGroupProps } = stateProps + const { + setGasPrice: dispatchSetGasPrice, + ...otherDispatchProps + } = dispatchProps + + return { + ...stateProps, + ...otherDispatchProps, + ...ownProps, + gasPriceButtonGroupProps: { + ...gasPriceButtonGroupProps, + handleGasPriceSelection: dispatchSetGasPrice, + }, + } +} \ No newline at end of file diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.selectors.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.selectors.js index 96f6293c2a4a..79c8385435dd 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.selectors.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.selectors.js @@ -1,6 +1,7 @@ const selectors = { gasFeeIsInError, getGasLoadingError, + getGasButtonGroupShown, } module.exports = selectors @@ -12,3 +13,7 @@ function getGasLoadingError (state) { function gasFeeIsInError (state) { return Boolean(state.send.errors.gasFee) } + +function getGasButtonGroupShown (state) { + return state.send.gasButtonGroupShown +} diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index c791a24c7bb5..4535ced52d89 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -579,7 +579,7 @@ font-family: Roboto; font-size: 16px; line-height: 22px; - width: 88px; + width: 112px; font-weight: 400; flex: 0 0 auto; } @@ -622,6 +622,7 @@ &__to-autocomplete { position: relative; + max-width: 260px; &__down-caret { z-index: 1026; @@ -684,6 +685,7 @@ display: flex; align-items: center; } + } &__sliders-icon-container { @@ -917,6 +919,15 @@ display: none; } } + +} + +.advanced-gas-options-btn { + display: flex; + justify-content: flex-end; + font-size: 14px; + color: #2f9ae0; + cursor: pointer; } .sliders-icon-container { @@ -935,6 +946,23 @@ font-size: 1em; } +.gas-fee-reset { + display: flex; + align-items: center; + justify-content: center; + height: 24px; + border-radius: 4px; + background-color: #fff; + position: absolute; + right: 12px; + top: 14px; + cursor: pointer; + font-size: 1em; + font-size: 14px; + color: #2f9ae0; + font-family: Roboto; +} + .sliders-icon { color: $curious-blue; } diff --git a/ui/app/ducks/send.duck.js b/ui/app/ducks/send.duck.js index db01bbaa9c16..758916d48744 100644 --- a/ui/app/ducks/send.duck.js +++ b/ui/app/ducks/send.duck.js @@ -7,11 +7,14 @@ const OPEN_TO_DROPDOWN = 'metamask/send/OPEN_TO_DROPDOWN' const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN' const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS' const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE' +const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP' +const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP' // TODO: determine if this approach to initState is consistent with conventional ducks pattern const initState = { fromDropdownOpen: false, toDropdownOpen: false, + gasButtonGroupShown: true, errors: {}, } @@ -43,6 +46,14 @@ export default function reducer ({ send: sendState = initState }, action = {}) { ...action.value, }, }) + case SHOW_GAS_BUTTON_GROUP: + return extend(newState, { + gasButtonGroupShown: true, + }) + case HIDE_GAS_BUTTON_GROUP: + return extend(newState, { + gasButtonGroupShown: false, + }) case RESET_SEND_STATE: return extend({}, initState) default: @@ -67,6 +78,14 @@ export function closeToDropdown () { return { type: CLOSE_TO_DROPDOWN } } +export function showGasButtonGroup () { + return { type: SHOW_GAS_BUTTON_GROUP } +} + +export function hideGasButtonGroup () { + return { type: HIDE_GAS_BUTTON_GROUP } +} + export function updateSendErrors (errorObject) { return { type: UPDATE_SEND_ERRORS, diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 61c0525df40c..f023b03b8639 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -25,6 +25,7 @@ const selectors = { getCustomGasLimit, getCustomGasPrice, getCustomGasTotal, + getRenderableEstimateDataForSmallButtons, getRenderableBasicEstimateData, getBasicGasEstimateLoadingStatus, getAveragePriceEstimateInHexWEI, @@ -34,6 +35,8 @@ const selectors = { module.exports = selectors +const NUMBER_OF_DECIMALS_SM_BTNS = 5 + function getCustomGasErrors (state) { return state.gas.errors } @@ -60,7 +63,9 @@ function getAveragePriceEstimateInHexWEI (state) { } function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { + console.log('gasButtonInfo', gasButtonInfo) return gasButtonInfo.findIndex(({ priceInHexWei }) => { + console.log('priceInHexWei', priceInHexWei, '|', customGasPriceInHex) return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice) }) } @@ -74,23 +79,24 @@ function apiEstimateModifiedToGWEI (estimate) { }) } -function basicPriceEstimateToETHTotal (estimate, gasLimit) { +function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) { return conversionUtil(calcGasTotal(gasLimit, estimate), { fromNumericBase: 'hex', toNumericBase: 'dec', fromDenomination: 'GWEI', - numberOfDecimals: 9, + numberOfDecimals, }) } -function getRenderableEthFee (estimate, gasLimit) { +function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) { return pipe( apiEstimateModifiedToGWEI, - partialRight(basicPriceEstimateToETHTotal, [gasLimit]), + partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]), formatETHFee )(estimate, gasLimit) } + function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) { return pipe( apiEstimateModifiedToGWEI, @@ -188,3 +194,46 @@ function getRenderableBasicEstimateData (state) { }, ] } + +function getRenderableEstimateDataForSmallButtons (state) { + if (getBasicGasEstimateLoadingStatus(state)) { + return [] + } + const gasLimit = state.metamask.send.gasLimit || getCustomGasLimit(state) + const conversionRate = state.metamask.conversionRate + const currentCurrency = getCurrentCurrency(state) + const { + gas: { + basicEstimates: { + safeLow, + average, + fast, + blockTime, + safeLowWait, + avgWait, + fastWait, + }, + }, + } = state + + return [ + { + labelKey: 'fast', + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), + feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS), + priceInHexWei: getGasPriceInHexWei(fast), + }, + { + labelKey: 'average', + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate), + feeInPrimaryCurrency: getRenderableEthFee(average, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS), + priceInHexWei: getGasPriceInHexWei(average), + }, + { + labelKey: 'slow', + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), + feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS), + priceInHexWei: getGasPriceInHexWei(safeLow), + }, + ] +} From 5354325fab9b9ab3091e3c49e6b940fa713d1799 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 20 Sep 2018 01:46:43 -0230 Subject: [PATCH 16/64] Test updates and additions for button integration with send screen. --- app/_locales/en/messages.json | 3 + .../button-group/button-group.component.js | 6 +- .../tests/button-group-component.test.js | 14 +++ .../gas-modal-page-container.component.js | 23 ++-- .../gas-modal-page-container.container.js | 10 +- ...gas-modal-page-container-component.test.js | 13 ++ ...gas-modal-page-container-container.test.js | 114 +++++++++++++++++- .../gas-price-button-group.component.js | 3 +- .../gas-price-button-group-component.test.js | 35 +++--- .../gas-fee-display.component.js | 4 +- .../test/gas-fee-display.component.test.js | 10 +- .../send-gas-row/send-gas-row.component.js | 9 +- .../send-gas-row/send-gas-row.container.js | 12 +- .../tests/send-gas-row-component.test.js | 37 +++++- .../tests/send-gas-row-container.test.js | 81 ++++++++++++- .../tests/send-gas-row-selectors.test.js | 13 ++ ui/app/ducks/tests/send-duck.test.js | 37 ++++++ ui/app/selectors/custom-gas.js | 6 - ui/app/selectors/tests/custom-gas.test.js | 99 +++++++++++++++ 19 files changed, 465 insertions(+), 64 deletions(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 7a79da2bdea2..1fd4c8e1efbd 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -65,6 +65,9 @@ "address": { "message": "Address" }, + "advancedOptions": { + "message": "Advanced Options" + }, "addCustomToken": { "message": "Add custom token" }, diff --git a/ui/app/components/button-group/button-group.component.js b/ui/app/components/button-group/button-group.component.js index 723f9b526f73..17a281030bd7 100644 --- a/ui/app/components/button-group/button-group.component.js +++ b/ui/app/components/button-group/button-group.component.js @@ -10,6 +10,7 @@ export default class ButtonGroup extends PureComponent { children: PropTypes.array, className: PropTypes.string, style: PropTypes.object, + newActiveButtonIndex: PropTypes.number, } static defaultProps = { @@ -23,9 +24,10 @@ export default class ButtonGroup extends PureComponent { : this.props.defaultActiveButtonIndex, } - componentDidUpdate (prevProps, prevState) { + componentDidUpdate (_, prevState) { + // Provides an API for dynamically updating the activeButtonIndex if (typeof this.props.newActiveButtonIndex === 'number' && prevState.activeButtonIndex !== this.props.newActiveButtonIndex) { - this.setState({ activeButtonIndex: prevProps.newActiveButtonIndex }) + this.setState({ activeButtonIndex: this.props.newActiveButtonIndex }) } } diff --git a/ui/app/components/button-group/tests/button-group-component.test.js b/ui/app/components/button-group/tests/button-group-component.test.js index f07bb97c8b27..0bece90d6fc7 100644 --- a/ui/app/components/button-group/tests/button-group-component.test.js +++ b/ui/app/components/button-group/tests/button-group-component.test.js @@ -35,6 +35,20 @@ describe('ButtonGroup Component', function () { ButtonGroup.prototype.renderButtons.resetHistory() }) + describe('componentDidUpdate', () => { + it('should set the activeButtonIndex to the updated newActiveButtonIndex', () => { + assert.equal(wrapper.state('activeButtonIndex'), 1) + wrapper.setProps({ newActiveButtonIndex: 2 }) + assert.equal(wrapper.state('activeButtonIndex'), 2) + }) + + it('should not set the activeButtonIndex to an updated newActiveButtonIndex that is not a number', () => { + assert.equal(wrapper.state('activeButtonIndex'), 1) + wrapper.setProps({ newActiveButtonIndex: null }) + assert.equal(wrapper.state('activeButtonIndex'), 1) + }) + }) + describe('handleButtonClick', () => { it('should set the activeButtonIndex', () => { assert.equal(wrapper.state('activeButtonIndex'), 1) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index db730458d6ba..41fe901fa573 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -92,23 +92,24 @@ export default class GasModalPageContainer extends Component { hideBasic, ...advancedTabProps }) { + let tabsToRender = [ + { name: 'basic', content: this.renderBasicTabContent(gasPriceButtonGroupProps) }, + { name: 'advanced', content: this.renderAdvancedTabContent(advancedTabProps) }, + ] + + if (hideBasic) { + tabsToRender = tabsToRender.slice(1) + } + return ( - {hideBasic - ? null - : + {tabsToRender.map(({ name, content }, i) =>
- { this.renderBasicTabContent(gasPriceButtonGroupProps) } + { content } { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) }
- } - -
- { this.renderAdvancedTabContent(advancedTabProps) } - { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } -
-
+ )}
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index a150e5009c8d..f9ed1cebba61 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -119,10 +119,12 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { ...stateProps, ...otherDispatchProps, ...ownProps, - onSubmit: isConfirm ? dispatchUpdateConfirmTxGasAndCalculate : (newLimit, newPrice) => { - dispatchSetGasData(newLimit, newPrice) - dispatchHideGasButtonGroup() - }, + onSubmit: isConfirm + ? dispatchUpdateConfirmTxGasAndCalculate + : (newLimit, newPrice) => { + dispatchSetGasData(newLimit, newPrice) + dispatchHideGasButtonGroup() + }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchUpdateCustomGasPrice, diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index c41adca83a03..fdd7709d91ef 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -161,6 +161,19 @@ describe('GasModalPageContainer Component', function () { assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) }) + + it('should not render the basic tab if hideBasic is true', () => { + const renderTabsResult = wrapper.instance().renderTabs(mockInfoRowProps, { + gasPriceButtonGroupProps: mockGasPriceButtonGroupProps, + otherProps: 'mockAdvancedTabProps', + hideBasic: true, + }) + + const renderedTabs = shallow(renderTabsResult) + const tabs = renderedTabs.find(Tab) + assert.equal(tabs.length, 1) + assert.equal(tabs.at(0).props().name, 'advanced') + }) }) describe('renderInfoRow', () => { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index e01fd38986cd..238f27ed6952 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -4,6 +4,7 @@ import sinon from 'sinon' let mapStateToProps let mapDispatchToProps +let mergeProps const actionSpies = { hideModal: sinon.spy(), @@ -20,11 +21,16 @@ const confirmTransactionActionSpies = { updateGasAndCalculate: sinon.spy(), } +const sendActionSpies = { + hideGasButtonGroup: sinon.spy(), +} + proxyquire('../gas-modal-page-container.container.js', { 'react-redux': { - connect: (ms, md) => { + connect: (ms, md, mp) => { mapStateToProps = ms mapDispatchToProps = md + mergeProps = mp return () => ({}) }, }, @@ -36,6 +42,7 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../actions': actionSpies, '../../../ducks/gas.duck': gasActionSpies, '../../../ducks/confirm-transaction.duck': confirmTransactionActionSpies, + '../../../ducks/send.duck': sendActionSpies, }) describe('gas-modal-page-container container', () => { @@ -44,6 +51,15 @@ describe('gas-modal-page-container container', () => { it('should map the correct properties to props', () => { const mockState2 = { + appState: { + modal: { + modalState: { + props: { + hideBasic: true, + }, + }, + }, + }, metamask: { send: { gasLimit: '16', @@ -80,10 +96,11 @@ describe('gas-modal-page-container container', () => { newTotalFiat: '637.41', gasPriceButtonGroupProps: { - buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:3', - defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:3ffffffff0x3200000', - gasButtonInfo: 'mockRenderableBasicEstimateData:3', + buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', + defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff0x3200000', + gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, + hideBasic: true, infoRowProps: { originalTotalFiat: '22.58', originalTotalEth: '0.451569 ETH', @@ -110,6 +127,14 @@ describe('gas-modal-page-container container', () => { gasActionSpies.setCustomGasLimit.resetHistory() }) + describe('hideGasButtonGroup()', () => { + it('should dispatch a hideGasButtonGroup action', () => { + mapDispatchToPropsObject.hideGasButtonGroup() + assert(dispatchSpy.calledOnce) + assert(sendActionSpies.hideGasButtonGroup.calledOnce) + }) + }) + describe('hideModal()', () => { it('should dispatch a hideModal action', () => { mapDispatchToPropsObject.hideModal() @@ -168,4 +193,85 @@ describe('gas-modal-page-container container', () => { }) + describe('mergeProps', () => { + let stateProps + let dispatchProps + let ownProps + + beforeEach(() => { + stateProps = { + gasPriceButtonGroupProps: { + someGasPriceButtonGroupProp: 'foo', + anotherGasPriceButtonGroupProp: 'bar', + }, + isConfirm: true, + someOtherStateProp: 'baz', + } + dispatchProps = { + updateCustomGasPrice: sinon.spy(), + hideGasButtonGroup: sinon.spy(), + setGasData: sinon.spy(), + updateConfirmTxGasAndCalculate: sinon.spy(), + someOtherDispatchProp: sinon.spy(), + } + ownProps = { someOwnProp: 123 } + }) + it('should return the expected props when isConfirm is true', () => { + const result = mergeProps(stateProps, dispatchProps, ownProps) + + assert.equal(result.isConfirm, true) + assert.equal(result.someOtherStateProp, 'baz') + assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') + assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') + assert.equal(result.someOwnProp, 123) + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) + assert.equal(dispatchProps.setGasData.callCount, 0) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + + result.onSubmit() + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1) + assert.equal(dispatchProps.setGasData.callCount, 0) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) + result.gasPriceButtonGroupProps.handleGasPriceSelection() + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 1) + + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) + result.someOtherDispatchProp() + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) + }) + + it('should return the expected props when isConfirm is false', () => { + const result = mergeProps(Object.assign({}, stateProps, { isConfirm: false }), dispatchProps, ownProps) + + assert.equal(result.isConfirm, false) + assert.equal(result.someOtherStateProp, 'baz') + assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') + assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') + assert.equal(result.someOwnProp, 123) + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) + assert.equal(dispatchProps.setGasData.callCount, 0) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + + result.onSubmit('mockNewLimit', 'mockNewPrice') + + assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) + assert.equal(dispatchProps.setGasData.callCount, 1) + assert.deepEqual(dispatchProps.setGasData.getCall(0).args, ['mockNewLimit', 'mockNewPrice']) + assert.equal(dispatchProps.hideGasButtonGroup.callCount, 1) + + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) + result.gasPriceButtonGroupProps.handleGasPriceSelection() + assert.equal(dispatchProps.updateCustomGasPrice.callCount, 1) + + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) + result.someOtherDispatchProp() + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) + }) + }) + }) diff --git a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js index 8d6675e1866f..62ebb512d55f 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js +++ b/ui/app/components/gas-customization/gas-price-button-group/gas-price-button-group.component.js @@ -22,6 +22,7 @@ export default class GasPriceButtonGroup extends Component { defaultActiveButtonIndex: PropTypes.number, gasButtonInfo: PropTypes.arrayOf(PropTypes.shape(GAS_OBJECT_PROPTYPES_SHAPE)), handleGasPriceSelection: PropTypes.func, + newActiveButtonIndex: PropTypes.number, noButtonActiveByDefault: PropTypes.bool, showCheck: PropTypes.bool, } @@ -82,7 +83,7 @@ export default class GasPriceButtonGroup extends Component { > { gasButtonInfo.map((obj, index) => this.renderButton(obj, buttonPropsAndFlags, index)) } - :
Loading...
+ :
{ this.context.t('loading') }
) } } diff --git a/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js index e1458188d087..79f74f8e40b8 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js +++ b/ui/app/components/gas-customization/gas-price-button-group/tests/gas-price-button-group-component.test.js @@ -1,6 +1,6 @@ import React from 'react' import assert from 'assert' -import { shallow } from 'enzyme' +import shallow from '../../../../../lib/shallow-with-context' import sinon from 'sinon' import GasPriceButtonGroup from '../gas-price-button-group.component' @@ -36,7 +36,6 @@ const mockGasPriceButtonGroupProps = { } const mockButtonPropsAndFlags = Object.assign({}, { - buttonDataLoading: mockGasPriceButtonGroupProps.buttonDataLoading, className: mockGasPriceButtonGroupProps.className, handleGasPriceSelection: mockGasPriceButtonGroupProps.handleGasPriceSelection, showCheck: mockGasPriceButtonGroupProps.showCheck, @@ -87,12 +86,19 @@ describe('GasPriceButtonGroup Component', function () { ) } - it('should called this.renderButton 3 times, with the correct args', () => { + it('should call this.renderButton 3 times, with the correct args', () => { assert.equal(GasPriceButtonGroup.prototype.renderButton.callCount, 3) renderButtonArgsTest(0, mockButtonPropsAndFlags) renderButtonArgsTest(1, mockButtonPropsAndFlags) renderButtonArgsTest(2, mockButtonPropsAndFlags) }) + + it('should show loading if buttonDataLoading', () => { + wrapper.setProps({ buttonDataLoading: true }) + assert(wrapper.is('div')) + assert(wrapper.hasClass('gas-price-button-group__loading-container')) + assert.equal(wrapper.text(), 'loading') + }) }) describe('renderButton', () => { @@ -147,29 +153,18 @@ describe('GasPriceButtonGroup Component', function () { ] ) }) - - it('should not call renderButtonContent if buttonDataLoading is true and should show a loading indicator', () => { - GasPriceButtonGroup.prototype.renderButtonContent.resetHistory() - const renderButtonResult = GasPriceButtonGroup.prototype.renderButton( - Object.assign({}, mockGasPriceButtonGroupProps.gasButtonInfo[0]), - Object.assign({}, mockButtonPropsAndFlags, {buttonDataLoading: true}) - ) - wrappedRenderButtonResult = shallow(renderButtonResult) - assert.equal(GasPriceButtonGroup.prototype.renderButtonContent.callCount, 0) - assert.equal(wrappedRenderButtonResult.childAt(0).text(), 'Loading...') - }) }) describe('renderButtonContent', () => { - it('should render a label if passed a label', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ - label: 'mockLabel', + it('should render a label if passed a labelKey', () => { + const renderButtonContentResult = wrapper.instance().renderButtonContent({ + labelKey: 'mockLabelKey', }, { className: 'someClass', }) const wrappedRenderButtonContentResult = shallow(renderButtonContentResult) assert.equal(wrappedRenderButtonContentResult.childAt(0).children().length, 1) - assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabel') + assert.equal(wrappedRenderButtonContentResult.find('.someClass__label').text(), 'mockLabelKey') }) it('should render a feeInPrimaryCurrency if passed a feeInPrimaryCurrency', () => { @@ -215,8 +210,8 @@ describe('GasPriceButtonGroup Component', function () { }) it('should render all elements if all args passed', () => { - const renderButtonContentResult = GasPriceButtonGroup.prototype.renderButtonContent({ - label: 'mockLabel', + const renderButtonContentResult = wrapper.instance().renderButtonContent({ + labelKey: 'mockLabel', feeInPrimaryCurrency: 'mockFeeInPrimaryCurrency', feeInSecondaryCurrency: 'mockFeeInSecondaryCurrency', timeEstimate: 'mockTimeEstimate', diff --git a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js index 9962f8028f24..40f8b1fe0e01 100644 --- a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js +++ b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/gas-fee-display.component.js @@ -11,7 +11,7 @@ export default class GasFeeDisplay extends Component { convertedCurrency: PropTypes.string, gasLoadingError: PropTypes.bool, gasTotal: PropTypes.string, - onClick: PropTypes.func, + showGasButtonGroup: PropTypes.func, }; static contextTypes = { @@ -49,7 +49,7 @@ export default class GasFeeDisplay extends Component { className="gas-fee-reset" onClick={showGasButtonGroup} > - Reset + { this.context.t('reset') }
) diff --git a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js index 9ff01493a91a..c7ac175d9749 100644 --- a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js +++ b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js @@ -17,9 +17,9 @@ describe('SendGasRow Component', function () { wrapper = shallow(, {context: {t: str => str + '_t'}}) }) @@ -41,13 +41,19 @@ describe('SendGasRow Component', function () { assert.equal(value, 'mockGasTotal') }) - it('should render the Button with the correct props', () => { + it('should render the reset button with the correct props', () => { const { onClick, + className, } = wrapper.find('button').props() + assert.equal(className, 'gas-fee-reset') assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) onClick() assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) }) + + it('should render the reset button with the correct text', () => { + assert.equal(wrapper.find('button').text(), 'reset_t') + }) }) }) diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js index 64a5cd603b37..507407306550 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js @@ -13,6 +13,9 @@ export default class SendGasRow extends Component { gasLoadingError: PropTypes.bool, gasTotal: PropTypes.string, showCustomizeGasModal: PropTypes.func, + gasPriceButtonGroupProps: PropTypes.object, + showGasButtonGroup: PropTypes.func, + gasButtonGroupShown: PropTypes.bool, } static contextTypes = { @@ -29,7 +32,7 @@ export default class SendGasRow extends Component { showCustomizeGasModal, gasPriceButtonGroupProps, gasButtonGroupShown, - showGasButtonGroup + showGasButtonGroup, } = this.props return ( @@ -43,10 +46,10 @@ export default class SendGasRow extends Component {
showCustomizeGasModal()}> - Advanced Options + { this.context.t('advancedOptions') }
: dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })), setGasPrice: newPrice => dispatch(setGasPrice(newPrice)), - showGasButtonGroup: () => dispatch(showGasButtonGroup()) + showGasButtonGroup: () => dispatch(showGasButtonGroup()), } } @@ -63,4 +63,4 @@ function mergeProps (stateProps, dispatchProps, ownProps) { handleGasPriceSelection: dispatchSetGasPrice, }, } -} \ No newline at end of file +} diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js index 54a92bd2d5df..171cd7bf6637 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js @@ -6,6 +6,7 @@ import SendGasRow from '../send-gas-row.component.js' import SendRowWrapper from '../../send-row-wrapper/send-row-wrapper.component' import GasFeeDisplay from '../gas-fee-display/gas-fee-display.component' +import GasPriceButtonGroup from '../../../../gas-customization/gas-price-button-group' const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), @@ -21,7 +22,13 @@ describe('SendGasRow Component', function () { gasFeeError={'mockGasFeeError'} gasLoadingError={false} gasTotal={'mockGasTotal'} + showGasButtonGroup={'mockShowGasPriceButtonGroup'} + gasButtonGroupShown={false} showCustomizeGasModal={propsMethodSpies.showCustomizeGasModal} + gasPriceButtonGroupProps={{ + someGasPriceButtonGroupProp: 'foo', + anotherGasPriceButtonGroupProp: 'bar', + }} />, { context: { t: str => str + '_t' } }) }) @@ -41,7 +48,7 @@ describe('SendGasRow Component', function () { errorType, } = wrapper.find(SendRowWrapper).props() - assert.equal(label, 'gasFee_t:') + assert.equal(label, 'transactionFee_t:') assert.equal(showError, 'mockGasFeeError') assert.equal(errorType, 'gasFee') }) @@ -57,14 +64,42 @@ describe('SendGasRow Component', function () { gasLoadingError, gasTotal, onClick, + showGasButtonGroup, } = wrapper.find(SendRowWrapper).childAt(0).props() assert.equal(conversionRate, 20) assert.equal(convertedCurrency, 'mockConvertedCurrency') assert.equal(gasLoadingError, false) assert.equal(gasTotal, 'mockGasTotal') + assert.equal(showGasButtonGroup, 'mockShowGasPriceButtonGroup') assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) onClick() assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) }) + + it('should render the GasPriceButtonGroup if gasButtonGroupShown is true', () => { + wrapper.setProps({ gasButtonGroupShown: true }) + const rendered = wrapper.find(SendRowWrapper).childAt(0) + assert.equal(rendered.children().length, 2) + + const gasPriceButtonGroup = rendered.childAt(0) + assert(gasPriceButtonGroup.is(GasPriceButtonGroup)) + assert(gasPriceButtonGroup.hasClass('gas-price-button-group--small')) + assert.equal(gasPriceButtonGroup.props().showCheck, false) + assert.equal(gasPriceButtonGroup.props().someGasPriceButtonGroupProp, 'foo') + assert.equal(gasPriceButtonGroup.props().anotherGasPriceButtonGroupProp, 'bar') + }) + + it('should render an advanced options button if gasButtonGroupShown is true', () => { + wrapper.setProps({ gasButtonGroupShown: true }) + const rendered = wrapper.find(SendRowWrapper).childAt(0) + assert.equal(rendered.children().length, 2) + + const advancedOptionsButton = rendered.childAt(1) + assert.equal(advancedOptionsButton.text(), 'advancedOptions_t') + + assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) + advancedOptionsButton.props().onClick() + assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) + }) }) }) diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js index 2ce062505670..1c385e2163c5 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js @@ -4,16 +4,23 @@ import sinon from 'sinon' let mapStateToProps let mapDispatchToProps +let mergeProps const actionSpies = { showModal: sinon.spy(), + setGasPrice: sinon.spy(), +} + +const sendDuckSpies = { + showGasButtonGroup: sinon.spy(), } proxyquire('../send-gas-row.container.js', { 'react-redux': { - connect: (ms, md) => { + connect: (ms, md, mp) => { mapStateToProps = ms mapDispatchToProps = md + mergeProps = mp return () => ({}) }, }, @@ -21,12 +28,20 @@ proxyquire('../send-gas-row.container.js', { getConversionRate: (s) => `mockConversionRate:${s}`, getCurrentCurrency: (s) => `mockConvertedCurrency:${s}`, getGasTotal: (s) => `mockGasTotal:${s}`, + getGasPrice: (s) => `mockGasPrice:${s}`, }, './send-gas-row.selectors.js': { getGasLoadingError: (s) => `mockGasLoadingError:${s}`, gasFeeIsInError: (s) => `mockGasFeeError:${s}`, + getGasButtonGroupShown: (s) => `mockGetGasButtonGroupShown:${s}`, }, '../../../../actions': actionSpies, + '../../../../selectors/custom-gas': { + getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`, + getRenderableEstimateDataForSmallButtons: (s) => `mockGasButtonInfo:${s}`, + getDefaultActiveButtonIndex: (gasButtonInfo, gasPrice) => gasButtonInfo.length + gasPrice.length, + }, + '../../../../ducks/send.duck': sendDuckSpies, }) describe('send-gas-row container', () => { @@ -40,6 +55,13 @@ describe('send-gas-row container', () => { gasTotal: 'mockGasTotal:mockState', gasFeeError: 'mockGasFeeError:mockState', gasLoadingError: 'mockGasLoadingError:mockState', + gasPriceButtonGroupProps: { + buttonDataLoading: `mockBasicGasEstimateLoadingStatus:mockState`, + defaultActiveButtonIndex: 1, + newActiveButtonIndex: 49, + gasButtonInfo: `mockGasButtonInfo:mockState`, + }, + gasButtonGroupShown: `mockGetGasButtonGroupShown:mockState`, }) }) @@ -60,11 +82,66 @@ describe('send-gas-row container', () => { assert(dispatchSpy.calledOnce) assert.deepEqual( actionSpies.showModal.getCall(0).args[0], - { name: 'CUSTOMIZE_GAS' } + { name: 'CUSTOMIZE_GAS', hideBasic: true } ) }) }) + describe('setGasPrice()', () => { + it('should dispatch an action', () => { + mapDispatchToPropsObject.setGasPrice('mockNewPrice') + assert(dispatchSpy.calledOnce) + assert(actionSpies.setGasPrice.calledOnce) + assert.equal(actionSpies.setGasPrice.getCall(0).args[0], 'mockNewPrice') + }) + }) + + describe('showGasButtonGroup()', () => { + it('should dispatch an action', () => { + mapDispatchToPropsObject.showGasButtonGroup() + assert(dispatchSpy.calledOnce) + assert(sendDuckSpies.showGasButtonGroup.calledOnce) + }) + }) + + }) + + describe('mergeProps', () => { + let stateProps + let dispatchProps + let ownProps + + beforeEach(() => { + stateProps = { + gasPriceButtonGroupProps: { + someGasPriceButtonGroupProp: 'foo', + anotherGasPriceButtonGroupProp: 'bar', + }, + someOtherStateProp: 'baz', + } + dispatchProps = { + setGasPrice: sinon.spy(), + someOtherDispatchProp: sinon.spy(), + } + ownProps = { someOwnProp: 123 } + }) + + it('should return the expected props when isConfirm is true', () => { + const result = mergeProps(stateProps, dispatchProps, ownProps) + + assert.equal(result.someOtherStateProp, 'baz') + assert.equal(result.gasPriceButtonGroupProps.someGasPriceButtonGroupProp, 'foo') + assert.equal(result.gasPriceButtonGroupProps.anotherGasPriceButtonGroupProp, 'bar') + assert.equal(result.someOwnProp, 123) + + assert.equal(dispatchProps.setGasPrice.callCount, 0) + result.gasPriceButtonGroupProps.handleGasPriceSelection() + assert.equal(dispatchProps.setGasPrice.callCount, 1) + + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 0) + result.someOtherDispatchProp() + assert.equal(dispatchProps.someOtherDispatchProp.callCount, 1) + }) }) }) diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js index d46dd9d8b0b5..bd3c9a257abc 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-selectors.test.js @@ -2,6 +2,7 @@ import assert from 'assert' import { gasFeeIsInError, getGasLoadingError, + getGasButtonGroupShown, } from '../send-gas-row.selectors.js' describe('send-gas-row selectors', () => { @@ -46,4 +47,16 @@ describe('send-gas-row selectors', () => { }) }) + describe('getGasButtonGroupShown()', () => { + it('should return send.gasButtonGroupShown', () => { + const state = { + send: { + gasButtonGroupShown: 'foobar', + }, + } + + assert.equal(getGasButtonGroupShown(state), 'foobar') + }) + }) + }) diff --git a/ui/app/ducks/tests/send-duck.test.js b/ui/app/ducks/tests/send-duck.test.js index c101132d9009..196fe226c107 100644 --- a/ui/app/ducks/tests/send-duck.test.js +++ b/ui/app/ducks/tests/send-duck.test.js @@ -6,6 +6,8 @@ import SendReducer, { openToDropdown, closeToDropdown, updateSendErrors, + showGasButtonGroup, + hideGasButtonGroup, } from '../send.duck.js' describe('Send Duck', () => { @@ -18,6 +20,7 @@ describe('Send Duck', () => { fromDropdownOpen: false, toDropdownOpen: false, errors: {}, + gasButtonGroupShown: true, } const OPEN_FROM_DROPDOWN = 'metamask/send/OPEN_FROM_DROPDOWN' const CLOSE_FROM_DROPDOWN = 'metamask/send/CLOSE_FROM_DROPDOWN' @@ -25,6 +28,8 @@ describe('Send Duck', () => { const CLOSE_TO_DROPDOWN = 'metamask/send/CLOSE_TO_DROPDOWN' const UPDATE_SEND_ERRORS = 'metamask/send/UPDATE_SEND_ERRORS' const RESET_SEND_STATE = 'metamask/send/RESET_SEND_STATE' + const SHOW_GAS_BUTTON_GROUP = 'metamask/send/SHOW_GAS_BUTTON_GROUP' + const HIDE_GAS_BUTTON_GROUP = 'metamask/send/HIDE_GAS_BUTTON_GROUP' describe('SendReducer()', () => { it('should initialize state', () => { @@ -85,6 +90,24 @@ describe('Send Duck', () => { ) }) + it('should set gasButtonGroupShown to true when receiving a SHOW_GAS_BUTTON_GROUP action', () => { + assert.deepEqual( + SendReducer(Object.assign({}, mockState, { gasButtonGroupShown: false }), { + type: SHOW_GAS_BUTTON_GROUP, + }), + Object.assign({gasButtonGroupShown: true}, mockState.send) + ) + }) + + it('should set gasButtonGroupShown to false when receiving a HIDE_GAS_BUTTON_GROUP action', () => { + assert.deepEqual( + SendReducer(mockState, { + type: HIDE_GAS_BUTTON_GROUP, + }), + Object.assign({gasButtonGroupShown: false}, mockState.send) + ) + }) + it('should extend send.errors with the value of a UPDATE_SEND_ERRORS action', () => { const modifiedMockState = Object.assign({}, mockState, { send: { @@ -145,6 +168,20 @@ describe('Send Duck', () => { ) }) + describe('showGasButtonGroup', () => { + assert.deepEqual( + showGasButtonGroup(), + { type: SHOW_GAS_BUTTON_GROUP } + ) + }) + + describe('hideGasButtonGroup', () => { + assert.deepEqual( + hideGasButtonGroup(), + { type: HIDE_GAS_BUTTON_GROUP } + ) + }) + describe('updateSendErrors', () => { assert.deepEqual( updateSendErrors('mockErrorObject'), diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index f023b03b8639..d5a3972df156 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -63,9 +63,7 @@ function getAveragePriceEstimateInHexWEI (state) { } function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { - console.log('gasButtonInfo', gasButtonInfo) return gasButtonInfo.findIndex(({ priceInHexWei }) => { - console.log('priceInHexWei', priceInHexWei, '|', customGasPriceInHex) return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice) }) } @@ -208,10 +206,6 @@ function getRenderableEstimateDataForSmallButtons (state) { safeLow, average, fast, - blockTime, - safeLowWait, - avgWait, - fastWait, }, }, } = state diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index d53c1ec9886d..5fde61c9be9e 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -7,6 +7,7 @@ const { getCustomGasPrice, getCustomGasTotal, getRenderableBasicEstimateData, + getRenderableEstimateDataForSmallButtons, } = proxyquire('../custom-gas', {}) describe('custom-gas selectors', () => { @@ -137,4 +138,102 @@ describe('custom-gas selectors', () => { }) + describe('getRenderableEstimateDataForSmallButtons()', () => { + const tests = [ + { + expectedResult: [ + { + feeInSecondaryCurrency: '$0.05', + feeInPrimaryCurrency: '0.00021 ETH', + labelKey: 'fast', + priceInHexWei: '0x2540be400', + }, + { + feeInSecondaryCurrency: '$0.03', + feeInPrimaryCurrency: '0.0001 ETH', + labelKey: 'average', + priceInHexWei: '0x12a05f200', + }, + { + feeInSecondaryCurrency: '$0.01', + feeInPrimaryCurrency: '0.00005 ETH', + labelKey: 'slow', + priceInHexWei: '0x9502f900', + }, + ], + mockState: { + metamask: { + conversionRate: 255.71, + currentCurrency: 'usd', + send: { + gasLimit: '0x5208', + }, + }, + gas: { + basicEstimates: { + blockTime: 14.16326530612245, + safeLow: 25, + safeLowWait: 6.6, + average: 50, + avgWait: 3.3, + fast: 100, + fastWait: 0.5, + }, + }, + }, + }, + { + expectedResult: [ + { + feeInSecondaryCurrency: '$1.07', + feeInPrimaryCurrency: '0.00042 ETH', + labelKey: 'fast', + priceInHexWei: '0x4a817c800', + }, + { + feeInSecondaryCurrency: '$0.54', + feeInPrimaryCurrency: '0.00021 ETH', + labelKey: 'average', + priceInHexWei: '0x2540be400', + }, + { + feeInSecondaryCurrency: '$0.27', + feeInPrimaryCurrency: '0.0001 ETH', + labelKey: 'slow', + priceInHexWei: '0x12a05f200', + }, + ], + mockState: { + metamask: { + conversionRate: 2557.1, + currentCurrency: 'usd', + send: { + gasLimit: '0x5208', + }, + }, + gas: { + basicEstimates: { + blockTime: 14.16326530612245, + safeLow: 50, + safeLowWait: 13.2, + average: 100, + avgWait: 6.6, + fast: 200, + fastWait: 1.0, + }, + }, + }, + }, + ] + it('should return renderable data about basic estimates appropriate for buttons with less info', () => { + tests.forEach(test => { + assert.deepEqual( + getRenderableEstimateDataForSmallButtons(test.mockState), + test.expectedResult + ) + }) + }) + + }) + }) From b95eb30ec60e4d169a61d987ad86fe333aa49523 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 20 Sep 2018 13:36:23 -0230 Subject: [PATCH 17/64] Adds redesign for the customize gas advanced tab. --- .../advanced-tab-content.component.js | 35 ++++------ .../advanced-tab-content/index.scss | 44 ++++++++---- .../advanced-tab-content-component.test.js | 56 +++++++++------ .../time-remaining/index.scss | 8 ++- .../basic-tab-content/index.scss | 1 + .../gas-modal-page-container.component.js | 63 +++++++++-------- .../gas-modal-page-container.container.js | 36 ++++++---- .../gas-modal-page-container/index.scss | 68 +++++++++++++++++-- ...gas-modal-page-container-component.test.js | 67 ++++++++++-------- ...gas-modal-page-container-container.test.js | 21 +++--- .../gas-price-chart.component.js | 16 +++++ .../gas-price-chart/index.js | 1 + .../gas-price-chart/index.scss | 6 ++ .../tests/gas-price-chart.component.test.js | 25 +++++++ .../components/gas-customization/index.scss | 2 + .../page-container-footer.component.js | 6 +- .../page-container-header.component.js | 13 ++-- .../page-container.component.js | 6 ++ ui/app/ducks/gas.duck.js | 10 +++ 19 files changed, 332 insertions(+), 152 deletions(-) create mode 100644 ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js create mode 100644 ui/app/components/gas-customization/gas-price-chart/index.js create mode 100644 ui/app/components/gas-customization/gas-price-chart/index.scss create mode 100644 ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 56d10cc2b852..5218dd477d03 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,6 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' -import TimeRemaining from './time-remaining' +import GasPriceChart from '../../gas-price-chart' export default class AdvancedTabContent extends Component { static contextTypes = { @@ -14,6 +14,7 @@ export default class AdvancedTabContent extends Component { customGasLimit: PropTypes.number, millisecondsRemaining: PropTypes.number, totalFee: PropTypes.string, + timeRemaining: PropTypes.string, } gasInput (value, onChange, min, precision, showGWEI) { @@ -27,9 +28,6 @@ export default class AdvancedTabContent extends Component { precision={precision} onChange={event => onChange(Number(event.target.value))} /> - {showGWEI - ? GWEI - : null}
) } @@ -38,7 +36,7 @@ export default class AdvancedTabContent extends Component { return } - renderDataSummary (totalFee, millisecondsRemaining) { + renderDataSummary (totalFee, timeRemaining) { return (
@@ -49,9 +47,7 @@ export default class AdvancedTabContent extends Component {
{totalFee}
- +
{timeRemaining}
) @@ -72,7 +68,7 @@ export default class AdvancedTabContent extends Component { renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit) { return (
- { this.renderGasEditRow('gasPriceNoDenom', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) } + { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, 9, true) } { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, 0) }
) @@ -82,7 +78,7 @@ export default class AdvancedTabContent extends Component { const { updateCustomGasPrice, updateCustomGasLimit, - millisecondsRemaining, + timeRemaining, customGasPrice, customGasLimit, totalFee, @@ -90,17 +86,16 @@ export default class AdvancedTabContent extends Component { return (
- { this.renderDataSummary(totalFee, millisecondsRemaining) } -
- { this.context.t('feeChartTitle') } + { this.renderDataSummary(totalFee, timeRemaining) } +
+ { this.renderGasEditRows( + customGasPrice, + updateCustomGasPrice, + customGasLimit, + updateCustomGasLimit + ) } +
-
- { this.renderGasEditRows( - customGasPrice, - updateCustomGasPrice, - customGasLimit, - updateCustomGasLimit - ) }
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index aced75449959..ae99ba4aafa6 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -3,11 +3,9 @@ .advanced-tab { display: flex; flex-flow: column; - height: 430px; &__transaction-data-summary, - &__fee-chart-title, - &__gas-edit-row { + &__fee-chart-title { padding-left: 24px; padding-right: 24px; } @@ -17,6 +15,8 @@ flex-flow: column; color: $mid-gray; margin-top: 12px; + padding-left: 18px; + padding-right: 18px; &__titles, &__container { @@ -24,11 +24,17 @@ flex-flow: row; justify-content: space-between; font-size: 12px; + color: #888EA3; } &__container { - font-size: 26px; - margin-top: 6px; + font-size: 16px; + margin-top: 0px; + } + + &__fee { + font-size: 16px; + color: #313A5E; } } @@ -40,8 +46,11 @@ &__fee-chart { padding-left: 10px; - margin-top: 24px; - height: 134px; + margin-top: 8px; + height: 258px; + background: #F8F9FB; + border-bottom: 1px solid #d2d8dd; + border-top: 1px solid #d2d8dd; } &__slider-container { @@ -50,21 +59,25 @@ } &__gas-edit-rows { - margin-top: 44px; height: 87px; display: flex; - flex-flow: column; + flex-flow: row; justify-content: space-between; + margin-left: 10px; + margin-right: 10px; + margin-top: 9px; } &__gas-edit-row { display: flex; - flex-flow: row; - justify-content: space-between; + flex-flow: column; &__label { - color: $mid-gray; - font-size: 16px; + color: #313B5E; + font-size: 14px; + display: flex; + justify-content: space-between; + align-items: center; .fa-info-circle { color: $silver; @@ -87,10 +100,11 @@ border-radius: 4px; color: $mid-gray; font-size: 16px; - height: 37px; - width: 163px; + height: 24px; + width: 155px; padding-left: 8px; padding-top: 2px; + margin-top: 7px; } input[type="number"]::-webkit-inner-spin-button { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 0ef286b8aad5..1489c7696f81 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -4,7 +4,7 @@ import shallow from '../../../../../../lib/shallow-with-context' import sinon from 'sinon' import AdvancedTabContent from '../advanced-tab-content.component.js' -import TimeRemaining from '../time-remaining' +import GasPriceChart from '../../../gas-price-chart' const propsMethodSpies = { updateCustomGasPrice: sinon.spy(), @@ -13,6 +13,8 @@ const propsMethodSpies = { sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRow') sinon.spy(AdvancedTabContent.prototype, 'gasInput') +sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRows') +sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary') describe('AdvancedTabContent Component', function () { let wrapper @@ -23,7 +25,7 @@ describe('AdvancedTabContent Component', function () { updateCustomGasLimit={propsMethodSpies.updateCustomGasLimit} customGasPrice={11} customGasLimit={23456} - millisecondsRemaining={21500} + timeRemaining={21500} totalFee={'$0.25'} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -31,6 +33,10 @@ describe('AdvancedTabContent Component', function () { afterEach(() => { propsMethodSpies.updateCustomGasPrice.resetHistory() propsMethodSpies.updateCustomGasLimit.resetHistory() + AdvancedTabContent.prototype.renderGasEditRow.resetHistory() + AdvancedTabContent.prototype.gasInput.resetHistory() + AdvancedTabContent.prototype.renderGasEditRows.resetHistory() + AdvancedTabContent.prototype.renderDataSummary.resetHistory() }) describe('render()', () => { @@ -40,12 +46,31 @@ describe('AdvancedTabContent Component', function () { it('should render the expected four children of the advanced-tab div', () => { const advancedTabChildren = wrapper.children() - assert.equal(advancedTabChildren.length, 4) + assert.equal(advancedTabChildren.length, 2) assert(advancedTabChildren.at(0).hasClass('advanced-tab__transaction-data-summary')) - assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart-title')) - assert(advancedTabChildren.at(2).hasClass('advanced-tab__fee-chart')) - assert(advancedTabChildren.at(3).hasClass('advanced-tab__gas-edit-rows')) + assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) + + const feeChartDiv = advancedTabChildren.at(1) + + assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows')) + assert(feeChartDiv.childAt(1).is(GasPriceChart)) + }) + + it('should call renderDataSummary with the expected params', () => { + assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) + const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall(0).args + assert.deepEqual(renderDataSummaryArgs, ['$0.25', 21500]) + + assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) + const renderGasEditRowArgs = AdvancedTabContent.prototype.renderGasEditRows.getCall(0).args + assert.deepEqual(renderGasEditRowArgs, [ + 11, propsMethodSpies.updateCustomGasPrice, 23456, propsMethodSpies.updateCustomGasLimit, + ]) + }) + + it('should call renderGasEditRows with the expected params', () => { + }) }) @@ -71,8 +96,8 @@ describe('AdvancedTabContent Component', function () { const dataNode = dataSummary.children().at(1) assert(dataNode.hasClass('advanced-tab__transaction-data-summary__container')) assert.equal(dataNode.children().at(0).text(), 'mockTotalFee') - assert(dataNode.children().at(1).is(TimeRemaining)) - assert.equal(dataNode.children().at(1).props().milliseconds, 'mockMsRemaining') + assert(dataNode.children().at(1).hasClass('time-remaining')) + assert.equal(dataNode.children().at(1).text(), 'mockMsRemaining') }) }) @@ -138,7 +163,7 @@ describe('AdvancedTabContent Component', function () { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPriceNoDenom', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true, + 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', 9, true, ].map(String)) assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', 0, @@ -186,19 +211,6 @@ describe('AdvancedTabContent Component', function () { assert(gasInput.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) }) - it('should show GWEI if the showGWEI prop is truthy', () => { - const gasInputWithGWEI = shallow(wrapper.instance().gasInput( - 321, - value => value + 7, - 0, - 8, - true - )) - assert.equal(gasInputWithGWEI.children().length, 2) - assert(gasInputWithGWEI.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) - assert(gasInputWithGWEI.children().at(1).hasClass('advanced-tab__gas-edit-row__gwei-symbol')) - }) - it('should pass the correct value min and precision props to the input', () => { const inputProps = gasInput.find('input').props() assert.equal(inputProps.min, 0) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss index 01bb06268155..e2115af7f632 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/time-remaining/index.scss @@ -1,13 +1,17 @@ .time-remaining { + color: #313A5E; + font-size: 16px; + .minutes-num, .seconds-num { - font-size: 26px; + font-size: 16px; } .seconds-num { margin-left: 7px; + font-size: 16px; } .minutes-label, .seconds-label { - font-size: 14px; + font-size: 16px; } } \ No newline at end of file diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss index d5eb5d4141c3..b7b6c0f941ab 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/index.scss @@ -3,6 +3,7 @@ flex-direction: column; align-items: center; margin-bottom: 22px; + height: 291px; &__title { margin-top: 19px; diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 41fe901fa573..07e55a1f022b 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -24,8 +24,9 @@ export default class GasModalPageContainer extends Component { newTotalEth: PropTypes.string, }), onSubmit: PropTypes.func, - customGasPriceInHex: PropTypes.string, - customGasLimitInHex: PropTypes.string, + customModalGasPriceInHex: PropTypes.string, + customModalGasLimitInHex: PropTypes.string, + cancelAndClose: PropTypes.func, } state = {} @@ -51,32 +52,34 @@ export default class GasModalPageContainer extends Component { updateCustomGasLimit={convertThenUpdateCustomGasLimit} customGasPrice={customGasPrice} customGasLimit={customGasLimit} - millisecondsRemaining={91000} + timeRemaining={'1 min 31 sec'} totalFee={newTotalFiat} /> ) } - renderInfoRow (className, totalLabelKey, fiatTotal, cryptoTotal) { - return ( -
-
- {`${this.context.t(totalLabelKey)}:`} - {fiatTotal} -
-
- {`${this.context.t('amountPlusTxFee')}`} - {cryptoTotal} -
-
- ) - } + renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) { + const baseClassName = 'gas-modal-content__info-row' - renderInfoRows (originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) { return (
- { this.renderInfoRow('gas-modal-content__info-row--fade', 'originalTotal', originalTotalFiat, originalTotalEth) } - { this.renderInfoRow('gas-modal-content__info-row', 'newTotal', newTotalFiat, newTotalEth) } +
+
+ {`Send Amount`} + {sendAmount} +
+
+ {`Transaction Fee`} + {transactionFee} +
+
+ {`New Total`} + {newTotalEth} +
+
+ {newTotalFiat} +
+
) } @@ -86,6 +89,8 @@ export default class GasModalPageContainer extends Component { originalTotalEth, newTotalFiat, newTotalEth, + sendAmount, + transactionFee, }, { gasPriceButtonGroupProps, @@ -106,7 +111,7 @@ export default class GasModalPageContainer extends Component { {tabsToRender.map(({ name, content }, i) =>
{ content } - { this.renderInfoRows(originalTotalFiat, originalTotalEth, newTotalFiat, newTotalEth) } + { this.renderInfoRows(newTotalFiat, newTotalEth, sendAmount, transactionFee) }
)} @@ -116,11 +121,11 @@ export default class GasModalPageContainer extends Component { render () { const { - hideModal, + cancelAndClose, infoRowProps, onSubmit, - customGasPriceInHex, - customGasLimitInHex, + customModalGasPriceInHex, + customModalGasLimitInHex, ...tabProps } = this.props @@ -131,13 +136,15 @@ export default class GasModalPageContainer extends Component { subtitle={this.context.t('customGasSubTitle')} tabsComponent={this.renderTabs(infoRowProps, tabProps)} disabled={false} - onCancel={() => hideModal()} - onClose={() => hideModal()} + onCancel={() => cancelAndClose()} + onClose={() => cancelAndClose()} onSubmit={() => { - onSubmit(customGasLimitInHex, customGasPriceInHex) - hideModal() + onSubmit(customModalGasLimitInHex, customModalGasPriceInHex) + cancelAndClose() }} submitText={this.context.t('save')} + headerCloseText={'Close'} + hideCancel={true} />
) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index f9ed1cebba61..ae233578baea 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -9,6 +9,7 @@ import { import { setCustomGasPrice, setCustomGasLimit, + resetCustomData, } from '../../../ducks/gas.duck' import { hideGasButtonGroup, @@ -48,12 +49,12 @@ import { addHexPrefix } from 'ethereumjs-util' const mapStateToProps = state => { const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) - const { gasPrice, gas: gasLimit, value } = getTxParams(state) - const gasTotal = calcGasTotal(gasLimit, gasPrice) + const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state) + const gasTotal = calcGasTotal(currentGasLimit, currentGasPrice) - const customGasPriceInHex = getCustomGasPrice(state) - const customGasLimitInHex = getCustomGasLimit(state) - const customGasTotal = calcGasTotal(customGasLimitInHex || gasLimit, customGasPriceInHex || gasPrice) + const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice + const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit + const customGasTotal = calcGasTotal(customModalGasLimitInHex, customModalGasPriceInHex) const gasButtonInfo = getRenderableBasicEstimateData(state) @@ -67,14 +68,14 @@ const mapStateToProps = state => { return { hideBasic, isConfirm: isConfirm(state), - customGasPriceInHex, - customGasLimitInHex, - customGasPrice: calcCustomGasPrice(customGasPriceInHex, gasPrice), - customGasLimit: calcCustomGasLimit(customGasLimitInHex, gasLimit), + customModalGasPriceInHex, + customModalGasLimitInHex, + customGasPrice: calcCustomGasPrice(customModalGasPriceInHex), + customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, gasPriceButtonGroupProps: { buttonDataLoading, - defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customGasPriceInHex, gasPrice), + defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), gasButtonInfo, }, infoRowProps: { @@ -82,6 +83,8 @@ const mapStateToProps = state => { originalTotalEth: addHexWEIsToRenderableEth(value, gasTotal), newTotalFiat, newTotalEth: addHexWEIsToRenderableEth(value, customGasTotal), + transactionFee: addHexWEIsToRenderableEth('0x0', customGasTotal), + sendAmount: addHexWEIsToRenderableEth(value, '0x0'), }, } } @@ -90,7 +93,10 @@ const mapDispatchToProps = dispatch => { const updateCustomGasPrice = newPrice => dispatch(setCustomGasPrice(addHexPrefix(newPrice))) return { - hideModal: () => dispatch(hideModal()), + cancelAndClose: () => { + dispatch(resetCustomData()) + dispatch(hideModal()) + }, updateCustomGasPrice, convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)), convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))), @@ -138,12 +144,12 @@ function isConfirm (state) { return Boolean(Object.keys(state.confirmTransaction.txData).length) } -function calcCustomGasPrice (customGasPriceInHex, gasPrice) { - return Number(hexWEIToDecGWEI(customGasPriceInHex || gasPrice)) +function calcCustomGasPrice (customGasPriceInHex) { + return Number(hexWEIToDecGWEI(customGasPriceInHex)) } -function calcCustomGasLimit (customGasLimitInHex, gasLimit) { - return parseInt(customGasLimitInHex || gasLimit, 16) +function calcCustomGasLimit (customGasLimitInHex) { + return parseInt(customGasLimitInHex, 16) } function getTxParams (state) { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index f02045fe3357..c49d69bf7f28 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -4,6 +4,57 @@ .gas-modal-page-container { .page-container { width: 391px; + + &__header { + padding: 0px; + padding-top: 16px; + + &--no-padding-bottom { + padding-bottom: 0; + } + } + + &__header-close-text { + font-size: 14px; + color: #4EADE7; + position: absolute; + top: 16px; + right: 16px; + cursor: pointer; + overflow: hidden; + } + + &__title { + color: $black; + font-size: 16px; + font-weight: 500; + line-height: 16px; + display: flex; + justify-content: center; + align-items: flex-start; + } + + &__subtitle { + display: none; + } + + &__tabs { + margin-top: 0px; + } + + &__tab { + width: 100%; + font-size: 14px; + + &:last-of-type { + margin-right: 0; + } + + &--selected { + color: $curious-blue; + border-bottom: 2px solid $curious-blue; + } + } } } @@ -20,30 +71,35 @@ display: flex; flex-flow: column; color: $scorpion; + font-size: 12px; - &__total-info, &__sum-info { + &__send-info, &__transaction-info, &__total-info, &__fiat-total-info { display: flex; flex-flow: row; justify-content: space-between; } + &__fiat-total-info { + justify-content: flex-end; + } + &__total-info { - &__total-label { + &__label { font-size: 16px; } - &__total-value { + &__value { font-size: 16px; font-weight: bold; } } - &__sum-info { - &__sum-label { + &__transaction-info, &__send-info { + &__label { font-size: 12px; } - &__sum-value { + &__value { font-size: 14px; } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index fdd7709d91ef..714f0153844a 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -9,7 +9,7 @@ import PageContainer from '../../../page-container' import { Tab } from '../../../tabs' const propsMethodSpies = { - hideModal: sinon.spy(), + cancelAndClose: sinon.spy(), onSubmit: sinon.spy(), } @@ -39,12 +39,16 @@ const mockGasPriceButtonGroupProps = { handleGasPriceSelection: 'mockSelectionFunction', noButtonActiveByDefault: true, showCheck: true, + newTotalFiat: 'mockNewTotalFiat', + newTotalEth: 'mockNewTotalEth', } const mockInfoRowProps = { originalTotalFiat: 'mockOriginalTotalFiat', originalTotalEth: 'mockOriginalTotalEth', newTotalFiat: 'mockNewTotalFiat', newTotalEth: 'mockNewTotalEth', + sendAmount: 'mockSendAmount', + transactionFee: 'mockTransactionFee', } const GP = GasModalPageContainer.prototype @@ -53,7 +57,7 @@ describe('GasModalPageContainer Component', function () { beforeEach(() => { wrapper = shallow( 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} @@ -67,7 +71,7 @@ describe('GasModalPageContainer Component', function () { }) afterEach(() => { - propsMethodSpies.hideModal.resetHistory() + propsMethodSpies.cancelAndClose.resetHistory() }) describe('render', () => { @@ -91,11 +95,11 @@ describe('GasModalPageContainer Component', function () { onCancel, onClose, } = wrapper.find(PageContainer).props() - assert.equal(propsMethodSpies.hideModal.callCount, 0) + assert.equal(propsMethodSpies.cancelAndClose.callCount, 0) onCancel() - assert.equal(propsMethodSpies.hideModal.callCount, 1) + assert.equal(propsMethodSpies.cancelAndClose.callCount, 1) onClose() - assert.equal(propsMethodSpies.hideModal.callCount, 2) + assert.equal(propsMethodSpies.cancelAndClose.callCount, 2) }) it('should pass the correct renderTabs property to PageContainer', () => { @@ -158,8 +162,8 @@ describe('GasModalPageContainer Component', function () { assert.equal(GP.renderInfoRows.callCount, 2) - assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) - assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockOriginalTotalFiat', 'mockOriginalTotalEth', 'mockNewTotalFiat', 'mockNewTotalEth']) + assert.deepEqual(GP.renderInfoRows.getCall(0).args, ['mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee']) + assert.deepEqual(GP.renderInfoRows.getCall(1).args, ['mockNewTotalFiat', 'mockNewTotalEth', 'mockSendAmount', 'mockTransactionFee']) }) it('should not render the basic tab if hideBasic is true', () => { @@ -176,25 +180,6 @@ describe('GasModalPageContainer Component', function () { }) }) - describe('renderInfoRow', () => { - it('should render a div with the passed className and two children, each with the expected text', () => { - const renderInfoRowResult = wrapper.instance().renderInfoRow('mockClassName', 'mockLabelKey', 'mockFiatAmount', 'mockCryptoAmount') - const renderedInfoRow = shallow(renderInfoRowResult) - assert.equal(renderedInfoRow.props().className, 'mockClassName') - - const firstChild = renderedInfoRow.childAt(0) - const secondhild = renderedInfoRow.childAt(1) - - assert.equal(firstChild.props().className, 'mockClassName__total-info') - assert.equal(secondhild.props().className, 'mockClassName__sum-info') - - assert.equal(firstChild.childAt(0).text(), 'mockLabelKey:') - assert.equal(firstChild.childAt(1).text(), 'mockFiatAmount') - assert.equal(secondhild.childAt(0).text(), 'amountPlusTxFee') - assert.equal(secondhild.childAt(1).text(), 'mockCryptoAmount') - }) - }) - describe('renderBasicTabContent', () => { it('should render', () => { const renderBasicTabContentResult = wrapper.instance().renderBasicTabContent(mockGasPriceButtonGroupProps) @@ -220,8 +205,34 @@ describe('GasModalPageContainer Component', function () { assert.equal(advancedTabContentProps.updateCustomGasLimit(), 'mockConvertThenUpdateCustomGasLimit') assert.equal(advancedTabContentProps.customGasPrice, 123) assert.equal(advancedTabContentProps.customGasLimit, 456) - assert.equal(advancedTabContentProps.millisecondsRemaining, 91000) + assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec') assert.equal(advancedTabContentProps.totalFee, '$0.30') }) }) + + describe('renderInfoRows', () => { + it('should render the info rows with the passed data', () => { + const baseClassName = 'gas-modal-content__info-row' + const renderedInfoRowsContainer = shallow(wrapper.instance().renderInfoRows( + 'mockNewTotalFiat', + ' mockNewTotalEth', + ' mockSendAmount', + ' mockTransactionFee' + )) + + assert(renderedInfoRowsContainer.childAt(0).hasClass(baseClassName)) + + const renderedInfoRows = renderedInfoRowsContainer.childAt(0).children() + assert.equal(renderedInfoRows.length, 4) + assert(renderedInfoRows.at(0).hasClass(`${baseClassName}__send-info`)) + assert(renderedInfoRows.at(1).hasClass(`${baseClassName}__transaction-info`)) + assert(renderedInfoRows.at(2).hasClass(`${baseClassName}__total-info`)) + assert(renderedInfoRows.at(3).hasClass(`${baseClassName}__fiat-total-info`)) + + assert.equal(renderedInfoRows.at(0).text(), 'Send Amount mockSendAmount') + assert.equal(renderedInfoRows.at(1).text(), 'Transaction Fee mockTransactionFee') + assert.equal(renderedInfoRows.at(2).text(), 'New Total mockNewTotalEth') + assert.equal(renderedInfoRows.at(3).text(), 'mockNewTotalFiat') + }) + }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 238f27ed6952..3d9fb2624141 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -15,6 +15,7 @@ const actionSpies = { const gasActionSpies = { setCustomGasPrice: sinon.spy(), setCustomGasLimit: sinon.spy(), + resetCustomData: sinon.spy(), } const confirmTransactionActionSpies = { @@ -37,7 +38,7 @@ proxyquire('../gas-modal-page-container.container.js', { '../../../selectors/custom-gas': { getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${Object.keys(s).length}`, getRenderableBasicEstimateData: (s) => `mockRenderableBasicEstimateData:${Object.keys(s).length}`, - getDefaultActiveButtonIndex: (a, b, c) => a + b + c, + getDefaultActiveButtonIndex: (a, b) => a + b, }, '../../../actions': actionSpies, '../../../ducks/gas.duck': gasActionSpies, @@ -89,15 +90,14 @@ describe('gas-modal-page-container container', () => { assert.deepEqual(result2, { isConfirm: true, - customGasPriceInHex: 'ffffffff', - customGasLimitInHex: 'aaaaaaaa', customGasPrice: 4.294967295, customGasLimit: 2863311530, newTotalFiat: '637.41', - gasPriceButtonGroupProps: - { + customModalGasLimitInHex: 'aaaaaaaa', + customModalGasPriceInHex: 'ffffffff', + gasPriceButtonGroupProps: { buttonDataLoading: 'mockBasicGasEstimateLoadingStatus:4', - defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff0x3200000', + defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, hideBasic: true, @@ -106,6 +106,8 @@ describe('gas-modal-page-container container', () => { originalTotalEth: '0.451569 ETH', newTotalFiat: '637.41', newTotalEth: '12.748189 ETH', + sendAmount: '0.45036 ETH', + transactionFee: '12.297829 ETH', }, }) }) @@ -135,11 +137,12 @@ describe('gas-modal-page-container container', () => { }) }) - describe('hideModal()', () => { + describe('cancelAndClose()', () => { it('should dispatch a hideModal action', () => { - mapDispatchToPropsObject.hideModal() - assert(dispatchSpy.calledOnce) + mapDispatchToPropsObject.cancelAndClose() + assert(dispatchSpy.calledTwice) assert(actionSpies.hideModal.calledOnce) + assert(gasActionSpies.resetCustomData.calledOnce) }) }) diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js new file mode 100644 index 000000000000..7c32058b7c8d --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js @@ -0,0 +1,16 @@ +import React, { Component } from 'react' +import PropTypes from 'prop-types' + +export default class GasPriceChart extends Component { + static contextTypes = { + t: PropTypes.func, + } + + render () { + return ( +
+
+
+ ) + } +} diff --git a/ui/app/components/gas-customization/gas-price-chart/index.js b/ui/app/components/gas-customization/gas-price-chart/index.js new file mode 100644 index 000000000000..9895acb620c3 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/index.js @@ -0,0 +1 @@ +export { default } from './gas-price-chart.component' diff --git a/ui/app/components/gas-customization/gas-price-chart/index.scss b/ui/app/components/gas-customization/gas-price-chart/index.scss new file mode 100644 index 000000000000..14e7a12a8680 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/index.scss @@ -0,0 +1,6 @@ +.gas-price-chart { + &__container { + display: flex; + position: relative; + } +} diff --git a/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js b/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js new file mode 100644 index 000000000000..474b7b7b6626 --- /dev/null +++ b/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js @@ -0,0 +1,25 @@ +import React from 'react' +import assert from 'assert' +import shallow from '../../../../../lib/shallow-with-context' +import GasPriceChart from '../gas-price-chart.component.js' + +describe('GasPriceChart Component', function () { + let wrapper + + beforeEach(() => { + wrapper = shallow() + }) + + describe('render()', () => { + it('should render', () => { + console.log('wrapper', wrapper.html()) + assert(wrapper.hasClass('gas-price-chart')) + }) + + it('should render the chart div', () => { + assert(wrapper.childAt(0).hasClass('gas-price-chart__container')) + assert.equal(wrapper.childAt(0).props().id, 'chart') + }) + }) + +}) diff --git a/ui/app/components/gas-customization/index.scss b/ui/app/components/gas-customization/index.scss index 91ca5004e3cd..e99d4e57ffea 100644 --- a/ui/app/components/gas-customization/index.scss +++ b/ui/app/components/gas-customization/index.scss @@ -1,3 +1,5 @@ @import './gas-slider/index'; @import './gas-modal-page-container/index'; + +@import './gas-price-chart/index'; diff --git a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js index 773fe1f56b29..5725c22acd7d 100644 --- a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js +++ b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js @@ -12,6 +12,7 @@ export default class PageContainerFooter extends Component { submitText: PropTypes.string, disabled: PropTypes.bool, submitButtonType: PropTypes.string, + hideCancel: PropTypes.func, } static contextTypes = { @@ -27,20 +28,21 @@ export default class PageContainerFooter extends Component { submitText, disabled, submitButtonType, + hideCancel, } = this.props return (
- + } diff --git a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js index c7ac175d9749..cb4180508986 100644 --- a/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js +++ b/ui/app/components/send/send-content/send-gas-row/gas-fee-display/test/gas-fee-display.component.test.js @@ -8,9 +8,10 @@ import sinon from 'sinon' const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), + onReset: sinon.spy(), } -describe('SendGasRow Component', function () { +describe('GasFeeDisplay Component', function () { let wrapper beforeEach(() => { @@ -20,6 +21,7 @@ describe('SendGasRow Component', function () { primaryCurrency={'mockPrimaryCurrency'} convertedCurrency={'mockConvertedCurrency'} showGasButtonGroup={propsMethodSpies.showCustomizeGasModal} + onReset={propsMethodSpies.onReset} />, {context: {t: str => str + '_t'}}) }) @@ -47,9 +49,9 @@ describe('SendGasRow Component', function () { className, } = wrapper.find('button').props() assert.equal(className, 'gas-fee-reset') - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) + assert.equal(propsMethodSpies.onReset.callCount, 0) onClick() - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) + assert.equal(propsMethodSpies.onReset.callCount, 1) }) it('should render the reset button with the correct text', () => { diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js index 507407306550..8d305dd4f857 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.component.js @@ -14,8 +14,8 @@ export default class SendGasRow extends Component { gasTotal: PropTypes.string, showCustomizeGasModal: PropTypes.func, gasPriceButtonGroupProps: PropTypes.object, - showGasButtonGroup: PropTypes.func, gasButtonGroupShown: PropTypes.bool, + resetGasButtons: PropTypes.func, } static contextTypes = { @@ -32,7 +32,7 @@ export default class SendGasRow extends Component { showCustomizeGasModal, gasPriceButtonGroupProps, gasButtonGroupShown, - showGasButtonGroup, + resetGasButtons, } = this.props return ( @@ -57,7 +57,7 @@ export default class SendGasRow extends Component { convertedCurrency={convertedCurrency} gasLoadingError={gasLoadingError} gasTotal={gasTotal} - showGasButtonGroup={showGasButtonGroup} + onReset={resetGasButtons} onClick={() => showCustomizeGasModal()} />} diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js index dd16559d08ee..39266e590ad4 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js @@ -13,6 +13,9 @@ import { import { showGasButtonGroup, } from '../../../../ducks/send.duck' +import { + resetCustomData, +} from '../../../../ducks/gas.duck' import { getGasLoadingError, gasFeeIsInError, getGasButtonGroupShown } from './send-gas-row.selectors.js' import { showModal, setGasPrice } from '../../../../actions' import SendGasRow from './send-gas-row.component' @@ -44,13 +47,17 @@ function mapDispatchToProps (dispatch) { showCustomizeGasModal: () => dispatch(showModal({ name: 'CUSTOMIZE_GAS', hideBasic: true })), setGasPrice: newPrice => dispatch(setGasPrice(newPrice)), showGasButtonGroup: () => dispatch(showGasButtonGroup()), + resetCustomData: () => dispatch(resetCustomData()), } } function mergeProps (stateProps, dispatchProps, ownProps) { const { gasPriceButtonGroupProps } = stateProps + const { gasButtonInfo } = gasPriceButtonGroupProps const { setGasPrice: dispatchSetGasPrice, + showGasButtonGroup: dispatchShowGasButtonGroup, + resetCustomData: dispatchResetCustomData, ...otherDispatchProps } = dispatchProps @@ -62,5 +69,10 @@ function mergeProps (stateProps, dispatchProps, ownProps) { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchSetGasPrice, }, + resetGasButtons: () => { + dispatchResetCustomData() + dispatchSetGasPrice(gasButtonInfo[1].priceInHexWei) + dispatchShowGasButtonGroup() + }, } } diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js index 171cd7bf6637..059c6cdd30a0 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-component.test.js @@ -10,6 +10,7 @@ import GasPriceButtonGroup from '../../../../gas-customization/gas-price-button- const propsMethodSpies = { showCustomizeGasModal: sinon.spy(), + resetGasButtons: sinon.spy(), } describe('SendGasRow Component', function () { @@ -22,9 +23,9 @@ describe('SendGasRow Component', function () { gasFeeError={'mockGasFeeError'} gasLoadingError={false} gasTotal={'mockGasTotal'} - showGasButtonGroup={'mockShowGasPriceButtonGroup'} gasButtonGroupShown={false} showCustomizeGasModal={propsMethodSpies.showCustomizeGasModal} + resetGasButtons={propsMethodSpies.resetGasButtons} gasPriceButtonGroupProps={{ someGasPriceButtonGroupProp: 'foo', anotherGasPriceButtonGroupProp: 'bar', @@ -33,7 +34,7 @@ describe('SendGasRow Component', function () { }) afterEach(() => { - propsMethodSpies.showCustomizeGasModal.resetHistory() + propsMethodSpies.resetGasButtons.resetHistory() }) describe('render', () => { @@ -63,17 +64,15 @@ describe('SendGasRow Component', function () { convertedCurrency, gasLoadingError, gasTotal, - onClick, - showGasButtonGroup, + onReset, } = wrapper.find(SendRowWrapper).childAt(0).props() assert.equal(conversionRate, 20) assert.equal(convertedCurrency, 'mockConvertedCurrency') assert.equal(gasLoadingError, false) assert.equal(gasTotal, 'mockGasTotal') - assert.equal(showGasButtonGroup, 'mockShowGasPriceButtonGroup') - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 0) - onClick() - assert.equal(propsMethodSpies.showCustomizeGasModal.callCount, 1) + assert.equal(propsMethodSpies.resetGasButtons.callCount, 0) + onReset() + assert.equal(propsMethodSpies.resetGasButtons.callCount, 1) }) it('should render the GasPriceButtonGroup if gasButtonGroupShown is true', () => { diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js index 1c385e2163c5..766bf6cab6e2 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js @@ -15,6 +15,10 @@ const sendDuckSpies = { showGasButtonGroup: sinon.spy(), } +const gasDuckSpies = { + resetCustomData: sinon.spy(), +} + proxyquire('../send-gas-row.container.js', { 'react-redux': { connect: (ms, md, mp) => { @@ -42,6 +46,7 @@ proxyquire('../send-gas-row.container.js', { getDefaultActiveButtonIndex: (gasButtonInfo, gasPrice) => gasButtonInfo.length + gasPrice.length, }, '../../../../ducks/send.duck': sendDuckSpies, + '../../../../ducks/gas.duck': gasDuckSpies, }) describe('send-gas-row container', () => { @@ -104,6 +109,14 @@ describe('send-gas-row container', () => { }) }) + describe('resetCustomData()', () => { + it('should dispatch an action', () => { + mapDispatchToPropsObject.resetCustomData() + assert(dispatchSpy.calledOnce) + assert(gasDuckSpies.resetCustomData.calledOnce) + }) + }) + }) describe('mergeProps', () => { diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js index 96c00383bcfe..009758cde223 100644 --- a/ui/app/ducks/tests/gas-duck.test.js +++ b/ui/app/ducks/tests/gas-duck.test.js @@ -1,7 +1,16 @@ import assert from 'assert' import sinon from 'sinon' +import proxyquire from 'proxyquire' -import GasReducer, { + +const GasDuck = proxyquire('../gas.duck.js', { + '../../lib/local-storage-helpers': { + loadLocalStorageData: sinon.spy(), + saveLocalStorageData: sinon.spy(), + }, +}) + +const { basicGasEstimatesLoadingStarted, basicGasEstimatesLoadingFinished, setBasicGasEstimateData, @@ -16,7 +25,8 @@ import GasReducer, { setPricesAndTimeEstimates, fetchGasEstimates, setApiEstimatesLastRetrieved, -} from '../gas.duck.js' +} = GasDuck +const GasReducer = GasDuck.default describe('Gas Duck', () => { let tempFetch @@ -312,6 +322,11 @@ describe('Gas Duck', () => { describe('fetchGasEstimates', () => { const mockDistpatch = sinon.spy() + + beforeEach(() => { + mockDistpatch.resetHistory() + }) + it('should call fetch with the expected params', async () => { global.fetch.resetHistory() await fetchGasEstimates(5)(mockDistpatch, () => ({ gas: Object.assign( @@ -377,6 +392,46 @@ describe('Gas Duck', () => { [{ type: GAS_ESTIMATE_LOADING_FINISHED }] ) }) + + it('should not call fetch if the estimates were retrieved < 75000 ms ago', async () => { + global.fetch.resetHistory() + await fetchGasEstimates(5)(mockDistpatch, () => ({ gas: Object.assign( + {}, + initState, + { + priceAndTimeEstimatesLastRetrieved: Date.now(), + priceAndTimeEstimates: [{ + expectedTime: '10', + expectedWait: 2, + gasprice: 50, + }], + } + ) })) + assert.deepEqual( + mockDistpatch.getCall(0).args, + [{ type: GAS_ESTIMATE_LOADING_STARTED} ] + ) + assert.equal(global.fetch.callCount, 0) + + assert.deepEqual( + mockDistpatch.getCall(1).args, + [{ + type: SET_PRICE_AND_TIME_ESTIMATES, + value: [ + { + expectedTime: '10', + expectedWait: 2, + gasprice: 50, + }, + ], + + }] + ) + assert.deepEqual( + mockDistpatch.getCall(2).args, + [{ type: GAS_ESTIMATE_LOADING_FINISHED }] + ) + }) }) describe('gasEstimatesLoadingStarted', () => { From 8c8359ca14efdbff2dd879f81090647036799607 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 6 Nov 2018 14:48:52 -0330 Subject: [PATCH 35/64] Remove gas customization integration tests (in favour of e2e tests) --- development/states/send-new-ui.json | 315 ++++++++++++++++++++++++++++ test/integration/lib/send-new-ui.js | 35 ---- ui/app/app.js | 3 +- 3 files changed, 317 insertions(+), 36 deletions(-) diff --git a/development/states/send-new-ui.json b/development/states/send-new-ui.json index 0cd2f23f2edc..9be4ef0da594 100644 --- a/development/states/send-new-ui.json +++ b/development/states/send-new-ui.json @@ -159,4 +159,319 @@ "nonce": "", "fetchingMethodData": false } + "gas": { + "customData": { + "price": null, + "limit": "0x186a0" + }, + "basicEstimates": { + "average": 73, + "avgWait": 10.6, + "blockTime": 13.871657754010695, + "blockNum": 6655504, + "fast": 160, + "fastest": 290, + "fastestWait": 0.5, + "fastWait": 0.6, + "safeLow": 50, + "safeLowWait": 16.1, + "speed": 0.6702462692280712 + }, + "basicEstimateIsLoading": false, + "gasEstimatesLoading": false, + "priceAndTimeEstimates": [ + { + "expectedTime": "1374.1168296452973076627", + "expectedWait": 99.0593088449, + "gasprice": 4.1 + }, + { + "expectedTime": "1280.88976972896682763716", + "expectedWait": 92.3386225672, + "gasprice": 4.4 + }, + { + "expectedTime": "1245.13314632680319175597", + "expectedWait": 89.7609477113, + "gasprice": 4.8 + }, + { + "expectedTime": "1227.99925007911014385881", + "expectedWait": 88.5257747744, + "gasprice": 4.9 + }, + { + "expectedTime": "965.52572720362993349654", + "expectedWait": 69.6042062402, + "gasprice": 5 + }, + { + "expectedTime": "917.466895447437420776", + "expectedWait": 66.1396721082, + "gasprice": 5.1 + }, + { + "expectedTime": "915.81694044041496090521", + "expectedWait": 66.0207277804, + "gasprice": 5.2 + }, + { + "expectedTime": "902.13145619709089691874", + "expectedWait": 65.034148924, + "gasprice": 5.3 + }, + { + "expectedTime": "890.83591122200105749896", + "expectedWait": 64.2198594443, + "gasprice": 5.4 + }, + { + "expectedTime": "879.10469542971335712248", + "expectedWait": 63.3741627006, + "gasprice": 5.5 + }, + { + "expectedTime": "876.99737395823100420974", + "expectedWait": 63.2222470818, + "gasprice": 5.6 + }, + { + "expectedTime": "865.96781957003849098957", + "expectedWait": 62.4271327138, + "gasprice": 5.7 + }, + { + "expectedTime": "865.44839472121496158482", + "expectedWait": 62.3896876688, + "gasprice": 5.8 + }, + { + "expectedTime": "802.16173170976255602161", + "expectedWait": 57.8273877524, + "gasprice": 6 + }, + { + "expectedTime": "780.79313908053047074843", + "expectedWait": 56.2869379368, + "gasprice": 6.1 + }, + { + "expectedTime": "770.04888359616469549233", + "expectedWait": 55.5123906062, + "gasprice": 6.2 + }, + { + "expectedTime": "745.01007965146736962697", + "expectedWait": 53.7073573226, + "gasprice": 6.3 + }, + { + "expectedTime": "735.19921111598501681816", + "expectedWait": 53.0000973318, + "gasprice": 6.6 + }, + { + "expectedTime": "705.68767153912619368694", + "expectedWait": 50.8726270539, + "gasprice": 6.7 + }, + { + "expectedTime": "705.26438593445239690121", + "expectedWait": 50.8421126329, + "gasprice": 6.9 + }, + { + "expectedTime": "652.51573119854865429742", + "expectedWait": 47.0394918019, + "gasprice": 7 + }, + { + "expectedTime": "635.51471669299464383162", + "expectedWait": 45.813898235, + "gasprice": 7.1 + }, + { + "expectedTime": "634.37181911960854759036", + "expectedWait": 45.7315073922, + "gasprice": 7.2 + }, + { + "expectedTime": "633.23097691113902888918", + "expectedWait": 45.6492647195, + "gasprice": 7.3 + }, + { + "expectedTime": "112.7753456245379663928", + "expectedWait": 8.1299111919, + "gasprice": 7.6 + }, + { + "expectedTime": "102.9665314468898381829", + "expectedWait": 7.4227992986, + "gasprice": 8 + }, + { + "expectedTime": "100.94784507024919649891", + "expectedWait": 7.2772733339, + "gasprice": 8.1 + }, + { + "expectedTime": "100.46445647447807351078", + "expectedWait": 7.2424261221, + "gasprice": 8.8 + }, + { + "expectedTime": "84.91686745986737853339", + "expectedWait": 6.1216091808, + "gasprice": 9 + }, + { + "expectedTime": "80.39566429296684383503", + "expectedWait": 5.7956781892, + "gasprice": 9.1 + }, + { + "expectedTime": "78.24522052614759252715", + "expectedWait": 5.6406539084, + "gasprice": 9.2 + }, + { + "expectedTime": "77.1685119880459882636", + "expectedWait": 5.5630345959, + "gasprice": 9.5 + }, + { + "expectedTime": "72.43649507646737870178", + "expectedWait": 5.2219061601, + "gasprice": 9.8 + }, + { + "expectedTime": "71.48259532351443753818", + "expectedWait": 5.1531400638, + "gasprice": 9.9 + }, + { + "expectedTime": "58.23892805162994573827", + "expectedWait": 4.1984115442, + "gasprice": 10 + }, + { + "expectedTime": "53.13065124862245917617", + "expectedWait": 3.8301587446, + "gasprice": 10.1 + }, + { + "expectedTime": "53.03510209647058751971", + "expectedWait": 3.82327066, + "gasprice": 10.3 + }, + { + "expectedTime": "49.06846157804491912403", + "expectedWait": 3.5373177776, + "gasprice": 11 + }, + { + "expectedTime": "48.30893330101818116637", + "expectedWait": 3.4825638116, + "gasprice": 11.1 + }, + { + "expectedTime": "48.25099734861818116715", + "expectedWait": 3.4783872414, + "gasprice": 11.3 + }, + { + "expectedTime": "47.64416885027272662988", + "expectedWait": 3.4346413165, + "gasprice": 11.9 + }, + { + "expectedTime": "46.76354741392085498401", + "expectedWait": 3.3711578128, + "gasprice": 12.6 + }, + { + "expectedTime": "44.99427448545882292232", + "expectedWait": 3.2436119232, + "gasprice": 13 + }, + { + "expectedTime": "44.61790554199251276697", + "expectedWait": 3.2164796979, + "gasprice": 13.1 + }, + { + "expectedTime": "42.87832690973048070488", + "expectedWait": 3.0910744534, + "gasprice": 14 + }, + { + "expectedTime": "42.21224091308663044649", + "expectedWait": 3.0430566888, + "gasprice": 14.9 + }, + { + "expectedTime": "41.15715335111336842864", + "expectedWait": 2.9669960203, + "gasprice": 15 + }, + { + "expectedTime": "40.9600723880876999821", + "expectedWait": 2.9527885646, + "gasprice": 15.1 + }, + { + "expectedTime": "38.89138450301711177472", + "expectedWait": 2.8036580193, + "gasprice": 15.8 + }, + { + "expectedTime": "37.89655640860213852611", + "expectedWait": 2.7319414219, + "gasprice": 16 + }, + { + "expectedTime": "37.35265517364705831954", + "expectedWait": 2.692731888, + "gasprice": 17.4 + }, + { + "expectedTime": "36.79447683873796741798", + "expectedWait": 2.652493126, + "gasprice": 17.8 + }, + { + "expectedTime": "36.11439350850802090309", + "expectedWait": 2.6034663015, + "gasprice": 19 + }, + { + "expectedTime": "31.32676199432192471101", + "expectedWait": 2.2583286403, + "gasprice": 20 + }, + { + "expectedTime": "30.76792490132192471855", + "expectedWait": 2.2180423888, + "gasprice": 20.1 + }, + { + "expectedTime": "29.94493658520962526441", + "expectedWait": 2.1587136243, + "gasprice": 25 + }, + { + "expectedTime": "29.53287347625561457478", + "expectedWait": 2.1290082267, + "gasprice": 29 + }, + { + "expectedTime": "29.09318627175614934008", + "expectedWait": 2.0973114236, + "gasprice": 47 + } + ], + "priceAndTimeEstimatesLastRetrieved": 1541527901281, + "errors": {} + }, } diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js index 271dd91cf977..98e5f549b954 100644 --- a/test/integration/lib/send-new-ui.js +++ b/test/integration/lib/send-new-ui.js @@ -21,37 +21,6 @@ global.ethQuery = { global.ethereumProvider = {} -async function customizeGas (assert, price, limit, ethFee, usdFee) { - const sendGasOpenCustomizeModalButton = await queryAsync($, '.sliders-icon-container') - sendGasOpenCustomizeModalButton[0].click() - - const customizeGasModal = await queryAsync($, '.send-v2__customize-gas') - assert.ok(customizeGasModal[0], 'should render the customize gas modal') - - const customizeGasPriceInput = (await queryAsync($, '.send-v2__gas-modal-card')).first().find('input') - customizeGasPriceInput.val(price) - reactTriggerChange(customizeGasPriceInput[0]) - const customizeGasLimitInput = (await queryAsync($, '.send-v2__gas-modal-card')).last().find('input') - customizeGasLimitInput.val(limit) - reactTriggerChange(customizeGasLimitInput[0]) - - const customizeGasSaveButton = await queryAsync($, '.send-v2__customize-gas__save') - customizeGasSaveButton[0].click() - const sendGasField = await queryAsync($, '.send-v2__gas-fee-display') - - assert.equal( - (await findAsync(sendGasField, '.currency-display-component'))[0].textContent, - ethFee, - 'send gas field should show customized gas total' - ) - - assert.equal( - (await findAsync(sendGasField, '.currency-display__converted-value'))[0].textContent, - usdFee, - 'send gas field should show customized gas total converted to USD' - ) -} - async function runSendFlowTest (assert, done) { console.log('*** start runSendFlowTest') const selectState = await queryAsync($, 'select') @@ -112,10 +81,6 @@ async function runSendFlowTest (assert, done) { errorMessage = $('.send-v2__error') assert.equal(errorMessage.length, 0, 'send should stop rendering amount error message after amount is corrected') - await customizeGas(assert, 0, 21000, '0ETH', '$0.00USD') - await customizeGas(assert, 1, 21000, '0.000021ETH', '$0.03USD') - await customizeGas(assert, 500, 60000, '0.03ETH', '$36.03USD') - const sendButton = await queryAsync($, 'button.btn-primary.btn--large.page-container__footer-button') assert.equal(sendButton[0].textContent, 'Next', 'next button rendered') sendButton[0].click() diff --git a/ui/app/app.js b/ui/app/app.js index 10428d1fd26e..7669a5db93f5 100644 --- a/ui/app/app.js +++ b/ui/app/app.js @@ -121,8 +121,9 @@ class App extends Component { isOpen: sidebarIsOpen, transitionName: sidebarTransitionName, type: sidebarType, - props: { transaction: sidebarTransaction }, + props, } = sidebar + const { transaction: sidebarTransaction } = props || {} return ( h('.flex-column.full-height', { From b7f873b96ecee8d4b6b3d78a3cde7b2495967970 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Wed, 7 Nov 2018 10:02:17 -0330 Subject: [PATCH 36/64] Add gas data to integration test json data set. --- development/states/send-edit.json | 315 +++++++++++++++++++++++++++ development/states/send-new-ui.json | 4 +- development/states/send.json | 317 +++++++++++++++++++++++++++- 3 files changed, 633 insertions(+), 3 deletions(-) diff --git a/development/states/send-edit.json b/development/states/send-edit.json index 6330b777d4c3..a519f30b49fc 100644 --- a/development/states/send-edit.json +++ b/development/states/send-edit.json @@ -176,5 +176,320 @@ "hexGasTotal": "", "nonce": "", "fetchingMethodData": false + }, + "gas": { + "customData": { + "price": null, + "limit": "0x186a0" + }, + "basicEstimates": { + "average": 73, + "avgWait": 10.6, + "blockTime": 13.871657754010695, + "blockNum": 6655504, + "fast": 160, + "fastest": 290, + "fastestWait": 0.5, + "fastWait": 0.6, + "safeLow": 50, + "safeLowWait": 16.1, + "speed": 0.6702462692280712 + }, + "basicEstimateIsLoading": false, + "gasEstimatesLoading": false, + "priceAndTimeEstimates": [ + { + "expectedTime": "1374.1168296452973076627", + "expectedWait": 99.0593088449, + "gasprice": 4.1 + }, + { + "expectedTime": "1280.88976972896682763716", + "expectedWait": 92.3386225672, + "gasprice": 4.4 + }, + { + "expectedTime": "1245.13314632680319175597", + "expectedWait": 89.7609477113, + "gasprice": 4.8 + }, + { + "expectedTime": "1227.99925007911014385881", + "expectedWait": 88.5257747744, + "gasprice": 4.9 + }, + { + "expectedTime": "965.52572720362993349654", + "expectedWait": 69.6042062402, + "gasprice": 5 + }, + { + "expectedTime": "917.466895447437420776", + "expectedWait": 66.1396721082, + "gasprice": 5.1 + }, + { + "expectedTime": "915.81694044041496090521", + "expectedWait": 66.0207277804, + "gasprice": 5.2 + }, + { + "expectedTime": "902.13145619709089691874", + "expectedWait": 65.034148924, + "gasprice": 5.3 + }, + { + "expectedTime": "890.83591122200105749896", + "expectedWait": 64.2198594443, + "gasprice": 5.4 + }, + { + "expectedTime": "879.10469542971335712248", + "expectedWait": 63.3741627006, + "gasprice": 5.5 + }, + { + "expectedTime": "876.99737395823100420974", + "expectedWait": 63.2222470818, + "gasprice": 5.6 + }, + { + "expectedTime": "865.96781957003849098957", + "expectedWait": 62.4271327138, + "gasprice": 5.7 + }, + { + "expectedTime": "865.44839472121496158482", + "expectedWait": 62.3896876688, + "gasprice": 5.8 + }, + { + "expectedTime": "802.16173170976255602161", + "expectedWait": 57.8273877524, + "gasprice": 6 + }, + { + "expectedTime": "780.79313908053047074843", + "expectedWait": 56.2869379368, + "gasprice": 6.1 + }, + { + "expectedTime": "770.04888359616469549233", + "expectedWait": 55.5123906062, + "gasprice": 6.2 + }, + { + "expectedTime": "745.01007965146736962697", + "expectedWait": 53.7073573226, + "gasprice": 6.3 + }, + { + "expectedTime": "735.19921111598501681816", + "expectedWait": 53.0000973318, + "gasprice": 6.6 + }, + { + "expectedTime": "705.68767153912619368694", + "expectedWait": 50.8726270539, + "gasprice": 6.7 + }, + { + "expectedTime": "705.26438593445239690121", + "expectedWait": 50.8421126329, + "gasprice": 6.9 + }, + { + "expectedTime": "652.51573119854865429742", + "expectedWait": 47.0394918019, + "gasprice": 7 + }, + { + "expectedTime": "635.51471669299464383162", + "expectedWait": 45.813898235, + "gasprice": 7.1 + }, + { + "expectedTime": "634.37181911960854759036", + "expectedWait": 45.7315073922, + "gasprice": 7.2 + }, + { + "expectedTime": "633.23097691113902888918", + "expectedWait": 45.6492647195, + "gasprice": 7.3 + }, + { + "expectedTime": "112.7753456245379663928", + "expectedWait": 8.1299111919, + "gasprice": 7.6 + }, + { + "expectedTime": "102.9665314468898381829", + "expectedWait": 7.4227992986, + "gasprice": 8 + }, + { + "expectedTime": "100.94784507024919649891", + "expectedWait": 7.2772733339, + "gasprice": 8.1 + }, + { + "expectedTime": "100.46445647447807351078", + "expectedWait": 7.2424261221, + "gasprice": 8.8 + }, + { + "expectedTime": "84.91686745986737853339", + "expectedWait": 6.1216091808, + "gasprice": 9 + }, + { + "expectedTime": "80.39566429296684383503", + "expectedWait": 5.7956781892, + "gasprice": 9.1 + }, + { + "expectedTime": "78.24522052614759252715", + "expectedWait": 5.6406539084, + "gasprice": 9.2 + }, + { + "expectedTime": "77.1685119880459882636", + "expectedWait": 5.5630345959, + "gasprice": 9.5 + }, + { + "expectedTime": "72.43649507646737870178", + "expectedWait": 5.2219061601, + "gasprice": 9.8 + }, + { + "expectedTime": "71.48259532351443753818", + "expectedWait": 5.1531400638, + "gasprice": 9.9 + }, + { + "expectedTime": "58.23892805162994573827", + "expectedWait": 4.1984115442, + "gasprice": 10 + }, + { + "expectedTime": "53.13065124862245917617", + "expectedWait": 3.8301587446, + "gasprice": 10.1 + }, + { + "expectedTime": "53.03510209647058751971", + "expectedWait": 3.82327066, + "gasprice": 10.3 + }, + { + "expectedTime": "49.06846157804491912403", + "expectedWait": 3.5373177776, + "gasprice": 11 + }, + { + "expectedTime": "48.30893330101818116637", + "expectedWait": 3.4825638116, + "gasprice": 11.1 + }, + { + "expectedTime": "48.25099734861818116715", + "expectedWait": 3.4783872414, + "gasprice": 11.3 + }, + { + "expectedTime": "47.64416885027272662988", + "expectedWait": 3.4346413165, + "gasprice": 11.9 + }, + { + "expectedTime": "46.76354741392085498401", + "expectedWait": 3.3711578128, + "gasprice": 12.6 + }, + { + "expectedTime": "44.99427448545882292232", + "expectedWait": 3.2436119232, + "gasprice": 13 + }, + { + "expectedTime": "44.61790554199251276697", + "expectedWait": 3.2164796979, + "gasprice": 13.1 + }, + { + "expectedTime": "42.87832690973048070488", + "expectedWait": 3.0910744534, + "gasprice": 14 + }, + { + "expectedTime": "42.21224091308663044649", + "expectedWait": 3.0430566888, + "gasprice": 14.9 + }, + { + "expectedTime": "41.15715335111336842864", + "expectedWait": 2.9669960203, + "gasprice": 15 + }, + { + "expectedTime": "40.9600723880876999821", + "expectedWait": 2.9527885646, + "gasprice": 15.1 + }, + { + "expectedTime": "38.89138450301711177472", + "expectedWait": 2.8036580193, + "gasprice": 15.8 + }, + { + "expectedTime": "37.89655640860213852611", + "expectedWait": 2.7319414219, + "gasprice": 16 + }, + { + "expectedTime": "37.35265517364705831954", + "expectedWait": 2.692731888, + "gasprice": 17.4 + }, + { + "expectedTime": "36.79447683873796741798", + "expectedWait": 2.652493126, + "gasprice": 17.8 + }, + { + "expectedTime": "36.11439350850802090309", + "expectedWait": 2.6034663015, + "gasprice": 19 + }, + { + "expectedTime": "31.32676199432192471101", + "expectedWait": 2.2583286403, + "gasprice": 20 + }, + { + "expectedTime": "30.76792490132192471855", + "expectedWait": 2.2180423888, + "gasprice": 20.1 + }, + { + "expectedTime": "29.94493658520962526441", + "expectedWait": 2.1587136243, + "gasprice": 25 + }, + { + "expectedTime": "29.53287347625561457478", + "expectedWait": 2.1290082267, + "gasprice": 29 + }, + { + "expectedTime": "29.09318627175614934008", + "expectedWait": 2.0973114236, + "gasprice": 47 + } + ], + "priceAndTimeEstimatesLastRetrieved": 1541527901281, + "errors": {} } } diff --git a/development/states/send-new-ui.json b/development/states/send-new-ui.json index 9be4ef0da594..479b6d3e3e25 100644 --- a/development/states/send-new-ui.json +++ b/development/states/send-new-ui.json @@ -158,7 +158,7 @@ "hexGasTotal": "", "nonce": "", "fetchingMethodData": false - } + }, "gas": { "customData": { "price": null, @@ -473,5 +473,5 @@ ], "priceAndTimeEstimatesLastRetrieved": 1541527901281, "errors": {} - }, + } } diff --git a/development/states/send.json b/development/states/send.json index 4c67f8ac6920..8ae385564c48 100644 --- a/development/states/send.json +++ b/development/states/send.json @@ -107,5 +107,320 @@ "scrollToBottom": false, "forgottenPassword": null }, - "identities": {} + "identities": {}, + "gas": { + "customData": { + "price": null, + "limit": "0x186a0" + }, + "basicEstimates": { + "average": 73, + "avgWait": 10.6, + "blockTime": 13.871657754010695, + "blockNum": 6655504, + "fast": 160, + "fastest": 290, + "fastestWait": 0.5, + "fastWait": 0.6, + "safeLow": 50, + "safeLowWait": 16.1, + "speed": 0.6702462692280712 + }, + "basicEstimateIsLoading": false, + "gasEstimatesLoading": false, + "priceAndTimeEstimates": [ + { + "expectedTime": "1374.1168296452973076627", + "expectedWait": 99.0593088449, + "gasprice": 4.1 + }, + { + "expectedTime": "1280.88976972896682763716", + "expectedWait": 92.3386225672, + "gasprice": 4.4 + }, + { + "expectedTime": "1245.13314632680319175597", + "expectedWait": 89.7609477113, + "gasprice": 4.8 + }, + { + "expectedTime": "1227.99925007911014385881", + "expectedWait": 88.5257747744, + "gasprice": 4.9 + }, + { + "expectedTime": "965.52572720362993349654", + "expectedWait": 69.6042062402, + "gasprice": 5 + }, + { + "expectedTime": "917.466895447437420776", + "expectedWait": 66.1396721082, + "gasprice": 5.1 + }, + { + "expectedTime": "915.81694044041496090521", + "expectedWait": 66.0207277804, + "gasprice": 5.2 + }, + { + "expectedTime": "902.13145619709089691874", + "expectedWait": 65.034148924, + "gasprice": 5.3 + }, + { + "expectedTime": "890.83591122200105749896", + "expectedWait": 64.2198594443, + "gasprice": 5.4 + }, + { + "expectedTime": "879.10469542971335712248", + "expectedWait": 63.3741627006, + "gasprice": 5.5 + }, + { + "expectedTime": "876.99737395823100420974", + "expectedWait": 63.2222470818, + "gasprice": 5.6 + }, + { + "expectedTime": "865.96781957003849098957", + "expectedWait": 62.4271327138, + "gasprice": 5.7 + }, + { + "expectedTime": "865.44839472121496158482", + "expectedWait": 62.3896876688, + "gasprice": 5.8 + }, + { + "expectedTime": "802.16173170976255602161", + "expectedWait": 57.8273877524, + "gasprice": 6 + }, + { + "expectedTime": "780.79313908053047074843", + "expectedWait": 56.2869379368, + "gasprice": 6.1 + }, + { + "expectedTime": "770.04888359616469549233", + "expectedWait": 55.5123906062, + "gasprice": 6.2 + }, + { + "expectedTime": "745.01007965146736962697", + "expectedWait": 53.7073573226, + "gasprice": 6.3 + }, + { + "expectedTime": "735.19921111598501681816", + "expectedWait": 53.0000973318, + "gasprice": 6.6 + }, + { + "expectedTime": "705.68767153912619368694", + "expectedWait": 50.8726270539, + "gasprice": 6.7 + }, + { + "expectedTime": "705.26438593445239690121", + "expectedWait": 50.8421126329, + "gasprice": 6.9 + }, + { + "expectedTime": "652.51573119854865429742", + "expectedWait": 47.0394918019, + "gasprice": 7 + }, + { + "expectedTime": "635.51471669299464383162", + "expectedWait": 45.813898235, + "gasprice": 7.1 + }, + { + "expectedTime": "634.37181911960854759036", + "expectedWait": 45.7315073922, + "gasprice": 7.2 + }, + { + "expectedTime": "633.23097691113902888918", + "expectedWait": 45.6492647195, + "gasprice": 7.3 + }, + { + "expectedTime": "112.7753456245379663928", + "expectedWait": 8.1299111919, + "gasprice": 7.6 + }, + { + "expectedTime": "102.9665314468898381829", + "expectedWait": 7.4227992986, + "gasprice": 8 + }, + { + "expectedTime": "100.94784507024919649891", + "expectedWait": 7.2772733339, + "gasprice": 8.1 + }, + { + "expectedTime": "100.46445647447807351078", + "expectedWait": 7.2424261221, + "gasprice": 8.8 + }, + { + "expectedTime": "84.91686745986737853339", + "expectedWait": 6.1216091808, + "gasprice": 9 + }, + { + "expectedTime": "80.39566429296684383503", + "expectedWait": 5.7956781892, + "gasprice": 9.1 + }, + { + "expectedTime": "78.24522052614759252715", + "expectedWait": 5.6406539084, + "gasprice": 9.2 + }, + { + "expectedTime": "77.1685119880459882636", + "expectedWait": 5.5630345959, + "gasprice": 9.5 + }, + { + "expectedTime": "72.43649507646737870178", + "expectedWait": 5.2219061601, + "gasprice": 9.8 + }, + { + "expectedTime": "71.48259532351443753818", + "expectedWait": 5.1531400638, + "gasprice": 9.9 + }, + { + "expectedTime": "58.23892805162994573827", + "expectedWait": 4.1984115442, + "gasprice": 10 + }, + { + "expectedTime": "53.13065124862245917617", + "expectedWait": 3.8301587446, + "gasprice": 10.1 + }, + { + "expectedTime": "53.03510209647058751971", + "expectedWait": 3.82327066, + "gasprice": 10.3 + }, + { + "expectedTime": "49.06846157804491912403", + "expectedWait": 3.5373177776, + "gasprice": 11 + }, + { + "expectedTime": "48.30893330101818116637", + "expectedWait": 3.4825638116, + "gasprice": 11.1 + }, + { + "expectedTime": "48.25099734861818116715", + "expectedWait": 3.4783872414, + "gasprice": 11.3 + }, + { + "expectedTime": "47.64416885027272662988", + "expectedWait": 3.4346413165, + "gasprice": 11.9 + }, + { + "expectedTime": "46.76354741392085498401", + "expectedWait": 3.3711578128, + "gasprice": 12.6 + }, + { + "expectedTime": "44.99427448545882292232", + "expectedWait": 3.2436119232, + "gasprice": 13 + }, + { + "expectedTime": "44.61790554199251276697", + "expectedWait": 3.2164796979, + "gasprice": 13.1 + }, + { + "expectedTime": "42.87832690973048070488", + "expectedWait": 3.0910744534, + "gasprice": 14 + }, + { + "expectedTime": "42.21224091308663044649", + "expectedWait": 3.0430566888, + "gasprice": 14.9 + }, + { + "expectedTime": "41.15715335111336842864", + "expectedWait": 2.9669960203, + "gasprice": 15 + }, + { + "expectedTime": "40.9600723880876999821", + "expectedWait": 2.9527885646, + "gasprice": 15.1 + }, + { + "expectedTime": "38.89138450301711177472", + "expectedWait": 2.8036580193, + "gasprice": 15.8 + }, + { + "expectedTime": "37.89655640860213852611", + "expectedWait": 2.7319414219, + "gasprice": 16 + }, + { + "expectedTime": "37.35265517364705831954", + "expectedWait": 2.692731888, + "gasprice": 17.4 + }, + { + "expectedTime": "36.79447683873796741798", + "expectedWait": 2.652493126, + "gasprice": 17.8 + }, + { + "expectedTime": "36.11439350850802090309", + "expectedWait": 2.6034663015, + "gasprice": 19 + }, + { + "expectedTime": "31.32676199432192471101", + "expectedWait": 2.2583286403, + "gasprice": 20 + }, + { + "expectedTime": "30.76792490132192471855", + "expectedWait": 2.2180423888, + "gasprice": 20.1 + }, + { + "expectedTime": "29.94493658520962526441", + "expectedWait": 2.1587136243, + "gasprice": 25 + }, + { + "expectedTime": "29.53287347625561457478", + "expectedWait": 2.1290082267, + "gasprice": 29 + }, + { + "expectedTime": "29.09318627175614934008", + "expectedWait": 2.0973114236, + "gasprice": 47 + } + ], + "priceAndTimeEstimatesLastRetrieved": 1541527901281, + "errors": {} + } } From a44596ec0dc45fa0d3a950847ff68f7a53f9625f Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 8 Nov 2018 07:53:34 -0330 Subject: [PATCH 37/64] Add c3 and d3 to the separate dependencies bundle. --- gulpfile.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gulpfile.js b/gulpfile.js index 1487f717e3f2..31888faacafb 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -30,10 +30,12 @@ const packageJSON = require('./package.json') const dependencies = Object.keys(packageJSON && packageJSON.dependencies || {}) const materialUIDependencies = ['@material-ui/core'] const reactDepenendencies = dependencies.filter(dep => dep.match(/react/)) +const d3Dependencies = ['c3', 'd3'] const uiDependenciesToBundle = [ ...materialUIDependencies, ...reactDepenendencies, + ...d3Dependencies, ] function gulpParallel (...args) { From d5411e772d1efd8d723eb81403fa22b03b904f49 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 8 Nov 2018 12:33:31 -0330 Subject: [PATCH 38/64] Make gas customization modal responsive. --- .../gas-customization/gas-modal-page-container/index.scss | 8 ++++++++ .../gas-customization/gas-price-button-group/index.scss | 8 ++++++++ .../gas-customization/gas-price-chart/index.scss | 5 +++++ ui/app/components/page-container/index.scss | 6 +++++- ui/app/css/itcss/components/newui-sections.scss | 1 + ui/app/css/itcss/components/send.scss | 1 + ui/app/css/itcss/generic/index.scss | 4 ++++ 7 files changed, 32 insertions(+), 1 deletion(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index debd9b5ee78e..9486eaf8f1f4 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -6,6 +6,10 @@ max-width: 391px; min-height: 585px; + @media screen and (max-width: $break-small) { + max-width: 344px; + } + &__header { padding: 0px; padding-top: 16px; @@ -60,6 +64,10 @@ } .gas-modal-content { + @media screen and (max-width: $break-small) { + width: 100%; + } + &__basic-tab { height: 219px; } diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.scss b/ui/app/components/gas-customization/gas-price-button-group/index.scss index 22661ed7b328..6e9d01c6e42e 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/index.scss +++ b/ui/app/components/gas-customization/gas-price-button-group/index.scss @@ -67,6 +67,10 @@ justify-content: stretch; max-width: 260px; + @media screen and (max-width: $break-small) { + max-width: 230px; + } + &__button-fiat-price { font-size: 13px; } @@ -98,6 +102,10 @@ padding-top: 9px; padding-left: 8.5px; + @media screen and (max-width: $break-small) { + padding-left: 4px; + } + div { display: flex; flex-flow: column; diff --git a/ui/app/components/gas-customization/gas-price-chart/index.scss b/ui/app/components/gas-customization/gas-price-chart/index.scss index 0990d6abb691..097543104cb4 100644 --- a/ui/app/components/gas-customization/gas-price-chart/index.scss +++ b/ui/app/components/gas-customization/gas-price-chart/index.scss @@ -1,12 +1,17 @@ .gas-price-chart { display: flex; position: relative; + justify-content: center; &__root { max-height: 154px; max-width: 391px; position: relative; overflow: hidden; + + @media screen and (max-width: $break-small) { + max-width: 326px; + } } .tick text, .c3-axis-x-label, .c3-axis-y-label { diff --git a/ui/app/components/page-container/index.scss b/ui/app/components/page-container/index.scss index ba1215e845c3..1634ab012df8 100644 --- a/ui/app/components/page-container/index.scss +++ b/ui/app/components/page-container/index.scss @@ -194,10 +194,14 @@ .page-container { height: 100%; width: 100%; - overflow-y: auto; background-color: $white; border-radius: 0; flex: 1; + + &__content { + display: flex; + overflow-y: initial; + } } } diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index 233e781ef0fd..b4b77ba1e163 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -216,6 +216,7 @@ $wallet-view-bg: $alabaster; .main-container-wrapper { height: 100%; + width: 100%; } } diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index 4535ced52d89..ba7db7aa89d2 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -530,6 +530,7 @@ @media screen and (max-width: $break-small) { margin: 0; flex: 1 1 auto; + width: 100%; } } diff --git a/ui/app/css/itcss/generic/index.scss b/ui/app/css/itcss/generic/index.scss index d1c65afedaf6..d8e62c97acde 100644 --- a/ui/app/css/itcss/generic/index.scss +++ b/ui/app/css/itcss/generic/index.scss @@ -18,6 +18,10 @@ body { height: 100%; margin: 0; padding: 0; + + @media screen and (max-width: $break-small) { + overflow-y: overlay; + } } html { From 4111e9f92d9b87fa46a9f28e767cdf6bfce21fa2 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 15 Nov 2018 17:02:12 -0330 Subject: [PATCH 39/64] Improve responsiveness of customize speed up slider. --- .../gas-modal-page-container/index.scss | 19 ++++++ ui/app/components/sidebars/index.scss | 5 ++ .../components/sidebars/sidebar-content.scss | 58 +++++++++++++++++-- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index 9486eaf8f1f4..2532c1fc2a1c 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -19,6 +19,13 @@ } } + &__footer { + header { + padding-top: 12px; + padding-bottom: 12px; + } + } + &__header-close-text { font-size: 14px; color: #4EADE7; @@ -82,6 +89,10 @@ color: $scorpion; font-size: 12px; + @media screen and (max-width: $break-small) { + padding: 4px 21px; + } + &__send-info, &__transaction-info, &__total-info, &__fiat-total-info { display: flex; flex-flow: row; @@ -95,11 +106,19 @@ &__total-info { &__label { font-size: 16px; + + @media screen and (max-width: $break-small) { + font-size: 14px; + } } &__value { font-size: 16px; font-weight: bold; + + @media screen and (max-width: $break-small) { + font-size: 14px; + } } } diff --git a/ui/app/components/sidebars/index.scss b/ui/app/components/sidebars/index.scss index 6fcd93e99f5b..b9845d564fe4 100644 --- a/ui/app/components/sidebars/index.scss +++ b/ui/app/components/sidebars/index.scss @@ -60,6 +60,11 @@ width: 408px; left: calc(100% - 408px); } + + @media screen and (max-width: $break-small) { + width: 100%; + left: 0%; + } } .sidebar-overlay { diff --git a/ui/app/components/sidebars/sidebar-content.scss b/ui/app/components/sidebars/sidebar-content.scss index c0973be2c543..7d1f719dcc90 100644 --- a/ui/app/components/sidebars/sidebar-content.scss +++ b/ui/app/components/sidebars/sidebar-content.scss @@ -2,10 +2,24 @@ .gas-modal-page-container { .page-container { max-width: 100%; + + &__content { + display: flex; + overflow-y: initial; + } + + @media screen and (max-width: $break-small) { + max-width: 344px; + min-height: auto; + } } .gas-price-chart { margin-left: 10px; + + &__root { + max-height: 160px !important; + } } .page-container__bottom { @@ -20,21 +34,53 @@ } .basic-tab-content { - height: 377px; + height: 318px; margin-bottom: 0px; border-bottom: 1px solid #d2d8dd; - } - .advanced-tab__fee-chart { - height: 320px; + @media screen and (max-width: $break-small) { + padding-left: 14px; + padding-bottom: 21px; + } + + .gas-price-button-group--alt { + @media screen and (max-width: $break-small) { + max-width: 318px; + + &__time-estimate { + font-size: 12px; + } + } + } } - .advanced-tab__fee-chart__speed-buttons { - bottom: 77px; + .advanced-tab { + &__fee-chart { + height: 320px; + + @media screen and (max-width: $break-small) { + height: initial; + } + } + + &__fee-chart__speed-buttons { + bottom: 77px; + + @media screen and (max-width: $break-small) { + display: none; + } + } } + .gas-modal-content__info-row { height: 170px; + + @media screen and (max-width: $break-small) { + height: initial; + display: flex; + justify-content: center; + } } } } \ No newline at end of file From fe535159bb3ec5849d670d9bc53067f5d6f330b7 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 12:26:12 -0330 Subject: [PATCH 40/64] Fix "fastest" translation message; change to sentence case --- app/_locales/en/messages.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index 69b9969beb69..d23de5fa0237 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -449,7 +449,7 @@ "message": "Fast" }, "fastest": { - "message": "FASTEST" + "message": "Fastest" }, "feeChartTitle": { "message": "Live Transaction Fee Predictions" From 7f2c5c09de67a67972fcbaae254d39aac6c96f56 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 13:06:52 -0330 Subject: [PATCH 41/64] Uses more reliable api on main send screen; caches basic api results in modal --- test/e2e/beta/fetch-mocks.js | 1 + test/e2e/beta/metamask-beta-ui.spec.js | 4 +- .../gas-modal-page-container.component.js | 19 ++++ .../gas-modal-page-container.container.js | 10 +- ...gas-modal-page-container-component.test.js | 32 +++++- ...gas-modal-page-container-container.test.js | 4 + .../confirm-transaction.component.js | 6 +- .../confirm-transaction.container.js | 4 +- .../send-gas-row/send-gas-row.container.js | 4 +- .../tests/send-gas-row-container.test.js | 2 +- ui/app/components/send/send.component.js | 4 +- ui/app/components/send/send.container.js | 2 - ui/app/components/send/send.selectors.js | 4 +- .../send/tests/send-component.test.js | 18 +--- .../transaction-list-item.component.js | 6 +- .../transaction-list-item.container.js | 4 +- ui/app/ducks/gas.duck.js | 98 ++++++++++++++++--- ui/app/ducks/tests/gas-duck.test.js | 34 ++++++- ui/app/selectors/custom-gas.js | 94 +++++++++++------- ui/app/selectors/tests/custom-gas.test.js | 94 +++++++++--------- ui/lib/test-timeout.js | 5 + 21 files changed, 309 insertions(+), 140 deletions(-) create mode 100644 ui/lib/test-timeout.js diff --git a/test/e2e/beta/fetch-mocks.js b/test/e2e/beta/fetch-mocks.js index ee2d54f24c2f..bb17025550e8 100644 --- a/test/e2e/beta/fetch-mocks.js +++ b/test/e2e/beta/fetch-mocks.js @@ -1,4 +1,5 @@ module.exports = { ethGasBasic: JSON.stringify({'average': 85.0, 'fastestWait': 0.6, 'fastWait': 0.6, 'fast': 200.0, 'safeLowWait': 4.8, 'blockNum': 6648312, 'avgWait': 4.2, 'block_time': 15.516129032258064, 'speed': 0.7828720873342716, 'fastest': 400.0, 'safeLow': 80.0}), ethGasPredictTable: JSON.stringify([{'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 7.2632423756, 'pct_remaining5m': 0.0, 'sum': 7.029975, 'tx_atabove': 4136.0, 'hashpower_accepting': 10.4166666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 1.2, 'pct_mined_5m': 0.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 7.433788122, 'pct_remaining5m': 0.0, 'sum': 7.01731875, 'tx_atabove': 4136.0, 'hashpower_accepting': 10.9375, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 1.5, 'pct_mined_5m': 0.0, 'total_seen_5m': 84.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 7.433788122, 'pct_remaining5m': 0.0, 'sum': 7.01731875, 'tx_atabove': 4136.0, 'hashpower_accepting': 10.9375, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 1.7, 'pct_mined_5m': 0.0, 'total_seen_5m': 5.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 7.4638844302, 'pct_remaining5m': 0.0, 'sum': 7.01731875, 'tx_atabove': 4136.0, 'hashpower_accepting': 10.9375, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 1.8, 'pct_mined_5m': 0.0, 'total_seen_5m': 20.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 7.4839486356, 'pct_remaining5m': 0.0, 'sum': 7.01731875, 'tx_atabove': 4136.0, 'hashpower_accepting': 10.9375, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 1.9, 'pct_mined_5m': 0.0, 'total_seen_5m': 8.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 7.7347512039, 'pct_remaining5m': 0.0, 'sum': 7.0046625, 'tx_atabove': 4136.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 2.0, 'pct_mined_5m': 0.0, 'total_seen_5m': 52.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 17.0, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 1.0, 'sum': 7.0046625, 'tx_atabove': 4136.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 2.1, 'pct_mined_5m': 0.0, 'total_seen_5m': 97.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 20.0, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 1.0, 'sum': 7.0040625, 'tx_atabove': 4135.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 6.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 2.2, 'pct_mined_5m': 0.0, 'total_seen_5m': 433.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 68.0, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 0.0, 'sum': 6.9986625, 'tx_atabove': 4126.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 50.0, 'gasprice': 2.3, 'pct_mined_5m': 0.0, 'total_seen_5m': 14.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 0.0, 'sum': 6.9980625, 'tx_atabove': 4125.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 2.4, 'pct_mined_5m': 0.0, 'total_seen_5m': 4.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 20.0, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 37.0, 'sum': 6.9956625, 'tx_atabove': 4121.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 75.0, 'gasprice': 2.5, 'pct_mined_5m': 0.0, 'total_seen_5m': 45.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 79.0, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 0.0, 'sum': 6.9788625, 'tx_atabove': 4093.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 2.6, 'pct_mined_5m': 0.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 27.5, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 100.0, 'sum': 6.9764625, 'tx_atabove': 4089.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 2.7, 'pct_mined_5m': 0.0, 'total_seen_5m': 3.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 22.5, 'hashpower_accepting2': 7.7447833066, 'pct_remaining5m': 66.0, 'sum': 6.9740625, 'tx_atabove': 4085.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 2.8, 'pct_mined_5m': 0.0, 'total_seen_5m': 6.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 20.0, 'hashpower_accepting2': 7.7548154093, 'pct_remaining5m': 38.0, 'sum': 6.9686625, 'tx_atabove': 4076.0, 'hashpower_accepting': 11.4583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 2.9, 'pct_mined_5m': 2.0, 'total_seen_5m': 36.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 27.0, 'hashpower_accepting2': 11.5268860353, 'pct_remaining5m': 77.0, 'sum': 6.8307, 'tx_atabove': 4057.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 127.0, 'int2': 6.9238, 'pct_remaining30m': 48.0, 'gasprice': 3.0, 'pct_mined_5m': 0.0, 'total_seen_5m': 322.0, 'pct_mined_30m': 39.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 67.0, 'hashpower_accepting2': 11.5268860353, 'pct_remaining5m': 100.0, 'sum': 6.5697, 'tx_atabove': 3622.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 85.0, 'int2': 6.9238, 'pct_remaining30m': 98.0, 'gasprice': 3.1, 'pct_mined_5m': 0.0, 'total_seen_5m': 79.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 71.0, 'hashpower_accepting2': 11.5268860353, 'pct_remaining5m': 100.0, 'sum': 6.4311, 'tx_atabove': 3391.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 7.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 3.2, 'pct_mined_5m': 0.0, 'total_seen_5m': 4.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 62.0, 'hashpower_accepting2': 11.5268860353, 'pct_remaining5m': 100.0, 'sum': 6.4209, 'tx_atabove': 3374.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 14.0, 'int2': 6.9238, 'pct_remaining30m': 92.0, 'gasprice': 3.3, 'pct_mined_5m': 0.0, 'total_seen_5m': 7.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1472.0, 'hashpower_accepting2': 11.5569823435, 'pct_remaining5m': 100.0, 'sum': 6.3951, 'tx_atabove': 3331.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 29.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 3.4, 'pct_mined_5m': 0.0, 'total_seen_5m': 27.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 307.0, 'hashpower_accepting2': 11.5670144462, 'pct_remaining5m': 100.0, 'sum': 6.1521, 'tx_atabove': 2926.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 3.7, 'pct_mined_5m': 0.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1399.0, 'hashpower_accepting2': 11.577046549, 'pct_remaining5m': 100.0, 'sum': 6.1395, 'tx_atabove': 2905.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 3.9, 'pct_mined_5m': 0.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1005.0, 'hashpower_accepting2': 11.5971107544, 'pct_remaining5m': 88.0, 'sum': 6.1035, 'tx_atabove': 2845.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 9.0, 'int2': 6.9238, 'pct_remaining30m': 88.0, 'gasprice': 4.0, 'pct_mined_5m': 0.0, 'total_seen_5m': 9.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1546.0, 'hashpower_accepting2': 11.6171749599, 'pct_remaining5m': null, 'sum': 5.6151, 'tx_atabove': 2031.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 4.1, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1065.0, 'hashpower_accepting2': 11.6171749599, 'pct_remaining5m': 100.0, 'sum': 5.5509, 'tx_atabove': 1924.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 4.3, 'pct_mined_5m': 0.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 459.0, 'hashpower_accepting2': 11.6171749599, 'pct_remaining5m': 50.0, 'sum': 5.5137, 'tx_atabove': 1862.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 4.4, 'pct_mined_5m': 0.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 298.0, 'hashpower_accepting2': 11.6171749599, 'pct_remaining5m': null, 'sum': 5.4903, 'tx_atabove': 1823.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 4.7, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 812.0, 'hashpower_accepting2': 11.6472712681, 'pct_remaining5m': 0.0, 'sum': 5.4831, 'tx_atabove': 1811.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 4.8, 'pct_mined_5m': 0.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 541.0, 'hashpower_accepting2': 11.6472712681, 'pct_remaining5m': 100.0, 'sum': 5.4375, 'tx_atabove': 1735.0, 'hashpower_accepting': 16.6666666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 4.9, 'pct_mined_5m': 0.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1134.0, 'hashpower_accepting2': 11.7375601926, 'pct_remaining5m': 100.0, 'sum': 5.41824375, 'tx_atabove': 1724.0, 'hashpower_accepting': 17.1875, 'hpa_coef2': -0.067, 'total_seen_30m': 6.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 5.0, 'pct_mined_5m': 0.0, 'total_seen_5m': 5.0, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1958.0, 'hashpower_accepting2': 11.7676565008, 'pct_remaining5m': null, 'sum': 4.9567875, 'tx_atabove': 976.0, 'hashpower_accepting': 17.7083333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 5.2, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1203.5, 'hashpower_accepting2': 11.8077849117, 'pct_remaining5m': null, 'sum': 4.9507875, 'tx_atabove': 966.0, 'hashpower_accepting': 17.7083333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 5.3, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 677.5, 'hashpower_accepting2': 11.8378812199, 'pct_remaining5m': null, 'sum': 4.9141875, 'tx_atabove': 905.0, 'hashpower_accepting': 17.7083333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 100.0, 'gasprice': 5.5, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 250.99, 'avgdiff': 0, 'expectedWait': 1000.0, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 3.0, 'hashpower_accepting2': 13.3928571429, 'pct_remaining5m': 0.0, 'sum': 3.16120625, 'tx_atabove': 832.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 9.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 6.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 12.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.92, 'avgdiff': 1, 'expectedWait': 23.5990451154, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 14.0248796148, 'pct_remaining5m': 0.0, 'sum': 3.10120625, 'tx_atabove': 732.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 6.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.58, 'avgdiff': 1, 'expectedWait': 22.2247437161, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 14.1753611557, 'pct_remaining5m': 0.0, 'sum': 3.09640625, 'tx_atabove': 724.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 6.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.55, 'avgdiff': 1, 'expectedWait': 22.1183205662, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 14.3459069021, 'pct_remaining5m': 0.0, 'sum': 3.09580625, 'tx_atabove': 723.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 6.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 4.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.55, 'avgdiff': 1, 'expectedWait': 22.1050535543, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 14.3960674157, 'pct_remaining5m': 0.0, 'sum': 3.09460625, 'tx_atabove': 721.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 6.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.54, 'avgdiff': 1, 'expectedWait': 22.0785433993, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 14.5465489567, 'pct_remaining5m': 0.0, 'sum': 3.09460625, 'tx_atabove': 721.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 6.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.54, 'avgdiff': 1, 'expectedWait': 22.0785433993, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 14.5666131621, 'pct_remaining5m': null, 'sum': 3.09460625, 'tx_atabove': 721.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 6.6, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.54, 'avgdiff': 1, 'expectedWait': 22.0785433993, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 2.0, 'hashpower_accepting2': 14.6769662921, 'pct_remaining5m': null, 'sum': 3.09460625, 'tx_atabove': 721.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 6.7, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.54, 'avgdiff': 1, 'expectedWait': 22.0785433993, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 14.7070626003, 'pct_remaining5m': null, 'sum': 3.09400625, 'tx_atabove': 720.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 6.8, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.54, 'avgdiff': 1, 'expectedWait': 22.0653002466, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 14.7271268058, 'pct_remaining5m': 0.0, 'sum': 3.09400625, 'tx_atabove': 720.0, 'hashpower_accepting': 20.3125, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 6.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.54, 'avgdiff': 1, 'expectedWait': 22.0653002466, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 3.0, 'hashpower_accepting2': 15.4795345104, 'pct_remaining5m': 0.0, 'sum': 3.06749375, 'tx_atabove': 718.0, 'hashpower_accepting': 21.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 11.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 7.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.39, 'avgdiff': 1, 'expectedWait': 21.4879808804, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 15.5898876404, 'pct_remaining5m': 0.0, 'sum': 3.06089375, 'tx_atabove': 707.0, 'hashpower_accepting': 21.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 7.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.36, 'avgdiff': 1, 'expectedWait': 21.3466271869, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 15.5999197432, 'pct_remaining5m': null, 'sum': 3.06029375, 'tx_atabove': 706.0, 'hashpower_accepting': 21.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 7.2, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.35, 'avgdiff': 1, 'expectedWait': 21.3338230522, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 15.8507223114, 'pct_remaining5m': 0.0, 'sum': 3.05969375, 'tx_atabove': 705.0, 'hashpower_accepting': 21.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 7.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.35, 'avgdiff': 1, 'expectedWait': 21.3210265977, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 15.8607544141, 'pct_remaining5m': null, 'sum': 3.05909375, 'tx_atabove': 704.0, 'hashpower_accepting': 21.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 7.7, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 0.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 5.35, 'avgdiff': 1, 'expectedWait': 21.3082378187, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 18.86035313, 'pct_remaining5m': 0.0, 'sum': 2.8933625, 'tx_atabove': 702.0, 'hashpower_accepting': 28.125, 'hpa_coef2': -0.067, 'total_seen_30m': 30.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 8.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 37.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 4.53, 'avgdiff': 1, 'expectedWait': 18.053913939, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 19.1011235955, 'pct_remaining5m': 0.0, 'sum': 2.85250625, 'tx_atabove': 655.0, 'hashpower_accepting': 28.6458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 8.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 5.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 4.35, 'avgdiff': 1, 'expectedWait': 17.331163684, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 19.1613162119, 'pct_remaining5m': 0.0, 'sum': 2.84890625, 'tx_atabove': 649.0, 'hashpower_accepting': 28.6458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 8.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 4.33, 'avgdiff': 1, 'expectedWait': 17.268883666, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 19.231540931, 'pct_remaining5m': 0.0, 'sum': 2.8097375, 'tx_atabove': 647.0, 'hashpower_accepting': 30.2083333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 8.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 4.17, 'avgdiff': 1, 'expectedWait': 16.6055586875, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 19.5224719101, 'pct_remaining5m': 0.0, 'sum': 2.777225, 'tx_atabove': 635.0, 'hashpower_accepting': 31.25, 'hpa_coef2': -0.067, 'total_seen_30m': 7.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 8.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 12.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 4.03, 'avgdiff': 1, 'expectedWait': 16.0743526708, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 19.7331460674, 'pct_remaining5m': 0.0, 'sum': 2.774225, 'tx_atabove': 630.0, 'hashpower_accepting': 31.25, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 8.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 4.02, 'avgdiff': 1, 'expectedWait': 16.0262018751, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 19.8033707865, 'pct_remaining5m': 0.0, 'sum': 2.72905625, 'tx_atabove': 618.0, 'hashpower_accepting': 32.8125, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 8.8, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 3.84, 'avgdiff': 1, 'expectedWait': 15.3184234339, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 19.9638844302, 'pct_remaining5m': 0.0, 'sum': 2.6954, 'tx_atabove': 583.0, 'hashpower_accepting': 33.3333333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 8.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 3.72, 'avgdiff': 1, 'expectedWait': 14.8114421454, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 23.6155698234, 'pct_remaining5m': 0.0, 'sum': 2.3937875, 'tx_atabove': 460.0, 'hashpower_accepting': 42.7083333333, 'hpa_coef2': -0.067, 'total_seen_30m': 43.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 120.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.75, 'avgdiff': 1, 'expectedWait': 10.9549071782, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 24.0268860353, 'pct_remaining5m': 0.0, 'sum': 2.30313125, 'tx_atabove': 330.0, 'hashpower_accepting': 43.2291666667, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 23.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.51, 'avgdiff': 1, 'expectedWait': 10.0054630618, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 24.1472712681, 'pct_remaining5m': 0.0, 'sum': 2.287475, 'tx_atabove': 325.0, 'hashpower_accepting': 43.75, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 9.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.47, 'avgdiff': 1, 'expectedWait': 9.8500349165, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 24.2174959872, 'pct_remaining5m': 0.0, 'sum': 2.2609625, 'tx_atabove': 323.0, 'hashpower_accepting': 44.7916666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 9.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.41, 'avgdiff': 1, 'expectedWait': 9.5923173304, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 24.3880417335, 'pct_remaining5m': 0.0, 'sum': 2.22239375, 'tx_atabove': 322.0, 'hashpower_accepting': 46.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 7.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.32, 'avgdiff': 1, 'expectedWait': 9.2293973144, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 24.5284911717, 'pct_remaining5m': 0.0, 'sum': 2.2091375, 'tx_atabove': 321.0, 'hashpower_accepting': 46.875, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.29, 'avgdiff': 1, 'expectedWait': 9.1078574773, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 24.7391653291, 'pct_remaining5m': 0.0, 'sum': 2.2073375, 'tx_atabove': 318.0, 'hashpower_accepting': 46.875, 'hpa_coef2': -0.067, 'total_seen_30m': 9.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 8.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.28, 'avgdiff': 1, 'expectedWait': 9.0914780797, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 24.9699036918, 'pct_remaining5m': 0.0, 'sum': 2.182025, 'tx_atabove': 318.0, 'hashpower_accepting': 47.9166666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.7, 'pct_mined_5m': 88.0, 'total_seen_5m': 9.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.22, 'avgdiff': 1, 'expectedWait': 8.8642381788, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 2.0, 'hashpower_accepting2': 25.1203852327, 'pct_remaining5m': 0.0, 'sum': 2.16936875, 'tx_atabove': 318.0, 'hashpower_accepting': 48.4375, 'hpa_coef2': -0.067, 'total_seen_30m': 6.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.8, 'pct_mined_5m': 75.0, 'total_seen_5m': 4.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.2, 'avgdiff': 1, 'expectedWait': 8.7527571186, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 25.1705457464, 'pct_remaining5m': 0.0, 'sum': 2.1561125, 'tx_atabove': 317.0, 'hashpower_accepting': 48.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 9.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 2.17, 'avgdiff': 1, 'expectedWait': 8.637494048, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 36.3864365971, 'pct_remaining5m': 0.0, 'sum': 1.769825, 'tx_atabove': 306.0, 'hashpower_accepting': 64.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 353.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.0, 'pct_mined_5m': 99.0, 'total_seen_5m': 245.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.47, 'avgdiff': 1, 'expectedWait': 5.8698260519, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 36.536918138, 'pct_remaining5m': 0.0, 'sum': 1.733225, 'tx_atabove': 245.0, 'hashpower_accepting': 64.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 7.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.42, 'avgdiff': 1, 'expectedWait': 5.658874382, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 36.7576243981, 'pct_remaining5m': 0.0, 'sum': 1.733225, 'tx_atabove': 245.0, 'hashpower_accepting': 64.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 6.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.42, 'avgdiff': 1, 'expectedWait': 5.658874382, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 36.8378812199, 'pct_remaining5m': 0.0, 'sum': 1.732625, 'tx_atabove': 244.0, 'hashpower_accepting': 64.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.42, 'avgdiff': 1, 'expectedWait': 5.6554800758, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 36.8679775281, 'pct_remaining5m': 0.0, 'sum': 1.732025, 'tx_atabove': 243.0, 'hashpower_accepting': 64.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.42, 'avgdiff': 1, 'expectedWait': 5.6520878055, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 37.8109951846, 'pct_remaining5m': 0.0, 'sum': 1.69405625, 'tx_atabove': 243.0, 'hashpower_accepting': 66.1458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 12.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 53.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.37, 'avgdiff': 1, 'expectedWait': 5.4415081179, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 37.871187801, 'pct_remaining5m': 0.0, 'sum': 1.69285625, 'tx_atabove': 241.0, 'hashpower_accepting': 66.1458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.36, 'avgdiff': 1, 'expectedWait': 5.4349822245, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 38.1019261637, 'pct_remaining5m': 0.0, 'sum': 1.69285625, 'tx_atabove': 241.0, 'hashpower_accepting': 66.1458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.8, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.36, 'avgdiff': 1, 'expectedWait': 5.4349822245, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 38.1821829856, 'pct_remaining5m': 0.0, 'sum': 1.68565625, 'tx_atabove': 229.0, 'hashpower_accepting': 66.1458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 10.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.35, 'avgdiff': 1, 'expectedWait': 5.3959908897, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 40.7002407705, 'pct_remaining5m': 0.0, 'sum': 1.520525, 'tx_atabove': 228.0, 'hashpower_accepting': 72.9166666667, 'hpa_coef2': -0.067, 'total_seen_30m': 84.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 84.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.15, 'avgdiff': 1, 'expectedWait': 4.5746262436, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 40.8206260032, 'pct_remaining5m': 0.0, 'sum': 1.507325, 'tx_atabove': 206.0, 'hashpower_accepting': 72.9166666667, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 4.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.13, 'avgdiff': 1, 'expectedWait': 4.5146379708, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 40.8908507223, 'pct_remaining5m': 0.0, 'sum': 1.507325, 'tx_atabove': 206.0, 'hashpower_accepting': 72.9166666667, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.13, 'avgdiff': 1, 'expectedWait': 4.5146379708, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 41.4024879615, 'pct_remaining5m': 0.0, 'sum': 1.49466875, 'tx_atabove': 206.0, 'hashpower_accepting': 73.4375, 'hpa_coef2': -0.067, 'total_seen_30m': 15.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.12, 'avgdiff': 1, 'expectedWait': 4.4578596422, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 41.4827447833, 'pct_remaining5m': 0.0, 'sum': 1.49466875, 'tx_atabove': 206.0, 'hashpower_accepting': 73.4375, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.12, 'avgdiff': 1, 'expectedWait': 4.4578596422, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 41.6131621188, 'pct_remaining5m': 0.0, 'sum': 1.49406875, 'tx_atabove': 205.0, 'hashpower_accepting': 73.4375, 'hpa_coef2': -0.067, 'total_seen_30m': 8.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.12, 'avgdiff': 1, 'expectedWait': 4.4551857287, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 41.6332263242, 'pct_remaining5m': 0.0, 'sum': 1.49406875, 'tx_atabove': 205.0, 'hashpower_accepting': 73.4375, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.12, 'avgdiff': 1, 'expectedWait': 4.4551857287, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 41.753611557, 'pct_remaining5m': 0.0, 'sum': 1.49406875, 'tx_atabove': 205.0, 'hashpower_accepting': 73.4375, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.8, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.12, 'avgdiff': 1, 'expectedWait': 4.4551857287, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 41.7736757624, 'pct_remaining5m': null, 'sum': 1.49406875, 'tx_atabove': 205.0, 'hashpower_accepting': 73.4375, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 11.9, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.12, 'avgdiff': 1, 'expectedWait': 4.4551857287, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 44.7030497592, 'pct_remaining5m': 0.0, 'sum': 1.41813125, 'tx_atabove': 205.0, 'hashpower_accepting': 76.5625, 'hpa_coef2': -0.067, 'total_seen_30m': 96.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 39.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.04, 'avgdiff': 1, 'expectedWait': 4.1293964158, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 44.9036918138, 'pct_remaining5m': 0.0, 'sum': 1.399475, 'tx_atabove': 195.0, 'hashpower_accepting': 77.0833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 11.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.02, 'avgdiff': 1, 'expectedWait': 4.0530715456, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 45.0341091493, 'pct_remaining5m': null, 'sum': 1.38681875, 'tx_atabove': 195.0, 'hashpower_accepting': 77.6041666667, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.2, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 1.0, 'avgdiff': 1, 'expectedWait': 4.0020981056, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 45.1845906902, 'pct_remaining5m': 0.0, 'sum': 1.3735625, 'tx_atabove': 194.0, 'hashpower_accepting': 78.125, 'hpa_coef2': -0.067, 'total_seen_30m': 9.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.99, 'avgdiff': 1, 'expectedWait': 3.9493953846, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 45.1946227929, 'pct_remaining5m': null, 'sum': 1.3735625, 'tx_atabove': 194.0, 'hashpower_accepting': 78.125, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.4, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.99, 'avgdiff': 1, 'expectedWait': 3.9493953846, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 45.3752006421, 'pct_remaining5m': 0.0, 'sum': 1.36090625, 'tx_atabove': 194.0, 'hashpower_accepting': 78.6458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 10.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.98, 'avgdiff': 1, 'expectedWait': 3.8997258274, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 45.4955858748, 'pct_remaining5m': 0.0, 'sum': 1.36090625, 'tx_atabove': 194.0, 'hashpower_accepting': 78.6458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.98, 'avgdiff': 1, 'expectedWait': 3.8997258274, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 45.525682183, 'pct_remaining5m': null, 'sum': 1.36090625, 'tx_atabove': 194.0, 'hashpower_accepting': 78.6458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.7, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.98, 'avgdiff': 1, 'expectedWait': 3.8997258274, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 45.5858747994, 'pct_remaining5m': 0.0, 'sum': 1.36090625, 'tx_atabove': 194.0, 'hashpower_accepting': 78.6458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.8, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.98, 'avgdiff': 1, 'expectedWait': 3.8997258274, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 45.636035313, 'pct_remaining5m': 0.0, 'sum': 1.36090625, 'tx_atabove': 194.0, 'hashpower_accepting': 78.6458333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 12.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.98, 'avgdiff': 1, 'expectedWait': 3.8997258274, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 46.9903691814, 'pct_remaining5m': 0.0, 'sum': 1.31028125, 'tx_atabove': 194.0, 'hashpower_accepting': 80.7291666667, 'hpa_coef2': -0.067, 'total_seen_30m': 47.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 34.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.93, 'avgdiff': 1, 'expectedWait': 3.7072162202, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 47.5321027287, 'pct_remaining5m': 0.0, 'sum': 1.292825, 'tx_atabove': 186.0, 'hashpower_accepting': 81.25, 'hpa_coef2': -0.067, 'total_seen_30m': 9.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.91, 'avgdiff': 1, 'expectedWait': 3.6430636874, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 47.5621990369, 'pct_remaining5m': 0.0, 'sum': 1.292825, 'tx_atabove': 186.0, 'hashpower_accepting': 81.25, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.91, 'avgdiff': 1, 'expectedWait': 3.6430636874, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 47.632423756, 'pct_remaining5m': null, 'sum': 1.292825, 'tx_atabove': 186.0, 'hashpower_accepting': 81.25, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.4, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.91, 'avgdiff': 1, 'expectedWait': 3.6430636874, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.5, 'hashpower_accepting2': 48.1440609952, 'pct_remaining5m': 0.0, 'sum': 1.28016875, 'tx_atabove': 186.0, 'hashpower_accepting': 81.7708333333, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 21.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.9, 'avgdiff': 1, 'expectedWait': 3.5972467097, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 48.4550561798, 'pct_remaining5m': 0.0, 'sum': 1.2651125, 'tx_atabove': 182.0, 'hashpower_accepting': 82.2916666667, 'hpa_coef2': -0.067, 'total_seen_30m': 10.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 10.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.89, 'avgdiff': 1, 'expectedWait': 3.5434913565, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 55.9590690209, 'pct_remaining5m': 0.0, 'sum': 1.2398, 'tx_atabove': 182.0, 'hashpower_accepting': 83.3333333333, 'hpa_coef2': -0.067, 'total_seen_30m': 253.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 212.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.87, 'avgdiff': 1, 'expectedWait': 3.4549224112, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 56.0593900482, 'pct_remaining5m': 0.0, 'sum': 1.226, 'tx_atabove': 159.0, 'hashpower_accepting': 83.3333333333, 'hpa_coef2': -0.067, 'total_seen_30m': 6.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.8, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.86, 'avgdiff': 1, 'expectedWait': 3.4075719515, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 56.1095505618, 'pct_remaining5m': 0.0, 'sum': 1.226, 'tx_atabove': 159.0, 'hashpower_accepting': 83.3333333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 13.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 4.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.86, 'avgdiff': 1, 'expectedWait': 3.4075719515, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.5, 'hashpower_accepting2': 59.6408507223, 'pct_remaining5m': 0.0, 'sum': 1.13740625, 'tx_atabove': 159.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 119.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 115.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1186688184, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 59.7311396469, 'pct_remaining5m': 0.0, 'sum': 1.13440625, 'tx_atabove': 154.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 14.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 5.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1093268319, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 59.8214285714, 'pct_remaining5m': 0.0, 'sum': 1.13440625, 'tx_atabove': 154.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 4.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1093268319, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 60.1524879615, 'pct_remaining5m': 0.0, 'sum': 1.13380625, 'tx_atabove': 153.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1074617954, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 60.1725521669, 'pct_remaining5m': 0.0, 'sum': 1.13320625, 'tx_atabove': 152.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1055978775, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 60.2528089888, 'pct_remaining5m': 0.0, 'sum': 1.13320625, 'tx_atabove': 152.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1055978775, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 60.6440609952, 'pct_remaining5m': 0.0, 'sum': 1.13320625, 'tx_atabove': 152.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 10.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 10.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1055978775, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 60.6641252006, 'pct_remaining5m': 0.0, 'sum': 1.13320625, 'tx_atabove': 152.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.8, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1055978775, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 60.6942215088, 'pct_remaining5m': null, 'sum': 1.13320625, 'tx_atabove': 152.0, 'hashpower_accepting': 86.9791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 14.9, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.78, 'avgdiff': 1, 'expectedWait': 3.1055978775, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 62.9113162119, 'pct_remaining5m': 0.0, 'sum': 1.0952375, 'tx_atabove': 152.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 65.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 15.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 48.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.75, 'avgdiff': 1, 'expectedWait': 2.9898926986, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 63.4129213483, 'pct_remaining5m': 0.0, 'sum': 1.0910375, 'tx_atabove': 145.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 11.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 15.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 8.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.75, 'avgdiff': 1, 'expectedWait': 2.9773614832, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 64.4161316212, 'pct_remaining5m': 0.0, 'sum': 1.0886375, 'tx_atabove': 141.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 15.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 4.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.75, 'avgdiff': 1, 'expectedWait': 2.9702243836, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 64.4863563403, 'pct_remaining5m': 0.0, 'sum': 1.0820375, 'tx_atabove': 130.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 15.6, 'pct_mined_5m': 50.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9506854521, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 66.1817817014, 'pct_remaining5m': 0.0, 'sum': 1.0820375, 'tx_atabove': 130.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 24.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 15.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 17.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9506854521, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 66.2620385233, 'pct_remaining5m': 0.0, 'sum': 1.0766375, 'tx_atabove': 121.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 15.8, 'pct_mined_5m': 83.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9347946943, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 67.2853130016, 'pct_remaining5m': 0.0, 'sum': 1.0766375, 'tx_atabove': 121.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 15.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 16.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 11.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9347946943, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 67.2953451043, 'pct_remaining5m': null, 'sum': 1.0748375, 'tx_atabove': 118.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 16.1, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9295168154, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 67.4458266453, 'pct_remaining5m': 0.0, 'sum': 1.0748375, 'tx_atabove': 118.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 16.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 7.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9295168154, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 67.455858748, 'pct_remaining5m': 0.0, 'sum': 1.0748375, 'tx_atabove': 118.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 16.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9295168154, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 67.6565008026, 'pct_remaining5m': 0.0, 'sum': 1.0748375, 'tx_atabove': 118.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 16.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 7.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.74, 'avgdiff': 1, 'expectedWait': 2.9295168154, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 67.7267255217, 'pct_remaining5m': 0.0, 'sum': 1.0742375, 'tx_atabove': 117.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 16.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9277596325, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 68.6697431782, 'pct_remaining5m': 0.0, 'sum': 1.0742375, 'tx_atabove': 117.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 42.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 16.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 27.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9277596325, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 68.8904494382, 'pct_remaining5m': 0.0, 'sum': 1.0718375, 'tx_atabove': 113.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 11.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 17.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9207414346, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 69.0308988764, 'pct_remaining5m': 0.0, 'sum': 1.0712375, 'tx_atabove': 112.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 8.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 17.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9189895153, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.0409309791, 'pct_remaining5m': null, 'sum': 1.0706375, 'tx_atabove': 111.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 17.3, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9172386469, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.0710272873, 'pct_remaining5m': 0.0, 'sum': 1.0706375, 'tx_atabove': 111.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 17.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9172386469, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.08105939, 'pct_remaining5m': 0.0, 'sum': 1.0706375, 'tx_atabove': 111.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 17.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9172386469, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.1011235955, 'pct_remaining5m': null, 'sum': 1.0706375, 'tx_atabove': 111.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 17.8, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9172386469, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.1111556982, 'pct_remaining5m': 0.0, 'sum': 1.0706375, 'tx_atabove': 111.0, 'hashpower_accepting': 88.5416666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 17.9, 'pct_mined_5m': 0.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.73, 'avgdiff': 1, 'expectedWait': 2.9172386469, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.7632423756, 'pct_remaining5m': 0.0, 'sum': 1.05798125, 'tx_atabove': 111.0, 'hashpower_accepting': 89.0625, 'hpa_coef2': -0.067, 'total_seen_30m': 16.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 18.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 16.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.72, 'avgdiff': 1, 'expectedWait': 2.8805500054, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.7732744783, 'pct_remaining5m': 0.0, 'sum': 1.05618125, 'tx_atabove': 108.0, 'hashpower_accepting': 89.0625, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 18.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.72, 'avgdiff': 1, 'expectedWait': 2.875369679, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.8134028892, 'pct_remaining5m': 0.0, 'sum': 1.05618125, 'tx_atabove': 108.0, 'hashpower_accepting': 89.0625, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 18.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.72, 'avgdiff': 1, 'expectedWait': 2.875369679, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.823434992, 'pct_remaining5m': 0.0, 'sum': 1.05618125, 'tx_atabove': 108.0, 'hashpower_accepting': 89.0625, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 18.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.72, 'avgdiff': 1, 'expectedWait': 2.875369679, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.8535313002, 'pct_remaining5m': null, 'sum': 1.05618125, 'tx_atabove': 108.0, 'hashpower_accepting': 89.0625, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 18.8, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.72, 'avgdiff': 1, 'expectedWait': 2.875369679, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 69.8735955056, 'pct_remaining5m': 0.0, 'sum': 1.05618125, 'tx_atabove': 108.0, 'hashpower_accepting': 89.0625, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 18.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.72, 'avgdiff': 1, 'expectedWait': 2.875369679, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 70.3150080257, 'pct_remaining5m': 0.0, 'sum': 1.043525, 'tx_atabove': 108.0, 'hashpower_accepting': 89.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 13.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 19.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 11.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.71, 'avgdiff': 1, 'expectedWait': 2.8392076024, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 70.3350722311, 'pct_remaining5m': 0.0, 'sum': 1.042325, 'tx_atabove': 106.0, 'hashpower_accepting': 89.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 19.3, 'pct_mined_5m': 66.0, 'total_seen_5m': 3.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.71, 'avgdiff': 1, 'expectedWait': 2.8358025967, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 70.3752006421, 'pct_remaining5m': 0.0, 'sum': 1.042325, 'tx_atabove': 106.0, 'hashpower_accepting': 89.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 19.4, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.71, 'avgdiff': 1, 'expectedWait': 2.8358025967, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 70.3852327448, 'pct_remaining5m': null, 'sum': 1.042325, 'tx_atabove': 106.0, 'hashpower_accepting': 89.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 19.5, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.71, 'avgdiff': 1, 'expectedWait': 2.8358025967, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 70.4052969502, 'pct_remaining5m': null, 'sum': 1.042325, 'tx_atabove': 106.0, 'hashpower_accepting': 89.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 19.8, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.71, 'avgdiff': 1, 'expectedWait': 2.8358025967, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 70.8266452648, 'pct_remaining5m': 0.0, 'sum': 1.042325, 'tx_atabove': 106.0, 'hashpower_accepting': 89.5833333333, 'hpa_coef2': -0.067, 'total_seen_30m': 18.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 19.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 10.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.71, 'avgdiff': 1, 'expectedWait': 2.8358025967, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 75.2708667737, 'pct_remaining5m': 0.0, 'sum': 0.90310625, 'tx_atabove': 106.0, 'hashpower_accepting': 95.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 144.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 20.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 185.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.62, 'avgdiff': 1, 'expectedWait': 2.4672551317, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 75.3009630819, 'pct_remaining5m': null, 'sum': 0.89650625, 'tx_atabove': 95.0, 'hashpower_accepting': 95.3125, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 20.2, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.62, 'avgdiff': 1, 'expectedWait': 2.4510248666, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 75.3210272873, 'pct_remaining5m': 0.0, 'sum': 0.89650625, 'tx_atabove': 95.0, 'hashpower_accepting': 95.3125, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 20.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.62, 'avgdiff': 1, 'expectedWait': 2.4510248666, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 77.7387640449, 'pct_remaining5m': 0.0, 'sum': 0.88385, 'tx_atabove': 95.0, 'hashpower_accepting': 95.8333333333, 'hpa_coef2': -0.067, 'total_seen_30m': 24.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 20.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 9.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.61, 'avgdiff': 1, 'expectedWait': 2.420199561, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 77.7688603531, 'pct_remaining5m': 0.0, 'sum': 0.88325, 'tx_atabove': 94.0, 'hashpower_accepting': 95.8333333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 20.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.61, 'avgdiff': 1, 'expectedWait': 2.4187478768, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 77.9093097913, 'pct_remaining5m': null, 'sum': 0.87059375, 'tx_atabove': 94.0, 'hashpower_accepting': 96.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 7.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 20.9, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.6, 'avgdiff': 1, 'expectedWait': 2.3883285027, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 79.7752808989, 'pct_remaining5m': 0.0, 'sum': 0.87059375, 'tx_atabove': 94.0, 'hashpower_accepting': 96.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 39.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 21.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 36.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.6, 'avgdiff': 1, 'expectedWait': 2.3883285027, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 79.7953451043, 'pct_remaining5m': 0.0, 'sum': 0.86819375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 21.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.6, 'avgdiff': 1, 'expectedWait': 2.3826033871, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 79.8154093098, 'pct_remaining5m': null, 'sum': 0.86819375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 21.4, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.6, 'avgdiff': 1, 'expectedWait': 2.3826033871, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 79.845505618, 'pct_remaining5m': 0.0, 'sum': 0.86819375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 21.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.6, 'avgdiff': 1, 'expectedWait': 2.3826033871, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.3069823435, 'pct_remaining5m': 0.0, 'sum': 0.86819375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.3541666667, 'hpa_coef2': -0.067, 'total_seen_30m': 9.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 21.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.6, 'avgdiff': 1, 'expectedWait': 2.3826033871, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.8888443018, 'pct_remaining5m': 0.0, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 13.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 22.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 13.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.9089085072, 'pct_remaining5m': null, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 22.1, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.91894061, 'pct_remaining5m': 0.0, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 22.2, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.9289727127, 'pct_remaining5m': null, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 22.3, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.9490369181, 'pct_remaining5m': 0.0, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 22.5, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.9791332263, 'pct_remaining5m': 0.0, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 22.8, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 80.9891653291, 'pct_remaining5m': null, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 22.9, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 81.47070626, 'pct_remaining5m': 0.0, 'sum': 0.8555375, 'tx_atabove': 90.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 15.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 23.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 19.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.352638584, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 81.4907704655, 'pct_remaining5m': 0.0, 'sum': 0.8531375, 'tx_atabove': 86.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 23.1, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3469990216, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 81.5108346709, 'pct_remaining5m': 0.0, 'sum': 0.8525375, 'tx_atabove': 85.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 23.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3455912446, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 81.6011235955, 'pct_remaining5m': 0.0, 'sum': 0.8525375, 'tx_atabove': 85.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 23.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3455912446, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 81.621187801, 'pct_remaining5m': 0.0, 'sum': 0.8525375, 'tx_atabove': 85.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 23.9, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3455912446, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 81.8719903692, 'pct_remaining5m': 0.0, 'sum': 0.8525375, 'tx_atabove': 85.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 7.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 24.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 9.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3455912446, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 81.8820224719, 'pct_remaining5m': 0.0, 'sum': 0.8501375, 'tx_atabove': 81.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 24.3, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3399685755, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 81.9121187801, 'pct_remaining5m': 0.0, 'sum': 0.8501375, 'tx_atabove': 81.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 24.6, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3399685755, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 81.9321829856, 'pct_remaining5m': 0.0, 'sum': 0.8501375, 'tx_atabove': 81.0, 'hashpower_accepting': 96.875, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 24.7, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.59, 'avgdiff': 1, 'expectedWait': 2.3399685755, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 83.3868378812, 'pct_remaining5m': 0.0, 'sum': 0.83688125, 'tx_atabove': 80.0, 'hashpower_accepting': 97.3958333333, 'hpa_coef2': -0.067, 'total_seen_30m': 24.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 25.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 32.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.58, 'avgdiff': 1, 'expectedWait': 2.3091540608, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 83.6276083467, 'pct_remaining5m': 0.0, 'sum': 0.82128125, 'tx_atabove': 54.0, 'hashpower_accepting': 97.3958333333, 'hpa_coef2': -0.067, 'total_seen_30m': 10.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 26.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 7.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.57, 'avgdiff': 1, 'expectedWait': 2.2734107799, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 83.7379614767, 'pct_remaining5m': 0.0, 'sum': 0.82008125, 'tx_atabove': 52.0, 'hashpower_accepting': 97.3958333333, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 27.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.57, 'avgdiff': 1, 'expectedWait': 2.2706843231, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 83.9887640449, 'pct_remaining5m': 0.0, 'sum': 0.81948125, 'tx_atabove': 51.0, 'hashpower_accepting': 97.3958333333, 'hpa_coef2': -0.067, 'total_seen_30m': 13.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 28.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 7.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.57, 'avgdiff': 1, 'expectedWait': 2.2693223212, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 84.0690208668, 'pct_remaining5m': 0.0, 'sum': 0.806825, 'tx_atabove': 51.0, 'hashpower_accepting': 97.9166666667, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 29.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.56, 'avgdiff': 1, 'expectedWait': 2.240782197, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 85.8447030498, 'pct_remaining5m': 0.0, 'sum': 0.7809125, 'tx_atabove': 50.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 55.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 30.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 49.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.55, 'avgdiff': 1, 'expectedWait': 2.1834637674, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 85.9751203852, 'pct_remaining5m': 0.0, 'sum': 0.7743125, 'tx_atabove': 39.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 6.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 31.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 5.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.169100358, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 86.1356340289, 'pct_remaining5m': 0.0, 'sum': 0.7743125, 'tx_atabove': 39.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 32.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 4.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.169100358, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 86.2760834671, 'pct_remaining5m': 0.0, 'sum': 0.7743125, 'tx_atabove': 39.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 33.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.169100358, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 86.4165329053, 'pct_remaining5m': 0.0, 'sum': 0.7737125, 'tx_atabove': 38.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 6.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 34.0, 'pct_mined_5m': 60.0, 'total_seen_5m': 5.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1677992881, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.5, 'hashpower_accepting2': 86.7475922953, 'pct_remaining5m': 0.0, 'sum': 0.7737125, 'tx_atabove': 38.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 10.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 35.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 17.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1677992881, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 86.7877207063, 'pct_remaining5m': 0.0, 'sum': 0.7725125, 'tx_atabove': 36.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 36.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1651994891, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 86.8579454254, 'pct_remaining5m': 0.0, 'sum': 0.7725125, 'tx_atabove': 36.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 37.0, 'pct_mined_5m': 66.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1651994891, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 86.908105939, 'pct_remaining5m': 0.0, 'sum': 0.7725125, 'tx_atabove': 36.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 38.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1651994891, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 86.9783306581, 'pct_remaining5m': 0.0, 'sum': 0.7725125, 'tx_atabove': 36.0, 'hashpower_accepting': 98.9583333333, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 39.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1651994891, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 87.4498394864, 'pct_remaining5m': 0.0, 'sum': 0.75985625, 'tx_atabove': 36.0, 'hashpower_accepting': 99.4791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 16.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 40.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 14.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1379688654, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 89.6167736758, 'pct_remaining5m': 0.0, 'sum': 0.75805625, 'tx_atabove': 33.0, 'hashpower_accepting': 99.4791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 112.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 41.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 57.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.54, 'avgdiff': 1, 'expectedWait': 2.1341239829, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 89.6869983949, 'pct_remaining5m': 0.0, 'sum': 0.75445625, 'tx_atabove': 27.0, 'hashpower_accepting': 99.4791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 42.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.1264549491, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 89.7070626003, 'pct_remaining5m': null, 'sum': 0.75385625, 'tx_atabove': 26.0, 'hashpower_accepting': 99.4791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 43.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.1251794588, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 89.9478330658, 'pct_remaining5m': 0.0, 'sum': 0.75385625, 'tx_atabove': 26.0, 'hashpower_accepting': 99.4791666667, 'hpa_coef2': -0.067, 'total_seen_30m': 9.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 44.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 9.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.1251794588, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 90.088282504, 'pct_remaining5m': 0.0, 'sum': 0.7394, 'tx_atabove': 23.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 8.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 45.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 5.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.0946783304, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 90.4995987159, 'pct_remaining5m': 0.0, 'sum': 0.7394, 'tx_atabove': 23.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 17.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 46.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 19.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.0946783304, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 90.5999197432, 'pct_remaining5m': 0.0, 'sum': 0.7382, 'tx_atabove': 21.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 47.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.0921662239, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 90.6199839486, 'pct_remaining5m': null, 'sum': 0.7382, 'tx_atabove': 21.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 48.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.0921662239, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 90.6500802568, 'pct_remaining5m': null, 'sum': 0.7382, 'tx_atabove': 21.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 49.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.0921662239, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 94.1412520064, 'pct_remaining5m': 0.0, 'sum': 0.7382, 'tx_atabove': 21.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 62.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 50.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 71.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.53, 'avgdiff': 1, 'expectedWait': 2.0921662239, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 94.2114767255, 'pct_remaining5m': 0.0, 'sum': 0.7358, 'tx_atabove': 17.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 51.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0871510456, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 94.4422150883, 'pct_remaining5m': 0.0, 'sum': 0.7358, 'tx_atabove': 17.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 5.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 52.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0871510456, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 94.4723113965, 'pct_remaining5m': null, 'sum': 0.7358, 'tx_atabove': 17.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 54.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0871510456, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 94.4823434992, 'pct_remaining5m': null, 'sum': 0.7346, 'tx_atabove': 15.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 56.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0846479665, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 95.0140449438, 'pct_remaining5m': 0.0, 'sum': 0.7346, 'tx_atabove': 15.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 27.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 60.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 17.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0846479665, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 95.6059390048, 'pct_remaining5m': 0.0, 'sum': 0.7334, 'tx_atabove': 13.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 28.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 61.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 14.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0821478893, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 96.8699839486, 'pct_remaining5m': 0.0, 'sum': 0.7322, 'tx_atabove': 11.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 21.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 63.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 25.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0796508104, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 1.0, 'hashpower_accepting2': 98.3948635634, 'pct_remaining5m': 0.0, 'sum': 0.7298, 'tx_atabove': 7.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 83.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 64.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 38.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0746656331, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.4149277689, 'pct_remaining5m': 0.0, 'sum': 0.728, 'tx_atabove': 4.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 65.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0709345939, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.4951845907, 'pct_remaining5m': 0.0, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 66.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.5052166934, 'pct_remaining5m': null, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 69.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.5152487961, 'pct_remaining5m': null, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 70.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.5553772071, 'pct_remaining5m': 0.0, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 72.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.5754414125, 'pct_remaining5m': 0.0, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 73.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.5854735152, 'pct_remaining5m': 0.0, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 77.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.6055377207, 'pct_remaining5m': null, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 79.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.8663723917, 'pct_remaining5m': 0.0, 'sum': 0.7274, 'tx_atabove': 3.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 14.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 80.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 6.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0696924058, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.8864365971, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 84.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.9466292135, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 88.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 98.9566613162, 'pct_remaining5m': null, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 90.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.0469502408, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 4.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 91.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 3.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.1272070626, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 3.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 96.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.1372391653, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 97.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.1472712681, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 99.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.7090690209, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 23.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 100.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 22.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.8394863563, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 7.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 101.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.9097110754, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 2.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 120.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.9297752809, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': null, 'int2': 6.9238, 'pct_remaining30m': null, 'gasprice': 134.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 2.0, 'pct_mined_30m': null, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': 0.0, 'hashpower_accepting2': 99.9498394864, 'pct_remaining5m': 0.0, 'sum': 0.7268, 'tx_atabove': 2.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 137.0, 'pct_mined_5m': 100.0, 'total_seen_5m': 1.0, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0684509628, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}, {'intercept': 4.8015, 'age': null, 'hashpower_accepting2': 99.9699036918, 'pct_remaining5m': null, 'sum': 0.7256, 'tx_atabove': 0.0, 'hashpower_accepting': 100.0, 'hpa_coef2': -0.067, 'total_seen_30m': 1.0, 'int2': 6.9238, 'pct_remaining30m': 0.0, 'gasprice': 180.0, 'pct_mined_5m': null, 'total_seen_5m': null, 'pct_mined_30m': 100.0, 'tx_atabove_coef': 0.0006, 'average': 600, 'safelow': 600, 'nomine': 550, 'expectedTime': 0.52, 'avgdiff': 1, 'expectedWait': 2.0659703104, 'avgdiff_coef': -1.6459, 'hpa_coef': -0.0243}]), + gasExpress: JSON.stringify({'safeLow': 2.0, 'standard': 3.0, 'fast': 10.0, 'fastest': 52.0, 'block_time': 15, 'blockNum': 6693030}), } diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js index d8f442fb1933..c5b7f40e4a43 100644 --- a/test/e2e/beta/metamask-beta-ui.spec.js +++ b/test/e2e/beta/metamask-beta-ui.spec.js @@ -74,7 +74,9 @@ describe('MetaMask', function () { 'if (args[0] === "https://ethgasstation.info/json/ethgasAPI.json") { return ' + 'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.ethGasBasic + '\')) }); } else if ' + '(args[0] === "https://ethgasstation.info/json/predictTable.json") { return ' + - 'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.ethGasPredictTable + '\')) }); } ' + + 'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.ethGasPredictTable + '\')) }); } else if ' + + '(args[0] === "https://dev.blockscale.net/api/gasexpress.json") { return ' + + 'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.gasExpress + '\')) }); } ' + 'return window.fetch(...args); }' ) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index a804f7b64cbf..b5b13c8490bf 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -12,10 +12,13 @@ export default class GasModalPageContainer extends Component { static propTypes = { hideModal: PropTypes.func, + hideBasic: PropTypes.bool, updateCustomGasPrice: PropTypes.func, updateCustomGasLimit: PropTypes.func, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + fetchBasicGasAndTimeEstimates: PropTypes.func, + fetchGasEstimates: PropTypes.func, gasPriceButtonGroupProps: PropTypes.object, infoRowProps: PropTypes.shape({ originalTotalFiat: PropTypes.string, @@ -28,10 +31,26 @@ export default class GasModalPageContainer extends Component { customModalGasLimitInHex: PropTypes.string, cancelAndClose: PropTypes.func, transactionFee: PropTypes.string, + blockTime: PropTypes.oneOfType([ + PropTypes.string, + PropTypes.number, + ]), } state = {} + componentDidMount () { + const promise = this.props.hideBasic + ? Promise.resolve(this.props.blockTime) + : this.props.fetchBasicGasAndTimeEstimates() + .then(basicEstimates => basicEstimates.blockTime) + + promise + .then(blockTime => { + this.props.fetchGasEstimates(blockTime) + }) + } + renderBasicTabContent (gasPriceButtonGroupProps) { return ( { customGasLimit: calcCustomGasLimit(customModalGasLimitInHex), newTotalFiat, currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, gasPrices, estimatedTimes), + blockTime: getBasicGasEstimateBlockTime(state), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), @@ -150,6 +154,8 @@ const mapDispatchToProps = dispatch => { hideGasButtonGroup: () => dispatch(hideGasButtonGroup()), setCustomTimeEstimate: (timeEstimateInSeconds) => dispatch(setCustomTimeEstimate(timeEstimateInSeconds)), hideSidebar: () => dispatch(hideSidebar()), + fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), + fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()), } } @@ -209,7 +215,7 @@ function getTxParams (state, transactionId) { return txData.txParams || pendingTxParams || { from: send.from, gas: send.gasLimit, - gasPrice: send.gasPrice || getAveragePriceEstimateInHexWEI(state), + gasPrice: send.gasPrice || getFastPriceEstimateInHexWEI(state, true), to: send.to, value: getSelectedToken(state) ? '0x0' : send.amount, } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 16f4b8cd7e0c..22f2f02dd976 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -3,14 +3,21 @@ import assert from 'assert' import shallow from '../../../../../lib/shallow-with-context' import sinon from 'sinon' import GasModalPageContainer from '../gas-modal-page-container.component.js' +import timeout from '../../../../../lib/test-timeout' import PageContainer from '../../../page-container' import { Tab } from '../../../tabs' +const mockBasicGasEstimates = { + blockTime: 'mockBlockTime', +} + const propsMethodSpies = { cancelAndClose: sinon.spy(), onSubmit: sinon.spy(), + fetchBasicGasAndTimeEstimates: sinon.stub().returns(Promise.resolve(mockBasicGasEstimates)), + fetchGasEstimates: sinon.spy(), } const mockGasPriceButtonGroupProps = { @@ -59,6 +66,8 @@ describe('GasModalPageContainer Component', function () { wrapper = shallow( 'mockupdateCustomGasPrice'} updateCustomGasLimit={() => 'mockupdateCustomGasLimit'} customGasPrice={21} @@ -76,6 +85,24 @@ describe('GasModalPageContainer Component', function () { propsMethodSpies.cancelAndClose.resetHistory() }) + describe('componentDidMount', () => { + it('should call props.fetchBasicGasAndTimeEstimates', () => { + propsMethodSpies.fetchBasicGasAndTimeEstimates.resetHistory() + assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 0) + wrapper.instance().componentDidMount() + assert.equal(propsMethodSpies.fetchBasicGasAndTimeEstimates.callCount, 1) + }) + + it('should call props.fetchGasEstimates with the block time returned by fetchBasicGasAndTimeEstimates', async () => { + propsMethodSpies.fetchGasEstimates.resetHistory() + assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0) + wrapper.instance().componentDidMount() + await timeout(250) + assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1) + assert.equal(propsMethodSpies.fetchGasEstimates.getCall(0).args[0], 'mockBlockTime') + }) + }) + describe('render', () => { it('should render a PageContainer compenent', () => { assert.equal(wrapper.find(PageContainer).length, 1) @@ -106,7 +133,10 @@ describe('GasModalPageContainer Component', function () { it('should pass the correct renderTabs property to PageContainer', () => { sinon.stub(GP, 'renderTabs').returns('mockTabs') - const renderTabsWrapperTester = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) + const renderTabsWrapperTester = shallow(, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) const { tabsComponent } = renderTabsWrapperTester.find(PageContainer).props() assert.equal(tabsComponent, 'mockTabs') GasModalPageContainer.prototype.renderTabs.restore() diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 1ed28f33e736..ba2cfe282c51 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -73,6 +73,9 @@ describe('gas-modal-page-container container', () => { conversionRate: 50, }, gas: { + basicEstimates: { + blockTime: 12, + }, customData: { limit: 'aaaaaaaa', price: 'ffffffff', @@ -100,6 +103,7 @@ describe('gas-modal-page-container container', () => { customGasLimit: 2863311530, currentTimeEstimate: '~1 min 11 sec', newTotalFiat: '637.41', + blockTime: 12, customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', gasChartProps: { diff --git a/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js b/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js index 7a3b58ffa1c2..2e460f3778b0 100644 --- a/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js +++ b/ui/app/components/pages/confirm-transaction/confirm-transaction.component.js @@ -32,7 +32,7 @@ export default class ConfirmTransaction extends Component { setTransactionToConfirm: PropTypes.func, confirmTransaction: PropTypes.object, clearConfirmTransaction: PropTypes.func, - fetchBasicGasEstimates: PropTypes.func, + fetchBasicGasAndTimeEstimates: PropTypes.func, } getParamsTransactionId () { @@ -46,7 +46,7 @@ export default class ConfirmTransaction extends Component { send = {}, history, confirmTransaction: { txData: { id: transactionId } = {} }, - fetchBasicGasEstimates, + fetchBasicGasAndTimeEstimates, } = this.props if (!totalUnapprovedCount && !send.to) { @@ -55,7 +55,7 @@ export default class ConfirmTransaction extends Component { } if (!transactionId) { - fetchBasicGasEstimates() + fetchBasicGasAndTimeEstimates() this.setTransactionToConfirm() } } diff --git a/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js b/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js index a7e6966aff17..46342dc76854 100644 --- a/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js +++ b/ui/app/components/pages/confirm-transaction/confirm-transaction.container.js @@ -6,7 +6,7 @@ import { clearConfirmTransaction, } from '../../../ducks/confirm-transaction.duck' import { - fetchBasicGasEstimates, + fetchBasicGasAndTimeEstimates, } from '../../../ducks/gas.duck' import ConfirmTransaction from './confirm-transaction.component' import { getTotalUnapprovedCount } from '../../../selectors' @@ -27,7 +27,7 @@ const mapDispatchToProps = dispatch => { return { setTransactionToConfirm: transactionId => dispatch(setTransactionToConfirm(transactionId)), clearConfirmTransaction: () => dispatch(clearConfirmTransaction()), - fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), + fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()), } } diff --git a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js index 39266e590ad4..977f8ab3ce68 100644 --- a/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js +++ b/ui/app/components/send/send-content/send-gas-row/send-gas-row.container.js @@ -7,7 +7,7 @@ import { } from '../../send.selectors.js' import { getBasicGasEstimateLoadingStatus, - getRenderableEstimateDataForSmallButtons, + getRenderableEstimateDataForSmallButtonsFromGWEI, getDefaultActiveButtonIndex, } from '../../../../selectors/custom-gas' import { @@ -23,7 +23,7 @@ import SendGasRow from './send-gas-row.component' export default connect(mapStateToProps, mapDispatchToProps, mergeProps)(SendGasRow) function mapStateToProps (state) { - const gasButtonInfo = getRenderableEstimateDataForSmallButtons(state) + const gasButtonInfo = getRenderableEstimateDataForSmallButtonsFromGWEI(state) const activeButtonIndex = getDefaultActiveButtonIndex(gasButtonInfo, getGasPrice(state)) return { diff --git a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js index 766bf6cab6e2..f0c82e4f7e7a 100644 --- a/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js +++ b/ui/app/components/send/send-content/send-gas-row/tests/send-gas-row-container.test.js @@ -42,7 +42,7 @@ proxyquire('../send-gas-row.container.js', { '../../../../actions': actionSpies, '../../../../selectors/custom-gas': { getBasicGasEstimateLoadingStatus: (s) => `mockBasicGasEstimateLoadingStatus:${s}`, - getRenderableEstimateDataForSmallButtons: (s) => `mockGasButtonInfo:${s}`, + getRenderableEstimateDataForSmallButtonsFromGWEI: (s) => `mockGasButtonInfo:${s}`, getDefaultActiveButtonIndex: (gasButtonInfo, gasPrice) => gasButtonInfo.length + gasPrice.length, }, '../../../../ducks/send.duck': sendDuckSpies, diff --git a/ui/app/components/send/send.component.js b/ui/app/components/send/send.component.js index 301acb1db03d..9b512aaf601b 100644 --- a/ui/app/components/send/send.component.js +++ b/ui/app/components/send/send.component.js @@ -35,6 +35,7 @@ export default class SendTransactionScreen extends PersistentForm { selectedToken: PropTypes.object, tokenBalance: PropTypes.string, tokenContract: PropTypes.object, + fetchBasicGasEstimates: PropTypes.func, updateAndSetGasTotal: PropTypes.func, updateSendErrors: PropTypes.func, updateSendTokenBalance: PropTypes.func, @@ -164,9 +165,8 @@ export default class SendTransactionScreen extends PersistentForm { componentDidMount () { this.props.fetchBasicGasEstimates() - .then(basicEstimates => { + .then(() => { this.updateGas() - this.props.fetchGasEstimates(basicEstimates.blockTime) }) } diff --git a/ui/app/components/send/send.container.js b/ui/app/components/send/send.container.js index ac804cf2a673..402e4bbe5de0 100644 --- a/ui/app/components/send/send.container.js +++ b/ui/app/components/send/send.container.js @@ -38,7 +38,6 @@ import { } from '../../ducks/send.duck' import { fetchBasicGasEstimates, - fetchGasEstimates, } from '../../ducks/gas.duck' import { calcGasTotal, @@ -109,6 +108,5 @@ function mapDispatchToProps (dispatch) { qrCodeDetected: (data) => dispatch(qrCodeDetected(data)), updateSendTo: (to, nickname) => dispatch(updateSendTo(to, nickname)), fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), - fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), } } diff --git a/ui/app/components/send/send.selectors.js b/ui/app/components/send/send.selectors.js index 71eb93d6140c..443c82af507c 100644 --- a/ui/app/components/send/send.selectors.js +++ b/ui/app/components/send/send.selectors.js @@ -11,7 +11,7 @@ const { calcGasTotal, } = require('./send.utils') import { - getAveragePriceEstimateInHexWEI, + getFastPriceEstimateInHexWEI, } from '../../selectors/custom-gas' const selectors = { @@ -139,7 +139,7 @@ function getGasLimit (state) { } function getGasPrice (state) { - return state.metamask.send.gasPrice || getAveragePriceEstimateInHexWEI(state) + return state.metamask.send.gasPrice || getFastPriceEstimateInHexWEI(state) } function getGasPriceFromRecentBlocks (state) { diff --git a/ui/app/components/send/tests/send-component.test.js b/ui/app/components/send/tests/send-component.test.js index 68d2fc47ebf3..81955cc1d2dc 100644 --- a/ui/app/components/send/tests/send-component.test.js +++ b/ui/app/components/send/tests/send-component.test.js @@ -3,17 +3,12 @@ import assert from 'assert' import proxyquire from 'proxyquire' import { shallow } from 'enzyme' import sinon from 'sinon' +import timeout from '../../../../lib/test-timeout' import SendHeader from '../send-header/send-header.container' import SendContent from '../send-content/send-content.component' import SendFooter from '../send-footer/send-footer.container' -function timeout (time) { - return new Promise((resolve, reject) => { - setTimeout(resolve, time || 1500) - }) -} - const mockBasicGasEstimates = { blockTime: 'mockBlockTime', } @@ -88,7 +83,7 @@ describe('Send Component', function () { }) describe('componentDidMount', () => { - it('should call props.fetchBasicGasEstimates', () => { + it('should call props.fetchBasicGasAndTimeEstimates', () => { propsMethodSpies.fetchBasicGasEstimates.resetHistory() assert.equal(propsMethodSpies.fetchBasicGasEstimates.callCount, 0) wrapper.instance().componentDidMount() @@ -103,15 +98,6 @@ describe('Send Component', function () { await timeout(250) assert.equal(SendTransactionScreen.prototype.updateGas.callCount, 1) }) - - it('should call props.fetchGasEstimates with the block time returned by fetchBasicGasEstimates', async () => { - propsMethodSpies.fetchGasEstimates.resetHistory() - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 0) - wrapper.instance().componentDidMount() - await timeout(250) - assert.equal(propsMethodSpies.fetchGasEstimates.callCount, 1) - assert.equal(propsMethodSpies.fetchGasEstimates.getCall(0).args[0], 'mockBlockTime') - }) }) describe('componentWillUnmount', () => { diff --git a/ui/app/components/transaction-list-item/transaction-list-item.component.js b/ui/app/components/transaction-list-item/transaction-list-item.component.js index d34dba2108ee..5334484dbbbd 100644 --- a/ui/app/components/transaction-list-item/transaction-list-item.component.js +++ b/ui/app/components/transaction-list-item/transaction-list-item.component.js @@ -27,7 +27,7 @@ export default class TransactionListItem extends PureComponent { tokenData: PropTypes.object, transaction: PropTypes.object, value: PropTypes.string, - fetchBasicGasEstimates: PropTypes.func, + fetchBasicGasAndTimeEstimates: PropTypes.func, fetchGasEstimates: PropTypes.func, } @@ -71,8 +71,8 @@ export default class TransactionListItem extends PureComponent { } resubmit () { - const { transaction, retryTransaction, fetchBasicGasEstimates, fetchGasEstimates } = this.props - fetchBasicGasEstimates().then(basicEstimates => { + const { transaction, retryTransaction, fetchBasicGasAndTimeEstimates, fetchGasEstimates } = this.props + fetchBasicGasAndTimeEstimates().then(basicEstimates => { fetchGasEstimates(basicEstimates.blockTime) }).then(() => { retryTransaction(transaction) diff --git a/ui/app/components/transaction-list-item/transaction-list-item.container.js b/ui/app/components/transaction-list-item/transaction-list-item.container.js index df408b36bc10..61ecb04d0360 100644 --- a/ui/app/components/transaction-list-item/transaction-list-item.container.js +++ b/ui/app/components/transaction-list-item/transaction-list-item.container.js @@ -8,7 +8,7 @@ import { hexToDecimal } from '../../helpers/conversions.util' import { getTokenData } from '../../helpers/transactions.util' import { formatDate } from '../../util' import { - fetchBasicGasEstimates, + fetchBasicGasAndTimeEstimates, fetchGasEstimates, setCustomGasPrice, setCustomGasLimit, @@ -29,7 +29,7 @@ const mapStateToProps = (state, ownProps) => { const mapDispatchToProps = dispatch => { return { - fetchBasicGasEstimates: () => dispatch(fetchBasicGasEstimates()), + fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()), fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), setSelectedToken: tokenAddress => dispatch(setSelectedToken(tokenAddress)), retryTransaction: (transaction) => { diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js index 6ae927b12a34..ffd1e773f76b 100644 --- a/ui/app/ducks/gas.duck.js +++ b/ui/app/ducks/gas.duck.js @@ -19,6 +19,7 @@ const SET_CUSTOM_GAS_PRICE = 'metamask/gas/SET_CUSTOM_GAS_PRICE' const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' const SET_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' +const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' // TODO: determine if this approach to initState is consistent with conventional ducks pattern const initState = { @@ -42,7 +43,9 @@ const initState = { basicEstimateIsLoading: true, gasEstimatesLoading: true, priceAndTimeEstimates: [], + basicPriceAndTimeEstimates: [], priceAndTimeEstimatesLastRetrieved: 0, + basicPriceAndTimeEstimatesLastRetrieved: 0, errors: {}, } @@ -118,6 +121,11 @@ export default function reducer ({ gas: gasState = initState }, action = {}) { ...newState, priceAndTimeEstimatesLastRetrieved: action.value, } + case SET_BASIC_API_ESTIMATES_LAST_RETRIEVED: + return { + ...newState, + basicPriceAndTimeEstimatesLastRetrieved: action.value, + } case RESET_CUSTOM_DATA: return { ...newState, @@ -159,9 +167,9 @@ export function fetchBasicGasEstimates () { return (dispatch) => { dispatch(basicGasEstimatesLoadingStarted()) - return fetch('https://ethgasstation.info/json/ethgasAPI.json', { + return fetch('https://dev.blockscale.net/api/gasexpress.json', { 'headers': {}, - 'referrer': 'http://ethgasstation.info/json/', + 'referrer': 'https://dev.blockscale.net/api/', 'referrerPolicy': 'no-referrer-when-downgrade', 'body': null, 'method': 'GET', @@ -169,23 +177,53 @@ export function fetchBasicGasEstimates () { ) .then(r => r.json()) .then(({ - average, - avgWait, - block_time: blockTime, - blockNum, + safeLow, + standard: average, fast, fastest, - fastestWait, - fastWait, - safeLow, - safeLowWait, - speed, + block_time: blockTime, + blockNum, }) => { const basicEstimates = { + safeLow, average, - avgWait, + fast, + fastest, blockTime, blockNum, + } + dispatch(setBasicGasEstimateData(basicEstimates)) + dispatch(basicGasEstimatesLoadingFinished()) + return basicEstimates + }) + } +} + +export function fetchBasicGasAndTimeEstimates () { + return (dispatch, getState) => { + const { + basicPriceAndTimeEstimatesLastRetrieved, + basicPriceAndTimeEstimates, + } = getState().gas + const timeLastRetrieved = basicPriceAndTimeEstimatesLastRetrieved || loadLocalStorageData('BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') || 0 + + dispatch(basicGasEstimatesLoadingStarted()) + + const promiseToFetch = Date.now() - timeLastRetrieved > 75000 + ? fetch('https://ethgasstation.info/json/ethgasAPI.json', { + 'headers': {}, + 'referrer': 'http://ethgasstation.info/json/', + 'referrerPolicy': 'no-referrer-when-downgrade', + 'body': null, + 'method': 'GET', + 'mode': 'cors'} + ) + .then(r => r.json()) + .then(({ + average, + avgWait, + block_time: blockTime, + blockNum, fast, fastest, fastestWait, @@ -193,7 +231,34 @@ export function fetchBasicGasEstimates () { safeLow, safeLowWait, speed, - } + }) => { + const basicEstimates = { + average, + avgWait, + blockTime, + blockNum, + fast, + fastest, + fastestWait, + fastWait, + safeLow, + safeLowWait, + speed, + } + + const timeRetrieved = Date.now() + dispatch(setBasicApiEstimatesLastRetrieved(timeRetrieved)) + saveLocalStorageData(timeRetrieved, 'BASIC_GAS_AND_TIME_API_ESTIMATES_LAST_RETRIEVED') + saveLocalStorageData(basicEstimates, 'BASIC_GAS_AND_TIME_API_ESTIMATES') + + return basicEstimates + }) + : Promise.resolve(basicPriceAndTimeEstimates.length + ? basicPriceAndTimeEstimates + : loadLocalStorageData('BASIC_GAS_AND_TIME_API_ESTIMATES') + ) + + return promiseToFetch.then(basicEstimates => { dispatch(setBasicGasEstimateData(basicEstimates)) dispatch(basicGasEstimatesLoadingFinished()) return basicEstimates @@ -301,6 +366,13 @@ export function setApiEstimatesLastRetrieved (retrievalTime) { } } +export function setBasicApiEstimatesLastRetrieved (retrievalTime) { + return { + type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, + value: retrievalTime, + } +} + export function resetCustomGasState () { return { type: RESET_CUSTOM_GAS_STATE } } diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js index 009758cde223..dff154dea1a9 100644 --- a/ui/app/ducks/tests/gas-duck.test.js +++ b/ui/app/ducks/tests/gas-duck.test.js @@ -19,7 +19,7 @@ const { setCustomGasTotal, setCustomGasErrors, resetCustomGasState, - fetchBasicGasEstimates, + fetchBasicGasAndTimeEstimates, gasEstimatesLoadingStarted, gasEstimatesLoadingFinished, setPricesAndTimeEstimates, @@ -100,6 +100,9 @@ describe('Gas Duck', () => { gasEstimatesLoading: true, priceAndTimeEstimates: [], priceAndTimeEstimatesLastRetrieved: 0, + basicPriceAndTimeEstimates: [], + basicPriceAndTimeEstimatesLastRetrieved: 0, + } const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' @@ -114,6 +117,7 @@ describe('Gas Duck', () => { const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' const SET_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' + const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' describe('GasReducer()', () => { it('should initialize state', () => { @@ -224,7 +228,7 @@ describe('Gas Duck', () => { ) }) - it('should set priceAndTimeEstimatesLastRetrieved when receivinga SET_API_ESTIMATES_LAST_RETRIEVED action', () => { + it('should set priceAndTimeEstimatesLastRetrieved when receiving a SET_API_ESTIMATES_LAST_RETRIEVED action', () => { assert.deepEqual( GasReducer(mockState, { type: SET_API_ESTIMATES_LAST_RETRIEVED, @@ -234,6 +238,16 @@ describe('Gas Duck', () => { ) }) + it('should set priceAndTimeEstimatesLastRetrieved when receiving a SET_BASIC_API_ESTIMATES_LAST_RETRIEVED action', () => { + assert.deepEqual( + GasReducer(mockState, { + type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, + value: 1700000000000, + }), + Object.assign({ basicPriceAndTimeEstimatesLastRetrieved: 1700000000000 }, mockState.gas) + ) + }) + it('should set errors when receiving a SET_CUSTOM_GAS_ERRORS action', () => { assert.deepEqual( GasReducer(mockState, { @@ -272,10 +286,14 @@ describe('Gas Duck', () => { }) }) - describe('fetchBasicGasEstimates', () => { + describe('fetchBasicGasAndTimeEstimates', () => { const mockDistpatch = sinon.spy() it('should call fetch with the expected params', async () => { - await fetchBasicGasEstimates()(mockDistpatch) + await fetchBasicGasAndTimeEstimates()(mockDistpatch, () => ({ gas: Object.assign( + {}, + initState, + { basicPriceAndTimeEstimatesLastRetrieved: 1000000 } + ) })) assert.deepEqual( mockDistpatch.getCall(0).args, [{ type: BASIC_GAS_ESTIMATE_LOADING_STARTED} ] @@ -294,8 +312,14 @@ describe('Gas Duck', () => { }, ] ) + assert.deepEqual( mockDistpatch.getCall(1).args, + [{ type: SET_BASIC_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 } ] + ) + + assert.deepEqual( + mockDistpatch.getCall(2).args, [{ type: SET_BASIC_GAS_ESTIMATE_DATA, value: { @@ -314,7 +338,7 @@ describe('Gas Duck', () => { }] ) assert.deepEqual( - mockDistpatch.getCall(2).args, + mockDistpatch.getCall(3).args, [{ type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }] ) }) diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 1c577c1b42ae..f06fb710d4dc 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -23,7 +23,9 @@ import { addHexPrefix } from 'ethereumjs-util' const selectors = { formatTimeEstimate, getAveragePriceEstimateInHexWEI, + getFastPriceEstimateInHexWEI, getBasicGasEstimateLoadingStatus, + getBasicGasEstimateBlockTime, getCustomGasErrors, getCustomGasLimit, getCustomGasPrice, @@ -33,7 +35,7 @@ const selectors = { getEstimatedGasTimes, getPriceAndTimeEstimates, getRenderableBasicEstimateData, - getRenderableEstimateDataForSmallButtons, + getRenderableEstimateDataForSmallButtonsFromGWEI, priceEstimateToWei, } @@ -78,12 +80,21 @@ function getAveragePriceEstimateInHexWEI (state) { return getGasPriceInHexWei(averagePriceEstimate || '0x0') } +function getFastPriceEstimateInHexWEI (state, convertFromDecGWEI) { + const fastPriceEstimate = state.gas.basicEstimates.fast + return getGasPriceInHexWei(fastPriceEstimate || '0x0', convertFromDecGWEI) +} + function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { return gasButtonInfo.findIndex(({ priceInHexWei }) => { return priceInHexWei === addHexPrefix(customGasPriceInHex || gasPrice) }) } +function getBasicGasEstimateBlockTime (state) { + return state.gas.basicEstimates.blockTime +} + function apiEstimateModifiedToGWEI (estimate) { return multiplyCurrencies(estimate, 0.10, { toNumericBase: 'hex', @@ -102,26 +113,34 @@ function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) }) } -function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) { +function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9, convertFromDecGWEI) { + const initialConversion = convertFromDecGWEI + ? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }) + : apiEstimateModifiedToGWEI + return pipe( - apiEstimateModifiedToGWEI, + initialConversion, partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]), formatETHFee )(estimate, gasLimit) } -function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) { +function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate, convertFromDecGWEI) { + const initialConversion = convertFromDecGWEI + ? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }) + : apiEstimateModifiedToGWEI + return pipe( - apiEstimateModifiedToGWEI, + initialConversion, partialRight(basicPriceEstimateToETHTotal, [gasLimit]), partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]), partialRight(formatCurrency, [convertedCurrency]) )(estimate, gasLimit, convertedCurrency, conversionRate) } -function getTimeEstimateInSeconds (blockWaitEstimate, currentBlockTime) { - return multiplyCurrencies(blockWaitEstimate, currentBlockTime, { +function getTimeEstimateInSeconds (blockWaitEstimate) { + return multiplyCurrencies(blockWaitEstimate, 60, { toNumericBase: 'dec', multiplicandBase: 10, multiplierBase: 10, @@ -141,11 +160,11 @@ function formatTimeEstimate (totalSeconds) { return formattedCombined } -function getRenderableTimeEstimate (blockWaitEstimate, currentBlockTime) { +function getRenderableTimeEstimate (blockWaitEstimate) { return pipe( getTimeEstimateInSeconds, formatTimeEstimate - )(blockWaitEstimate, currentBlockTime) + )(blockWaitEstimate) } function priceEstimateToWei (priceEstimate) { @@ -158,9 +177,13 @@ function priceEstimateToWei (priceEstimate) { }) } -function getGasPriceInHexWei (price) { +function getGasPriceInHexWei (price, convertFromDecGWEI) { + const initialConversion = convertFromDecGWEI + ? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }) + : apiEstimateModifiedToGWEI + return pipe( - apiEstimateModifiedToGWEI, + initialConversion, priceEstimateToWei, addHexPrefix )(price) @@ -177,11 +200,10 @@ function getRenderableBasicEstimateData (state) { gas: { basicEstimates: { safeLow, - average, fast, - blockTime, + fastest, safeLowWait, - avgWait, + fastestWait, fastWait, }, }, @@ -190,29 +212,29 @@ function getRenderableBasicEstimateData (state) { return [ { labelKey: 'fastest', - feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), - feeInSecondaryCurrency: getRenderableEthFee(fast, gasLimit), - timeEstimate: getRenderableTimeEstimate(fastWait, blockTime), - priceInHexWei: getGasPriceInHexWei(fast), + feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate), + feeInSecondaryCurrency: getRenderableEthFee(fastest, gasLimit), + timeEstimate: fastestWait && getRenderableTimeEstimate(fastestWait), + priceInHexWei: getGasPriceInHexWei(fastest), }, { labelKey: 'fast', - feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate), - feeInSecondaryCurrency: getRenderableEthFee(average, gasLimit), - timeEstimate: getRenderableTimeEstimate(avgWait, blockTime), - priceInHexWei: getGasPriceInHexWei(average), + feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), + feeInSecondaryCurrency: getRenderableEthFee(fast, gasLimit), + timeEstimate: fastWait && getRenderableTimeEstimate(fastWait), + priceInHexWei: getGasPriceInHexWei(fast), }, { labelKey: 'slow', feeInPrimaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), feeInSecondaryCurrency: getRenderableEthFee(safeLow, gasLimit), - timeEstimate: getRenderableTimeEstimate(safeLowWait, blockTime), + timeEstimate: safeLowWait && getRenderableTimeEstimate(safeLowWait), priceInHexWei: getGasPriceInHexWei(safeLow), }, ] } -function getRenderableEstimateDataForSmallButtons (state) { +function getRenderableEstimateDataForSmallButtonsFromGWEI (state) { if (getBasicGasEstimateLoadingStatus(state)) { return [] } @@ -223,30 +245,30 @@ function getRenderableEstimateDataForSmallButtons (state) { gas: { basicEstimates: { safeLow, - average, fast, + fastest, }, }, } = state return [ { - labelKey: 'fast', - feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), - feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS), - priceInHexWei: getGasPriceInHexWei(fast), + labelKey: 'fastest', + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate, true), + feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), + priceInHexWei: getGasPriceInHexWei(fastest, true), }, { - labelKey: 'average', - feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(average, gasLimit, currentCurrency, conversionRate), - feeInPrimaryCurrency: getRenderableEthFee(average, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS), - priceInHexWei: getGasPriceInHexWei(average), + labelKey: 'fast', + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate, true), + feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), + priceInHexWei: getGasPriceInHexWei(fast, true), }, { labelKey: 'slow', - feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), - feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS), - priceInHexWei: getGasPriceInHexWei(safeLow), + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate, true), + feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), + priceInHexWei: getGasPriceInHexWei(safeLow, true), }, ] } diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index 8a6e7e3519c6..037b1e86e0c7 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -10,7 +10,7 @@ const { getEstimatedGasTimes, getPriceAndTimeEstimates, getRenderableBasicEstimateData, - getRenderableEstimateDataForSmallButtons, + getRenderableEstimateDataForSmallButtonsFromGWEI, } = proxyquire('../custom-gas', {}) describe('custom-gas selectors', () => { @@ -80,21 +80,21 @@ describe('custom-gas selectors', () => { labelKey: 'fastest', feeInPrimaryCurrency: '$0.05', feeInSecondaryCurrency: '0.00021 ETH', - timeEstimate: '~7 sec', + timeEstimate: '~30 sec', priceInHexWei: '0x2540be400', }, { labelKey: 'fast', feeInPrimaryCurrency: '$0.03', feeInSecondaryCurrency: '0.000105 ETH', - timeEstimate: '~46 sec', + timeEstimate: '~3 min 18 sec', priceInHexWei: '0x12a05f200', }, { labelKey: 'slow', feeInPrimaryCurrency: '$0.01', feeInSecondaryCurrency: '0.0000525 ETH', - timeEstimate: '~1 min 33 sec', + timeEstimate: '~6 min 36 sec', priceInHexWei: '0x9502f900', }, ], @@ -111,10 +111,10 @@ describe('custom-gas selectors', () => { blockTime: 14.16326530612245, safeLow: 25, safeLowWait: 6.6, - average: 50, - avgWait: 3.3, - fast: 100, - fastWait: 0.5, + fast: 50, + fastWait: 3.3, + fastest: 100, + fastestWait: 0.5, }, }, }, @@ -125,21 +125,21 @@ describe('custom-gas selectors', () => { labelKey: 'fastest', feeInPrimaryCurrency: '$1.07', feeInSecondaryCurrency: '0.00042 ETH', - timeEstimate: '~14 sec', + timeEstimate: '~1 min', priceInHexWei: '0x4a817c800', }, { labelKey: 'fast', feeInPrimaryCurrency: '$0.54', feeInSecondaryCurrency: '0.00021 ETH', - timeEstimate: '~1 min 33 sec', + timeEstimate: '~6 min 36 sec', priceInHexWei: '0x2540be400', }, { labelKey: 'slow', feeInPrimaryCurrency: '$0.27', feeInSecondaryCurrency: '0.000105 ETH', - timeEstimate: '~3 min 7 sec', + timeEstimate: '~13 min 12 sec', priceInHexWei: '0x12a05f200', }, ], @@ -156,10 +156,10 @@ describe('custom-gas selectors', () => { blockTime: 14.16326530612245, safeLow: 50, safeLowWait: 13.2, - average: 100, - avgWait: 6.6, - fast: 200, - fastWait: 1.0, + fast: 100, + fastWait: 6.6, + fastest: 200, + fastestWait: 1.0, }, }, }, @@ -176,27 +176,27 @@ describe('custom-gas selectors', () => { }) - describe('getRenderableEstimateDataForSmallButtons()', () => { + describe('getRenderableEstimateDataForSmallButtonsFromGWEI()', () => { const tests = [ { expectedResult: [ { - feeInSecondaryCurrency: '$0.05', - feeInPrimaryCurrency: '0.00021 ETH', - labelKey: 'fast', - priceInHexWei: '0x2540be400', + feeInSecondaryCurrency: '$0.54', + feeInPrimaryCurrency: '0.0021 ETH', + labelKey: 'fastest', + priceInHexWei: '0x174876e800', }, { - feeInSecondaryCurrency: '$0.03', - feeInPrimaryCurrency: '0.0001 ETH', - labelKey: 'average', - priceInHexWei: '0x12a05f200', + feeInSecondaryCurrency: '$0.27', + feeInPrimaryCurrency: '0.00105 ETH', + labelKey: 'fast', + priceInHexWei: '0xba43b7400', }, { - feeInSecondaryCurrency: '$0.01', - feeInPrimaryCurrency: '0.00005 ETH', + feeInSecondaryCurrency: '$0.13', + feeInPrimaryCurrency: '0.00052 ETH', labelKey: 'slow', - priceInHexWei: '0x9502f900', + priceInHexWei: '0x5d21dba00', }, ], mockState: { @@ -212,10 +212,10 @@ describe('custom-gas selectors', () => { blockTime: 14.16326530612245, safeLow: 25, safeLowWait: 6.6, - average: 50, - avgWait: 3.3, - fast: 100, - fastWait: 0.5, + fast: 50, + fastWait: 3.3, + fastest: 100, + fastestWait: 0.5, }, }, }, @@ -223,22 +223,22 @@ describe('custom-gas selectors', () => { { expectedResult: [ { - feeInSecondaryCurrency: '$1.07', - feeInPrimaryCurrency: '0.00042 ETH', - labelKey: 'fast', - priceInHexWei: '0x4a817c800', + feeInSecondaryCurrency: '$10.74', + feeInPrimaryCurrency: '0.0042 ETH', + labelKey: 'fastest', + priceInHexWei: '0x2e90edd000', }, { - feeInSecondaryCurrency: '$0.54', - feeInPrimaryCurrency: '0.00021 ETH', - labelKey: 'average', - priceInHexWei: '0x2540be400', + feeInSecondaryCurrency: '$5.37', + feeInPrimaryCurrency: '0.0021 ETH', + labelKey: 'fast', + priceInHexWei: '0x174876e800', }, { - feeInSecondaryCurrency: '$0.27', - feeInPrimaryCurrency: '0.0001 ETH', + feeInSecondaryCurrency: '$2.68', + feeInPrimaryCurrency: '0.00105 ETH', labelKey: 'slow', - priceInHexWei: '0x12a05f200', + priceInHexWei: '0xba43b7400', }, ], mockState: { @@ -254,10 +254,10 @@ describe('custom-gas selectors', () => { blockTime: 14.16326530612245, safeLow: 50, safeLowWait: 13.2, - average: 100, - avgWait: 6.6, - fast: 200, - fastWait: 1.0, + fast: 100, + fastWait: 6.6, + fastest: 200, + fastestWait: 1.0, }, }, }, @@ -266,7 +266,7 @@ describe('custom-gas selectors', () => { it('should return renderable data about basic estimates appropriate for buttons with less info', () => { tests.forEach(test => { assert.deepEqual( - getRenderableEstimateDataForSmallButtons(test.mockState), + getRenderableEstimateDataForSmallButtonsFromGWEI(test.mockState), test.expectedResult ) }) diff --git a/ui/lib/test-timeout.js b/ui/lib/test-timeout.js new file mode 100644 index 000000000000..957b0fce2e38 --- /dev/null +++ b/ui/lib/test-timeout.js @@ -0,0 +1,5 @@ +export default function timeout (time) { + return new Promise((resolve, reject) => { + setTimeout(resolve, time || 1500) + }) +} From 7ffea926f23b2542c5182df7958defcdd9398b04 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 13:32:04 -0330 Subject: [PATCH 42/64] Add loading spinners when waiting for APIs in the gas customization modal --- .../advanced-tab-content.component.js | 8 +++++++- .../advanced-tab-content-component.test.js | 17 +++++++++++++++++ .../basic-tab-content.component.js | 16 +++++++++++----- .../tests/basic-tab-content-component.test.js | 11 +++++++++++ .../gas-modal-page-container.component.js | 2 ++ .../gas-modal-page-container.container.js | 4 ++++ .../gas-modal-page-container-component.test.js | 2 ++ .../gas-modal-page-container-container.test.js | 2 ++ ui/app/selectors/custom-gas.js | 5 +++++ 9 files changed, 61 insertions(+), 6 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index 23945483daa6..ac68b833cbf9 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -1,6 +1,7 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' +import Loading from '../../../loading-screen' import GasPriceChart from '../../gas-price-chart' export default class AdvancedTabContent extends Component { @@ -13,6 +14,7 @@ export default class AdvancedTabContent extends Component { updateCustomGasLimit: PropTypes.func, customGasPrice: PropTypes.number, customGasLimit: PropTypes.number, + gasEstimatesLoading: PropTypes.bool, millisecondsRemaining: PropTypes.number, totalFee: PropTypes.string, timeRemaining: PropTypes.string, @@ -98,6 +100,7 @@ export default class AdvancedTabContent extends Component { insufficientBalance, totalFee, gasChartProps, + gasEstimatesLoading, } = this.props return ( @@ -112,7 +115,10 @@ export default class AdvancedTabContent extends Component { insufficientBalance ) }
Live Gas Price Predictions
- + {!gasEstimatesLoading + ? + : + }
Slower Faster diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index 0c25874bb782..f321ca696eab 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -5,6 +5,7 @@ import sinon from 'sinon' import AdvancedTabContent from '../advanced-tab-content.component.js' import GasPriceChart from '../../../gas-price-chart' +import Loading from '../../../../loading-screen' const propsMethodSpies = { updateCustomGasPrice: sinon.spy(), @@ -60,6 +61,22 @@ describe('AdvancedTabContent Component', function () { assert(feeChartDiv.childAt(3).hasClass('advanced-tab__fee-chart__speed-buttons')) }) + it('should render a loading component instead of the chart if gasEstimatesLoading is true', () => { + wrapper.setProps({ gasEstimatesLoading: true }) + const advancedTabChildren = wrapper.children() + assert.equal(advancedTabChildren.length, 2) + + assert(advancedTabChildren.at(0).hasClass('advanced-tab__transaction-data-summary')) + assert(advancedTabChildren.at(1).hasClass('advanced-tab__fee-chart')) + + const feeChartDiv = advancedTabChildren.at(1) + + assert(feeChartDiv.childAt(0).hasClass('advanced-tab__gas-edit-rows')) + assert(feeChartDiv.childAt(1).hasClass('advanced-tab__fee-chart__title')) + assert(feeChartDiv.childAt(2).is(Loading)) + assert(feeChartDiv.childAt(3).hasClass('advanced-tab__fee-chart__speed-buttons')) + }) + it('should call renderDataSummary with the expected params', () => { assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) const renderDataSummaryArgs = AdvancedTabContent.prototype.renderDataSummary.getCall(0).args diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js index 4483b71df9cb..264d038daae9 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/basic-tab-content.component.js @@ -1,5 +1,6 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +import Loading from '../../../loading-screen' import GasPriceButtonGroup from '../../gas-price-button-group' export default class BasicTabContent extends Component { @@ -12,15 +13,20 @@ export default class BasicTabContent extends Component { } render () { + const { gasPriceButtonGroupProps } = this.props + return (
Estimated Processing Times
Select a higher gas fee to accelerate the processing of your transaction.*
- + {!gasPriceButtonGroupProps.loading + ? + : + }
* Accelerating a transaction by using a higher gas price increases its chances of getting processed by the network faster, but it is not always guaranteed.
) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js index 0c9c6ac63383..25abdd997bf2 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/basic-tab-content/tests/basic-tab-content-component.test.js @@ -4,6 +4,7 @@ import { shallow } from 'enzyme' import BasicTabContent from '../basic-tab-content.component' import GasPriceButtonGroup from '../../../gas-price-button-group/' +import Loading from '../../../../loading-screen' const mockGasPriceButtonGroupProps = { buttonDataLoading: false, @@ -60,6 +61,7 @@ describe('BasicTabContent Component', function () { noButtonActiveByDefault, showCheck, } = wrapper.find(GasPriceButtonGroup).props() + assert.equal(wrapper.find(GasPriceButtonGroup).length, 1) assert.equal(buttonDataLoading, mockGasPriceButtonGroupProps.buttonDataLoading) assert.equal(className, mockGasPriceButtonGroupProps.className) assert.equal(noButtonActiveByDefault, mockGasPriceButtonGroupProps.noButtonActiveByDefault) @@ -67,5 +69,14 @@ describe('BasicTabContent Component', function () { assert.deepEqual(gasButtonInfo, mockGasPriceButtonGroupProps.gasButtonInfo) assert.equal(JSON.stringify(handleGasPriceSelection), JSON.stringify(mockGasPriceButtonGroupProps.handleGasPriceSelection)) }) + + it('should render a loading component instead of the GasPriceButtonGroup if gasPriceButtonGroupProps.loading is true', () => { + wrapper.setProps({ + gasPriceButtonGroupProps: { ...mockGasPriceButtonGroupProps, loading: true }, + }) + + assert.equal(wrapper.find(GasPriceButtonGroup).length, 0) + assert.equal(wrapper.find(Loading).length, 1) + }) }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index b5b13c8490bf..5d8f92a59ec9 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -68,6 +68,7 @@ export default class GasModalPageContainer extends Component { gasChartProps, currentTimeEstimate, insufficientBalance, + gasEstimatesLoading, }) { const { transactionFee } = this.props return ( @@ -81,6 +82,7 @@ export default class GasModalPageContainer extends Component { totalFee={newTotalFiat} gasChartProps={gasChartProps} insufficientBalance={insufficientBalance} + gasEstimatesLoading={gasEstimatesLoading} /> ) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 770493be0bc8..42b96a729870 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -32,6 +32,7 @@ import { formatTimeEstimate, getFastPriceEstimateInHexWEI, getBasicGasEstimateLoadingStatus, + getGasEstimatesLoadingStatus, getCustomGasLimit, getCustomGasPrice, getDefaultActiveButtonIndex, @@ -65,6 +66,8 @@ import { getAdjacentGasPrices, extrapolateY } from '../gas-price-chart/gas-price const mapStateToProps = (state, ownProps) => { const { transaction = {} } = ownProps const buttonDataLoading = getBasicGasEstimateLoadingStatus(state) + const gasEstimatesLoading = getGasEstimatesLoadingStatus(state) + const { gasPrice: currentGasPrice, gas: currentGasLimit, value } = getTxParams(state, transaction.id) const customModalGasPriceInHex = getCustomGasPrice(state) || currentGasPrice const customModalGasLimitInHex = getCustomGasLimit(state) || currentGasLimit @@ -127,6 +130,7 @@ const mapStateToProps = (state, ownProps) => { isSpeedUp: transaction.status === 'submitted', txId: transaction.id, insufficientBalance, + gasEstimatesLoading, } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 22f2f02dd976..2ba2fa9e7abf 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -232,6 +232,7 @@ describe('GasModalPageContainer Component', function () { customGasLimit: 456, newTotalFiat: '$0.30', currentTimeEstimate: '1 min 31 sec', + gasEstimatesLoading: 'mockGasEstimatesLoading', }) const advancedTabContentProps = renderAdvancedTabContentResult.props assert.equal(advancedTabContentProps.updateCustomGasPrice(), 'mockConvertThenUpdateCustomGasPrice') @@ -240,6 +241,7 @@ describe('GasModalPageContainer Component', function () { assert.equal(advancedTabContentProps.customGasLimit, 456) assert.equal(advancedTabContentProps.timeRemaining, '1 min 31 sec') assert.equal(advancedTabContentProps.totalFee, '$0.30') + assert.equal(advancedTabContentProps.gasEstimatesLoading, 'mockGasEstimatesLoading') }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index ba2cfe282c51..82c6dcd699b2 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -80,6 +80,7 @@ describe('gas-modal-page-container container', () => { limit: 'aaaaaaaa', price: 'ffffffff', }, + gasEstimatesLoading: false, priceAndTimeEstimates: [ { gasprice: 3, expectedTime: '31' }, { gasprice: 4, expectedTime: '62' }, @@ -118,6 +119,7 @@ describe('gas-modal-page-container container', () => { defaultActiveButtonIndex: 'mockRenderableBasicEstimateData:4ffffffff', gasButtonInfo: 'mockRenderableBasicEstimateData:4', }, + gasEstimatesLoading: false, hideBasic: true, infoRowProps: { originalTotalFiat: '637.41', diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index f06fb710d4dc..ec234500da9a 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -33,6 +33,7 @@ const selectors = { getDefaultActiveButtonIndex, getEstimatedGasPrices, getEstimatedGasTimes, + getGasEstimatesLoadingStatus, getPriceAndTimeEstimates, getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, @@ -63,6 +64,10 @@ function getBasicGasEstimateLoadingStatus (state) { return state.gas.basicEstimateIsLoading } +function getGasEstimatesLoadingStatus (state) { + return state.gas.gasEstimatesLoading +} + function getPriceAndTimeEstimates (state) { return state.gas.priceAndTimeEstimates } From f8ffdaedc9a8fac631deafbc1d377430c980af94 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 14:06:35 -0330 Subject: [PATCH 43/64] Modify results of API data to better fit gas chart: remove outliers, pad data --- .../gas-price-chart.component.js | 11 ++- .../gas-price-chart/gas-price-chart.utils.js | 15 ++- .../tests/gas-price-chart.component.test.js | 2 +- ui/app/ducks/gas.duck.js | 93 +++++++++++++++++-- ui/app/ducks/tests/gas-duck.test.js | 49 +++++----- 5 files changed, 126 insertions(+), 44 deletions(-) diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js index 5ca465ba9691..3f382e5b2094 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js @@ -33,16 +33,19 @@ export default class GasPriceChart extends Component { updateCustomGasPrice, }) { const chart = generateChart(gasPrices, estimatedTimes, gasPricesMax, estimatedTimesMax) - setTimeout(function () { setTickPosition('y', 0, -5, 8) setTickPosition('y', 1, -3, -5) - setTickPosition('x', 0, 3, 15) + setTickPosition('x', 0, 3) setTickPosition('x', 1, 3, -8) - // TODO: Confirm the below constants work with all data sets and screen sizes + const { x: domainX } = getCoordinateData('.domain') + const { x: yAxisX } = getCoordinateData('.c3-axis-y-label') + const { x: tickX } = getCoordinateData('.c3-axis-x .tick') + + d3.select('.c3-axis-x .tick').attr('transform', 'translate(' + (domainX - tickX) / 2 + ', 0)') d3.select('.c3-axis-x-label').attr('transform', 'translate(0,-15)') - d3.select('.c3-axis-y-label').attr('transform', 'translate(52, 2) rotate(-90)') + d3.select('.c3-axis-y-label').attr('transform', 'translate(' + (domainX - yAxisX - 12) + ', 2) rotate(-90)') d3.select('.c3-xgrid-focus line').attr('y2', 98) d3.select('.c3-chart').on('mouseout', () => { diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js index 67508703fdf4..0b9dfbd118fb 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -12,6 +12,7 @@ export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices if (currentPosValue === null && newTimeEstimate === null) { hideDataUI(chart, '#overlayed-circle') + return } const indexOfNewCircle = estimatedTimes.length + 1 @@ -162,7 +163,13 @@ export function setSelectedCircle ({ }) { const numberOfValues = chart.internal.data.xs.data1.length const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`) - const { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) + let { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) + + if (lowerX === higherX) { + const { x: higherXAdjusted, y: higherYAdjusted } = getCoordinateData(`.c3-circle-${closestHigherValueIndex + 1}`) + higherY = higherYAdjusted + higherX = higherXAdjusted + } const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue) const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) @@ -203,13 +210,13 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate axis: { x: { min: gasPrices[0], - max: gasPricesMaxPadded, + max: gasPricesMax, tick: { - values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMaxPadded)], + values: [Math.floor(gasPrices[0]), Math.ceil(gasPricesMax)], outer: false, format: function (val) { return val + ' GWEI' }, }, - padding: {left: gasPricesMaxPadded / 50, right: gasPricesMaxPadded / 50}, + padding: {left: gasPricesMax / 50, right: gasPricesMax / 50}, label: { text: 'Gas Price ($)', position: 'outer-center', diff --git a/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js b/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js index 46341195be84..74eddae421d8 100644 --- a/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js +++ b/ui/app/components/gas-customization/gas-price-chart/tests/gas-price-chart.component.test.js @@ -136,7 +136,7 @@ describe('GasPriceChart Component', function () { assert.equal(gasPriceChartUtilsSpies.setTickPosition.callCount, 4) assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(0).args, ['y', 0, -5, 8]) assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(1).args, ['y', 1, -3, -5]) - assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(2).args, ['x', 0, 3, 15]) + assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(2).args, ['x', 0, 3]) assert.deepEqual(gasPriceChartUtilsSpies.setTickPosition.getCall(3).args, ['x', 1, 3, -8]) }) diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js index ffd1e773f76b..20a125dbb661 100644 --- a/ui/app/ducks/gas.duck.js +++ b/ui/app/ducks/gas.duck.js @@ -1,4 +1,4 @@ -import { clone, uniqBy } from 'ramda' +import { clone, uniqBy, flatten } from 'ramda' import BigNumber from 'bignumber.js' import { loadLocalStorageData, @@ -266,6 +266,56 @@ export function fetchBasicGasAndTimeEstimates () { } } +function extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) { + higherY = new BigNumber(higherY, 10) + lowerY = new BigNumber(lowerY, 10) + higherX = new BigNumber(higherX, 10) + lowerX = new BigNumber(lowerX, 10) + xForExtrapolation = new BigNumber(xForExtrapolation, 10) + const slope = (higherY.minus(lowerY)).div(higherX.minus(lowerX)) + const newTimeEstimate = slope.times(higherX.minus(xForExtrapolation)).minus(higherY).negated() + + return Number(newTimeEstimate.toPrecision(10)) +} + +function getRandomArbitrary (min, max) { + min = new BigNumber(min, 10) + max = new BigNumber(max, 10) + const random = new BigNumber(String(Math.random()), 10) + return new BigNumber(random.times(max.minus(min)).plus(min)).toPrecision(10) +} + +function calcMedian (list) { + const medianPos = (Math.floor(list.length / 2) + Math.ceil(list.length / 2)) / 2 + return medianPos === Math.floor(medianPos) + ? (list[medianPos - 1] + list[medianPos]) / 2 + : list[Math.floor(medianPos)] +} + +function quartiles (data) { + const lowerHalf = data.slice(0, Math.floor(data.length / 2)) + const upperHalf = data.slice(Math.floor(data.length / 2) + (data.length % 2 === 0 ? 0 : 1)) + const median = calcMedian(data) + const lowerQuartile = calcMedian(lowerHalf) + const upperQuartile = calcMedian(upperHalf) + return { + median, + lowerQuartile, + upperQuartile, + } +} + +function inliersByIQR (data, prop) { + const { lowerQuartile, upperQuartile } = quartiles(data.map(d => prop ? d[prop] : d)) + const IQR = upperQuartile - lowerQuartile + const lowerBound = lowerQuartile - 1.5 * IQR + const upperBound = upperQuartile + 1.5 * IQR + return data.filter(d => { + const value = prop ? d[prop] : d + return value >= lowerBound && value <= upperBound + }) +} + export function fetchGasEstimates (blockTime) { return (dispatch, getState) => { const { @@ -289,21 +339,50 @@ export function fetchGasEstimates (blockTime) { .then(r => { const estimatedPricesAndTimes = r.map(({ expectedTime, expectedWait, gasprice }) => ({ expectedTime, expectedWait, gasprice })) const estimatedTimeWithUniquePrices = uniqBy(({ expectedTime }) => expectedTime, estimatedPricesAndTimes) - const timeMappedToSeconds = estimatedTimeWithUniquePrices.map(({ expectedWait, gasprice }) => { - const expectedTime = (new BigNumber(expectedWait)).times(Number(blockTime), 10).toString(10) + + const withSupplementalTimeEstimates = flatten(estimatedTimeWithUniquePrices.map(({ expectedWait, gasprice }, i, arr) => { + const next = arr[i + 1] + if (!next) { + return [{ expectedWait, gasprice }] + } else { + const supplementalPrice = getRandomArbitrary(gasprice, next.gasprice) + const supplementalTime = extrapolateY({ + higherY: next.expectedWait, + lowerY: expectedWait, + higherX: next.gasprice, + lowerX: gasprice, + xForExtrapolation: supplementalPrice, + }) + const supplementalPrice2 = getRandomArbitrary(supplementalPrice, next.gasprice) + const supplementalTime2 = extrapolateY({ + higherY: next.expectedWait, + lowerY: supplementalTime, + higherX: next.gasprice, + lowerX: supplementalPrice, + xForExtrapolation: supplementalPrice2, + }) + return [ + { expectedWait, gasprice }, + { expectedWait: supplementalTime, gasprice: supplementalPrice }, + { expectedWait: supplementalTime2, gasprice: supplementalPrice2 }, + ] + } + })) + const withOutliersRemoved = inliersByIQR(withSupplementalTimeEstimates.slice(0).reverse(), 'expectedWait').reverse() + const timeMappedToSeconds = withOutliersRemoved.map(({ expectedWait, gasprice }) => { + const expectedTime = (new BigNumber(expectedWait)).times(Number(blockTime), 10).toNumber() return { expectedTime, - expectedWait, - gasprice, + gasprice: (new BigNumber(gasprice, 10).toNumber()), } }) const timeRetrieved = Date.now() dispatch(setApiEstimatesLastRetrieved(timeRetrieved)) saveLocalStorageData(timeRetrieved, 'GAS_API_ESTIMATES_LAST_RETRIEVED') - saveLocalStorageData(timeMappedToSeconds.slice(1), 'GAS_API_ESTIMATES') + saveLocalStorageData(timeMappedToSeconds, 'GAS_API_ESTIMATES') - return timeMappedToSeconds.slice(1) + return timeMappedToSeconds }) : Promise.resolve(priceAndTimeEstimates.length ? priceAndTimeEstimates diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js index dff154dea1a9..4783db30c434 100644 --- a/ui/app/ducks/tests/gas-duck.test.js +++ b/ui/app/ducks/tests/gas-duck.test.js @@ -45,10 +45,25 @@ describe('Gas Duck', () => { speed: 'mockSpeed', } const mockPredictTableResponse = [ + { expectedTime: 400, expectedWait: 40, gasprice: 0.25, somethingElse: 'foobar' }, + { expectedTime: 200, expectedWait: 20, gasprice: 0.5, somethingElse: 'foobar' }, { expectedTime: 100, expectedWait: 10, gasprice: 1, somethingElse: 'foobar' }, + { expectedTime: 75, expectedWait: 7.5, gasprice: 1.5, somethingElse: 'foobar' }, { expectedTime: 50, expectedWait: 5, gasprice: 2, somethingElse: 'foobar' }, + { expectedTime: 35, expectedWait: 4.5, gasprice: 3, somethingElse: 'foobar' }, + { expectedTime: 34, expectedWait: 4.4, gasprice: 3.1, somethingElse: 'foobar' }, + { expectedTime: 25, expectedWait: 4.2, gasprice: 3.5, somethingElse: 'foobar' }, { expectedTime: 20, expectedWait: 4, gasprice: 4, somethingElse: 'foobar' }, + { expectedTime: 19, expectedWait: 3.9, gasprice: 4.1, somethingElse: 'foobar' }, + { expectedTime: 15, expectedWait: 3, gasprice: 7, somethingElse: 'foobar' }, + { expectedTime: 14, expectedWait: 2.9, gasprice: 7.1, somethingElse: 'foobar' }, + { expectedTime: 12, expectedWait: 2.5, gasprice: 8, somethingElse: 'foobar' }, { expectedTime: 10, expectedWait: 2, gasprice: 10, somethingElse: 'foobar' }, + { expectedTime: 9, expectedWait: 1.9, gasprice: 10.1, somethingElse: 'foobar' }, + { expectedTime: 5, expectedWait: 1, gasprice: 15, somethingElse: 'foobar' }, + { expectedTime: 4, expectedWait: 0.9, gasprice: 15.1, somethingElse: 'foobar' }, + { expectedTime: 2, expectedWait: 0.8, gasprice: 17, somethingElse: 'foobar' }, + { expectedTime: 1.1, expectedWait: 0.6, gasprice: 19.9, somethingElse: 'foobar' }, { expectedTime: 1, expectedWait: 0.5, gasprice: 20, somethingElse: 'foobar' }, ] const fetchStub = sinon.stub().callsFake((url) => new Promise(resolve => { @@ -382,35 +397,13 @@ describe('Gas Duck', () => { [{ type: SET_API_ESTIMATES_LAST_RETRIEVED, value: 2000000 }] ) - assert.deepEqual( - mockDistpatch.getCall(2).args, - [{ - type: SET_PRICE_AND_TIME_ESTIMATES, - value: [ - { - expectedTime: '25', - expectedWait: 5, - gasprice: 2, - }, - { - expectedTime: '20', - expectedWait: 4, - gasprice: 4, - }, - { - expectedTime: '10', - expectedWait: 2, - gasprice: 10, - }, - { - expectedTime: '2.5', - expectedWait: 0.5, - gasprice: 20, - }, - ], + const { type: thirdDispatchCallType, value: priceAndTimeEstimateResult } = mockDistpatch.getCall(2).args[0] + assert.equal(thirdDispatchCallType, SET_PRICE_AND_TIME_ESTIMATES) + assert(priceAndTimeEstimateResult.length < mockPredictTableResponse.length * 3 - 2) + assert(!priceAndTimeEstimateResult.find(d => d.expectedTime > 100)) + assert(!priceAndTimeEstimateResult.find((d, i, a) => a[a + 1] && d.expectedTime > a[a + 1].expectedTime)) + assert(!priceAndTimeEstimateResult.find((d, i, a) => a[a + 1] && d.gasprice > a[a + 1].gasprice)) - }] - ) assert.deepEqual( mockDistpatch.getCall(3).args, [{ type: GAS_ESTIMATE_LOADING_FINISHED }] From 75d75454374d98bf904b817bc2dd2b81b9e97a9d Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 13 Nov 2018 14:55:34 -0330 Subject: [PATCH 44/64] Clear custom gas data on hiding of gas customization modal. --- ui/app/components/modals/modal.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 46347312cd11..7ed0b6944cf0 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -4,6 +4,7 @@ const inherits = require('util').inherits const connect = require('react-redux').connect const FadeModal = require('boron').FadeModal const actions = require('../../actions') +const { resetCustomData: resetCustomGasData } = require('../../ducks/gas.duck') const isMobileView = require('../../../lib/is-mobile-view') const { getEnvironmentType } = require('../../../../app/scripts/lib/util') const { ENVIRONMENT_TYPE_POPUP } = require('../../../../app/scripts/lib/enums') @@ -317,6 +318,10 @@ const MODALS = { contentStyle: { borderRadius: '8px', }, + customOnHideOpts: { + action: resetCustomGasData, + args: [], + }, }, TRANSACTION_CONFIRMED: { @@ -392,8 +397,11 @@ function mapStateToProps (state) { function mapDispatchToProps (dispatch) { return { - hideModal: () => { + hideModal: (customOnHideOpts) => { dispatch(actions.hideModal()) + if (customOnHideOpts.action) { + dispatch(customOnHideOpts.action(...customOnHideOpts.args)) + } }, hideWarning: () => { dispatch(actions.hideWarning()) @@ -425,7 +433,7 @@ Modal.prototype.render = function () { if (modal.onHide) { modal.onHide(this.props) } - this.onHide() + this.onHide(modal.customOnHideOpts) }, ref: (ref) => { this.modalRef = ref @@ -447,11 +455,11 @@ Modal.prototype.componentWillReceiveProps = function (nextProps) { } } -Modal.prototype.onHide = function () { +Modal.prototype.onHide = function (customOnHideOpts) { if (this.props.onHideCallback) { this.props.onHideCallback() } - this.props.hideModal() + this.props.hideModal(customOnHideOpts) } Modal.prototype.hide = function () { From d8e41a6aa5a4c64538063c6dde7afdf77b0e5793 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 27 Nov 2018 14:00:41 -0330 Subject: [PATCH 45/64] Final gas customization fixes --- .../transactions/tx-controller-test.js | 2 +- .../advanced-tab-content.component.js | 26 ++++++-- .../advanced-tab-content/index.scss | 1 + .../advanced-tab-content-component.test.js | 16 +++-- .../gas-modal-page-container.component.js | 3 +- .../gas-modal-page-container.container.js | 29 ++++++++- .../gas-modal-page-container/index.scss | 1 + ...gas-modal-page-container-container.test.js | 18 ++++-- .../gas-price-button-group/index.scss | 2 +- .../gas-price-chart.component.js | 2 +- .../gas-price-chart/gas-price-chart.utils.js | 54 ++++++++++------ ui/app/components/modals/modal.js | 2 +- .../page-container-footer.component.js | 2 +- .../components/sidebars/sidebar-content.scss | 40 +++++++++--- ui/app/ducks/gas.duck.js | 15 +++-- ui/app/ducks/tests/gas-duck.test.js | 16 ++--- ui/app/selectors/custom-gas.js | 61 ++++++++----------- ui/app/selectors/tests/custom-gas.test.js | 12 ++-- 18 files changed, 198 insertions(+), 104 deletions(-) diff --git a/test/unit/app/controllers/transactions/tx-controller-test.js b/test/unit/app/controllers/transactions/tx-controller-test.js index 6889f9bb2bd1..74161e26cbb5 100644 --- a/test/unit/app/controllers/transactions/tx-controller-test.js +++ b/test/unit/app/controllers/transactions/tx-controller-test.js @@ -413,7 +413,7 @@ describe('Transaction Controller', function () { gasPrice: '0xa', } txController.txStateManager._saveTxList([ - { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [] }, + { id: 1, status: 'submitted', metamaskNetworkId: currentNetworkId, txParams, history: [{}] }, ]) expectedTxParams = Object.assign({}, txParams, { gasPrice: '0xb'}) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index ac68b833cbf9..ba738ff750f9 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -3,6 +3,7 @@ import PropTypes from 'prop-types' import classnames from 'classnames' import Loading from '../../../loading-screen' import GasPriceChart from '../../gas-price-chart' +import debounce from 'lodash.debounce' export default class AdvancedTabContent extends Component { static contextTypes = { @@ -22,7 +23,21 @@ export default class AdvancedTabContent extends Component { insufficientBalance: PropTypes.bool, } - gasInput (value, onChange, min, insufficientBalance, precision, showGWEI) { + constructor (props) { + super(props) + + this.debouncedGasLimitReset = debounce((dVal) => { + if (dVal < 21000) { + props.updateCustomGasLimit(21000) + } + }, 1000, { trailing: true }) + this.onChangeGasLimit = (val) => { + props.updateCustomGasLimit(val) + this.debouncedGasLimitReset(val) + } + } + + gasInput (value, onChange, min, insufficientBalance, showGWEI) { return (
onChange(Number(event.target.value))} />
-
onChange(value + 1)} />
-
onChange(value - 1)} />
+
onChange(value + 1)}>
+
onChange(value - 1)}>
{insufficientBalance &&
Insufficient Balance @@ -84,8 +98,8 @@ export default class AdvancedTabContent extends Component { renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit, insufficientBalance) { return (
- { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, 9, true) } - { this.renderGasEditRow('gasLimit', customGasLimit, updateCustomGasLimit, customGasLimit, insufficientBalance, 0) } + { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, true) } + { this.renderGasEditRow('gasLimit', customGasLimit, this.onChangeGasLimit, customGasLimit, insufficientBalance) }
) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index b62919c0a49e..88c69faf4dfd 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -148,6 +148,7 @@ height: 100%; display: flex; justify-content: center; + cursor: pointer; } &__i-wrap:hover { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index f321ca696eab..d6920454d06f 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -155,8 +155,11 @@ describe('AdvancedTabContent Component', function () { describe('renderGasEditRows()', () => { let gasEditRows + let tempOnChangeGasLimit beforeEach(() => { + tempOnChangeGasLimit = wrapper.instance().onChangeGasLimit + wrapper.instance().onChangeGasLimit = () => 'mockOnChangeGasLimit' AdvancedTabContent.prototype.renderGasEditRow.resetHistory() gasEditRows = shallow(wrapper.instance().renderGasEditRows( 'mockGasPrice', @@ -167,6 +170,10 @@ describe('AdvancedTabContent Component', function () { )) }) + afterEach(() => { + wrapper.instance().onChangeGasLimit = tempOnChangeGasLimit + }) + it('should render the gas-edit-rows root node', () => { assert(gasEditRows.hasClass('advanced-tab__gas-edit-rows')) }) @@ -182,10 +189,10 @@ describe('AdvancedTabContent Component', function () { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, 9, true, + 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, true, ].map(String)) assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ - 'gasLimit', 'mockGasLimit', () => 'mockUpdateCustomGasLimitReturn', 'mockGasLimit', false, 0, + 'gasLimit', 'mockGasLimit', () => 'mockOnChangeGasLimit', 'mockGasLimit', false, ].map(String)) }) }) @@ -234,7 +241,6 @@ describe('AdvancedTabContent Component', function () { const inputProps = gasInput.find('input').props() assert.equal(inputProps.min, 0) assert.equal(inputProps.value, 321) - assert.equal(inputProps.precision, 8) }) it('should call the passed onChange method with the value of the input onChange event', () => { @@ -257,9 +263,9 @@ describe('AdvancedTabContent Component', function () { 8, false )) - const upArrow = gasInput.find('.fa-angle-up') + const upArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(0) assert.equal(upArrow.props().onClick(), 329) - const downArrow = gasInput.find('.fa-angle-down') + const downArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(1) assert.equal(downArrow.props().onClick(), 327) }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index 5d8f92a59ec9..be91bef0f818 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -89,7 +89,7 @@ export default class GasModalPageContainer extends Component { renderInfoRows (newTotalFiat, newTotalEth, sendAmount, transactionFee) { return ( -
+
{this.context.t('sendAmount')} @@ -167,7 +167,6 @@ export default class GasModalPageContainer extends Component { onClose={() => cancelAndClose()} onSubmit={() => { onSubmit(customModalGasLimitInHex, customModalGasPriceInHex) - cancelAndClose() }} submitText={this.context.t('save')} headerCloseText={'Close'} diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index 42b96a729870..c619a0988088 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -142,6 +142,7 @@ const mapDispatchToProps = dispatch => { dispatch(resetCustomData()) dispatch(hideModal()) }, + hideModal: () => dispatch(hideModal()), updateCustomGasPrice, convertThenUpdateCustomGasPrice: newPrice => updateCustomGasPrice(decGWEIToHexWEI(newPrice)), convertThenUpdateCustomGasLimit: newLimit => dispatch(setCustomGasLimit(addHexPrefix(newLimit.toString(16)))), @@ -150,6 +151,8 @@ const mapDispatchToProps = dispatch => { dispatch(setGasPrice(newPrice)) }, updateConfirmTxGasAndCalculate: (gasLimit, gasPrice) => { + updateCustomGasPrice(gasPrice) + dispatch(setCustomGasLimit(addHexPrefix(gasLimit.toString(16)))) return dispatch(updateGasAndCalculate({ gasLimit, gasPrice })) }, createSpeedUpTransaction: (txId, gasPrice) => { @@ -172,6 +175,8 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { updateConfirmTxGasAndCalculate: dispatchUpdateConfirmTxGasAndCalculate, createSpeedUpTransaction: dispatchCreateSpeedUpTransaction, hideSidebar: dispatchHideSidebar, + cancelAndClose: dispatchCancelAndClose, + hideModal: dispatchHideModal, ...otherDispatchProps } = dispatchProps @@ -182,18 +187,27 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { onSubmit: (gasLimit, gasPrice) => { if (isConfirm) { dispatchUpdateConfirmTxGasAndCalculate(gasLimit, gasPrice) + dispatchHideModal() } else if (isSpeedUp) { dispatchCreateSpeedUpTransaction(txId, gasPrice) dispatchHideSidebar() + dispatchCancelAndClose() } else { dispatchSetGasData(gasLimit, gasPrice) dispatchHideGasButtonGroup() + dispatchCancelAndClose() } }, gasPriceButtonGroupProps: { ...gasPriceButtonGroupProps, handleGasPriceSelection: dispatchUpdateCustomGasPrice, }, + cancelAndClose: () => { + dispatchCancelAndClose() + if (isSpeedUp) { + dispatchHideSidebar() + } + }, } } @@ -241,20 +255,29 @@ function addHexWEIsToRenderableFiat (aHexWEI, bHexWEI, convertedCurrency, conver } function getRenderableTimeEstimate (currentGasPrice, gasPrices, estimatedTimes) { + const minGasPrice = gasPrices[0] + const maxGasPrice = gasPrices[gasPrices.length - 1] + let priceForEstimation = currentGasPrice + if (currentGasPrice < minGasPrice) { + priceForEstimation = minGasPrice + } else if (currentGasPrice > maxGasPrice) { + priceForEstimation = maxGasPrice + } + const { closestLowerValueIndex, closestHigherValueIndex, closestHigherValue, closestLowerValue, - } = getAdjacentGasPrices({ gasPrices, priceToPosition: currentGasPrice }) + } = getAdjacentGasPrices({ gasPrices, priceToPosition: priceForEstimation }) const newTimeEstimate = extrapolateY({ higherY: estimatedTimes[closestHigherValueIndex], lowerY: estimatedTimes[closestLowerValueIndex], higherX: closestHigherValue, lowerX: closestLowerValue, - xForExtrapolation: currentGasPrice, + xForExtrapolation: priceForEstimation, }) - return formatTimeEstimate(newTimeEstimate) + return formatTimeEstimate(newTimeEstimate, currentGasPrice > maxGasPrice, currentGasPrice < minGasPrice) } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index 2532c1fc2a1c..6c76f1bddde9 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -44,6 +44,7 @@ display: flex; justify-content: center; align-items: flex-start; + margin-right: 0; } &__subtitle { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 82c6dcd699b2..512832866f9c 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -82,10 +82,10 @@ describe('gas-modal-page-container container', () => { }, gasEstimatesLoading: false, priceAndTimeEstimates: [ - { gasprice: 3, expectedTime: '31' }, - { gasprice: 4, expectedTime: '62' }, - { gasprice: 5, expectedTime: '93' }, - { gasprice: 6, expectedTime: '124' }, + { gasprice: 3, expectedTime: 31 }, + { gasprice: 4, expectedTime: 62 }, + { gasprice: 5, expectedTime: 93 }, + { gasprice: 6, expectedTime: 124 }, ], }, confirmTransaction: { @@ -235,7 +235,7 @@ describe('gas-modal-page-container container', () => { describe('updateConfirmTxGasAndCalculate()', () => { it('should dispatch a updateGasAndCalculate action with the correct props', () => { mapDispatchToPropsObject.updateConfirmTxGasAndCalculate('ffff', 'aaaa') - assert(dispatchSpy.calledOnce) + assert.equal(dispatchSpy.callCount, 3) assert(confirmTransactionActionSpies.updateGasAndCalculate.calledOnce) assert.deepEqual(confirmTransactionActionSpies.updateGasAndCalculate.getCall(0).args[0], { gasLimit: 'ffff', gasPrice: 'aaaa' }) }) @@ -265,6 +265,8 @@ describe('gas-modal-page-container container', () => { someOtherDispatchProp: sinon.spy(), createSpeedUpTransaction: sinon.spy(), hideSidebar: sinon.spy(), + hideModal: sinon.spy(), + cancelAndClose: sinon.spy(), } ownProps = { someOwnProp: 123 } }) @@ -277,6 +279,7 @@ describe('gas-modal-page-container container', () => { dispatchProps.someOtherDispatchProp.resetHistory() dispatchProps.createSpeedUpTransaction.resetHistory() dispatchProps.hideSidebar.resetHistory() + dispatchProps.hideModal.resetHistory() }) it('should return the expected props when isConfirm is true', () => { const result = mergeProps(stateProps, dispatchProps, ownProps) @@ -290,12 +293,14 @@ describe('gas-modal-page-container container', () => { assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) assert.equal(dispatchProps.setGasData.callCount, 0) assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + assert.equal(dispatchProps.hideModal.callCount, 0) result.onSubmit() assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 1) assert.equal(dispatchProps.setGasData.callCount, 0) assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + assert.equal(dispatchProps.hideModal.callCount, 1) assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) result.gasPriceButtonGroupProps.handleGasPriceSelection() @@ -318,6 +323,7 @@ describe('gas-modal-page-container container', () => { assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) assert.equal(dispatchProps.setGasData.callCount, 0) assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + assert.equal(dispatchProps.cancelAndClose.callCount, 0) result.onSubmit('mockNewLimit', 'mockNewPrice') @@ -325,6 +331,7 @@ describe('gas-modal-page-container container', () => { assert.equal(dispatchProps.setGasData.callCount, 1) assert.deepEqual(dispatchProps.setGasData.getCall(0).args, ['mockNewLimit', 'mockNewPrice']) assert.equal(dispatchProps.hideGasButtonGroup.callCount, 1) + assert.equal(dispatchProps.cancelAndClose.callCount, 1) assert.equal(dispatchProps.updateCustomGasPrice.callCount, 0) result.gasPriceButtonGroupProps.handleGasPriceSelection() @@ -343,6 +350,7 @@ describe('gas-modal-page-container container', () => { assert.equal(dispatchProps.updateConfirmTxGasAndCalculate.callCount, 0) assert.equal(dispatchProps.setGasData.callCount, 0) assert.equal(dispatchProps.hideGasButtonGroup.callCount, 0) + assert.equal(dispatchProps.cancelAndClose.callCount, 1) assert.equal(dispatchProps.createSpeedUpTransaction.callCount, 1) assert.equal(dispatchProps.hideSidebar.callCount, 1) diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.scss b/ui/app/components/gas-customization/gas-price-button-group/index.scss index 6e9d01c6e42e..0d14505940a8 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/index.scss +++ b/ui/app/components/gas-customization/gas-price-button-group/index.scss @@ -137,7 +137,7 @@ .gas-price-button-group--alt { display: flex; justify-content: stretch; - max-width: 342px; + width: 95%; &__button-fiat-price { font-size: 13px; diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js index 3f382e5b2094..d4c67bbde6a9 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.component.js @@ -19,7 +19,7 @@ export default class GasPriceChart extends Component { gasPrices: PropTypes.array, estimatedTimes: PropTypes.array, gasPricesMax: PropTypes.number, - estimatedTimesMax: PropTypes.string, + estimatedTimesMax: PropTypes.number, currentPrice: PropTypes.number, updateCustomGasPrice: PropTypes.func, } diff --git a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js index 0b9dfbd118fb..f19dafcc125a 100644 --- a/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js +++ b/ui/app/components/gas-customization/gas-price-chart/gas-price-chart.utils.js @@ -1,5 +1,11 @@ import * as d3 from 'd3' import c3 from 'c3' +import BigNumber from 'bignumber.js' + +const newBigSigDig = n => (new BigNumber(n.toPrecision(15))) +const createOp = (a, b, op) => (newBigSigDig(a))[op](newBigSigDig(b)) +const bigNumMinus = (a = 0, b = 0) => createOp(a, b, 'minus') +const bigNumDiv = (a = 0, b = 1) => createOp(a, b, 'div') export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes, chart }) { const { currentPosValue, newTimeEstimate } = getNewXandTimeEstimate({ @@ -24,7 +30,8 @@ export function handleMouseMove ({ xMousePos, chartXStart, chartWidth, gasPrices } export function getCoordinateData (selector) { - return d3.select(selector).node().getBoundingClientRect() + const node = d3.select(selector).node() + return node ? node.getBoundingClientRect() : {} } export function generateDataUIObj (x, index, value) { @@ -70,19 +77,22 @@ export function getAdjacentGasPrices ({ gasPrices, priceToPosition }) { } } -export function extrapolateY ({ higherY, lowerY, higherX, lowerX, xForExtrapolation }) { - const slope = (higherY - lowerY) / (higherX - lowerX) - const newTimeEstimate = -1 * (slope * (higherX - xForExtrapolation) - higherY) +export function extrapolateY ({ higherY = 0, lowerY = 0, higherX = 0, lowerX = 0, xForExtrapolation = 0 }) { + const slope = bigNumMinus(higherY, lowerY).div(bigNumMinus(higherX, lowerX)) + const newTimeEstimate = slope.times(bigNumMinus(higherX, xForExtrapolation)).minus(newBigSigDig(higherY)).negated() - return newTimeEstimate + return newTimeEstimate.toNumber() } export function getNewXandTimeEstimate ({ xMousePos, chartXStart, chartWidth, gasPrices, estimatedTimes }) { - const chartMouseXPos = xMousePos - chartXStart - const posPercentile = chartMouseXPos / chartWidth + const chartMouseXPos = bigNumMinus(xMousePos, chartXStart) + const posPercentile = bigNumDiv(chartMouseXPos, chartWidth) - const currentPosValue = (gasPrices[gasPrices.length - 1] - gasPrices[0]) * posPercentile + gasPrices[0] + const currentPosValue = (bigNumMinus(gasPrices[gasPrices.length - 1], gasPrices[0])) + .times(newBigSigDig(posPercentile)) + .plus(newBigSigDig(gasPrices[0])) + .toNumber() const { closestLowerValueIndex, @@ -162,20 +172,28 @@ export function setSelectedCircle ({ closestHigherValue, }) { const numberOfValues = chart.internal.data.xs.data1.length + const { x: lowerX, y: lowerY } = getCoordinateData(`.c3-circle-${closestLowerValueIndex}`) let { x: higherX, y: higherY } = getCoordinateData(`.c3-circle-${closestHigherValueIndex}`) + let count = closestHigherValueIndex + 1 - if (lowerX === higherX) { - const { x: higherXAdjusted, y: higherYAdjusted } = getCoordinateData(`.c3-circle-${closestHigherValueIndex + 1}`) - higherY = higherYAdjusted - higherX = higherXAdjusted + if (lowerX && higherX) { + while (lowerX === higherX) { + higherX = getCoordinateData(`.c3-circle-${count}`).x + higherY = getCoordinateData(`.c3-circle-${count}`).y + count++ + } } - const currentX = lowerX + (higherX - lowerX) * (newPrice - closestLowerValue) / (closestHigherValue - closestLowerValue) + const currentX = bigNumMinus(higherX, lowerX) + .times(bigNumMinus(newPrice, closestLowerValue)) + .div(bigNumMinus(closestHigherValue, closestLowerValue)) + .plus(newBigSigDig(lowerX)) + const newTimeEstimate = extrapolateY({ higherY, lowerY, higherX, lowerX, xForExtrapolation: currentX }) chart.internal.selectPoint( - generateDataUIObj(currentX, numberOfValues, newTimeEstimate), + generateDataUIObj(currentX.toNumber(), numberOfValues, newTimeEstimate), numberOfValues ) } @@ -282,8 +300,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate .style('margin-top', flipTooltip ? '-16px' : '4px') return { - top: circleY - chartYStart - 19 + (flipTooltip ? circleWidth + 38 : 0), - left: circleX - chartXStart + circleWidth - (gasPricesMaxPadded / 50), + top: bigNumMinus(circleY, chartYStart).minus(19).plus(flipTooltip ? circleWidth + 38 : 0).toNumber(), + left: bigNumMinus(circleX, chartXStart).plus(newBigSigDig(circleWidth)).minus(bigNumDiv(gasPricesMaxPadded, 50)).toNumber(), } }, show: true, @@ -298,8 +316,8 @@ export function generateChart (gasPrices, estimatedTimes, gasPricesMax, estimate appendOrUpdateCircle.bind(this)({ data, itemIndex, - cx: () => data.x - chartXStart + 11, - cy: () => data.value - chartYStart + 10, + cx: () => bigNumMinus(data.x, chartXStart).plus(11).toNumber(), + cy: () => bigNumMinus(data.value, chartYStart).plus(10).toNumber(), cssId: 'set-circle', appendOnly: true, }) diff --git a/ui/app/components/modals/modal.js b/ui/app/components/modals/modal.js index 7ed0b6944cf0..0a603db4e230 100644 --- a/ui/app/components/modals/modal.js +++ b/ui/app/components/modals/modal.js @@ -399,7 +399,7 @@ function mapDispatchToProps (dispatch) { return { hideModal: (customOnHideOpts) => { dispatch(actions.hideModal()) - if (customOnHideOpts.action) { + if (customOnHideOpts && customOnHideOpts.action) { dispatch(customOnHideOpts.action(...customOnHideOpts.args)) } }, diff --git a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js index 5725c22acd7d..85b16cefeb5d 100644 --- a/ui/app/components/page-container/page-container-footer/page-container-footer.component.js +++ b/ui/app/components/page-container/page-container-footer/page-container-footer.component.js @@ -12,7 +12,7 @@ export default class PageContainerFooter extends Component { submitText: PropTypes.string, disabled: PropTypes.bool, submitButtonType: PropTypes.string, - hideCancel: PropTypes.func, + hideCancel: PropTypes.bool, } static contextTypes = { diff --git a/ui/app/components/sidebars/sidebar-content.scss b/ui/app/components/sidebars/sidebar-content.scss index 7d1f719dcc90..ca6b0a458a3f 100644 --- a/ui/app/components/sidebars/sidebar-content.scss +++ b/ui/app/components/sidebars/sidebar-content.scss @@ -1,6 +1,11 @@ .sidebar-left { + display: flex; + .gas-modal-page-container { + display: flex; + .page-container { + flex: 1; max-width: 100%; &__content { @@ -12,6 +17,10 @@ max-width: 344px; min-height: auto; } + + @media screen and (min-width: $break-small) { + max-height: none; + } } .gas-price-chart { @@ -34,9 +43,10 @@ } .basic-tab-content { - height: 318px; + height: auto; margin-bottom: 0px; border-bottom: 1px solid #d2d8dd; + flex: 1 1 70%; @media screen and (max-width: $break-small) { padding-left: 14px; @@ -55,6 +65,10 @@ } .advanced-tab { + @media screen and (min-width: $break-small) { + flex: 1 1 70%; + } + &__fee-chart { height: 320px; @@ -72,14 +86,26 @@ } } + .gas-modal-content { + display: flex; + flex-direction: column; + width: 100%; - .gas-modal-content__info-row { - height: 170px; - - @media screen and (max-width: $break-small) { - height: initial; + &__info-row-wrapper { display: flex; - justify-content: center; + @media screen and (min-width: $break-small) { + flex: 1 1 30%; + } + } + + &__info-row { + height: 170px; + + @media screen and (max-width: $break-small) { + height: initial; + display: flex; + justify-content: center; + } } } } diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js index 20a125dbb661..8db24cc837f5 100644 --- a/ui/app/ducks/gas.duck.js +++ b/ui/app/ducks/gas.duck.js @@ -220,18 +220,25 @@ export function fetchBasicGasAndTimeEstimates () { ) .then(r => r.json()) .then(({ - average, + average: averageTimes10, avgWait, block_time: blockTime, blockNum, - fast, - fastest, + fast: fastTimes10, + fastest: fastestTimes10, fastestWait, fastWait, - safeLow, + safeLow: safeLowTimes10, safeLowWait, speed, }) => { + const [average, fast, fastest, safeLow] = [ + averageTimes10, + fastTimes10, + fastestTimes10, + safeLowTimes10, + ].map(price => (new BigNumber(price)).div(10).toNumber()) + const basicEstimates = { average, avgWait, diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js index 4783db30c434..bf374c7eca89 100644 --- a/ui/app/ducks/tests/gas-duck.test.js +++ b/ui/app/ducks/tests/gas-duck.test.js @@ -32,15 +32,15 @@ describe('Gas Duck', () => { let tempFetch let tempDateNow const mockEthGasApiResponse = { - average: 'mockAverage', + average: 20, avgWait: 'mockAvgWait', block_time: 'mockBlock_time', blockNum: 'mockBlockNum', - fast: 'mockFast', - fastest: 'mockFastest', + fast: 30, + fastest: 40, fastestWait: 'mockFastestWait', fastWait: 'mockFastWait', - safeLow: 'mockSafeLow', + safeLow: 10, safeLowWait: 'mockSafeLowWait', speed: 'mockSpeed', } @@ -338,15 +338,15 @@ describe('Gas Duck', () => { [{ type: SET_BASIC_GAS_ESTIMATE_DATA, value: { - average: 'mockAverage', + average: 2, avgWait: 'mockAvgWait', blockTime: 'mockBlock_time', blockNum: 'mockBlockNum', - fast: 'mockFast', - fastest: 'mockFastest', + fast: 3, + fastest: 4, fastestWait: 'mockFastestWait', fastWait: 'mockFastWait', - safeLow: 'mockSafeLow', + safeLow: 1, safeLowWait: 'mockSafeLowWait', speed: 'mockSpeed', }, diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index ec234500da9a..59f240f9c635 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -85,9 +85,9 @@ function getAveragePriceEstimateInHexWEI (state) { return getGasPriceInHexWei(averagePriceEstimate || '0x0') } -function getFastPriceEstimateInHexWEI (state, convertFromDecGWEI) { +function getFastPriceEstimateInHexWEI (state) { const fastPriceEstimate = state.gas.basicEstimates.fast - return getGasPriceInHexWei(fastPriceEstimate || '0x0', convertFromDecGWEI) + return getGasPriceInHexWei(fastPriceEstimate || '0x0') } function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPrice) { @@ -100,15 +100,6 @@ function getBasicGasEstimateBlockTime (state) { return state.gas.basicEstimates.blockTime } -function apiEstimateModifiedToGWEI (estimate) { - return multiplyCurrencies(estimate, 0.10, { - toNumericBase: 'hex', - multiplicandBase: 10, - multiplierBase: 10, - numberOfDecimals: 9, - }) -} - function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) { return conversionUtil(calcGasTotal(gasLimit, estimate), { fromNumericBase: 'hex', @@ -118,26 +109,18 @@ function basicPriceEstimateToETHTotal (estimate, gasLimit, numberOfDecimals = 9) }) } -function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9, convertFromDecGWEI) { - const initialConversion = convertFromDecGWEI - ? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }) - : apiEstimateModifiedToGWEI - +function getRenderableEthFee (estimate, gasLimit, numberOfDecimals = 9) { return pipe( - initialConversion, + x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }), partialRight(basicPriceEstimateToETHTotal, [gasLimit, numberOfDecimals]), formatETHFee )(estimate, gasLimit) } -function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate, convertFromDecGWEI) { - const initialConversion = convertFromDecGWEI - ? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }) - : apiEstimateModifiedToGWEI - +function getRenderableConvertedCurrencyFee (estimate, gasLimit, convertedCurrency, conversionRate) { return pipe( - initialConversion, + x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }), partialRight(basicPriceEstimateToETHTotal, [gasLimit]), partialRight(ethTotalToConvertedCurrency, [convertedCurrency, conversionRate]), partialRight(formatCurrency, [convertedCurrency]) @@ -153,14 +136,26 @@ function getTimeEstimateInSeconds (blockWaitEstimate) { }) } -function formatTimeEstimate (totalSeconds) { +function formatTimeEstimate (totalSeconds, greaterThanMax, lessThanMin) { const minutes = Math.floor(totalSeconds / 60) const seconds = Math.floor(totalSeconds % 60) + + if (!minutes && !seconds) { + return '...' + } + + let symbol = '~' + if (greaterThanMax) { + symbol = '< ' + } else if (lessThanMin) { + symbol = '> ' + } + const formattedMin = `${minutes ? minutes + ' min' : ''}` const formattedSec = `${seconds ? seconds + ' sec' : ''}` const formattedCombined = formattedMin && formattedSec - ? `~${formattedMin} ${formattedSec}` - : '~' + [formattedMin, formattedSec].find(t => t) + ? `${symbol}${formattedMin} ${formattedSec}` + : symbol + [formattedMin, formattedSec].find(t => t) return formattedCombined } @@ -182,13 +177,9 @@ function priceEstimateToWei (priceEstimate) { }) } -function getGasPriceInHexWei (price, convertFromDecGWEI) { - const initialConversion = convertFromDecGWEI - ? x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }) - : apiEstimateModifiedToGWEI - +function getGasPriceInHexWei (price) { return pipe( - initialConversion, + x => conversionUtil(x, { fromNumericBase: 'dec', toNumericBase: 'hex' }), priceEstimateToWei, addHexPrefix )(price) @@ -259,19 +250,19 @@ function getRenderableEstimateDataForSmallButtonsFromGWEI (state) { return [ { labelKey: 'fastest', - feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate, true), + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fastest, gasLimit, currentCurrency, conversionRate), feeInPrimaryCurrency: getRenderableEthFee(fastest, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), priceInHexWei: getGasPriceInHexWei(fastest, true), }, { labelKey: 'fast', - feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate, true), + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(fast, gasLimit, currentCurrency, conversionRate), feeInPrimaryCurrency: getRenderableEthFee(fast, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), priceInHexWei: getGasPriceInHexWei(fast, true), }, { labelKey: 'slow', - feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate, true), + feeInSecondaryCurrency: getRenderableConvertedCurrencyFee(safeLow, gasLimit, currentCurrency, conversionRate), feeInPrimaryCurrency: getRenderableEthFee(safeLow, gasLimit, NUMBER_OF_DECIMALS_SM_BTNS, true), priceInHexWei: getGasPriceInHexWei(safeLow, true), }, diff --git a/ui/app/selectors/tests/custom-gas.test.js b/ui/app/selectors/tests/custom-gas.test.js index 037b1e86e0c7..ebc3001609ff 100644 --- a/ui/app/selectors/tests/custom-gas.test.js +++ b/ui/app/selectors/tests/custom-gas.test.js @@ -109,11 +109,11 @@ describe('custom-gas selectors', () => { gas: { basicEstimates: { blockTime: 14.16326530612245, - safeLow: 25, + safeLow: 2.5, safeLowWait: 6.6, - fast: 50, + fast: 5, fastWait: 3.3, - fastest: 100, + fastest: 10, fastestWait: 0.5, }, }, @@ -154,11 +154,11 @@ describe('custom-gas selectors', () => { gas: { basicEstimates: { blockTime: 14.16326530612245, - safeLow: 50, + safeLow: 5, safeLowWait: 13.2, - fast: 100, + fast: 10, fastWait: 6.6, - fastest: 200, + fastest: 20, fastestWait: 1.0, }, }, From 8194309a9a7319bcebd6761a4596c208375adfab Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Mon, 3 Dec 2018 16:43:32 -0330 Subject: [PATCH 46/64] Fix styling of send screen in extension view when hex data on. --- .../gas-modal-page-container/index.scss | 6 ++++++ .../gas-price-button-group/index.scss | 12 ++++++++---- ui/app/components/page-container/index.scss | 7 ++----- ui/app/css/itcss/components/send.scss | 4 +--- 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/index.scss index 6c76f1bddde9..efba24e0298d 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/index.scss @@ -5,9 +5,15 @@ .page-container { max-width: 391px; min-height: 585px; + overflow-y: initial; @media screen and (max-width: $break-small) { max-width: 344px; + + &__content { + display: flex; + overflow-y: initial; + } } &__header { diff --git a/ui/app/components/gas-customization/gas-price-button-group/index.scss b/ui/app/components/gas-customization/gas-price-button-group/index.scss index 0d14505940a8..c8b31fc835ba 100644 --- a/ui/app/components/gas-customization/gas-price-button-group/index.scss +++ b/ui/app/components/gas-customization/gas-price-button-group/index.scss @@ -67,10 +67,6 @@ justify-content: stretch; max-width: 260px; - @media screen and (max-width: $break-small) { - max-width: 230px; - } - &__button-fiat-price { font-size: 13px; } @@ -85,10 +81,18 @@ &__primary-currency { font-size: 12px; + + @media screen and (max-width: 575px) { + font-size: 10px; + } } &__secondary-currency { font-size: 12px; + + @media screen and (max-width: 575px) { + font-size: 10px; + } } &__loading-container { diff --git a/ui/app/components/page-container/index.scss b/ui/app/components/page-container/index.scss index 1634ab012df8..6fc97820ac0c 100644 --- a/ui/app/components/page-container/index.scss +++ b/ui/app/components/page-container/index.scss @@ -6,6 +6,7 @@ display: flex; flex-flow: column; border-radius: 8px; + overflow-y: auto; &__header { display: flex; @@ -197,11 +198,7 @@ background-color: $white; border-radius: 0; flex: 1; - - &__content { - display: flex; - overflow-y: initial; - } + overflow-y: auto; } } diff --git a/ui/app/css/itcss/components/send.scss b/ui/app/css/itcss/components/send.scss index ba7db7aa89d2..19e840094932 100644 --- a/ui/app/css/itcss/components/send.scss +++ b/ui/app/css/itcss/components/send.scss @@ -530,7 +530,6 @@ @media screen and (max-width: $break-small) { margin: 0; flex: 1 1 auto; - width: 100%; } } @@ -580,7 +579,7 @@ font-family: Roboto; font-size: 16px; line-height: 22px; - width: 112px; + width: 88px; font-weight: 400; flex: 0 0 auto; } @@ -623,7 +622,6 @@ &__to-autocomplete { position: relative; - max-width: 260px; &__down-caret { z-index: 1026; From 6a0993a45efd11de0bc4716d89952089a3f5bf67 Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Tue, 4 Dec 2018 23:17:51 -0330 Subject: [PATCH 47/64] Replace height: 100% rule with workaround for flexbox quirks --- ui/app/css/itcss/components/newui-sections.scss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/ui/app/css/itcss/components/newui-sections.scss b/ui/app/css/itcss/components/newui-sections.scss index b4b77ba1e163..a016fdce3a8d 100644 --- a/ui/app/css/itcss/components/newui-sections.scss +++ b/ui/app/css/itcss/components/newui-sections.scss @@ -215,7 +215,8 @@ $wallet-view-bg: $alabaster; } .main-container-wrapper { - height: 100%; + flex: 1; + min-height: 0; width: 100%; } } From 80d7be0a19ea6141eb47942eb5f7ffd75b22bbdc Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 11:11:02 -0330 Subject: [PATCH 48/64] Fill in more Polish message translations --- app/_locales/pl/messages.json | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/_locales/pl/messages.json b/app/_locales/pl/messages.json index 7e64ec689b21..026f4b3eccba 100644 --- a/app/_locales/pl/messages.json +++ b/app/_locales/pl/messages.json @@ -119,6 +119,9 @@ "clickCopy": { "message": "Kliknij żeby skopiować" }, + "clickToAdd": { + "message": "Przycisnij $1, aby dodać go do swojego konta" + }, "close": { "message": "Zamknij" }, @@ -337,6 +340,9 @@ "exchangeRate": { "message": "Kurs wymiany" }, + "expandView": { + "message": "Rozwiń widok" + }, "exportPrivateKey": { "message": "Eksportuj klucz prywatny" }, @@ -596,6 +602,9 @@ "min": { "message": "Minimum" }, + "missingYourTokens": { + "message": "Nie widzisz swoich token?" + }, "myAccounts": { "message": "Moje konta" }, From 161fdcfba6f5aea8dc765f2f63202ed4a8a4079a Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 11:28:04 -0330 Subject: [PATCH 49/64] Update lockfile to fix errors npm has informed me that the lockfile has "errors": npm ERR! code ELOCKVERIFY npm ERR! Errors were found in your package-lock.json, run npm install to fix them. npm ERR! Missing: c3@^0.6.7 npm ERR! Invalid: lock file's d3@3.5.17 does not satisfy d3@^5.7.0 --- package-lock.json | 345 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 334 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 57e3db6aec21..e11f5aecd756 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5513,6 +5513,14 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "c3": { + "version": "0.6.10", + "resolved": "https://registry.npmjs.org/c3/-/c3-0.6.10.tgz", + "integrity": "sha512-8HjpD1eSma75HI66hLQ+jD5KEvUMhSiiKfovQlyJk+Wxa1ebRL7Smxgu3ybBHkv9khe9m94TJRHpZ9Svcjo40w==", + "requires": { + "d3": "^5.0.0" + } + }, "cacache": { "version": "10.0.4", "resolved": "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", @@ -7192,9 +7200,268 @@ } }, "d3": { - "version": "3.5.17", - "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", - "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=" + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/d3/-/d3-5.7.0.tgz", + "integrity": "sha512-8KEIfx+dFm8PlbJN9PI0suazrZ41QcaAufsKE9PRcqYPWLngHIyWJZX96n6IQKePGgeSu0l7rtlueSSNq8Zc3g==", + "requires": { + "d3-array": "1", + "d3-axis": "1", + "d3-brush": "1", + "d3-chord": "1", + "d3-collection": "1", + "d3-color": "1", + "d3-contour": "1", + "d3-dispatch": "1", + "d3-drag": "1", + "d3-dsv": "1", + "d3-ease": "1", + "d3-fetch": "1", + "d3-force": "1", + "d3-format": "1", + "d3-geo": "1", + "d3-hierarchy": "1", + "d3-interpolate": "1", + "d3-path": "1", + "d3-polygon": "1", + "d3-quadtree": "1", + "d3-random": "1", + "d3-scale": "2", + "d3-scale-chromatic": "1", + "d3-selection": "1", + "d3-shape": "1", + "d3-time": "1", + "d3-time-format": "2", + "d3-timer": "1", + "d3-transition": "1", + "d3-voronoi": "1", + "d3-zoom": "1" + } + }, + "d3-array": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-1.2.4.tgz", + "integrity": "sha512-KHW6M86R+FUPYGb3R5XiYjXPq7VzwxZ22buHhAEVG5ztoEcZZMLov530mmccaqA1GghZArjQV46fuc8kUqhhHw==" + }, + "d3-axis": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-1.0.12.tgz", + "integrity": "sha512-ejINPfPSNdGFKEOAtnBtdkpr24c4d4jsei6Lg98mxf424ivoDP2956/5HDpIAtmHo85lqT4pruy+zEgvRUBqaQ==" + }, + "d3-brush": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-1.0.6.tgz", + "integrity": "sha512-lGSiF5SoSqO5/mYGD5FAeGKKS62JdA1EV7HPrU2b5rTX4qEJJtpjaGLJngjnkewQy7UnGstnFd3168wpf5z76w==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } + }, + "d3-chord": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-1.0.6.tgz", + "integrity": "sha512-JXA2Dro1Fxw9rJe33Uv+Ckr5IrAa74TlfDEhE/jfLOaXegMQFQTAgAw9WnZL8+HxVBRXaRGCkrNU7pJeylRIuA==", + "requires": { + "d3-array": "1", + "d3-path": "1" + } + }, + "d3-collection": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-collection/-/d3-collection-1.0.7.tgz", + "integrity": "sha512-ii0/r5f4sjKNTfh84Di+DpztYwqKhEyUlKoPrzUFfeSkWxjW49xU2QzO9qrPrNkpdI0XJkfzvmTu8V2Zylln6A==" + }, + "d3-color": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.2.3.tgz", + "integrity": "sha512-x37qq3ChOTLd26hnps36lexMRhNXEtVxZ4B25rL0DVdDsGQIJGB18S7y9XDwlDD6MD/ZBzITCf4JjGMM10TZkw==" + }, + "d3-contour": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-1.3.2.tgz", + "integrity": "sha512-hoPp4K/rJCu0ladiH6zmJUEz6+u3lgR+GSm/QdM2BBvDraU39Vr7YdDCicJcxP1z8i9B/2dJLgDC1NcvlF8WCg==", + "requires": { + "d3-array": "^1.1.1" + } + }, + "d3-dispatch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-1.0.5.tgz", + "integrity": "sha512-vwKx+lAqB1UuCeklr6Jh1bvC4SZgbSqbkGBLClItFBIYH4vqDJCA7qfoy14lXmJdnBOdxndAMxjCbImJYW7e6g==" + }, + "d3-drag": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-1.2.3.tgz", + "integrity": "sha512-8S3HWCAg+ilzjJsNtWW1Mutl74Nmzhb9yU6igspilaJzeZVFktmY6oO9xOh5TDk+BM2KrNFjttZNoJJmDnkjkg==", + "requires": { + "d3-dispatch": "1", + "d3-selection": "1" + } + }, + "d3-dsv": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-1.0.10.tgz", + "integrity": "sha512-vqklfpxmtO2ZER3fq/B33R/BIz3A1PV0FaZRuFM8w6jLo7sUX1BZDh73fPlr0s327rzq4H6EN1q9U+eCBCSN8g==", + "requires": { + "commander": "2", + "iconv-lite": "0.4", + "rw": "1" + } + }, + "d3-ease": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-1.0.5.tgz", + "integrity": "sha512-Ct1O//ly5y5lFM9YTdu+ygq7LleSgSE4oj7vUt9tPLHUi8VCV7QoizGpdWRWAwCO9LdYzIrQDg97+hGVdsSGPQ==" + }, + "d3-fetch": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-1.1.2.tgz", + "integrity": "sha512-S2loaQCV/ZeyTyIF2oP8D1K9Z4QizUzW7cWeAOAS4U88qOt3Ucf6GsmgthuYSdyB2HyEm4CeGvkQxWsmInsIVA==", + "requires": { + "d3-dsv": "1" + } + }, + "d3-force": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-1.1.2.tgz", + "integrity": "sha512-p1vcHAUF1qH7yR+e8ip7Bs61AHjLeKkIn8Z2gzwU2lwEf2wkSpWdjXG0axudTHsVFnYGlMkFaEsVy2l8tAg1Gw==", + "requires": { + "d3-collection": "1", + "d3-dispatch": "1", + "d3-quadtree": "1", + "d3-timer": "1" + } + }, + "d3-format": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.3.2.tgz", + "integrity": "sha512-Z18Dprj96ExragQ0DeGi+SYPQ7pPfRMtUXtsg/ChVIKNBCzjO8XYJvRTC1usblx52lqge56V5ect+frYTQc8WQ==" + }, + "d3-geo": { + "version": "1.11.3", + "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-1.11.3.tgz", + "integrity": "sha512-n30yN9qSKREvV2fxcrhmHUdXP9TNH7ZZj3C/qnaoU0cVf/Ea85+yT7HY7i8ySPwkwjCNYtmKqQFTvLFngfkItQ==", + "requires": { + "d3-array": "1" + } + }, + "d3-hierarchy": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-1.1.8.tgz", + "integrity": "sha512-L+GHMSZNwTpiq4rt9GEsNcpLa4M96lXMR8M/nMG9p5hBE0jy6C+3hWtyZMenPQdwla249iJy7Nx0uKt3n+u9+w==" + }, + "d3-interpolate": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.3.2.tgz", + "integrity": "sha512-NlNKGopqaz9qM1PXh9gBF1KSCVh+jSFErrSlD/4hybwoNX/gt1d8CDbDW+3i+5UOHhjC6s6nMvRxcuoMVNgL2w==", + "requires": { + "d3-color": "1" + } + }, + "d3-path": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.7.tgz", + "integrity": "sha512-q0cW1RpvA5c5ma2rch62mX8AYaiLX0+bdaSM2wxSU9tXjU4DNvkx9qiUvjkuWCj3p22UO/hlPivujqMiR9PDzA==" + }, + "d3-polygon": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-1.0.5.tgz", + "integrity": "sha512-RHhh1ZUJZfhgoqzWWuRhzQJvO7LavchhitSTHGu9oj6uuLFzYZVeBzaWTQ2qSO6bz2w55RMoOCf0MsLCDB6e0w==" + }, + "d3-quadtree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-1.0.5.tgz", + "integrity": "sha512-U2tjwDFbZ75JRAg8A+cqMvqPg1G3BE7UTJn3h8DHjY/pnsAfWdbJKgyfcy7zKjqGtLAmI0q8aDSeG1TVIKRaHQ==" + }, + "d3-random": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-1.1.2.tgz", + "integrity": "sha512-6AK5BNpIFqP+cx/sreKzNjWbwZQCSUatxq+pPRmFIQaWuoD+NrbVWw7YWpHiXpCQ/NanKdtGDuB+VQcZDaEmYQ==" + }, + "d3-scale": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-2.1.2.tgz", + "integrity": "sha512-bESpd64ylaKzCDzvULcmHKZTlzA/6DGSVwx7QSDj/EnX9cpSevsdiwdHFYI9ouo9tNBbV3v5xztHS2uFeOzh8Q==", + "requires": { + "d3-array": "^1.2.0", + "d3-collection": "1", + "d3-format": "1", + "d3-interpolate": "1", + "d3-time": "1", + "d3-time-format": "2" + } + }, + "d3-scale-chromatic": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-1.3.3.tgz", + "integrity": "sha512-BWTipif1CimXcYfT02LKjAyItX5gKiwxuPRgr4xM58JwlLocWbjPLI7aMEjkcoOQXMkYsmNsvv3d2yl/OKuHHw==", + "requires": { + "d3-color": "1", + "d3-interpolate": "1" + } + }, + "d3-selection": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-1.3.2.tgz", + "integrity": "sha512-OoXdv1nZ7h2aKMVg3kaUFbLLK5jXUFAMLD/Tu5JA96mjf8f2a9ZUESGY+C36t8R1WFeWk/e55hy54Ml2I62CRQ==" + }, + "d3-shape": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.2.2.tgz", + "integrity": "sha512-hUGEozlKecFZ2bOSNt7ENex+4Tk9uc/m0TtTEHBvitCBxUNjhzm5hS2GrrVRD/ae4IylSmxGeqX5tWC2rASMlQ==", + "requires": { + "d3-path": "1" + } + }, + "d3-time": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.0.10.tgz", + "integrity": "sha512-hF+NTLCaJHF/JqHN5hE8HVGAXPStEq6/omumPE/SxyHVrR7/qQxusFDo0t0c/44+sCGHthC7yNGFZIEgju0P8g==" + }, + "d3-time-format": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.1.3.tgz", + "integrity": "sha512-6k0a2rZryzGm5Ihx+aFMuO1GgelgIz+7HhB4PH4OEndD5q2zGn1mDfRdNrulspOfR6JXkb2sThhDK41CSK85QA==", + "requires": { + "d3-time": "1" + } + }, + "d3-timer": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-1.0.9.tgz", + "integrity": "sha512-rT34J5HnQUHhcLvhSB9GjCkN0Ddd5Y8nCwDBG2u6wQEeYxT/Lf51fTFFkldeib/sE/J0clIe0pnCfs6g/lRbyg==" + }, + "d3-transition": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-1.1.3.tgz", + "integrity": "sha512-tEvo3qOXL6pZ1EzcXxFcPNxC/Ygivu5NoBY6mbzidATAeML86da+JfVIUzon3dNM6UX6zjDx+xbYDmMVtTSjuA==", + "requires": { + "d3-color": "1", + "d3-dispatch": "1", + "d3-ease": "1", + "d3-interpolate": "1", + "d3-selection": "^1.1.0", + "d3-timer": "1" + } + }, + "d3-voronoi": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/d3-voronoi/-/d3-voronoi-1.1.4.tgz", + "integrity": "sha512-dArJ32hchFsrQ8uMiTBLq256MpnZjeuBtdHpaDlYuQyjU0CVzCJl/BVW+SkszaAeH95D/8gxqAhgx0ouAWAfRg==" + }, + "d3-zoom": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-1.7.3.tgz", + "integrity": "sha512-xEBSwFx5Z9T3/VrwDkMt+mr0HCzv7XjpGURJ8lWmIC8wxe32L39eWHIasEe/e7Ox8MPU4p1hvH8PKN2olLzIBg==", + "requires": { + "d3-dispatch": "1", + "d3-drag": "1", + "d3-interpolate": "1", + "d3-selection": "1", + "d3-transition": "1" + } }, "dashdash": { "version": "1.14.1", @@ -7606,6 +7873,13 @@ "plucker": "0.0.0", "through": "^2.3.4", "uniq": "^1.0.0" + }, + "dependencies": { + "d3": { + "version": "3.5.17", + "resolved": "https://registry.npmjs.org/d3/-/d3-3.5.17.tgz", + "integrity": "sha1-vEZ0gAQ3iyGjYMn8fPUjF5B2L7g=" + } } }, "discontinuous-range": { @@ -9423,8 +9697,17 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereumjs-abi": { @@ -9494,8 +9777,17 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereumjs-abi": { @@ -9639,14 +9931,22 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "dev": true, "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9656,7 +9956,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -10228,8 +10527,17 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereum-common": { @@ -14592,6 +14900,17 @@ "merkle-patricia-tree": "^2.1.2", "rustbn.js": "~0.1.1", "safe-buffer": "^5.1.1" + }, + "dependencies": { + "async-eventemitter": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", + "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", + "dev": true, + "requires": { + "async": "^2.4.0" + } + } } }, "pify": { @@ -32791,6 +33110,11 @@ "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.1.1.tgz", "integrity": "sha512-+Xq0RaL+HEErm4vaTUSWq8uq94OuzOu2UR16LowDvj/C8gclDsoYGp8hKpmakKW2dKqL433v2tkf8HCa2za+Eg==" }, + "rw": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz", + "integrity": "sha1-P4Yt+pGrdmsUiF700BEkv9oHT7Q=" + }, "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", @@ -37716,7 +38040,6 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.3.tgz", "integrity": "sha1-yqRDc9yIFayHZ73ba6cwc5ZMqos=", "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2": "*", @@ -37725,7 +38048,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" } } }, From 9beac977d89bb4f9e03a91d5c4392920db9b4a95 Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 11:33:54 -0330 Subject: [PATCH 50/64] circleci: Disable npm audit when installing packages Auditing packages when installing here doesn't help anyone as the summary isn't visible and vulnerabilities don't produce a non-zero exit code. We will have `npm audit` as an extra CI job. --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 22d14476bb90..1e7e8cc98cd4 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -91,7 +91,7 @@ jobs: - run: name: Install npm 6 + deps via npm command: | - sudo npm install -g npm@6 && npm install --no-save + sudo npm install -g npm@6 && npm install --no-save --no-audit - persist_to_workspace: root: . paths: From c7f46f77cab29cc839b8d8bad61bed45e2f415ab Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 11:46:05 -0330 Subject: [PATCH 51/64] npm audit fix --- package-lock.json | 840 +++++++++++++++++++++------------------------- package.json | 4 +- 2 files changed, 392 insertions(+), 452 deletions(-) diff --git a/package-lock.json b/package-lock.json index e11f5aecd756..f9c41b27d0f0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1906,23 +1906,37 @@ } }, "acorn-node": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/acorn-node/-/acorn-node-1.3.0.tgz", - "integrity": "sha512-efP54n3d1aLfjL2UMdaXa6DsswwzJeI5rqhbFvXMrKiJ6eJFpf+7R0zN7t8IC+XKn2YOAFAv6xbBNgHUkoHWLw==", + "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": "^5.4.1", + "acorn": "^6.0.2", + "acorn-dynamic-import": "^4.0.0", + "acorn-walk": "^6.1.0", "xtend": "^4.0.1" }, "dependencies": { "acorn": { - "version": "5.5.3", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz", - "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==", + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.0.4.tgz", + "integrity": "sha512-VY4i5EKSKkofY2I+6QLTbTTN/UvEQPCo6eiwzzSaSWfpaDhOmStMCMod6wmuPciNq+XS0faCglFu2lHZpdHUtg==", + "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-walk": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz", + "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==", + "dev": true + }, "addons-linter": { "version": "1.3.4", "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-1.3.4.tgz", @@ -3176,15 +3190,6 @@ "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=" }, - "astw": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/astw/-/astw-2.2.0.tgz", - "integrity": "sha1-e9QXhNMkk5h66yOba04cV6hzuRc=", - "dev": true, - "requires": { - "acorn": "^4.0.3" - } - }, "async": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/async/-/async-2.6.0.tgz", @@ -5118,9 +5123,9 @@ "dev": true }, "browser-resolve": { - "version": "1.11.2", - "resolved": "https://registry.npmjs.org/browser-resolve/-/browser-resolve-1.11.2.tgz", - "integrity": "sha1-j/CbCixCFxihBRwmCzLkj0QpOM4=", + "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" @@ -5152,9 +5157,9 @@ } }, "browserify": { - "version": "16.1.1", - "resolved": "https://registry.npmjs.org/browserify/-/browserify-16.1.1.tgz", - "integrity": "sha512-iSH21jK0+IApV8YHOfmGt1qsGd74oflQ1Ko/28JOkWLFNBngAQfKb6WYIJ9CufH8vycqKX1sYU3y7ZrVhwevAg==", + "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", @@ -5195,7 +5200,7 @@ "shell-quote": "^1.6.1", "stream-browserify": "^2.0.0", "stream-http": "^2.0.0", - "string_decoder": "~1.0.0", + "string_decoder": "^1.1.1", "subarg": "^1.0.0", "syntax-error": "^1.1.1", "through2": "^2.0.0", @@ -5203,14 +5208,14 @@ "tty-browserify": "0.0.1", "url": "~0.11.0", "util": "~0.10.1", - "vm-browserify": "~0.0.1", + "vm-browserify": "^1.0.0", "xtend": "^4.0.0" }, "dependencies": { "browser-pack": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/browser-pack/-/browser-pack-6.0.4.tgz", - "integrity": "sha512-Q4Rvn7P6ObyWfc4stqLWHtG1MJ8vVtjgT24Zbu+8UTzxYuZouqZsmNRRTFVMY/Ux0eIKv1d+JWzsInTX+fdHPQ==", + "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", @@ -5249,9 +5254,9 @@ } }, "events": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-2.0.0.tgz", - "integrity": "sha512-r/M5YkNg9zwI8QbSf7tsDWWJvO3PGwZXyG7GpFAxtMASnHL2eblFd7iHiGPtyGKKFPZ59S63NeX10Ws6WqGDcg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-2.1.0.tgz", + "integrity": "sha512-3Zmiobend8P9DjmKAty0Era4jV8oJ0yGYe2nJJAxgymF9+N8F2m0hhZiMoWtcfepExzNKZumFU3ksdQbInGWCg==", "dev": true }, "inline-source-map": { @@ -5281,11 +5286,26 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "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" + } + }, "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 + }, + "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 } } }, @@ -5446,9 +5466,9 @@ "integrity": "sha512-SB4/MIGlsiVkMcHmT+pSmIPoNDoHg+7cMzmt3Uxt628MTz2487DKSqK/fuhFBrkuqrYv5UCEnACpF4dTFNKc/g==" }, "buffer": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", - "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", + "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", @@ -5488,6 +5508,12 @@ "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", "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", @@ -5513,6 +5539,25 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, + "bytewise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", + "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=", + "dev": true, + "requires": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "bytewise-core": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", + "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=", + "dev": true, + "requires": { + "typewise-core": "^1.2" + } + }, "c3": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/c3/-/c3-0.6.10.tgz", @@ -5574,9 +5619,9 @@ } }, "cached-path-relative": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cached-path-relative/-/cached-path-relative-1.0.1.tgz", - "integrity": "sha1-0JxLUoAKpMB44t2BqGmqyQ0uVOc=", + "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 }, "caller-path": { @@ -9697,12 +9742,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9777,12 +9823,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9931,12 +9978,14 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "dev": true, "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10527,12 +10576,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -12040,12 +12090,6 @@ "which": "^1.0.5" } }, - "find-index": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/find-index/-/find-index-0.1.1.tgz", - "integrity": "sha1-Z101iyyjiS15Whq0cjL4tuLg3eQ=", - "dev": true - }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -13708,29 +13752,6 @@ "safe-buffer": "^5.0.1" } }, - "bl": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-0.8.2.tgz", - "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=", - "dev": true, - "requires": { - "readable-stream": "~1.0.26" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } - } - }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -13957,25 +13978,6 @@ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, - "bytewise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", - "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=", - "dev": true, - "requires": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } - }, - "bytewise-core": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", - "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=", - "dev": true, - "requires": { - "typewise-core": "^1.2" - } - }, "cachedown": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz", @@ -16162,112 +16164,6 @@ } } }, - "level-post": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz", - "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==", - "dev": true, - "requires": { - "ltgt": "^2.1.2" - } - }, - "level-sublevel": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.2.tgz", - "integrity": "sha512-+hptqmFYPKFju9QG4F6scvx3ZXkhrSmmhYui+hPzRn/jiC3DJ6VNZRKsIhGMpeajVBWfRV7XiysUThrJ/7PgXQ==", - "dev": true, - "requires": { - "bytewise": "~1.1.0", - "levelup": "~0.19.0", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "0.12.4", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", - "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=", - "dev": true, - "requires": { - "xtend": "~3.0.0" - }, - "dependencies": { - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "deferred-leveldown": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz", - "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=", - "dev": true, - "requires": { - "abstract-leveldown": "~0.12.1" - } - }, - "levelup": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.19.1.tgz", - "integrity": "sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs=", - "dev": true, - "requires": { - "bl": "~0.8.1", - "deferred-leveldown": "~0.2.0", - "errno": "~0.1.1", - "prr": "~0.0.0", - "readable-stream": "~1.0.26", - "semver": "~5.1.0", - "xtend": "~3.0.0" - }, - "dependencies": { - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "ltgt": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", - "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", - "dev": true - }, - "prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "semver": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.1.tgz", - "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk=", - "dev": true - } - } - }, "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", @@ -16392,12 +16288,6 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" }, - "looper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", - "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=", - "dev": true - }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -17034,64 +16924,6 @@ "randombytes": "^2.0.1" } }, - "pull-cat": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", - "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=", - "dev": true - }, - "pull-defer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.2.tgz", - "integrity": "sha1-CIew/7MK8ypW2+z6csFnInHwexM=", - "dev": true - }, - "pull-level": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz", - "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==", - "dev": true, - "requires": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" - } - }, - "pull-live": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", - "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=", - "dev": true, - "requires": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } - }, - "pull-pushable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", - "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=", - "dev": true - }, - "pull-stream": { - "version": "3.6.8", - "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.8.tgz", - "integrity": "sha512-wQUIptQBcM0rFsUhZoEpOT3vUn73DtTGVq3NQ86c4T7iMOSprDzeKWYq2ksXnbwiuExTKvt+8G9fzNLFQuiO+A==", - "dev": true - }, - "pull-window": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", - "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=", - "dev": true, - "requires": { - "looper": "^2.0.0" - } - }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -17687,24 +17519,6 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, - "stream-to-pull-stream": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz", - "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=", - "dev": true, - "requires": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" - }, - "dependencies": { - "looper": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", - "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=", - "dev": true - } - } - }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -18061,27 +17875,6 @@ "is-typedarray": "^1.0.0" } }, - "typewise": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", - "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=", - "dev": true, - "requires": { - "typewise-core": "^1.2.0" - } - }, - "typewise-core": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", - "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=", - "dev": true - }, - "typewiselite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz", - "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=", - "dev": true - }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -18836,6 +18629,12 @@ "is-property": "^1.0.0" } }, + "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-caller-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", @@ -19471,15 +19270,6 @@ } } }, - "glob2base": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/glob2base/-/glob2base-0.0.12.tgz", - "integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=", - "dev": true, - "requires": { - "find-index": "^0.1.1" - } - }, "global": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz", @@ -22044,25 +21834,27 @@ "dev": true }, "insert-module-globals": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/insert-module-globals/-/insert-module-globals-7.0.2.tgz", - "integrity": "sha512-p3s7g96Nm62MbHRuj9ZXab0DuJNWD7qcmdUXCOQ/ZZn42DtDXfsLill7bq19lDCx3K3StypqUnuE3H2VmIJFUw==", + "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", - "combine-source-map": "~0.7.1", - "concat-stream": "~1.5.1", + "acorn-node": "^1.5.2", + "combine-source-map": "^0.8.0", + "concat-stream": "^1.6.1", "is-buffer": "^1.1.0", - "lexical-scope": "^1.2.0", + "path-is-absolute": "^1.0.1", "process": "~0.11.0", "through2": "^2.0.0", + "undeclared-identifiers": "^1.1.2", "xtend": "^4.0.0" }, "dependencies": { "combine-source-map": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.7.2.tgz", - "integrity": "sha1-CHAxKFazB6h8xKxIbzqaYq7MwJ4=", + "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", @@ -22072,14 +21864,15 @@ } }, "concat-stream": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.5.2.tgz", - "integrity": "sha1-cIl4Yk2FavQaWnQd790mHadSwmY=", + "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": { - "inherits": "~2.0.1", - "readable-stream": "~2.0.0", - "typedarray": "~0.0.5" + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" } }, "inline-source-map": { @@ -22103,31 +21896,11 @@ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", "dev": true }, - "readable-stream": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", - "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "~1.0.0", - "process-nextick-args": "~1.0.6", - "string_decoder": "~0.10.x", - "util-deprecate": "~1.0.1" - } - }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true } } }, @@ -24107,20 +23880,20 @@ "dev": true }, "labeled-stream-splicer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/labeled-stream-splicer/-/labeled-stream-splicer-2.0.0.tgz", - "integrity": "sha1-pS4dE4AkwAuGscDJH2d5GLiuClk=", + "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": "~0.0.1", + "isarray": "^2.0.4", "stream-splicer": "^2.0.0" }, "dependencies": { "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.4.tgz", + "integrity": "sha512-GMxXOiUirWg1xTKRipM0Ek07rX+ubx4nNVElTJdNLYmNO/2YrDkgJGw9CljXn+r4EWiDQg/8lsRdHyg2PJuUaA==", "dev": true }, "stream-splicer": { @@ -24285,6 +24058,133 @@ } } }, + "level-post": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz", + "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==", + "dev": true, + "requires": { + "ltgt": "^2.1.2" + } + }, + "level-sublevel": { + "version": "6.6.5", + "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.5.tgz", + "integrity": "sha512-SBSR60x+dghhwGUxPKS+BvV1xNqnwsEUBKmnFepPaHJ6VkBXyPK9SImGc3K2BkwBfpxlt7GKkBNlCnrdufsejA==", + "dev": true, + "requires": { + "bytewise": "~1.1.0", + "levelup": "~0.19.0", + "ltgt": "~2.1.1", + "pull-defer": "^0.2.2", + "pull-level": "^2.0.3", + "pull-stream": "^3.6.8", + "typewiselite": "~1.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "0.12.4", + "resolved": "http://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", + "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=", + "dev": true, + "requires": { + "xtend": "~3.0.0" + }, + "dependencies": { + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "bl": { + "version": "0.8.2", + "resolved": "http://registry.npmjs.org/bl/-/bl-0.8.2.tgz", + "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=", + "dev": true, + "requires": { + "readable-stream": "~1.0.26" + } + }, + "deferred-leveldown": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz", + "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=", + "dev": true, + "requires": { + "abstract-leveldown": "~0.12.1" + } + }, + "isarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true + }, + "levelup": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.19.1.tgz", + "integrity": "sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs=", + "dev": true, + "requires": { + "bl": "~0.8.1", + "deferred-leveldown": "~0.2.0", + "errno": "~0.1.1", + "prr": "~0.0.0", + "readable-stream": "~1.0.26", + "semver": "~5.1.0", + "xtend": "~3.0.0" + }, + "dependencies": { + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "ltgt": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", + "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", + "dev": true + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "semver": { + "version": "5.1.1", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.1.1.tgz", + "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk=", + "dev": true + }, + "string_decoder": { + "version": "0.10.31", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true + } + } + }, "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", @@ -24353,15 +24253,6 @@ "type-check": "~0.3.2" } }, - "lexical-scope": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/lexical-scope/-/lexical-scope-1.2.0.tgz", - "integrity": "sha1-/Ope3HBKSzqHls3KQZw6CvryLfQ=", - "dev": true, - "requires": { - "astw": "^2.0.0" - } - }, "lie": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", @@ -24819,6 +24710,12 @@ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, + "looper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", + "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=", + "dev": true + }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -25933,9 +25830,9 @@ "dev": true }, "module-deps": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/module-deps/-/module-deps-6.0.0.tgz", - "integrity": "sha512-BKsMhJJENEM4dTgqq2MDTTHXRHcNUFegoAwlG4HO4VMdUyMcJDKgfgI+MOv6tR5Iv8G3MKZFgsSiyP3ZoosRMw==", + "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", @@ -29324,85 +29221,32 @@ "dev": true }, "png-file-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/png-file-stream/-/png-file-stream-1.0.0.tgz", - "integrity": "sha1-4IPQ/lbgl6XL0NNBoThzeQUsrTU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/png-file-stream/-/png-file-stream-1.1.0.tgz", + "integrity": "sha512-uZuSd4yuLXik2H/XqR+7hcGU30nCeBHhPsejR8JA91oKom57aeL379hO5ZJ4SS1Nujk/hDUN0VE8UiT+FuwNZg==", "dev": true, "requires": { - "glob-stream": "~3.1.9", + "glob-stream": "^6.1.0", "png-js": "~0.1.1", "through2": "~0.2.3" }, "dependencies": { - "glob": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz", - "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^2.0.1", - "once": "^1.3.0" - } - }, - "glob-stream": { - "version": "3.1.18", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-3.1.18.tgz", - "integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=", - "dev": true, - "requires": { - "glob": "^4.3.1", - "glob2base": "^0.0.12", - "minimatch": "^2.0.1", - "ordered-read-streams": "^0.1.0", - "through2": "^0.6.1", - "unique-stream": "^1.0.0" - }, - "dependencies": { - "through2": { - "version": "0.6.5", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", "dev": true }, - "minimatch": { - "version": "2.0.10", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz", - "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=", - "dev": true, - "requires": { - "brace-expansion": "^1.0.0" - } - }, "object-keys": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", "dev": true }, - "ordered-read-streams": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.1.0.tgz", - "integrity": "sha1-/VZamvjrRHO6abbtijQ1LLVS8SY=", - "dev": true - }, "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "version": "1.1.14", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -29413,7 +29257,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, @@ -29425,36 +29269,16 @@ "requires": { "readable-stream": "~1.1.9", "xtend": "~2.1.1" - }, - "dependencies": { - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } } }, - "unique-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-1.0.0.tgz", - "integrity": "sha1-1ZpKdUJ0R9mqbJHnAmP40mpLEEs=", - "dev": true + "xtend": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", + "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", + "dev": true, + "requires": { + "object-keys": "~0.4.0" + } } } }, @@ -31254,6 +31078,64 @@ "randombytes": "^2.0.1" } }, + "pull-cat": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", + "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=", + "dev": true + }, + "pull-defer": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz", + "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==", + "dev": true + }, + "pull-level": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz", + "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==", + "dev": true, + "requires": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "pull-live": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", + "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=", + "dev": true, + "requires": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "pull-pushable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", + "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=", + "dev": true + }, + "pull-stream": { + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.9.tgz", + "integrity": "sha512-hJn4POeBrkttshdNl0AoSCVjMVSuBwuHocMerUdoZ2+oIUzrWHFTwJMlbHND7OiKLVgvz6TFj8ZUVywUMXccbw==", + "dev": true + }, + "pull-window": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", + "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=", + "dev": true, + "requires": { + "looper": "^2.0.0" + } + }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -33833,6 +33715,12 @@ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=" }, + "simple-concat": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", + "integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY=", + "dev": true + }, "sinon": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/sinon/-/sinon-5.0.0.tgz", @@ -35317,6 +35205,24 @@ } } }, + "stream-to-pull-stream": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz", + "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=", + "dev": true, + "requires": { + "looper": "^3.0.0", + "pull-stream": "^3.2.3" + }, + "dependencies": { + "looper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", + "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=", + "dev": true + } + } + }, "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", @@ -37070,6 +36976,27 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, + "typewise": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", + "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=", + "dev": true, + "requires": { + "typewise-core": "^1.2.0" + } + }, + "typewise-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", + "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=", + "dev": true + }, + "typewiselite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz", + "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=", + "dev": true + }, "ua-parser-js": { "version": "0.7.17", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", @@ -37232,6 +37159,18 @@ "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" }, + "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" + } + }, "undefsafe": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.2.tgz", @@ -38040,6 +37979,7 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.3.tgz", "integrity": "sha1-yqRDc9yIFayHZ73ba6cwc5ZMqos=", "requires": { + "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2": "*", @@ -38048,7 +37988,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" } } }, diff --git a/package.json b/package.json index 5e5b9e893869..b4bd14537eca 100644 --- a/package.json +++ b/package.json @@ -248,7 +248,7 @@ "babelify": "^8.0.0", "beefy": "^2.1.5", "brfs": "^1.6.1", - "browserify": "^16.1.1", + "browserify": "^16.2.3", "chai": "^4.1.0", "chromedriver": "^2.41.0", "clipboardy": "^1.2.3", @@ -312,7 +312,7 @@ "nyc": "^13.0.0", "open": "0.0.5", "path": "^0.12.7", - "png-file-stream": "^1.0.0", + "png-file-stream": "^1.1.0", "prepend-file": "^1.3.1", "prompt": "^1.0.0", "proxyquire": "2.0.1", From c804185081bed076e2b29936370c14bf2a61f09d Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 11:47:40 -0330 Subject: [PATCH 52/64] circleci: Replace nsp with npm audit Refs #4751 --- .circleci/config.yml | 2 +- .nsprc | 7 - package-lock.json | 844 ++++++++++++++----------------------------- package.json | 1 - 4 files changed, 264 insertions(+), 590 deletions(-) delete mode 100644 .nsprc diff --git a/.circleci/config.yml b/.circleci/config.yml index 1e7e8cc98cd4..d89a6ef4cb43 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -174,7 +174,7 @@ jobs: at: . - run: name: Test - command: npx nsp check + command: sudo npm install -g npm@6 && npm audit test-e2e-beta-drizzle: docker: diff --git a/.nsprc b/.nsprc deleted file mode 100644 index bd3a4f039712..000000000000 --- a/.nsprc +++ /dev/null @@ -1,7 +0,0 @@ -{ - "exceptions": [ - "https://nodesecurity.io/advisories/566", - "https://nodesecurity.io/advisories/157", - "https://nodesecurity.io/advisories/577" - ] -} diff --git a/package-lock.json b/package-lock.json index f9c41b27d0f0..481b7927fc16 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5539,25 +5539,6 @@ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=" }, - "bytewise": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", - "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=", - "dev": true, - "requires": { - "bytewise-core": "^1.2.2", - "typewise": "^1.0.3" - } - }, - "bytewise-core": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", - "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=", - "dev": true, - "requires": { - "typewise-core": "^1.2" - } - }, "c3": { "version": "0.6.10", "resolved": "https://registry.npmjs.org/c3/-/c3-0.6.10.tgz", @@ -6014,32 +5995,6 @@ "restore-cursor": "^2.0.0" } }, - "cli-table2": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/cli-table2/-/cli-table2-0.2.0.tgz", - "integrity": "sha1-LR738hig54biFFQFYtS9F3/jLZc=", - "dev": true, - "requires": { - "colors": "^1.1.2", - "lodash": "^3.10.1", - "string-width": "^1.0.1" - }, - "dependencies": { - "colors": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.2.3.tgz", - "integrity": "sha512-qTfM2pNFeMZcLvf/RbrVAzDEVttZjFhaApfx9dplNjvHSX88Ui66zBRb/4YGob/xUWxDceirgoC1lT676asfCQ==", - "dev": true, - "optional": true - }, - "lodash": { - "version": "3.10.1", - "resolved": "http://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz", - "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=", - "dev": true - } - } - }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", @@ -7218,12 +7173,6 @@ "integrity": "sha1-XQKkaFCt8bSjF5RqOSj8y1v9BCU=", "dev": true }, - "cvss": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cvss/-/cvss-1.0.2.tgz", - "integrity": "sha1-32fpK/EqeW9J6Sh5nI2zunS5/NY=", - "dev": true - }, "cycle": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/cycle/-/cycle-1.0.3.tgz", @@ -13752,6 +13701,29 @@ "safe-buffer": "^5.0.1" } }, + "bl": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-0.8.2.tgz", + "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=", + "dev": true, + "requires": { + "readable-stream": "~1.0.26" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + } + } + }, "block-stream": { "version": "0.0.9", "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", @@ -13978,6 +13950,25 @@ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", "dev": true }, + "bytewise": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/bytewise/-/bytewise-1.1.0.tgz", + "integrity": "sha1-HRPL/3F65xWAlKqIGzXQgbOHJT4=", + "dev": true, + "requires": { + "bytewise-core": "^1.2.2", + "typewise": "^1.0.3" + } + }, + "bytewise-core": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/bytewise-core/-/bytewise-core-1.2.3.tgz", + "integrity": "sha1-P7QQx+kVWOsasiqCg0V3qmvWHUI=", + "dev": true, + "requires": { + "typewise-core": "^1.2" + } + }, "cachedown": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cachedown/-/cachedown-1.0.0.tgz", @@ -14902,17 +14893,6 @@ "merkle-patricia-tree": "^2.1.2", "rustbn.js": "~0.1.1", "safe-buffer": "^5.1.1" - }, - "dependencies": { - "async-eventemitter": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/async-eventemitter/-/async-eventemitter-0.2.4.tgz", - "integrity": "sha512-pd20BwL7Yt1zwDFy+8MX8F1+WCT8aQeKj0kQnTrH9WaeRETlRamVhD0JtRPmrV4GfOJ2F9CvdQkZeZhnh2TuHw==", - "dev": true, - "requires": { - "async": "^2.4.0" - } - } } }, "pify": { @@ -16164,6 +16144,112 @@ } } }, + "level-post": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz", + "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==", + "dev": true, + "requires": { + "ltgt": "^2.1.2" + } + }, + "level-sublevel": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.2.tgz", + "integrity": "sha512-+hptqmFYPKFju9QG4F6scvx3ZXkhrSmmhYui+hPzRn/jiC3DJ6VNZRKsIhGMpeajVBWfRV7XiysUThrJ/7PgXQ==", + "dev": true, + "requires": { + "bytewise": "~1.1.0", + "levelup": "~0.19.0", + "ltgt": "~2.1.1", + "pull-defer": "^0.2.2", + "pull-level": "^2.0.3", + "pull-stream": "^3.6.8", + "typewiselite": "~1.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", + "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=", + "dev": true, + "requires": { + "xtend": "~3.0.0" + }, + "dependencies": { + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "deferred-leveldown": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz", + "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=", + "dev": true, + "requires": { + "abstract-leveldown": "~0.12.1" + } + }, + "levelup": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.19.1.tgz", + "integrity": "sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs=", + "dev": true, + "requires": { + "bl": "~0.8.1", + "deferred-leveldown": "~0.2.0", + "errno": "~0.1.1", + "prr": "~0.0.0", + "readable-stream": "~1.0.26", + "semver": "~5.1.0", + "xtend": "~3.0.0" + }, + "dependencies": { + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", + "dev": true + } + } + }, + "ltgt": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", + "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", + "dev": true + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", + "dev": true + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.1", + "isarray": "0.0.1", + "string_decoder": "~0.10.x" + } + }, + "semver": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.1.tgz", + "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk=", + "dev": true + } + } + }, "level-ws": { "version": "0.0.0", "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", @@ -16288,6 +16374,12 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" }, + "looper": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", + "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=", + "dev": true + }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -16924,6 +17016,64 @@ "randombytes": "^2.0.1" } }, + "pull-cat": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", + "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=", + "dev": true + }, + "pull-defer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.2.tgz", + "integrity": "sha1-CIew/7MK8ypW2+z6csFnInHwexM=", + "dev": true + }, + "pull-level": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz", + "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==", + "dev": true, + "requires": { + "level-post": "^1.0.7", + "pull-cat": "^1.1.9", + "pull-live": "^1.0.1", + "pull-pushable": "^2.0.0", + "pull-stream": "^3.4.0", + "pull-window": "^2.1.4", + "stream-to-pull-stream": "^1.7.1" + } + }, + "pull-live": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", + "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=", + "dev": true, + "requires": { + "pull-cat": "^1.1.9", + "pull-stream": "^3.4.0" + } + }, + "pull-pushable": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", + "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=", + "dev": true + }, + "pull-stream": { + "version": "3.6.8", + "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.8.tgz", + "integrity": "sha512-wQUIptQBcM0rFsUhZoEpOT3vUn73DtTGVq3NQ86c4T7iMOSprDzeKWYq2ksXnbwiuExTKvt+8G9fzNLFQuiO+A==", + "dev": true + }, + "pull-window": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", + "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=", + "dev": true, + "requires": { + "looper": "^2.0.0" + } + }, "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", @@ -17519,6 +17669,24 @@ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", "dev": true }, + "stream-to-pull-stream": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz", + "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=", + "dev": true, + "requires": { + "looper": "^3.0.0", + "pull-stream": "^3.2.3" + }, + "dependencies": { + "looper": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", + "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=", + "dev": true + } + } + }, "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", @@ -17875,6 +18043,27 @@ "is-typedarray": "^1.0.0" } }, + "typewise": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", + "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=", + "dev": true, + "requires": { + "typewise-core": "^1.2.0" + } + }, + "typewise-core": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", + "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=", + "dev": true + }, + "typewiselite": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz", + "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=", + "dev": true + }, "ultron": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz", @@ -24058,151 +24247,24 @@ } } }, - "level-post": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/level-post/-/level-post-1.0.7.tgz", - "integrity": "sha512-PWYqG4Q00asOrLhX7BejSajByB4EmG2GaKHfj3h5UmmZ2duciXLPGYWIjBzLECFWUGOZWlm5B20h/n3Gs3HKew==", - "dev": true, - "requires": { - "ltgt": "^2.1.2" - } - }, - "level-sublevel": { - "version": "6.6.5", - "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.5.tgz", - "integrity": "sha512-SBSR60x+dghhwGUxPKS+BvV1xNqnwsEUBKmnFepPaHJ6VkBXyPK9SImGc3K2BkwBfpxlt7GKkBNlCnrdufsejA==", - "dev": true, + "level-ws": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", + "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", "requires": { - "bytewise": "~1.1.0", - "levelup": "~0.19.0", - "ltgt": "~2.1.1", - "pull-defer": "^0.2.2", - "pull-level": "^2.0.3", - "pull-stream": "^3.6.8", - "typewiselite": "~1.0.0", - "xtend": "~4.0.0" + "readable-stream": "~1.0.15", + "xtend": "~2.1.1" }, "dependencies": { - "abstract-leveldown": { - "version": "0.12.4", - "resolved": "http://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", - "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=", - "dev": true, - "requires": { - "xtend": "~3.0.0" - }, - "dependencies": { - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "bl": { - "version": "0.8.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-0.8.2.tgz", - "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=", - "dev": true, - "requires": { - "readable-stream": "~1.0.26" - } - }, - "deferred-leveldown": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz", - "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=", - "dev": true, - "requires": { - "abstract-leveldown": "~0.12.1" - } - }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "levelup": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.19.1.tgz", - "integrity": "sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs=", - "dev": true, - "requires": { - "bl": "~0.8.1", - "deferred-leveldown": "~0.2.0", - "errno": "~0.1.1", - "prr": "~0.0.0", - "readable-stream": "~1.0.26", - "semver": "~5.1.0", - "xtend": "~3.0.0" - }, - "dependencies": { - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "ltgt": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", - "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, - "prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "semver": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/semver/-/semver-5.1.1.tgz", - "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, - "level-ws": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/level-ws/-/level-ws-0.0.0.tgz", - "integrity": "sha1-Ny5RIXeSSgBCSwtDrvK7QkltIos=", - "requires": { - "readable-stream": "~1.0.15", - "xtend": "~2.1.1" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" + "object-keys": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", + "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=" }, "readable-stream": { "version": "1.0.34", @@ -24710,12 +24772,6 @@ "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz", "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=" }, - "looper": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", - "integrity": "sha1-Zs0Md0rz1P7axTeU90LbVtqPCew=", - "dev": true - }, "loose-envify": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", @@ -26527,12 +26583,6 @@ "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", "dev": true }, - "nodesecurity-npm-utils": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nodesecurity-npm-utils/-/nodesecurity-npm-utils-6.0.0.tgz", - "integrity": "sha512-NLRle1woNaT2orR6fue2jNqkhxDTktgJj3sZxvR/8kp21pvOY7Gwlx5wvo0H8ZVPqdgd2nE2ADB9wDu5Cl8zNg==", - "dev": true - }, "nomnom": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.6.2.tgz", @@ -26630,250 +26680,6 @@ "set-blocking": "~2.0.0" } }, - "nsp": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/nsp/-/nsp-3.2.1.tgz", - "integrity": "sha512-dLmGi7IGixJEHKetErIH460MYiYIzAoxuVsloZFu9e1p9U8K0yULx7YQ1+VzrjZbB+wqq67ES1SfOvKVb/qMDQ==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "cli-table2": "^0.2.0", - "cvss": "^1.0.2", - "https-proxy-agent": "^2.1.0", - "inquirer": "^3.3.0", - "nodesecurity-npm-utils": "^6.0.0", - "semver": "^5.4.1", - "wreck": "^12.5.1", - "yargs": "^9.0.1" - }, - "dependencies": { - "agent-base": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.0.tgz", - "integrity": "sha512-c+R/U5X+2zz2+UCrCFv6odQzJdoqI+YecuhnAJLa1zYaMc13zPfwMwZrr91Pd1DYNo/yPRbiM4WVf9whgwFsIg==", - "dev": true, - "requires": { - "es6-promisify": "^5.0.0" - } - }, - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "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" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "load-json-file": { - "version": "2.0.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", - "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^2.2.0", - "pify": "^2.0.0", - "strip-bom": "^3.0.0" - } - }, - "os-locale": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz", - "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==", - "dev": true, - "requires": { - "execa": "^0.7.0", - "lcid": "^1.0.0", - "mem": "^1.1.0" - } - }, - "path-type": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", - "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", - "dev": true, - "requires": { - "pify": "^2.0.0" - } - }, - "pify": { - "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - }, - "read-pkg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", - "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", - "dev": true, - "requires": { - "load-json-file": "^2.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^2.0.0" - } - }, - "read-pkg-up": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", - "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^2.0.0" - } - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - } - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, - "supports-color": { - "version": "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" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "yargs": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-9.0.1.tgz", - "integrity": "sha1-UqzCP+7Kw0BCB47njAwAf1CF20w=", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "os-locale": "^2.0.0", - "read-pkg-up": "^2.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1", - "yargs-parser": "^7.0.0" - } - }, - "yargs-parser": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-7.0.0.tgz", - "integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, "nth-check": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz", @@ -29257,7 +29063,7 @@ }, "string_decoder": { "version": "0.10.31", - "resolved": "http://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", "dev": true }, @@ -31078,64 +30884,6 @@ "randombytes": "^2.0.1" } }, - "pull-cat": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/pull-cat/-/pull-cat-1.1.11.tgz", - "integrity": "sha1-tkLdElXaN2pwa220+pYvX9t0wxs=", - "dev": true - }, - "pull-defer": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz", - "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==", - "dev": true - }, - "pull-level": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/pull-level/-/pull-level-2.0.4.tgz", - "integrity": "sha512-fW6pljDeUThpq5KXwKbRG3X7Ogk3vc75d5OQU/TvXXui65ykm+Bn+fiktg+MOx2jJ85cd+sheufPL+rw9QSVZg==", - "dev": true, - "requires": { - "level-post": "^1.0.7", - "pull-cat": "^1.1.9", - "pull-live": "^1.0.1", - "pull-pushable": "^2.0.0", - "pull-stream": "^3.4.0", - "pull-window": "^2.1.4", - "stream-to-pull-stream": "^1.7.1" - } - }, - "pull-live": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/pull-live/-/pull-live-1.0.1.tgz", - "integrity": "sha1-pOzuAeMwFV6RJLu89HYfIbOPUfU=", - "dev": true, - "requires": { - "pull-cat": "^1.1.9", - "pull-stream": "^3.4.0" - } - }, - "pull-pushable": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pull-pushable/-/pull-pushable-2.2.0.tgz", - "integrity": "sha1-Xy867UethpGfAbEqLpnW8b13ZYE=", - "dev": true - }, - "pull-stream": { - "version": "3.6.9", - "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.9.tgz", - "integrity": "sha512-hJn4POeBrkttshdNl0AoSCVjMVSuBwuHocMerUdoZ2+oIUzrWHFTwJMlbHND7OiKLVgvz6TFj8ZUVywUMXccbw==", - "dev": true - }, - "pull-window": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/pull-window/-/pull-window-2.1.4.tgz", - "integrity": "sha1-/DuG/uvRkgx64pdpHiP3BfiFUvA=", - "dev": true, - "requires": { - "looper": "^2.0.0" - } - }, "pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -35205,24 +34953,6 @@ } } }, - "stream-to-pull-stream": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/stream-to-pull-stream/-/stream-to-pull-stream-1.7.2.tgz", - "integrity": "sha1-dXYJrhzr0zx0MtSvvjH/eGULnd4=", - "dev": true, - "requires": { - "looper": "^3.0.0", - "pull-stream": "^3.2.3" - }, - "dependencies": { - "looper": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/looper/-/looper-3.0.0.tgz", - "integrity": "sha1-LvpUw7HLq6m5Su4uWRSwvlf7t0k=", - "dev": true - } - } - }, "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", @@ -36976,27 +36706,6 @@ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=" }, - "typewise": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/typewise/-/typewise-1.0.3.tgz", - "integrity": "sha1-EGeTZUCvl5N8xdz5kiSG6fooRlE=", - "dev": true, - "requires": { - "typewise-core": "^1.2.0" - } - }, - "typewise-core": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/typewise-core/-/typewise-core-1.2.0.tgz", - "integrity": "sha1-l+uRgFx/VdL5QXSPpQ0xXZke8ZU=", - "dev": true - }, - "typewiselite": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/typewiselite/-/typewiselite-1.0.0.tgz", - "integrity": "sha1-yIgvobsQksBgBal/NO9chQjjZk4=", - "dev": true - }, "ua-parser-js": { "version": "0.7.17", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.17.tgz", @@ -38340,33 +38049,6 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, - "wreck": { - "version": "12.5.1", - "resolved": "https://registry.npmjs.org/wreck/-/wreck-12.5.1.tgz", - "integrity": "sha512-l5DUGrc+yDyIflpty1x9XuMj1ehVjC/dTbF3/BasOO77xk0EdEa4M/DuOY8W88MQDAD0fEDqyjc8bkIMHd2E9A==", - "dev": true, - "requires": { - "boom": "5.x.x", - "hoek": "4.x.x" - }, - "dependencies": { - "boom": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz", - "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==", - "dev": true, - "requires": { - "hoek": "4.x.x" - } - }, - "hoek": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.1.tgz", - "integrity": "sha512-QLg82fGkfnJ/4iy1xZ81/9SIJiq1NGFUMGs6ParyjBZr6jW2Ufj/snDqTHixNlHdPNwN2RLVD0Pi3igeK9+JfA==", - "dev": true - } - } - }, "write": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", diff --git a/package.json b/package.json index b4bd14537eca..2dd35ac7c777 100644 --- a/package.json +++ b/package.json @@ -308,7 +308,6 @@ "mocha-sinon": "^2.0.0", "nock": "^9.0.14", "node-sass": "^4.9.2", - "nsp": "^3.2.1", "nyc": "^13.0.0", "open": "0.0.5", "path": "^0.12.7", From b6789a6e2fd9168e0bf8d386611d4c439ccd9e18 Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 11:56:54 -0330 Subject: [PATCH 53/64] Remove beefy dependency and its usages Refs #4768 Refs #5389 This changeset removes the beefy package that: 1. Was last published 2 yrs ago 2. Brought with it 1 moderate and 1 critical vulnerability 3. Was only used in scripts that no longer work --- development/beefy.js | 16 -- package-lock.json | 499 ++----------------------------------------- package.json | 3 - 3 files changed, 14 insertions(+), 504 deletions(-) delete mode 100644 development/beefy.js diff --git a/development/beefy.js b/development/beefy.js deleted file mode 100644 index c1c436cb69fb..000000000000 --- a/development/beefy.js +++ /dev/null @@ -1,16 +0,0 @@ -const beefy = require('beefy') -const http = require('http') -const port = 8124 - -const handler = beefy({ - entries: {'mocker.js': 'bundle.js'}, - cwd: __dirname, - live: true, - open: true, - quiet: false, - bundlerFlags: ['-t', 'brfs'], -}) - - -http.createServer(handler).listen(port) -console.log(`Now listening on port ${port}`) diff --git a/package-lock.json b/package-lock.json index 481b7927fc16..d1b73b29b8f1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4755,109 +4755,6 @@ "tweetnacl": "^0.14.3" } }, - "beefy": { - "version": "2.1.8", - "resolved": "https://registry.npmjs.org/beefy/-/beefy-2.1.8.tgz", - "integrity": "sha1-e8Ebmkh6mjRnnYXinTtS83T9ACk=", - "dev": true, - "requires": { - "ansicolors": "~0.3.2", - "chokidar": "^1.0.0", - "concat-stream": "^1.4.3", - "find-global-packages": "0.0.1", - "ignorepatterns": "^1.0.1", - "leftpad": "0.0.0", - "mime": "~1.2.9", - "minimist": "0.0.8", - "open": "0.0.3", - "portfinder": "~0.2.1", - "pretty-bytes": "~0.1.0", - "readable-stream": "^1.0.27-1", - "resolve": "^0.6.1", - "response-stream": "0.0.0", - "script-injector": "~1.0.0", - "through": "~2.2.0", - "which": "~1.0.5", - "xtend": "~2.1.2" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "mime": { - "version": "1.2.11", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.2.11.tgz", - "integrity": "sha1-WCA+7Ybjpe8XrtK32evUfwpg3RA=", - "dev": true - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, - "open": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/open/-/open-0.0.3.tgz", - "integrity": "sha1-+jd/T/MIIS2SqbjmOVJAhUZGpxM=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "resolve": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-0.6.3.tgz", - "integrity": "sha1-3ZV5gufnNt699TtYpN2RdUV13UY=", - "dev": true - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through": { - "version": "2.2.7", - "resolved": "http://registry.npmjs.org/through/-/through-2.2.7.tgz", - "integrity": "sha1-bo4hIAGR1OtqmfbwEN9Gqhxusr0=", - "dev": true - }, - "which": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/which/-/which-1.0.9.tgz", - "integrity": "sha1-RgwdoPgQED0DIam2M6+eV15kSG8=", - "dev": true - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, "beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", @@ -7007,15 +6904,6 @@ "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=", "dev": true }, - "cssauron": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/cssauron/-/cssauron-1.4.0.tgz", - "integrity": "sha1-pmAt/34EqDBtwNuaVR6S6LVmKtg=", - "dev": true, - "requires": { - "through": "X.X.X" - } - }, "cssesc": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", @@ -12030,15 +11918,6 @@ } } }, - "find-global-packages": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/find-global-packages/-/find-global-packages-0.0.1.tgz", - "integrity": "sha1-S6f9/xfun6fagzCV94tejNvfPis=", - "dev": true, - "requires": { - "which": "^1.0.5" - } - }, "find-up": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz", @@ -13703,7 +13582,7 @@ }, "bl": { "version": "0.8.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-0.8.2.tgz", + "resolved": "http://registry.npmjs.org/bl/-/bl-0.8.2.tgz", "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=", "dev": true, "requires": { @@ -13712,7 +13591,7 @@ "dependencies": { "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -16154,9 +16033,9 @@ } }, "level-sublevel": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.2.tgz", - "integrity": "sha512-+hptqmFYPKFju9QG4F6scvx3ZXkhrSmmhYui+hPzRn/jiC3DJ6VNZRKsIhGMpeajVBWfRV7XiysUThrJ/7PgXQ==", + "version": "6.6.5", + "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.5.tgz", + "integrity": "sha512-SBSR60x+dghhwGUxPKS+BvV1xNqnwsEUBKmnFepPaHJ6VkBXyPK9SImGc3K2BkwBfpxlt7GKkBNlCnrdufsejA==", "dev": true, "requires": { "bytewise": "~1.1.0", @@ -16171,7 +16050,7 @@ "dependencies": { "abstract-leveldown": { "version": "0.12.4", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", + "resolved": "http://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=", "dev": true, "requires": { @@ -16232,7 +16111,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -16244,7 +16123,7 @@ }, "semver": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.1.tgz", + "resolved": "http://registry.npmjs.org/semver/-/semver-5.1.1.tgz", "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk=", "dev": true } @@ -17023,9 +16902,9 @@ "dev": true }, "pull-defer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.2.tgz", - "integrity": "sha1-CIew/7MK8ypW2+z6csFnInHwexM=", + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/pull-defer/-/pull-defer-0.2.3.tgz", + "integrity": "sha512-/An3KE7mVjZCqNhZsr22k1Tx8MACnUnHZZNPSJ0S62td8JtYr/AiRG42Vz7Syu31SoTLUzVIe61jtT/pNdjVYA==", "dev": true }, "pull-level": { @@ -17060,9 +16939,9 @@ "dev": true }, "pull-stream": { - "version": "3.6.8", - "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.8.tgz", - "integrity": "sha512-wQUIptQBcM0rFsUhZoEpOT3vUn73DtTGVq3NQ86c4T7iMOSprDzeKWYq2ksXnbwiuExTKvt+8G9fzNLFQuiO+A==", + "version": "3.6.9", + "resolved": "https://registry.npmjs.org/pull-stream/-/pull-stream-3.6.9.tgz", + "integrity": "sha512-hJn4POeBrkttshdNl0AoSCVjMVSuBwuHocMerUdoZ2+oIUzrWHFTwJMlbHND7OiKLVgvz6TFj8ZUVywUMXccbw==", "dev": true }, "pull-window": { @@ -21321,64 +21200,6 @@ } } }, - "html-select": { - "version": "2.3.24", - "resolved": "https://registry.npmjs.org/html-select/-/html-select-2.3.24.tgz", - "integrity": "sha1-Rq1tcS5zLPMcZznV0BEKX6vxdYU=", - "dev": true, - "requires": { - "cssauron": "^1.1.0", - "duplexer2": "~0.0.2", - "inherits": "^2.0.1", - "minimist": "~0.0.8", - "readable-stream": "^1.0.27-1", - "split": "~0.3.0", - "stream-splicer": "^1.2.0", - "through2": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/through2/-/through2-1.1.1.tgz", - "integrity": "sha1-CEfLxESfNAVXTb3M2buEG4OsNUU=", - "dev": true, - "requires": { - "readable-stream": ">=1.1.13-1 <1.2.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, "html-tag-names": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/html-tag-names/-/html-tag-names-1.1.3.tgz", @@ -21391,75 +21212,6 @@ "integrity": "sha1-ELMKOGCF9Dzt41PMj6fLDe7qZos=", "dev": true }, - "html-tokenize": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/html-tokenize/-/html-tokenize-1.2.5.tgz", - "integrity": "sha1-flupnstR75Buyaf83ubKMmfHiX4=", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "minimist": "~0.0.8", - "readable-stream": "~1.0.27-1", - "through2": "~0.4.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 - }, - "minimist": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", - "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=", - "dev": true - }, - "object-keys": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz", - "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.4.2", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.4.2.tgz", - "integrity": "sha1-2/WGYDEVHsg1K7bE22SiKSqEC5s=", - "dev": true, - "requires": { - "readable-stream": "~1.0.17", - "xtend": "~2.1.1" - } - }, - "xtend": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz", - "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=", - "dev": true, - "requires": { - "object-keys": "~0.4.0" - } - } - } - }, "html-webpack-plugin": { "version": "2.30.1", "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-2.30.1.tgz", @@ -21822,12 +21574,6 @@ "minimatch": "^3.0.4" } }, - "ignorepatterns": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ignorepatterns/-/ignorepatterns-1.1.0.tgz", - "integrity": "sha1-rI9DbyI5td+2bV8NOpBKh6xnzF4=", - "dev": true - }, "image-size": { "version": "0.6.2", "resolved": "https://registry.npmjs.org/image-size/-/image-size-0.6.2.tgz", @@ -24194,12 +23940,6 @@ "integrity": "sha1-0wpzxrggHY99jnlWupYWCHpo4O4=", "dev": true }, - "leftpad": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/leftpad/-/leftpad-0.0.0.tgz", - "integrity": "sha1-Agya0HhyFroPMNedR5tLNV19OcM=", - "dev": true - }, "level-codec": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", @@ -29163,23 +28903,6 @@ "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.12.9.tgz", "integrity": "sha1-DfvC3/lsRRuzMu3Pz6r1ZtMx1bM=" }, - "portfinder": { - "version": "0.2.1", - "resolved": "http://registry.npmjs.org/portfinder/-/portfinder-0.2.1.tgz", - "integrity": "sha1-srmwFk+eF/o6nH2yME0KdRQMca0=", - "dev": true, - "requires": { - "mkdirp": "0.0.x" - }, - "dependencies": { - "mkdirp": { - "version": "0.0.7", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.0.7.tgz", - "integrity": "sha1-2JtPDkw+XlylQjWTFnXglP4aUHI=", - "dev": true - } - } - }, "posix-character-classes": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", @@ -30649,12 +30372,6 @@ "resolved": "https://registry.npmjs.org/preserve/-/preserve-0.2.0.tgz", "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=" }, - "pretty-bytes": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-0.1.2.tgz", - "integrity": "sha1-zZApTVihyk6KXQ+5yCJZmIgazwA=", - "dev": true - }, "pretty-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", @@ -31911,41 +31628,6 @@ "util-deprecate": "~1.0.1" } }, - "readable-wrap": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/readable-wrap/-/readable-wrap-1.0.0.tgz", - "integrity": "sha1-O1ohHGMeEjA6VJkcgGwX564ga/8=", - "dev": true, - "requires": { - "readable-stream": "^1.1.13-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 - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - } - } - }, "readdirp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.1.0.tgz", @@ -32606,12 +32288,6 @@ } } }, - "response-stream": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/response-stream/-/response-stream-0.0.0.tgz", - "integrity": "sha1-2ksXzHaEyYyWK+tNlfZoyNytCdU=", - "dev": true - }, "restore-cursor": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", @@ -32957,53 +32633,6 @@ } } }, - "script-injector": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/script-injector/-/script-injector-1.0.0.tgz", - "integrity": "sha1-9vTH9qXcxZ4IJG52vfyDoKFAaSY=", - "dev": true, - "requires": { - "duplexer2": "0.0.2", - "through2": "^0.6.5", - "trumpet": "^1.7.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 - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "0.6.5", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", - "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", - "dev": true, - "requires": { - "readable-stream": ">=1.0.33-1 <1.1.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, "scroll": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/scroll/-/scroll-2.0.3.tgz", @@ -34903,56 +34532,6 @@ "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=" }, - "stream-splicer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stream-splicer/-/stream-splicer-1.3.2.tgz", - "integrity": "sha1-PARBvhW5v04iYnXm3IOWR0VUZmE=", - "dev": true, - "requires": { - "indexof": "0.0.1", - "inherits": "^2.0.1", - "isarray": "~0.0.1", - "readable-stream": "^1.1.13-1", - "readable-wrap": "^1.0.0", - "through2": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/through2/-/through2-1.1.1.tgz", - "integrity": "sha1-CEfLxESfNAVXTb3M2buEG4OsNUU=", - "dev": true, - "requires": { - "readable-stream": ">=1.1.13-1 <1.2.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, "streamroller": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/streamroller/-/streamroller-0.7.0.tgz", @@ -36598,56 +36177,6 @@ } } }, - "trumpet": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/trumpet/-/trumpet-1.7.2.tgz", - "integrity": "sha1-sCxp5GXRcfVeRJJL+bW90gl0yDA=", - "dev": true, - "requires": { - "duplexer2": "~0.0.2", - "html-select": "^2.3.5", - "html-tokenize": "^1.1.1", - "inherits": "^2.0.0", - "readable-stream": "^1.0.27-1", - "through2": "^1.0.0" - }, - "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true - }, - "readable-stream": { - "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", - "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "string_decoder": { - "version": "0.10.31", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true - }, - "through2": { - "version": "1.1.1", - "resolved": "http://registry.npmjs.org/through2/-/through2-1.1.1.tgz", - "integrity": "sha1-CEfLxESfNAVXTb3M2buEG4OsNUU=", - "dev": true, - "requires": { - "readable-stream": ">=1.1.13-1 <1.2.0-0", - "xtend": ">=4.0.0 <4.1.0-0" - } - } - } - }, "ts-custom-error": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ts-custom-error/-/ts-custom-error-2.2.1.tgz", diff --git a/package.json b/package.json index 2dd35ac7c777..5915dd185212 100644 --- a/package.json +++ b/package.json @@ -43,8 +43,6 @@ "lint": "eslint .", "lint:fix": "eslint . --fix", "mozilla-lint": "addons-linter dist/firefox", - "ui": "npm run test:flat:build:states && beefy development/ui-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", - "mock": "beefy development/mock-dev.js:bundle.js --live --open --index=./development/index.html --cwd ./", "watch": "mocha watch --recursive \"test/unit/**/*.js\"", "disc": "gulp disc --debug", "announce": "node development/announcer.js", @@ -246,7 +244,6 @@ "babel-preset-stage-0": "^6.24.1", "babel-register": "^6.7.2", "babelify": "^8.0.0", - "beefy": "^2.1.5", "brfs": "^1.6.1", "browserify": "^16.2.3", "chai": "^4.1.0", From 855c8b209cf77e67b667d720231e65e67e6b8b96 Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 12:04:44 -0330 Subject: [PATCH 54/64] npm uninstall open --- package-lock.json | 6 ------ package.json | 1 - 2 files changed, 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index d1b73b29b8f1..b24480136a73 100644 --- a/package-lock.json +++ b/package-lock.json @@ -28023,12 +28023,6 @@ "mimic-fn": "^1.0.0" } }, - "open": { - "version": "0.0.5", - "resolved": "https://registry.npmjs.org/open/-/open-0.0.5.tgz", - "integrity": "sha1-QsPhjslUZra/DcQvOilFw/DK2Pw=", - "dev": true - }, "opener": { "version": "1.4.3", "resolved": "https://registry.npmjs.org/opener/-/opener-1.4.3.tgz", diff --git a/package.json b/package.json index 5915dd185212..5600b5f37ed7 100644 --- a/package.json +++ b/package.json @@ -306,7 +306,6 @@ "nock": "^9.0.14", "node-sass": "^4.9.2", "nyc": "^13.0.0", - "open": "0.0.5", "path": "^0.12.7", "png-file-stream": "^1.1.0", "prepend-file": "^1.3.1", From ac6b0bd31cb5f2e48b349f64c47021d37c27dbd5 Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 12:08:39 -0330 Subject: [PATCH 55/64] Update ganache-core to mitigate vuln MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit === npm audit security report === > # Run npm install --save-dev ganache-core@2.3.1 to resolve 1 vulnerability ┌───────────────┬──────────────────────────────────────────────────────────────┐ │ Moderate │ Memory Exposure │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Package │ bl │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Dependency of │ ganache-core [dev] │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ Path │ ganache-core > level-sublevel > levelup > bl │ ├───────────────┼──────────────────────────────────────────────────────────────┤ │ More info │ https://nodesecurity.io/advisories/596 │ └───────────────┴──────────────────────────────────────────────────────────────┘ --- package-lock.json | 2352 +++++++++++++++++++++------------------------ package.json | 2 +- 2 files changed, 1092 insertions(+), 1262 deletions(-) diff --git a/package-lock.json b/package-lock.json index b24480136a73..4decb301d10a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12687,46 +12687,37 @@ } }, "ganache-core": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.2.1.tgz", - "integrity": "sha512-JMLZj7CKxtC5M0qceQYn8FLOx+CZyfISpSRfGdwnKy3juXO8siSAodjq8hviqUY1J0tEdEGqvNm16wSUxtiRjQ==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/ganache-core/-/ganache-core-2.3.1.tgz", + "integrity": "sha512-I4t4P+LYUZRnGbxDseqSa5vIJ8C5e35vw5Fr7f2iMMN6jmO5TVjWWgNib60G2iL+XTbYUFmou040hHxrTaNtnA==", "dev": true, "requires": { - "abstract-leveldown": "^3.0.0", - "async": "^2.5.0", - "bip39": "~2.4.0", - "bn.js": "4.11.6", - "cachedown": "^1.0.0", - "chai": "^3.5.0", - "clone": "^2.1.1", - "eth-sig-util": "^2.0.2", - "ethereumjs-abi": "^0.6.5", - "ethereumjs-account": "~2.0.4", - "ethereumjs-block": "~1.2.2", - "ethereumjs-tx": "1.3.4", - "ethereumjs-util": "^5.2.0", - "ethereumjs-vm": "2.3.5", - "ethereumjs-wallet": "0.6.0", - "fake-merkle-patricia-tree": "~1.0.1", - "heap": "~0.2.6", - "js-scrypt": "^0.2.0", - "level-sublevel": "^6.6.1", - "levelup": "^1.1.0", - "localstorage-down": "^0.6.7", - "lodash": "^4.17.5", - "merkle-patricia-tree": "^2.2.0", - "pify": "^3.0.0", - "prepend-file": "^1.3.1", - "request": "^2.87.0", - "seedrandom": "~2.4.2", - "shebang-loader": "0.0.1", - "solc": "0.4.24", - "temp": "^0.8.3", - "tmp": "0.0.31", - "web3": "^1.0.0-beta.34", - "web3-provider-engine": "^14.0.6", - "websocket": "^1.0.24", - "yargs": "^7.0.2" + "abstract-leveldown": "3.0.0", + "async": "2.6.1", + "bip39": "2.5.0", + "bn.js": "4.11.8", + "cachedown": "1.0.0", + "clone": "2.1.2", + "debug": "3.1.0", + "encoding-down": "5.0.4", + "eth-sig-util": "2.0.2", + "ethereumjs-abi": "0.6.5", + "ethereumjs-account": "2.0.5", + "ethereumjs-block": "1.2.2", + "ethereumjs-tx": "1.3.7", + "ethereumjs-util": "5.2.0", + "ethereumjs-vm": "2.4.0", + "ethereumjs-wallet": "0.6.2", + "heap": "0.2.6", + "level-sublevel": "6.6.4", + "levelup": "3.1.1", + "lodash": "4.17.10", + "merkle-patricia-tree": "2.3.1", + "seedrandom": "2.4.4", + "tmp": "0.0.33", + "web3": "1.0.0-beta.35", + "web3-provider-engine": "14.1.0", + "websocket": "1.0.26" }, "dependencies": { "abstract-leveldown": { @@ -12749,21 +12740,22 @@ } }, "aes-js": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-0.2.4.tgz", - "integrity": "sha1-lLiBq3FyhtAV+iGeCPtmcJ3aWj0=", - "dev": true + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/aes-js/-/aes-js-3.1.2.tgz", + "integrity": "sha512-e5pEa2kBnBOgR4Y/p20pskXI74UEz7de8ZGVo58asOtvSVG5YAbJeELPZxOmt+Bnz3rX753YKhfIn4X4l1PPRQ==", + "dev": true, + "optional": true }, "ajv": { - "version": "5.5.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz", - "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=", + "version": "6.5.5", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.5.tgz", + "integrity": "sha512-7q7gtRQDJSyuEHjuVgHoUa2VuemFiCMrfQc9Tc08XTAc4Zj/5U1buQJ0HU6i7fKjXU09SVgSmxa4sLvuvS8Iyg==", "dev": true, "requires": { - "co": "^4.6.0", - "fast-deep-equal": "^1.0.0", + "fast-deep-equal": "^2.0.1", "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.3.0" + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" } }, "ansi-regex": { @@ -12784,12 +12776,6 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, - "argsarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", - "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=", - "dev": true - }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -12797,53 +12783,32 @@ "dev": true }, "asn1": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.3.tgz", - "integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y=", - "dev": true + "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, + "optional": 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=", - "requires": { - "util": "0.10.3" - } - }, - "assert-match": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/assert-match/-/assert-match-1.1.1.tgz", - "integrity": "sha512-c0QY2kpYVrH/jis6cCq9Mnt4/bIdGALDh1N8HY9ZARZedsMs5LSbgywxkjd5A1uNVLN0L8evANxBPxKiabVoZw==", - "requires": { - "assert": "^1.4.1", - "babel-runtime": "^6.23.0", - "es-to-primitive": "^1.1.1", - "lodash.merge": "^4.6.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 }, - "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.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", @@ -12881,9 +12846,9 @@ "dev": true }, "aws4": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz", - "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz", + "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==", "dev": true }, "babel-code-frame": { @@ -12922,6 +12887,17 @@ "private": "^0.1.8", "slash": "^1.0.0", "source-map": "^0.5.7" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "babel-generator": { @@ -12942,7 +12918,7 @@ "dependencies": { "jsesc": { "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=", "dev": true } @@ -13105,13 +13081,13 @@ }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=", "dev": true }, "babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=", "dev": true }, @@ -13447,12 +13423,24 @@ "lodash": "^4.17.4", "mkdirp": "^0.5.1", "source-map-support": "^0.4.15" + }, + "dependencies": { + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "^0.5.6" + } + } } }, "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" @@ -13486,6 +13474,17 @@ "globals": "^9.18.0", "invariant": "^2.2.2", "lodash": "^4.17.4" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } } }, "babel-types": { @@ -13502,7 +13501,7 @@ }, "babelify": { "version": "7.3.0", - "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "dev": true, "requires": { @@ -13531,23 +13530,27 @@ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base-x": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz", - "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w=", - "dev": true + "version": "3.0.5", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.5.tgz", + "integrity": "sha512-C3picSgzPSLE+jW3tcBzJoGwitOtazb5B+5YmAxZm2ybmTi9LNgAtDO/jjVEBZwHoXmDBZ9m/IELj3elJVRBcA==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.0.1" + } }, "base64-js": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz", "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==", - "dev": true + "dev": true, + "optional": true }, "bcrypt-pbkdf": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz", - "integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=", + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz", + "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=", "dev": true, - "optional": true, "requires": { "tweetnacl": "^0.14.3" } @@ -13555,13 +13558,12 @@ "bindings": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz", - "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==", - "dev": true + "integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw==" }, "bip39": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.4.0.tgz", - "integrity": "sha512-1++HywqIyPtWDo7gm4v0ylYbwkLvHkuwVSKbBlZBbTCP/mnkyrlARBny906VLAwxJbC5xw9EvuJasHFIZaIFMQ==", + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz", + "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==", "dev": true, "requires": { "create-hash": "^1.1.0", @@ -13575,32 +13577,19 @@ "version": "1.1.5", "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz", "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=", - "dev": true, "requires": { "safe-buffer": "^5.0.1" } }, "bl": { - "version": "0.8.2", - "resolved": "http://registry.npmjs.org/bl/-/bl-0.8.2.tgz", - "integrity": "sha1-yba8oI0bwuoA/Ir7Txpf0eHGbk4=", + "version": "1.2.2", + "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, + "optional": true, "requires": { - "readable-stream": "~1.0.26" - }, - "dependencies": { - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - } + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" } }, "block-stream": { @@ -13608,21 +13597,22 @@ "resolved": "https://registry.npmjs.org/block-stream/-/block-stream-0.0.9.tgz", "integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=", "dev": true, + "optional": true, "requires": { "inherits": "~2.0.0" } }, "bluebird": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz", - "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==", - "dev": true + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.3.tgz", + "integrity": "sha512-/qKPUQlaW1OyR51WeCPBvRnAlnZFUJkCSG5HzGnuIqhgyJtF+T94lFnn33eiazjRm2LAHVy2guNnaq48X9SJuw==", + "dev": true, + "optional": true }, "bn.js": { - "version": "4.11.6", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", - "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", - "dev": true + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" }, "body-parser": { "version": "1.18.3", @@ -13640,6 +13630,17 @@ "qs": "6.5.2", "raw-body": "2.3.3", "type-is": "~1.6.16" + }, + "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" + } + } } }, "brace-expansion": { @@ -13654,19 +13655,12 @@ "brorand": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "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==" + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, "browserify-aes": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "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", @@ -13681,6 +13675,7 @@ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", "dev": true, + "optional": true, "requires": { "browserify-aes": "^1.0.4", "browserify-des": "^1.0.0", @@ -13688,21 +13683,24 @@ } }, "browserify-des": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz", - "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==", + "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, + "optional": true, "requires": { "cipher-base": "^1.0.1", "des.js": "^1.0.0", - "inherits": "^2.0.1" + "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", + "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, + "optional": true, "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" @@ -13722,6 +13720,7 @@ "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", "dev": true, + "optional": true, "requires": { "bn.js": "^4.1.1", "browserify-rsa": "^4.0.0", @@ -13743,66 +13742,74 @@ } }, "bs58": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/bs58/-/bs58-3.1.0.tgz", - "integrity": "sha1-1MJjiL9IBMrHFBQbGUWqR+XrJI4=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz", + "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=", "dev": true, + "optional": true, "requires": { - "base-x": "^1.1.0" + "base-x": "^3.0.2" } }, "bs58check": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.3.4.tgz", - "integrity": "sha1-xSVABzdJEXcU+gQsMEfrj5FRy/g=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.2.tgz", + "integrity": "sha512-0TS1jicxdU09dwJMNZtVAfzPi6Q6QeN0pM1Fkzrjn+XYHvzMKPU3pHVpva+769iNVSfIYWf7LJ6WR+BuuMf8cA==", "dev": true, + "optional": true, "requires": { - "bs58": "^3.1.0", - "create-hash": "^1.1.0" + "bs58": "^4.0.0", + "create-hash": "^1.1.0", + "safe-buffer": "^5.1.2" } }, "buffer": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.1.0.tgz", - "integrity": "sha512-YkIRgwsZwJWTnyQrsBTWefizHh+8GYj3kbL1BTiAQ/9pwpino0G7B2gp5tx/FUBqUlvtxV85KNR3mwfAtv15Yw==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz", + "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==", "dev": true, + "optional": true, "requires": { "base64-js": "^1.0.2", "ieee754": "^1.1.4" } }, "buffer-alloc": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz", - "integrity": "sha1-BVFNM78WVtNUDGhPZbEgLpDsowM=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", + "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, + "optional": true, "requires": { - "buffer-alloc-unsafe": "^0.1.0", - "buffer-fill": "^0.1.0" + "buffer-alloc-unsafe": "^1.1.0", + "buffer-fill": "^1.0.0" } }, "buffer-alloc-unsafe": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz", - "integrity": "sha1-/+H2dVHdBVc33iUzN7/oU9+rGmo=", - "dev": true + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", + "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", + "dev": true, + "optional": true }, "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 + "dev": true, + "optional": true }, "buffer-fill": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-0.1.1.tgz", - "integrity": "sha512-YgBMBzdRLEfgxJIGu2wrvI2E03tMCFU1p7d1KhB4BOoMN0VxmTFjSyN5JtKt9z8Z9JajMHruI6SE25W96wNv7Q==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", + "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", + "dev": true, + "optional": true }, "buffer-from": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-0.1.2.tgz", - "integrity": "sha512-RiWIenusJsmI2KcvqQABB83tLxCByE3upSP8QU3rJDMVFGPWLvPQJt/O1Su9moRWeH7d+Q2HYb68f6+v+tw2vg==", + "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-to-arraybuffer": { @@ -13814,8 +13821,7 @@ "buffer-xor": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=" }, "builtin-modules": { "version": "1.1.1", @@ -13876,9 +13882,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30000850", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000850.tgz", - "integrity": "sha512-iHK48UR/InydhpPAzgSmsJXRAR925T0kwJhZ1wk0xRatpGMvi2f06LABg6HXfV4WW4P2wChzlcFa/TEmbTyXQA==", + "version": "1.0.30000907", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000907.tgz", + "integrity": "sha512-No5sQ/OB2Nmka8MNOOM6nJx+Hxt6MQ6h7t7kgJFu9oTuwjykyKRSBP/+i/QAyFHxeHB+ddE0Da1CG5ihx9oehQ==", "dev": true }, "caseless": { @@ -13887,20 +13893,9 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, - "chai": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", - "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", - "dev": true, - "requires": { - "assertion-error": "^1.0.1", - "deep-eql": "^0.1.3", - "type-detect": "^1.0.0" - } - }, "chalk": { "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "dev": true, "requires": { @@ -13924,7 +13919,6 @@ "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" @@ -13942,15 +13936,9 @@ } }, "clone": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz", - "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs=", - "dev": true - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, "code-point-at": { @@ -13964,6 +13952,7 @@ "resolved": "https://registry.npmjs.org/coinstring/-/coinstring-2.3.0.tgz", "integrity": "sha1-zbYzY6lhUCQEolr7gsLibV/2J6Q=", "dev": true, + "optional": true, "requires": { "bs58": "^2.0.1", "create-hash": "^1.1.1" @@ -13973,14 +13962,15 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz", "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40=", - "dev": true + "dev": true, + "optional": true } } }, "combined-stream": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz", - "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=", + "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" @@ -13988,9 +13978,10 @@ }, "commander": { "version": "2.8.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.8.1.tgz", + "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, + "optional": true, "requires": { "graceful-readlink": ">= 1.0.0" } @@ -14010,14 +14001,6 @@ "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" - }, - "dependencies": { - "buffer-from": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", - "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", - "dev": true - } } }, "content-disposition": { @@ -14033,10 +14016,13 @@ "dev": true }, "convert-source-map": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz", - "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU=", - "dev": true + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } }, "cookie": { "version": "0.3.1", @@ -14050,10 +14036,17 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, "core-js": { - "version": "2.5.6", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz", - "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ==" + "version": "2.5.7", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", + "dev": true }, "core-util-is": { "version": "1.0.2", @@ -14062,9 +14055,9 @@ "dev": true }, "cors": { - "version": "2.8.4", - "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.4.tgz", - "integrity": "sha1-K9OB8usgECAQXNUOpZ2mMJBpRoY=", + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", "dev": true, "requires": { "object-assign": "^4", @@ -14076,6 +14069,7 @@ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", "dev": true, + "optional": true, "requires": { "bn.js": "^4.1.0", "elliptic": "^6.0.0" @@ -14083,9 +14077,8 @@ }, "create-hash": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "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", @@ -14096,9 +14089,8 @@ }, "create-hmac": { "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "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", @@ -14109,9 +14101,9 @@ } }, "cross-fetch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.1.tgz", - "integrity": "sha1-lshZEE113vyWf7XbYkdOdUJrArA=", + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", + "integrity": "sha512-PrWWNH3yL2NYIb/7WF/5vFG3DCQiXDOVf8k3ijatbrtnwNuhMWLC7YF7uqf53tbTFDzHIUD8oITw4Bxt8ST3Nw==", "dev": true, "requires": { "node-fetch": "2.1.2", @@ -14123,6 +14115,7 @@ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", "dev": true, + "optional": true, "requires": { "browserify-cipher": "^1.0.0", "browserify-sign": "^4.0.0", @@ -14137,12 +14130,6 @@ "randomfill": "^1.0.3" } }, - "d64": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", - "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=", - "dev": true - }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -14153,9 +14140,9 @@ } }, "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "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" @@ -14178,6 +14165,7 @@ "resolved": "https://registry.npmjs.org/decompress/-/decompress-4.2.0.tgz", "integrity": "sha1-eu3YVCflqS2s/lVnSnxQXpbQH50=", "dev": true, + "optional": true, "requires": { "decompress-tar": "^4.0.0", "decompress-tarbz2": "^4.0.0", @@ -14191,9 +14179,10 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "dev": true, + "optional": true } } }, @@ -14211,6 +14200,7 @@ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "dev": true, + "optional": true, "requires": { "file-type": "^5.2.0", "is-stream": "^1.1.0", @@ -14222,6 +14212,7 @@ "resolved": "https://registry.npmjs.org/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz", "integrity": "sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A==", "dev": true, + "optional": true, "requires": { "decompress-tar": "^4.1.0", "file-type": "^6.1.0", @@ -14234,7 +14225,8 @@ "version": "6.2.0", "resolved": "https://registry.npmjs.org/file-type/-/file-type-6.2.0.tgz", "integrity": "sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg==", - "dev": true + "dev": true, + "optional": true } } }, @@ -14243,6 +14235,7 @@ "resolved": "https://registry.npmjs.org/decompress-targz/-/decompress-targz-4.1.1.tgz", "integrity": "sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w==", "dev": true, + "optional": true, "requires": { "decompress-tar": "^4.1.1", "file-type": "^5.2.0", @@ -14254,6 +14247,7 @@ "resolved": "https://registry.npmjs.org/decompress-unzip/-/decompress-unzip-4.0.1.tgz", "integrity": "sha1-3qrM39FK6vhVePczroIQ+bSEj2k=", "dev": true, + "optional": true, "requires": { "file-type": "^3.8.0", "get-stream": "^2.2.0", @@ -14263,15 +14257,17 @@ "dependencies": { "file-type": { "version": "3.9.0", - "resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", + "resolved": "http://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz", "integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek=", - "dev": true + "dev": true, + "optional": true }, "get-stream": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-2.3.1.tgz", "integrity": "sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4=", "dev": true, + "optional": true, "requires": { "object-assign": "^4.0.1", "pinkie-promise": "^2.0.0" @@ -14279,26 +14275,10 @@ }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true - } - } - }, - "deep-eql": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", - "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", - "dev": true, - "requires": { - "type-detect": "0.1.1" - }, - "dependencies": { - "type-detect": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", - "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", - "dev": true + "dev": true, + "optional": true } } }, @@ -14329,19 +14309,18 @@ } }, "define-properties": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.2.tgz", - "integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { - "foreach": "^2.0.5", - "object-keys": "^1.0.8" + "object-keys": "^1.0.12" }, "dependencies": { "object-keys": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.11.tgz", - "integrity": "sha1-xUYBd4rVYPEULODgG8yotW0TQm0=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.0.12.tgz", + "integrity": "sha512-FTMyFUm2wBcGHnH2eXmz7tC6IwlqQZ6mVZ+6dm6vZ4IQIHjs6FdNsQBuKGPuUUUY6NfJw2PshC08Tn6LzLDOag==", "dev": true } } @@ -14369,6 +14348,7 @@ "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", "dev": true, + "optional": true, "requires": { "inherits": "^2.0.1", "minimalistic-assert": "^1.0.0" @@ -14389,16 +14369,12 @@ "repeating": "^2.0.0" } }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" - }, "diffie-hellman": { "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", "dev": true, + "optional": true, "requires": { "bn.js": "^4.1.0", "miller-rabin": "^4.0.0", @@ -14415,7 +14391,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz", "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=", - "dev": true, "requires": { "browserify-aes": "^1.0.6", "create-hash": "^1.1.2", @@ -14429,13 +14404,13 @@ "dev": true }, "ecc-jsbn": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz", - "integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=", + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz", + "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=", "dev": true, - "optional": true, "requires": { - "jsbn": "~0.1.0" + "jsbn": "~0.1.0", + "safer-buffer": "^2.1.0" } }, "ee-first": { @@ -14445,16 +14420,15 @@ "dev": true }, "electron-to-chromium": { - "version": "1.3.47", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.47.tgz", - "integrity": "sha1-dk6IfKkQTQGgrI6r7n38DizhQQQ=", + "version": "1.3.84", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.84.tgz", + "integrity": "sha512-IYhbzJYOopiTaNWMBp7RjbecUBsbnbDneOP86f3qvS0G0xfzwNSvMJpTrvi5/Y1gU7tg2NAgeg8a8rCYvW9Whw==", "dev": true }, "elliptic": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz", - "integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=", - "dev": true, + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.1.tgz", + "integrity": "sha512-BsXLz5sqX8OHcsh7CqBMztyXARmGQ3LWPtGjJi6DiJHq5C/qvi9P3OqgswKSDftbu8+IoI/QDTAm2fFnQ9SZSQ==", "requires": { "bn.js": "^4.4.0", "brorand": "^1.0.1", @@ -14480,6 +14454,30 @@ "iconv-lite": "~0.4.13" } }, + "encoding-down": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz", + "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==", + "dev": true, + "requires": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", + "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + } + } + }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -14499,9 +14497,9 @@ } }, "error-ex": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz", - "integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=", + "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" @@ -14521,13 +14519,14 @@ } }, "es-to-primitive": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.1.1.tgz", - "integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=", + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, "requires": { - "is-callable": "^1.1.1", + "is-callable": "^1.1.4", "is-date-object": "^1.0.1", - "is-symbol": "^1.0.1" + "is-symbol": "^1.0.2" } }, "escape-html": { @@ -14539,7 +14538,8 @@ "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=" + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true }, "esutils": { "version": "2.0.2", @@ -14570,7 +14570,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -14591,7 +14591,7 @@ }, "eth-json-rpc-middleware": { "version": "1.6.0", - "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", + "resolved": "http://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==", "dev": true, "requires": { @@ -14618,7 +14618,7 @@ }, "ethereumjs-block": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", "dev": true, "requires": { @@ -14687,20 +14687,6 @@ "web3-provider-engine": "^13.3.2" }, "dependencies": { - "async-eventemitter": { - "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "from": "async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "dev": true, - "requires": { - "async": "^2.4.0" - } - }, - "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 - }, "eth-block-tracker": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-2.3.1.tgz", @@ -14715,6 +14701,16 @@ "json-rpc-engine": "^3.6.0", "pify": "^2.3.0", "tape": "^4.6.3" + }, + "dependencies": { + "async-eventemitter": { + "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", + "from": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", + "dev": true, + "requires": { + "async": "^2.4.0" + } + } } }, "eth-sig-util": { @@ -14723,8 +14719,17 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", "ethereumjs-util": "^5.1.1" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ethereum-common": { @@ -14733,18 +14738,9 @@ "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", "dev": true }, - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - }, "ethereumjs-block": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", "dev": true, "requires": { @@ -14774,15 +14770,33 @@ "safe-buffer": "^5.1.1" } }, + "fs-extra": { + "version": "0.30.0", + "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" + } + }, "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, + "rustbn.js": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.1.2.tgz", + "integrity": "sha512-bAkNqSHYdJdFsBC7Z11JgzYktL31HIpB2o70jZcGiL1U1TVtPyvaVhDrGWwS8uZtaqwW2k6NOPGZCqW/Dgh5Lg==", + "dev": true + }, "web3-provider-engine": { "version": "13.8.0", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz", + "resolved": "http://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-13.8.0.tgz", "integrity": "sha512-fZXhX5VWwWpoFfrfocslyg6P7cN3YWPG/ASaevNfeO80R+nzgoPUBXcWQekSGSsNDkeRTis4aMmpmofYf1TNtQ==", "dev": true, "requires": { @@ -14827,7 +14841,7 @@ "dependencies": { "ethereumjs-util": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", + "resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "dev": true, "requires": { @@ -14853,7 +14867,7 @@ }, "ethereumjs-block": { "version": "1.2.2", - "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.2.2.tgz", + "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.2.2.tgz", "integrity": "sha1-LsdTSlkCG47JuDww5JaQxuuu3aE=", "dev": true, "requires": { @@ -14866,13 +14880,13 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "ethereumjs-util": { "version": "4.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", + "resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "dev": true, "requires": { @@ -14885,10 +14899,16 @@ } } }, + "ethereumjs-common": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-0.4.1.tgz", + "integrity": "sha512-ywYGsOeGCsMNWso5Y4GhjWI24FJv9FK7+VyVKiQgXg8ZRDPXJ7F/kJ1CnjtkjTvDF4e0yqU+FWswlqR3bmZQ9Q==", + "dev": true + }, "ethereumjs-tx": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.4.tgz", - "integrity": "sha512-kOgUd5jC+0tgV7t52UDECMMz9Uf+Lro+6fSpCvzWemtXfMEcwI3EOxf5mVPMRbTFkMMhuERokNNVF3jItAjidg==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", + "integrity": "sha512-wvLMxzt1RPhAQ9Yi3/HKZTn0FZYpnsmQdbKYfUUpi4j1SEIcbkd9tndVjcPrufY3V7j2IebOpC00Zp2P/Ay2kA==", "dev": true, "requires": { "ethereum-common": "^0.0.18", @@ -14907,7 +14927,6 @@ "version": "5.2.0", "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-5.2.0.tgz", "integrity": "sha512-CJAKdI0wgMbQFLlLRtZKGcy/L6pzVRgelIZqRqNbuVFM3K9VEnyfbcvz0ncWMRNCe4kaHWjwRYQcYMucmwsnWA==", - "dev": true, "requires": { "bn.js": "^4.11.0", "create-hash": "^1.1.2", @@ -14919,21 +14938,21 @@ } }, "ethereumjs-vm": { - "version": "2.3.5", - "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.3.5.tgz", - "integrity": "sha512-AJ7x44+xqyE5+UO3Nns19WkTdZfyqFZ+sEjIEpvme7Ipbe3iBU1uwCcHEdiu/yY9bdhr3IfSa/NfIKNeXPaRVQ==", + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/ethereumjs-vm/-/ethereumjs-vm-2.4.0.tgz", + "integrity": "sha512-MJ4lCWa5c6LhahhhvoDKW+YGjK00ZQn0RHHLh4L+WaH1k6Qv7/q3uTluew6sJGNCZdlO0yYMDXYW9qyxLHKlgQ==", "dev": true, "requires": { "async": "^2.1.2", "async-eventemitter": "^0.2.2", - "ethereum-common": "0.2.0", "ethereumjs-account": "^2.0.3", "ethereumjs-block": "~1.7.0", - "ethereumjs-util": "^5.1.3", + "ethereumjs-common": "~0.4.0", + "ethereumjs-util": "^5.2.0", "fake-merkle-patricia-tree": "^1.0.1", "functional-red-black-tree": "^1.0.1", "merkle-patricia-tree": "^2.1.2", - "rustbn.js": "~0.1.1", + "rustbn.js": "~0.2.0", "safe-buffer": "^5.1.1" }, "dependencies": { @@ -14945,7 +14964,7 @@ }, "ethereumjs-block": { "version": "1.7.1", - "resolved": "https://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", + "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", "integrity": "sha512-B+sSdtqm78fmKkBq78/QLKJbu/4Ts4P2KFISdgcuZUPDm9x+N7qgBPIIFUGbaakQh8bzuquiRVbdmvPKqbILRg==", "dev": true, "requires": { @@ -14959,33 +14978,20 @@ } }, "ethereumjs-wallet": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.0.tgz", - "integrity": "sha1-gnY7Fpfuenlr5xVdqd+0my+Yz9s=", + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/ethereumjs-wallet/-/ethereumjs-wallet-0.6.2.tgz", + "integrity": "sha512-DHEKPV9lYORM7dL8602dkb+AgdfzCYz2lxpdYQoD3OwG355LLDuivW9rGuLpDMCry/ORyBYV6n+QCo/71SwACg==", "dev": true, + "optional": true, "requires": { - "aes-js": "^0.2.3", - "bs58check": "^1.0.8", - "ethereumjs-util": "^4.4.0", - "hdkey": "^0.7.0", + "aes-js": "^3.1.1", + "bs58check": "^2.1.2", + "ethereumjs-util": "^5.2.0", + "hdkey": "^1.0.0", + "safe-buffer": "^5.1.2", "scrypt.js": "^0.2.0", - "utf8": "^2.1.1", - "uuid": "^2.0.1" - }, - "dependencies": { - "ethereumjs-util": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", - "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", - "dev": true, - "requires": { - "bn.js": "^4.8.0", - "create-hash": "^1.1.2", - "keccakjs": "^0.2.0", - "rlp": "^2.0.0", - "secp256k1": "^3.0.1" - } - } + "utf8": "^3.0.0", + "uuid": "^3.3.2" } }, "ethjs-unit": { @@ -14996,13 +15002,20 @@ "requires": { "bn.js": "4.11.6", "number-to-bn": "1.7.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + } } }, "ethjs-util": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.4.tgz", - "integrity": "sha1-HItoeSV0RO9NPz+7rC3tEs2ZfZM=", - "dev": true, + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/ethjs-util/-/ethjs-util-0.1.6.tgz", + "integrity": "sha512-CUnVOQq7gSpDHZVVrQW8ExxUETWrnrvXYvYz55wOU8Uj4VCgw56XC2B/fVqQN+f7gmrnRHSLVnFAwsCuNwji8w==", "requires": { "is-hex-prefixed": "1.0.0", "strip-hex-prefix": "1.0.0" @@ -15014,25 +15027,30 @@ "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=", "dev": true }, + "events": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", + "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", + "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" } }, "express": { - "version": "4.16.3", - "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz", - "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=", + "version": "4.16.4", + "resolved": "https://registry.npmjs.org/express/-/express-4.16.4.tgz", + "integrity": "sha512-j12Uuyb4FMrd/qQAm6uCHAkPtO8FDTRJZBDd5D2KOL2eLaz1yUNdUB/NOIyq0iU4q4cFarsUCrnFDPBcnksuOg==", "dev": true, "requires": { "accepts": "~1.3.5", "array-flatten": "1.1.1", - "body-parser": "1.18.2", + "body-parser": "1.18.3", "content-disposition": "0.5.2", "content-type": "~1.0.4", "cookie": "0.3.1", @@ -15049,10 +15067,10 @@ "on-finished": "~2.3.0", "parseurl": "~1.3.2", "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.3", - "qs": "6.5.1", + "proxy-addr": "~2.0.4", + "qs": "6.5.2", "range-parser": "~1.2.0", - "safe-buffer": "5.1.1", + "safe-buffer": "5.1.2", "send": "0.16.2", "serve-static": "1.13.2", "setprototypeof": "1.1.0", @@ -15062,80 +15080,15 @@ "vary": "~1.1.2" }, "dependencies": { - "body-parser": { - "version": "1.18.2", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", - "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-type": "~1.0.4", - "debug": "2.6.9", - "depd": "~1.1.1", - "http-errors": "~1.6.2", - "iconv-lite": "0.4.19", - "on-finished": "~2.3.0", - "qs": "6.5.1", - "raw-body": "2.3.2", - "type-is": "~1.6.15" - } - }, - "iconv-lite": { - "version": "0.4.19", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", - "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", - "dev": true - }, - "qs": { - "version": "6.5.1", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", - "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", - "dev": true - }, - "raw-body": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", - "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "dev": true, "requires": { - "bytes": "3.0.0", - "http-errors": "1.6.2", - "iconv-lite": "0.4.19", - "unpipe": "1.0.0" - }, - "dependencies": { - "depd": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", - "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", - "dev": true - }, - "http-errors": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", - "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", - "dev": true, - "requires": { - "depd": "1.1.1", - "inherits": "2.0.3", - "setprototypeof": "1.0.3", - "statuses": ">= 1.3.1 < 2" - } - }, - "setprototypeof": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", - "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", - "dev": true - } + "ms": "2.0.0" } }, - "safe-buffer": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "dev": true - }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -15145,9 +15098,9 @@ } }, "extend": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz", - "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", "dev": true }, "extsprintf": { @@ -15166,9 +15119,9 @@ } }, "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=", + "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": { @@ -15178,10 +15131,11 @@ "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=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "dev": true, + "optional": true, "requires": { "pend": "~1.2.0" } @@ -15215,7 +15169,7 @@ }, "finalhandler": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", + "resolved": "http://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz", "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==", "dev": true, "requires": { @@ -15228,6 +15182,15 @@ "unpipe": "~1.0.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" + } + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -15247,20 +15210,14 @@ } }, "for-each": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz", - "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=", + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", "dev": true, "requires": { - "is-function": "~1.0.0" + "is-callable": "^1.1.3" } }, - "foreach": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", - "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=", - "dev": true - }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -15268,13 +15225,13 @@ "dev": true }, "form-data": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz", - "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=", + "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", + "combined-stream": "^1.0.6", "mime-types": "^2.1.12" } }, @@ -15294,19 +15251,18 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true + "dev": true, + "optional": true }, "fs-extra": { - "version": "0.30.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "dev": true, + "optional": true, "requires": { "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" + "jsonfile": "^2.1.0" } }, "fs-promise": { @@ -15314,23 +15270,12 @@ "resolved": "https://registry.npmjs.org/fs-promise/-/fs-promise-2.0.3.tgz", "integrity": "sha1-9k5PhUvPaJqovdy6JokW2z20aFQ=", "dev": true, + "optional": true, "requires": { "any-promise": "^1.3.0", "fs-extra": "^2.0.0", "mz": "^2.6.0", "thenify-all": "^1.6.0" - }, - "dependencies": { - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" - } - } } }, "fs.realpath": { @@ -15343,6 +15288,7 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "dev": true, + "optional": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -15362,21 +15308,15 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, - "generic-pool": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.0.4.tgz", - "integrity": "sha1-+XGN7agvoSXtXEPjQcmiFadm2aM=", - "dev": true - }, "get-caller-file": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", - "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "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-stream": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, @@ -15390,9 +15330,9 @@ } }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -15441,21 +15381,16 @@ } }, "graceful-fs": { - "version": "4.1.11", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", - "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", - "dev": true + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==" }, "graceful-readlink": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true - }, - "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" + "dev": true, + "optional": true }, "har-schema": { "version": "2.0.0", @@ -15464,12 +15399,12 @@ "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=", + "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": "^5.1.0", + "ajv": "^6.5.5", "har-schema": "^2.0.0" } }, @@ -15491,23 +15426,18 @@ "ansi-regex": "^2.0.0" } }, - "has-flag": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" - }, - "has-localstorage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/has-localstorage/-/has-localstorage-1.0.1.tgz", - "integrity": "sha1-/mJAbEdn+9bXhNrGkFkoEIuClxs=", - "dev": true - }, "has-symbol-support-x": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", "dev": true }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, "has-to-string-tag-x": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", @@ -15521,37 +15451,32 @@ "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.3", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.3.tgz", - "integrity": "sha512-/UETyP0W22QILqS+6HowevwhEFJ3MBJnwTf75Qob9Wz9t0DPuisL8kW8YZMK62dHAKE1c1p+gY1TtOLY+USEHA==", - "dev": true, + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.5.tgz", + "integrity": "sha512-eWI5HG9Np+eHV1KQhisXWwM+4EPPYe5dFX1UZZH7k/E3JzDEazVH+VGlZi6R94ZqImq+A3D1mCEtrFIfg/E7sA==", "requires": { "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.0" + "minimalistic-assert": "^1.0.1" } }, "hdkey": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-0.7.1.tgz", - "integrity": "sha1-yu5L6BqneSHpCbjSKN0PKayu5jI=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hdkey/-/hdkey-1.1.0.tgz", + "integrity": "sha512-E7aU8pNlWUJbXGjTz/+lKf1LkMcA3hUrC5ZleeizrmLSd++kvf8mSOe3q8CmBDA9j4hdfXO5iY6hGiTUCOV2jQ==", "dev": true, + "optional": true, "requires": { "coinstring": "^2.0.0", + "safe-buffer": "^5.1.1", "secp256k1": "^3.0.1" } }, - "he": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", - "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" - }, "heap": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", @@ -15562,7 +15487,6 @@ "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", @@ -15580,14 +15504,14 @@ } }, "hosted-git-info": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz", - "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw==", + "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-errors": { "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "resolved": "http://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", "dev": true, "requires": { @@ -15614,16 +15538,6 @@ "sshpk": "^1.7.0" } }, - "humble-localstorage": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/humble-localstorage/-/humble-localstorage-1.4.2.tgz", - "integrity": "sha1-0Fqw1SbE7b3b98amDfb/WAUoNGk=", - "dev": true, - "requires": { - "has-localstorage": "^1.0.1", - "localstorage-memory": "^1.0.1" - } - }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -15634,10 +15548,11 @@ } }, "ieee754": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz", - "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==", - "dev": true + "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, + "optional": true }, "immediate": { "version": "3.2.3", @@ -15675,9 +15590,9 @@ "dev": true }, "ipaddr.js": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz", - "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.8.0.tgz", + "integrity": "sha1-6qM9bd16zo9/b+DJygRA5wZzix4=", "dev": true }, "is-arrayish": { @@ -15688,7 +15603,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "dev": true, "requires": { @@ -15696,14 +15611,16 @@ } }, "is-callable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.3.tgz", - "integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=" + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true }, "is-date-object": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=" + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true }, "is-finite": { "version": "1.0.2", @@ -15738,14 +15655,14 @@ "is-hex-prefixed": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-hex-prefixed/-/is-hex-prefixed-1.0.0.tgz", - "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=", - "dev": true + "integrity": "sha1-fY035q135dEnFIkTxXPggtd39VQ=" }, "is-natural-number": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-natural-number/-/is-natural-number-4.0.1.tgz", "integrity": "sha1-q5124dtM7VHjXeDHLr7PCfc0zeg=", - "dev": true + "dev": true, + "optional": true }, "is-object": { "version": "1.0.1", @@ -15781,9 +15698,13 @@ "dev": true }, "is-symbol": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz", - "integrity": "sha1-PMWfAAJRlLarLjjbrmaJJWtmBXI=" + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } }, "is-typedarray": { "version": "1.0.0", @@ -15819,15 +15740,6 @@ "is-object": "^1.0.1" } }, - "js-scrypt": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/js-scrypt/-/js-scrypt-0.2.0.tgz", - "integrity": "sha1-emK3AbRhbnCtDN5URiequ5nX/jk=", - "dev": true, - "requires": { - "generic-pool": "~2.0.4" - } - }, "js-sha3": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", @@ -15844,27 +15756,26 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz", "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=", - "dev": true, - "optional": true + "dev": true }, "jsesc": { "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "resolved": "http://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", "dev": true }, "json-rpc-engine": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.7.3.tgz", - "integrity": "sha512-+FO3UWu/wafh/+MZ6BXy0HZU+f5plwUn82FgxpC0scJkEh5snOjFrAAtqCITPDfvfLHRUFOG5pQDUx2pspfERQ==", + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", "dev": true, "requires": { "async": "^2.0.1", - "babel-preset-env": "^1.3.2", + "babel-preset-env": "^1.7.0", "babelify": "^7.3.0", - "clone": "^2.1.1", "json-rpc-error": "^2.0.0", - "promise-to-callback": "^1.0.0" + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" } }, "json-rpc-error": { @@ -15889,9 +15800,9 @@ "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=", + "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": { @@ -15911,15 +15822,14 @@ }, "json5": { "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=", "dev": true }, "jsonfile": { "version": "2.4.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", - "dev": true, "requires": { "graceful-fs": "^4.1.6" } @@ -15946,7 +15856,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/keccak/-/keccak-1.4.0.tgz", "integrity": "sha512-eZVaCpblK5formjPjeTBik7TAg+pqnDrMHIffSvi9Lh7PQgM1+hSzakUeZFCk9DVVG0dacZJuaz2ntwlzZUIBw==", - "dev": true, "requires": { "bindings": "^1.2.1", "inherits": "^2.0.3", @@ -15968,7 +15877,6 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", - "dev": true, "requires": { "graceful-fs": "^4.1.9" } @@ -15983,15 +15891,15 @@ } }, "level-codec": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", - "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.0.tgz", + "integrity": "sha512-OIpVvjCcZNP5SdhcNupnsI1zo5Y9Vpm+k/F1gfG5kXrtctlrwanisakweJtE0uA0OpLukRfOQae+Fg0M5Debhg==", "dev": true }, "level-errors": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", - "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.0.tgz", + "integrity": "sha512-AmY4HCp9h3OiU19uG+3YWkdELgy05OTP/r23aNHaQKWv8DO787yZgsEuGVkoph40uwN+YdUKnANlrxSsoOaaxg==", "dev": true, "requires": { "errno": "~0.1.1" @@ -15999,7 +15907,7 @@ }, "level-iterator-stream": { "version": "1.3.1", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "resolved": "http://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", "dev": true, "requires": { @@ -16009,9 +15917,18 @@ "xtend": "^4.0.0" }, "dependencies": { + "level-errors": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.1.2.tgz", + "integrity": "sha512-Sw/IJwWbPKF5Ai4Wz60B52yj0zYeqzObLh8k1Tk88jVmD51cJSKWSYpRyhVIvFzZdvsPqlH5wfhp/yxdsaQH4w==", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, "readable-stream": { "version": "1.1.14", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -16033,13 +15950,15 @@ } }, "level-sublevel": { - "version": "6.6.5", - "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.5.tgz", - "integrity": "sha512-SBSR60x+dghhwGUxPKS+BvV1xNqnwsEUBKmnFepPaHJ6VkBXyPK9SImGc3K2BkwBfpxlt7GKkBNlCnrdufsejA==", + "version": "6.6.4", + "resolved": "https://registry.npmjs.org/level-sublevel/-/level-sublevel-6.6.4.tgz", + "integrity": "sha512-pcCrTUOiO48+Kp6F1+UAzF/OtWqLcQVTVF39HLdZ3RO8XBoXt+XVPKZO1vVr1aUoxHZA9OtD2e1v7G+3S5KFDA==", "dev": true, "requires": { "bytewise": "~1.1.0", - "levelup": "~0.19.0", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "level-iterator-stream": "^2.0.3", "ltgt": "~2.1.1", "pull-defer": "^0.2.2", "pull-level": "^2.0.3", @@ -16048,53 +15967,15 @@ "xtend": "~4.0.0" }, "dependencies": { - "abstract-leveldown": { - "version": "0.12.4", - "resolved": "http://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", - "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=", - "dev": true, - "requires": { - "xtend": "~3.0.0" - }, - "dependencies": { - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "deferred-leveldown": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz", - "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=", - "dev": true, - "requires": { - "abstract-leveldown": "~0.12.1" - } - }, - "levelup": { - "version": "0.19.1", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.19.1.tgz", - "integrity": "sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs=", + "level-iterator-stream": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz", + "integrity": "sha512-I6Heg70nfF+e5Y3/qfthJFexhRw/Gi3bIymCoXAlijZdAcLaPuWSJs3KXyTYf23ID6g0o2QF62Yh+grOXY3Rig==", "dev": true, "requires": { - "bl": "~0.8.1", - "deferred-leveldown": "~0.2.0", - "errno": "~0.1.1", - "prr": "~0.0.0", - "readable-stream": "~1.0.26", - "semver": "~5.1.0", - "xtend": "~3.0.0" - }, - "dependencies": { - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } + "inherits": "^2.0.1", + "readable-stream": "^2.0.5", + "xtend": "^4.0.0" } }, "ltgt": { @@ -16102,30 +15983,6 @@ "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", "dev": true - }, - "prr": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", - "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=", - "dev": true - }, - "readable-stream": { - "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", - "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.1", - "isarray": "0.0.1", - "string_decoder": "~0.10.x" - } - }, - "semver": { - "version": "5.1.1", - "resolved": "http://registry.npmjs.org/semver/-/semver-5.1.1.tgz", - "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk=", - "dev": true } } }, @@ -16141,7 +15998,7 @@ "dependencies": { "readable-stream": { "version": "1.0.34", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -16163,23 +16020,52 @@ } }, "levelup": { - "version": "1.3.9", - "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", - "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-3.1.1.tgz", + "integrity": "sha512-9N10xRkUU4dShSRRFTBdNaBxofz+PGaIZO962ckboJZiNmLuhVT6FZ6ZKAsICKfUBO76ySaYU6fJWX/jnj3Lcg==", "dev": true, "requires": { - "deferred-leveldown": "~1.2.1", - "level-codec": "~7.0.0", - "level-errors": "~1.0.3", - "level-iterator-stream": "~1.3.0", - "prr": "~1.0.1", - "semver": "~5.4.1", + "deferred-leveldown": "~4.0.0", + "level-errors": "~2.0.0", + "level-iterator-stream": "~3.0.0", "xtend": "~4.0.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", + "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "deferred-leveldown": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", + "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", + "dev": true, + "requires": { + "abstract-leveldown": "~5.0.0", + "inherits": "^2.0.3" + } + }, + "level-iterator-stream": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz", + "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "xtend": "^4.0.0" + } + } } }, "load-json-file": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "dev": true, "requires": { @@ -16192,50 +16078,12 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, - "localstorage-down": { - "version": "0.6.7", - "resolved": "https://registry.npmjs.org/localstorage-down/-/localstorage-down-0.6.7.tgz", - "integrity": "sha1-0Hmak7MebF+lGI7AYkLrHM6dbRU=", - "dev": true, - "requires": { - "abstract-leveldown": "0.12.3", - "argsarray": "0.0.1", - "buffer-from": "^0.1.1", - "d64": "^1.0.0", - "humble-localstorage": "^1.4.2", - "inherits": "^2.0.1", - "tiny-queue": "0.2.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "0.12.3", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.3.tgz", - "integrity": "sha1-EWsexcdxDvei1XBnaLvbREC+EHA=", - "dev": true, - "requires": { - "xtend": "~3.0.0" - } - }, - "xtend": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", - "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=", - "dev": true - } - } - }, - "localstorage-memory": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/localstorage-memory/-/localstorage-memory-1.0.2.tgz", - "integrity": "sha1-zUqPIQ5V3VGckp9LTMgoKbWPmlE=", - "dev": true - }, "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", @@ -16248,11 +16096,6 @@ "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", "dev": true }, - "lodash.merge": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", - "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" - }, "looper": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/looper/-/looper-2.0.0.tgz", @@ -16260,12 +16103,12 @@ "dev": true }, "loose-envify": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz", - "integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "dev": true, "requires": { - "js-tokens": "^3.0.0" + "js-tokens": "^3.0.0 || ^4.0.0" } }, "lowercase-keys": { @@ -16294,23 +16137,33 @@ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", "dev": true, + "optional": true, "requires": { "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "optional": true + } } }, "md5.js": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz", - "integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=", - "dev": true, + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", "requires": { "hash-base": "^3.0.0", - "inherits": "^2.0.1" + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "media-typer": { "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", "dev": true }, @@ -16353,7 +16206,7 @@ }, "merkle-patricia-tree": { "version": "2.3.1", - "resolved": "https://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", + "resolved": "http://registry.npmjs.org/merkle-patricia-tree/-/merkle-patricia-tree-2.3.1.tgz", "integrity": "sha512-Qp9Mpb3xazznXzzGQBqHbqCpT2AR9joUOHYYPiQjYCarrdCPCnLWXo4BFv77y4xN26KR224xoU1n/qYY7RYYgw==", "dev": true, "requires": { @@ -16369,9 +16222,39 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true + }, + "level-codec": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-7.0.1.tgz", + "integrity": "sha512-Ua/R9B9r3RasXdRmOtd+t9TCOEIIlts+TN/7XTT2unhDaL6sJn83S3rUyljbr6lVtw49N3/yA0HHjpV6Kzb2aQ==", + "dev": true + }, + "level-errors": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-1.0.5.tgz", + "integrity": "sha512-/cLUpQduF6bNrWuAC4pwtUKA5t669pCsCi2XbmojG2tFeOr9j6ShtdDCtFFQO1DRt+EVZhx9gPzP9G2bUaG4ig==", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + }, + "levelup": { + "version": "1.3.9", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-1.3.9.tgz", + "integrity": "sha512-VVGHfKIlmw8w1XqpGOAGwq6sZm2WwWLmlDcULkKWQXEA5EopA8OBNJ2Ck2v6bdk8HeEZSbCSEgzXadyQFm76sQ==", + "dev": true, + "requires": { + "deferred-leveldown": "~1.2.1", + "level-codec": "~7.0.0", + "level-errors": "~1.0.3", + "level-iterator-stream": "~1.3.0", + "prr": "~1.0.1", + "semver": "~5.4.1", + "xtend": "~4.0.0" + } } } }, @@ -16386,6 +16269,7 @@ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", "dev": true, + "optional": true, "requires": { "bn.js": "^4.0.0", "brorand": "^1.0.1" @@ -16398,24 +16282,24 @@ "dev": true }, "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", + "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.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", + "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.33.0" + "mime-db": "~1.37.0" } }, "mimic-response": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.0.tgz", - "integrity": "sha1-3z02Uqc/3ta5sLJBRub9BSNTRY4=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", "dev": true }, "min-document": { @@ -16430,14 +16314,12 @@ "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 + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==" }, "minimalistic-crypto-utils": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=" }, "minimatch": { "version": "3.0.4", @@ -16449,13 +16331,15 @@ }, "minimist": { "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" + "resolved": "http://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", + "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, "requires": { "minimist": "0.0.8" } @@ -16465,62 +16349,24 @@ "resolved": "https://registry.npmjs.org/mkdirp-promise/-/mkdirp-promise-5.0.1.tgz", "integrity": "sha1-6bj2jlUsaKnBcTuEiD96HdA5uKE=", "dev": true, + "optional": true, "requires": { "mkdirp": "*" } }, - "mocha": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", - "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", - "requires": { - "browser-stdout": "1.3.1", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "supports-color": "4.4.0" - }, - "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "supports-color": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", - "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", - "requires": { - "has-flag": "^2.0.0" - } - } - } - }, "mock-fs": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.5.0.tgz", - "integrity": "sha512-qqudNfOX7ZmX9vm1WIAU+gWlmxVNAnwY6UG3RkFutNywmRCUGP83tujP6IxX2DS1TmcaEZBOhYwDuYEmJYE+3w==", - "dev": true + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.7.0.tgz", + "integrity": "sha512-WlQNtUlzMRpvLHf8dqeUmNqfdPjGY29KrJF50Ldb4AcL+vQeR8QH3wQcFMgrhTwb1gHjZn9xggho+84tBskLgA==", + "dev": true, + "optional": true }, "mout": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/mout/-/mout-0.11.1.tgz", "integrity": "sha1-ujYR318OWx/7/QEWa48C0fX6K5k=", - "dev": true + "dev": true, + "optional": true }, "ms": { "version": "2.0.0", @@ -16532,6 +16378,7 @@ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz", "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==", "dev": true, + "optional": true, "requires": { "any-promise": "^1.0.0", "object-assign": "^4.0.1", @@ -16540,9 +16387,8 @@ }, "nan": { "version": "2.10.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", - "dev": true + "resolved": "http://registry.npmjs.org/nan/-/nan-2.10.0.tgz", + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" }, "nano-json-stream-parser": { "version": "0.1.2", @@ -16558,7 +16404,7 @@ }, "node-fetch": { "version": "2.1.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", + "resolved": "http://registry.npmjs.org/node-fetch/-/node-fetch-2.1.2.tgz", "integrity": "sha1-q4hOjn5X44qUR1POxwb3iNF2i7U=", "dev": true }, @@ -16588,12 +16434,20 @@ "requires": { "bn.js": "4.11.6", "strip-hex-prefix": "1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + } } }, "oauth-sign": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.8.2.tgz", - "integrity": "sha1-Rqarfwrq2N6unsBWV4C31O/rnUM=", + "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": { @@ -16603,9 +16457,9 @@ "dev": true }, "object-inspect": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.5.0.tgz", - "integrity": "sha512-UmOFbHbwvv+XHj7BerrhVq+knjceBdkvU5AriwLMvhv2qi+e7DJzxfBeFpILEjVzCp+xA+W/pIf06RGPWlZNfw==", + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.6.0.tgz", + "integrity": "sha512-GJzfBZ6DgDAmnuaM3104jR4s1Myxr3Y3zfIyN4z3UdqN69oSRacNK8UhnobDdC+7J2AHCjGwxQubNJfE70SXXQ==", "dev": true }, "object-keys": { @@ -16642,13 +16496,13 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=", "dev": true }, "os-locale": { "version": "1.4.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "dev": true, "requires": { @@ -16657,7 +16511,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", "dev": true }, @@ -16684,9 +16538,10 @@ }, "parse-asn1": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", + "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, + "optional": true, "requires": { "asn1.js": "^4.0.0", "browserify-aes": "^1.0.0", @@ -16731,13 +16586,13 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-parse": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.5.tgz", - "integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=", + "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": { @@ -16759,16 +16614,16 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } } }, "pbkdf2": { - "version": "3.0.16", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz", - "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==", + "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", @@ -16782,7 +16637,8 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA=", - "dev": true + "dev": true, + "optional": true }, "performance-now": { "version": "2.1.0", @@ -16790,12 +16646,6 @@ "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", @@ -16817,15 +16667,6 @@ "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=", "dev": true }, - "prepend-file": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/prepend-file/-/prepend-file-1.3.1.tgz", - "integrity": "sha1-g7FuC0rBkB/OiNvZRaIvTMgd9Xk=", - "dev": true, - "requires": { - "tmp": "0.0.31" - } - }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -16861,13 +16702,13 @@ } }, "proxy-addr": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz", - "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.4.tgz", + "integrity": "sha512-5erio2h9jp5CHGwcybmxmVqHmnCBZeewlfJ0pex+UW7Qny7OOZXTtH56TGNyBizkgiOwhJtMKrVzDTeKcySZwA==", "dev": true, "requires": { "forwarded": "~0.1.2", - "ipaddr.js": "1.6.0" + "ipaddr.js": "1.8.0" } }, "prr": { @@ -16882,17 +16723,25 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, + "psl": { + "version": "1.1.29", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", + "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", + "dev": true + }, "public-encrypt": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz", - "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", "dev": true, + "optional": 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" + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" } }, "pull-cat": { @@ -16954,9 +16803,9 @@ } }, "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", "dev": true }, "qs": { @@ -16967,7 +16816,7 @@ }, "query-string": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", + "resolved": "http://registry.npmjs.org/query-string/-/query-string-5.1.1.tgz", "integrity": "sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw==", "dev": true, "requires": { @@ -16990,6 +16839,7 @@ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", "dev": true, + "optional": true, "requires": { "randombytes": "^2.0.5", "safe-buffer": "^5.1.0" @@ -17042,7 +16892,7 @@ }, "readable-stream": { "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", "dev": true, "requires": { @@ -17081,7 +16931,8 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", + "dev": true }, "regenerator-transform": { "version": "0.10.1", @@ -17107,7 +16958,7 @@ }, "regjsgen": { "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=", "dev": true }, @@ -17130,39 +16981,31 @@ } }, "request": { - "version": "2.87.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz", - "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==", + "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.6.0", + "aws4": "^1.8.0", "caseless": "~0.12.0", - "combined-stream": "~1.0.5", - "extend": "~3.0.1", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", "forever-agent": "~0.6.1", - "form-data": "~2.3.1", - "har-validator": "~5.0.3", + "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.17", - "oauth-sign": "~0.8.2", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", "performance-now": "^2.1.0", - "qs": "~6.5.1", - "safe-buffer": "^5.1.1", - "tough-cookie": "~2.3.3", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", - "uuid": "^3.1.0" - }, - "dependencies": { - "uuid": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", - "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", - "dev": true - } + "uuid": "^3.3.2" } }, "require-directory": { @@ -17184,9 +17027,9 @@ "dev": true }, "resolve": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.5.0.tgz", - "integrity": "sha512-hgoSGrc3pjzAPHNBg+KnFcK2HwlHTs/YrAGUr6qgTVUZmXv1UEXXl0bZNBKMA9fud6lRYFdPGz0xXxycPzmmiw==", + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.7.1.tgz", + "integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==", "dev": true, "requires": { "path-parse": "^1.0.5" @@ -17205,7 +17048,6 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", - "dev": true, "requires": { "glob": "^7.0.5" } @@ -17214,29 +17056,38 @@ "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" } }, "rlp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.0.0.tgz", - "integrity": "sha1-nbOE/0uJqPYVY9kjldhiWxjzr7A=", - "dev": true + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.1.0.tgz", + "integrity": "sha512-93U7IKH5j7nmXFVg19MeNBGzQW5uXW1pmCuKY8veeKIhYTE32C2d0mOegfiIAfXcHOKJjjPlJisn8iHDF5AezA==", + "requires": { + "safe-buffer": "^5.1.1" + } }, "rustbn.js": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.1.2.tgz", - "integrity": "sha512-bAkNqSHYdJdFsBC7Z11JgzYktL31HIpB2o70jZcGiL1U1TVtPyvaVhDrGWwS8uZtaqwW2k6NOPGZCqW/Dgh5Lg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", + "integrity": "sha512-4VlvkRUuCJvr2J6Y0ImW7NvTCriMi7ErOAqWk1y69vAdoNIzCF3yPmgeNzx+RQTLEDFq5sHfscn1MwHxP9hNfA==", "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==", - "dev": true + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + }, + "safe-event-emitter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz", + "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==", + "dev": true, + "requires": { + "events": "^3.0.0" + } }, "safer-buffer": { "version": "2.1.2", @@ -17249,6 +17100,7 @@ "resolved": "https://registry.npmjs.org/scrypt/-/scrypt-6.0.3.tgz", "integrity": "sha1-BOAUpWgrU/pQwtXM4WfXGcBthw0=", "dev": true, + "optional": true, "requires": { "nan": "^2.0.8" } @@ -17258,6 +17110,7 @@ "resolved": "https://registry.npmjs.org/scrypt.js/-/scrypt.js-0.2.0.tgz", "integrity": "sha1-r40UZbcemZARC+38WTuUeeA6ito=", "dev": true, + "optional": true, "requires": { "scrypt": "^6.0.2", "scryptsy": "^1.2.1" @@ -17268,15 +17121,15 @@ "resolved": "https://registry.npmjs.org/scryptsy/-/scryptsy-1.2.1.tgz", "integrity": "sha1-oyJfpLJST4AnAHYeKFW987LZIWM=", "dev": true, + "optional": true, "requires": { "pbkdf2": "^3.0.3" } }, "secp256k1": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", - "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", - "dev": true, + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.2.tgz", + "integrity": "sha512-iin3kojdybY6NArd+UFsoTuapOF7bnJNf2UbcWXaY3z+E1sJDipl60vtzB5hbO/uquBu7z0fd4VC4Irp+xoFVQ==", "requires": { "bindings": "^1.2.1", "bip66": "^1.1.3", @@ -17289,9 +17142,9 @@ } }, "seedrandom": { - "version": "2.4.3", - "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.3.tgz", - "integrity": "sha1-JDhQTa0zkXMUv/GKxNeU8W1qrsw=", + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/seedrandom/-/seedrandom-2.4.4.tgz", + "integrity": "sha512-9A+PDmgm+2du77B5i0Ip2cxOqqHjgNxnBgglxLcX78A2D6c2rTo61z4jnVABpF4cKeDMDG+cmXXvdnqse2VqMA==", "dev": true }, "seek-bzip": { @@ -17299,6 +17152,7 @@ "resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz", "integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=", "dev": true, + "optional": true, "requires": { "commander": "~2.8.1" } @@ -17336,6 +17190,15 @@ "statuses": "~1.4.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" + } + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -17385,7 +17248,8 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true + "dev": true, + "optional": true }, "setprototypeof": { "version": "1.1.0", @@ -17395,9 +17259,8 @@ }, "sha.js": { "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "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" @@ -17412,12 +17275,6 @@ "nan": "2.10.0" } }, - "shebang-loader": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/shebang-loader/-/shebang-loader-0.0.1.tgz", - "integrity": "sha1-pAAEldRMzu++xjQ157FphWn6Uuw=", - "dev": true - }, "simple-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", @@ -17454,26 +17311,17 @@ "yargs": "^4.7.1" }, "dependencies": { - "yargs": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", - "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "fs-extra": { + "version": "0.30.0", + "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "dev": true, "requires": { - "cliui": "^3.2.0", - "decamelize": "^1.1.1", - "get-caller-file": "^1.0.1", - "lodash.assign": "^4.0.3", - "os-locale": "^1.4.0", - "read-pkg-up": "^1.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^1.0.1", - "which-module": "^1.0.0", - "window-size": "^0.2.0", - "y18n": "^3.2.1", - "yargs-parser": "^2.4.1" + "graceful-fs": "^4.1.2", + "jsonfile": "^2.1.0", + "klaw": "^1.0.0", + "path-is-absolute": "^1.0.0", + "rimraf": "^2.2.8" } } } @@ -17484,19 +17332,10 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - }, "spdx-correct": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz", - "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", + "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", @@ -17504,9 +17343,9 @@ } }, "spdx-exceptions": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz", - "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg==", + "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": { @@ -17520,15 +17359,15 @@ } }, "spdx-license-ids": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.0.tgz", - "integrity": "sha512-2+EPwgbnmOIl8HjGBXXMd9NAu02vLjOO1nWw4kmeRDFyHn+M/ETfHxQUK0oXg8ctgVnl9t3rosNVsZ1jG61nDA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", + "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", "dev": true }, "sshpk": { - "version": "1.14.2", - "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.2.tgz", - "integrity": "sha1-xvxhZIo9nE52T9P8306hBeSSupg=", + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.15.2.tgz", + "integrity": "sha512-Ra/OXQtuh0/enyl4ETZAfTaeksa6BXks5ZcjpSUNrjBr0DvrJKX+1fsKDPpT9TBXgHAFsa4510aNVgI8g/+SzA==", "dev": true, "requires": { "asn1": "~0.2.3", @@ -17602,7 +17441,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "dev": true, "requires": { @@ -17623,6 +17462,7 @@ "resolved": "https://registry.npmjs.org/strip-dirs/-/strip-dirs-2.1.0.tgz", "integrity": "sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g==", "dev": true, + "optional": true, "requires": { "is-natural-number": "^4.0.1" } @@ -17631,7 +17471,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/strip-hex-prefix/-/strip-hex-prefix-1.0.0.tgz", "integrity": "sha1-DF8VX+8RUTczd96du1iNoFUA428=", - "dev": true, "requires": { "is-hex-prefixed": "1.0.0" } @@ -17647,6 +17486,7 @@ "resolved": "https://registry.npmjs.org/swarm-js/-/swarm-js-0.1.37.tgz", "integrity": "sha512-G8gi5fcXP/2upwiuOShJ258sIufBVztekgobr3cVgYXObZwJ5AXLqZn52AI+/ffft29pJexF9WNdUxjlkVehoQ==", "dev": true, + "optional": true, "requires": { "bluebird": "^3.5.0", "buffer": "^5.0.5", @@ -17661,36 +17501,24 @@ "setimmediate": "^1.0.5", "tar.gz": "^1.0.5", "xhr-request-promise": "^0.1.2" - }, - "dependencies": { - "fs-extra": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", - "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0" - } - } } }, "tape": { - "version": "4.9.0", - "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.0.tgz", - "integrity": "sha512-j0jO9BiScfqtPBb9QmPLL0qvxXMz98xjkMb7x8lKipFlJZwNJkqkWPou+NU4V6T9RnVh1kuSthLE8gLrN8bBfw==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/tape/-/tape-4.9.1.tgz", + "integrity": "sha512-6fKIXknLpoe/Jp4rzHKFPpJUHDHDqn8jus99IfPnHIjyz78HYlefTGD3b5EkbQzuLfaEvmfPK3IolLgq2xT3kw==", "dev": true, "requires": { "deep-equal": "~1.0.1", "defined": "~1.0.0", - "for-each": "~0.3.2", + "for-each": "~0.3.3", "function-bind": "~1.1.1", "glob": "~7.1.2", - "has": "~1.0.1", + "has": "~1.0.3", "inherits": "~2.0.3", "minimist": "~1.2.0", - "object-inspect": "~1.5.0", - "resolve": "~1.5.0", + "object-inspect": "~1.6.0", + "resolve": "~1.7.1", "resumer": "~0.0.0", "string.prototype.trim": "~1.1.2", "through": "~2.3.8" @@ -17698,7 +17526,7 @@ "dependencies": { "minimist": { "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "resolved": "http://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", "dev": true } @@ -17706,9 +17534,10 @@ }, "tar": { "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, + "optional": true, "requires": { "block-stream": "*", "fstream": "^1.0.2", @@ -17716,30 +17545,19 @@ } }, "tar-stream": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.1.tgz", - "integrity": "sha512-IFLM5wp3QrJODQFPm6/to3LJZrONdBY/otxcvDIQzu217zKye6yVR3hhi9lAjrC2Z+m/j5oDxMPb1qcd8cIvpA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", + "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, + "optional": true, "requires": { "bl": "^1.0.0", - "buffer-alloc": "^1.1.0", + "buffer-alloc": "^1.2.0", "end-of-stream": "^1.0.0", "fs-constants": "^1.0.0", "readable-stream": "^2.3.0", - "to-buffer": "^1.1.0", + "to-buffer": "^1.1.1", "xtend": "^4.0.0" - }, - "dependencies": { - "bl": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", - "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, - "requires": { - "readable-stream": "^2.3.5", - "safe-buffer": "^5.1.1" - } - } } }, "tar.gz": { @@ -17747,6 +17565,7 @@ "resolved": "https://registry.npmjs.org/tar.gz/-/tar.gz-1.0.7.tgz", "integrity": "sha512-uhGatJvds/3diZrETqMj4RxBR779LKlIE74SsMcn5JProZsfs9j0QBwWO1RW+IWNJxS2x8Zzra1+AW6OQHWphg==", "dev": true, + "optional": true, "requires": { "bluebird": "^2.9.34", "commander": "^2.8.1", @@ -17757,27 +17576,10 @@ "dependencies": { "bluebird": { "version": "2.11.0", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", + "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-2.11.0.tgz", "integrity": "sha1-U0uQM8AiyVecVro7Plpcqvu2UOE=", - "dev": true - } - } - }, - "temp": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", - "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", - "dev": true, - "requires": { - "os-tmpdir": "^1.0.0", - "rimraf": "~2.2.6" - }, - "dependencies": { - "rimraf": { - "version": "2.2.8", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", - "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=", - "dev": true + "dev": true, + "optional": true } } }, @@ -17786,6 +17588,7 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", "dev": true, + "optional": true, "requires": { "any-promise": "^1.0.0" } @@ -17795,23 +17598,24 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", "dev": true, + "optional": true, "requires": { "thenify": ">= 3.1.0 < 4" } }, "through": { "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", "dev": true }, "through2": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", - "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", + "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.1.5", + "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, @@ -17821,26 +17625,21 @@ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, - "tiny-queue": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.0.tgz", - "integrity": "sha1-xJ/LXIdVW+G0pd9+uHEB1beLydw=", - "dev": true - }, "tmp": { - "version": "0.0.31", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.31.tgz", - "integrity": "sha1-jzirlDjhcxXl29izZX6L+yd65Kc=", + "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.1" + "os-tmpdir": "~1.0.2" } }, "to-buffer": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true + "dev": true, + "optional": true }, "to-fast-properties": { "version": "1.0.3", @@ -17849,12 +17648,21 @@ "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==", + "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 + } } }, "treeify": { @@ -17888,13 +17696,6 @@ "version": "0.14.5", "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz", "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", - "dev": true, - "optional": true - }, - "type-detect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", - "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=", "dev": true }, "type-is": { @@ -17950,10 +17751,11 @@ "dev": true }, "unbzip2-stream": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.2.5.tgz", - "integrity": "sha512-izD3jxT8xkzwtXRUZjtmRwKnZoeECrfZ8ra/ketwOcusbZEp4mjULMnJOCfTDZBgGQAAY1AJ/IgxcwkavcX9Og==", + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.1.tgz", + "integrity": "sha512-fIZnvdjblYs7Cru/xC6tCPVhz7JkYcVQQkePwMLyQELzYTds2Xn8QefPVnvdVhhZqubxNA1cASXEH5wcK0Bucw==", "dev": true, + "optional": true, "requires": { "buffer": "^3.0.1", "through": "^2.3.6" @@ -17963,13 +17765,15 @@ "version": "0.0.8", "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-0.0.8.tgz", "integrity": "sha1-EQHpVE9KdrG8OybUUsqW16NeeXg=", - "dev": true + "dev": true, + "optional": true }, "buffer": { "version": "3.6.0", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", + "resolved": "http://registry.npmjs.org/buffer/-/buffer-3.6.0.tgz", "integrity": "sha1-pyyTb3e5a/UvX357RnGAYoVR3vs=", "dev": true, + "optional": true, "requires": { "base64-js": "0.0.8", "ieee754": "^1.1.4", @@ -17980,7 +17784,8 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true + "dev": true, + "optional": true } } }, @@ -18002,6 +17807,15 @@ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", "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" + } + }, "url-parse-lax": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-1.0.0.tgz", @@ -18024,25 +17838,11 @@ "dev": true }, "utf8": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", - "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "requires": { - "inherits": "2.0.1" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" - } - } + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==", + "dev": true, + "optional": true }, "util-deprecate": { "version": "1.0.2", @@ -18057,15 +17857,15 @@ "dev": true }, "uuid": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz", - "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=", + "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.3", - "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz", - "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==", + "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", @@ -18090,25 +17890,27 @@ } }, "web3": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.34.tgz", - "integrity": "sha1-NH5WG3hAmMtVYzFfSQR5odkfKrE=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3/-/web3-1.0.0-beta.35.tgz", + "integrity": "sha512-xwDmUhvTcHQvvNnOPcPZZgCxKUsI2e+GbHy7JkTK3/Rmnutazy8x7fsAXT9myw7V1qpi3GgLoZ3fkglSUbg1Mg==", "dev": true, + "optional": true, "requires": { - "web3-bzz": "1.0.0-beta.34", - "web3-core": "1.0.0-beta.34", - "web3-eth": "1.0.0-beta.34", - "web3-eth-personal": "1.0.0-beta.34", - "web3-net": "1.0.0-beta.34", - "web3-shh": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-bzz": "1.0.0-beta.35", + "web3-core": "1.0.0-beta.35", + "web3-eth": "1.0.0-beta.35", + "web3-eth-personal": "1.0.0-beta.35", + "web3-net": "1.0.0-beta.35", + "web3-shh": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-bzz": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.34.tgz", - "integrity": "sha1-Bo03d3q2Xlxg+OyLmlDP5FJ3kpw=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-bzz/-/web3-bzz-1.0.0-beta.35.tgz", + "integrity": "sha512-BhAU0qhlr8zltm4gs/+P1gki2VkxHJaM2Rrh4DGesDW0lzwufRoNvWFlwx1bKHoFPWNbSmm9PRkHOYOINL/Tgw==", "dev": true, + "optional": true, "requires": { "got": "7.1.0", "swarm-js": "0.1.37", @@ -18116,45 +17918,45 @@ } }, "web3-core": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.34.tgz", - "integrity": "sha1-EhvoVV6fsA0sXQXd0zgdDJ5GmH4=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-core/-/web3-core-1.0.0-beta.35.tgz", + "integrity": "sha512-ayGavbgVk4KL9Y88Uv411fBJ0SVgVfKhKEBweKYzmP0zOqneMzWt6YsyD1n6kRvjAbqA0AfUPEOKyMNjcx2tjw==", "dev": true, "requires": { - "web3-core-helpers": "1.0.0-beta.34", - "web3-core-method": "1.0.0-beta.34", - "web3-core-requestmanager": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core-helpers": "1.0.0-beta.35", + "web3-core-method": "1.0.0-beta.35", + "web3-core-requestmanager": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-core-helpers": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.34.tgz", - "integrity": "sha1-sWjaANPhnhVrwVriAyA91N/uLQM=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-core-helpers/-/web3-core-helpers-1.0.0-beta.35.tgz", + "integrity": "sha512-APOu3sEsamyqWt//8o4yq9KF25/uqGm+pQShson/sC4gKzmfJB07fLo2ond0X30E8fIqAPeVCotPXQxGciGUmA==", "dev": true, "requires": { "underscore": "1.8.3", - "web3-eth-iban": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-eth-iban": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-core-method": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.34.tgz", - "integrity": "sha1-7BY8iixJD6AqfsFVWfpzB/x8xt0=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-core-method/-/web3-core-method-1.0.0-beta.35.tgz", + "integrity": "sha512-jidImCide8q0GpfsO4L73qoHrbkeWgwU3uOH5DKtJtv0ccmG086knNMRgryb/o9ZgetDWLmDEsJnHjBSoIwcbA==", "dev": true, "requires": { "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.34", - "web3-core-promievent": "1.0.0-beta.34", - "web3-core-subscriptions": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core-helpers": "1.0.0-beta.35", + "web3-core-promievent": "1.0.0-beta.35", + "web3-core-subscriptions": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-core-promievent": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.34.tgz", - "integrity": "sha1-pPT6Z4S7KT6CxglgrltWqUzQPtw=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-core-promievent/-/web3-core-promievent-1.0.0-beta.35.tgz", + "integrity": "sha512-GvqXqKq07OmHuVi5uNRg6k79a1/CI0ViCC+EtNv4CORHtDRmYEt5Bvdv6z6FJEiaaQkD0lKbFwNhLxutx7HItw==", "dev": true, "requires": { "any-promise": "1.3.0", @@ -18162,66 +17964,76 @@ } }, "web3-core-requestmanager": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.34.tgz", - "integrity": "sha1-Afj2zyrmtvC3DDi64e90G1urIVw=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-core-requestmanager/-/web3-core-requestmanager-1.0.0-beta.35.tgz", + "integrity": "sha512-S+zW2h17ZZQU9oe3yaCJE0E7aJS4C3Kf4kGPDv+nXjW0gKhQQhgVhw1Doq/aYQGqNSWJp7f1VHkz5gQWwg6RRg==", "dev": true, "requires": { "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.34", - "web3-providers-http": "1.0.0-beta.34", - "web3-providers-ipc": "1.0.0-beta.34", - "web3-providers-ws": "1.0.0-beta.34" + "web3-core-helpers": "1.0.0-beta.35", + "web3-providers-http": "1.0.0-beta.35", + "web3-providers-ipc": "1.0.0-beta.35", + "web3-providers-ws": "1.0.0-beta.35" } }, "web3-core-subscriptions": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.34.tgz", - "integrity": "sha1-n+0UQDPyIcPPIQYDAv/a9e8t4t4=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-core-subscriptions/-/web3-core-subscriptions-1.0.0-beta.35.tgz", + "integrity": "sha512-gXzLrWvcGkGiWq1y33Z4Y80XI8XMrwowiQJkrPSjQ81K5PBKquOGwcMffLaKcwdmEy/NpsOXDeFo3eLE1Ghvvw==", "dev": true, "requires": { "eventemitter3": "1.1.1", "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.34" + "web3-core-helpers": "1.0.0-beta.35" } }, "web3-eth": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.34.tgz", - "integrity": "sha1-dAhgAIUMb+b1Ne9Jg31tS7YRMmg=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-eth/-/web3-eth-1.0.0-beta.35.tgz", + "integrity": "sha512-04mcb2nGPXThawuuYICPOxv0xOHofvQKsjZeIq+89nyOC8DQMGTAErDkGyMHQYtjpth5XDhic0wuEsA80AmFZA==", "dev": true, + "optional": true, "requires": { "underscore": "1.8.3", - "web3-core": "1.0.0-beta.34", - "web3-core-helpers": "1.0.0-beta.34", - "web3-core-method": "1.0.0-beta.34", - "web3-core-subscriptions": "1.0.0-beta.34", - "web3-eth-abi": "1.0.0-beta.34", - "web3-eth-accounts": "1.0.0-beta.34", - "web3-eth-contract": "1.0.0-beta.34", - "web3-eth-iban": "1.0.0-beta.34", - "web3-eth-personal": "1.0.0-beta.34", - "web3-net": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core": "1.0.0-beta.35", + "web3-core-helpers": "1.0.0-beta.35", + "web3-core-method": "1.0.0-beta.35", + "web3-core-subscriptions": "1.0.0-beta.35", + "web3-eth-abi": "1.0.0-beta.35", + "web3-eth-accounts": "1.0.0-beta.35", + "web3-eth-contract": "1.0.0-beta.35", + "web3-eth-iban": "1.0.0-beta.35", + "web3-eth-personal": "1.0.0-beta.35", + "web3-net": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-eth-abi": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.34.tgz", - "integrity": "sha1-A0Uz46ovfln/MXk+rqaFwO1a9no=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-eth-abi/-/web3-eth-abi-1.0.0-beta.35.tgz", + "integrity": "sha512-KUDC+EtFFYG8z01ZleKrASdjj327/rtWHzEt6RWsEj7bBa0bGp9nEh+nqdZx/Sdgz1O8tnfFzJlrRcXpfr1vGg==", "dev": true, "requires": { "bn.js": "4.11.6", "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core-helpers": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + } } }, "web3-eth-accounts": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.34.tgz", - "integrity": "sha1-4JFC7uzHl6w0WbdemyOUbTaV8zM=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-eth-accounts/-/web3-eth-accounts-1.0.0-beta.35.tgz", + "integrity": "sha512-duIgRsfht/0kAW/eQ0X9lKtVIykbETrnM2H7EnvplCzPHtQLodpib4o9JXfh9n6ZDgdDC7cuJoiVB9QJg089ew==", "dev": true, + "optional": true, "requires": { "any-promise": "1.3.0", "crypto-browserify": "3.12.0", @@ -18229,10 +18041,10 @@ "scrypt.js": "0.2.0", "underscore": "1.8.3", "uuid": "2.0.1", - "web3-core": "1.0.0-beta.34", - "web3-core-helpers": "1.0.0-beta.34", - "web3-core-method": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core": "1.0.0-beta.35", + "web3-core-helpers": "1.0.0-beta.35", + "web3-core-method": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" }, "dependencies": { "eth-lib": { @@ -18240,6 +18052,7 @@ "resolved": "https://registry.npmjs.org/eth-lib/-/eth-lib-0.2.7.tgz", "integrity": "sha1-L5Pxex4jrsN1nNSj/iDBKGo/wco=", "dev": true, + "optional": true, "requires": { "bn.js": "^4.11.6", "elliptic": "^6.4.0", @@ -18248,66 +18061,76 @@ }, "uuid": { "version": "2.0.1", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", + "resolved": "http://registry.npmjs.org/uuid/-/uuid-2.0.1.tgz", "integrity": "sha1-wqMN7bPlNdcsz4LjQ5QaULqFM6w=", - "dev": true + "dev": true, + "optional": true } } }, "web3-eth-contract": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.34.tgz", - "integrity": "sha1-nbs4+udkOoCEJ6IBgEcOx0FckeY=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-eth-contract/-/web3-eth-contract-1.0.0-beta.35.tgz", + "integrity": "sha512-foPohOg5O1UCGKGZOIs+kQK5IZdV2QQ7pAWwNxH8WHplUA+fre1MurXNpoxknUmH6mYplFhXjqgYq2MsrBpHrA==", "dev": true, + "optional": true, "requires": { "underscore": "1.8.3", - "web3-core": "1.0.0-beta.34", - "web3-core-helpers": "1.0.0-beta.34", - "web3-core-method": "1.0.0-beta.34", - "web3-core-promievent": "1.0.0-beta.34", - "web3-core-subscriptions": "1.0.0-beta.34", - "web3-eth-abi": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core": "1.0.0-beta.35", + "web3-core-helpers": "1.0.0-beta.35", + "web3-core-method": "1.0.0-beta.35", + "web3-core-promievent": "1.0.0-beta.35", + "web3-core-subscriptions": "1.0.0-beta.35", + "web3-eth-abi": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-eth-iban": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.34.tgz", - "integrity": "sha1-mvRYYFhnzPdOqXmq8yazi6alugw=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-eth-iban/-/web3-eth-iban-1.0.0-beta.35.tgz", + "integrity": "sha512-H5wkcNcAIc+h/WoDIKv7ZYmrM2Xqu3O7jBQl1IWo73EDVQji+AoB2i3J8tuwI1yZRInRwrfpI3Zuwuf54hXHmQ==", "dev": true, "requires": { "bn.js": "4.11.6", - "web3-utils": "1.0.0-beta.34" + "web3-utils": "1.0.0-beta.35" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + } } }, "web3-eth-personal": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.34.tgz", - "integrity": "sha1-mvuhZzQuveVCC81YlcP2w0OI8gU=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-eth-personal/-/web3-eth-personal-1.0.0-beta.35.tgz", + "integrity": "sha512-AcM9nnlxu7ZRRxPvkrFB9eLxMM4A2cPfj2aCg21Wb2EpMnhR+b/O1cT33k7ApRowoMpM+T9M8vx2oPNwXfaCOQ==", "dev": true, "requires": { - "web3-core": "1.0.0-beta.34", - "web3-core-helpers": "1.0.0-beta.34", - "web3-core-method": "1.0.0-beta.34", - "web3-net": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core": "1.0.0-beta.35", + "web3-core-helpers": "1.0.0-beta.35", + "web3-core-method": "1.0.0-beta.35", + "web3-net": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-net": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.34.tgz", - "integrity": "sha1-QnzqL0MYgUScjjjVIykPFz+f9j0=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-net/-/web3-net-1.0.0-beta.35.tgz", + "integrity": "sha512-bbwaQ/KohGjIJ6HAKbZ6KrklCAaG6/B7hIbAbVLSFLxF+Yz9lmAgQYaDInpidpC/NLb3WOmcbRF+P77J4qMVIA==", "dev": true, "requires": { - "web3-core": "1.0.0-beta.34", - "web3-core-method": "1.0.0-beta.34", - "web3-utils": "1.0.0-beta.34" + "web3-core": "1.0.0-beta.35", + "web3-core-method": "1.0.0-beta.35", + "web3-utils": "1.0.0-beta.35" } }, "web3-provider-engine": { - "version": "14.0.6", - "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.0.6.tgz", - "integrity": "sha512-tr5cGSyxfSC/JqiUpBlJtfZpwQf1yAA8L/zy1C6fDFm0ntR974pobJ4v4676atpZne4Ze5VFy3kPPahHe9gQiQ==", + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/web3-provider-engine/-/web3-provider-engine-14.1.0.tgz", + "integrity": "sha512-vGZtqhSUzGTiMGhJXNnB/aRDlrPZLhLnBZ2NPArkZtr8XSrwg9m08tw4+PuWg5za0TJuoE/vuPQc501HddZZWw==", "dev": true, "requires": { "async": "^2.5.0", @@ -18325,9 +18148,8 @@ "json-stable-stringify": "^1.0.1", "promise-to-callback": "^1.0.0", "readable-stream": "^2.2.9", - "request": "^2.67.0", + "request": "^2.85.0", "semaphore": "^1.0.3", - "tape": "^4.4.0", "ws": "^5.1.1", "xhr": "^2.2.0", "xtend": "^4.0.1" @@ -18339,23 +18161,23 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", "ethereumjs-util": "^5.1.1" - } - }, - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "from": "ethereumjs-abi@git+https://github.com/ethereumjs/ethereumjs-abi.git#00ba8463a7f7a67fcad737ff9c2ebd95643427f7", - "dev": true, - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" + }, + "dependencies": { + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + } } }, "ws": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.0.tgz", - "integrity": "sha512-c18dMeW+PEQdDFzkhDsnBAlS4Z8KGStBQQUcQ5mf7Nf689jyGk0594L+i9RaQuf4gog6SvWLJorz2NfSaqxZ7w==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", + "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==", "dev": true, "requires": { "async-limiter": "~1.0.0" @@ -18364,66 +18186,63 @@ } }, "web3-providers-http": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.34.tgz", - "integrity": "sha1-5WG1K7tDdmKCAH1AKFv+NVDCfno=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-providers-http/-/web3-providers-http-1.0.0-beta.35.tgz", + "integrity": "sha512-DcIMFq52Fb08UpWyZ3ZlES6NsNqJnco4hBS/Ej6eOcASfuUayPI+GLkYVZsnF3cBYqlH+DOKuArcKSuIxK7jIA==", "dev": true, "requires": { - "web3-core-helpers": "1.0.0-beta.34", - "xhr2": "0.1.4" + "web3-core-helpers": "1.0.0-beta.35", + "xhr2-cookies": "1.1.0" } }, "web3-providers-ipc": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.34.tgz", - "integrity": "sha1-obd/GjBtc2SanAOQUuQMtxMo0Ao=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-providers-ipc/-/web3-providers-ipc-1.0.0-beta.35.tgz", + "integrity": "sha512-iB0FG0HcpUnayfa8pn4guqEQ4Y1nrroi/jffdtQgFkrNt0sD3fMSwwC0AbmECqj3tDLl0e1slBR0RENll+ZF0g==", "dev": true, "requires": { "oboe": "2.1.3", "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.34" + "web3-core-helpers": "1.0.0-beta.35" } }, "web3-providers-ws": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.34.tgz", - "integrity": "sha1-fecPG4Py3jZHZ3IVa+z+9uNRbrM=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-providers-ws/-/web3-providers-ws-1.0.0-beta.35.tgz", + "integrity": "sha512-Cx64NgDStynKaUGDIIOfaCd0fZusL8h5avKTkdTjUu2aHhFJhZoVBGVLhoDtUaqZGWIZGcBJOoVf2JkGUOjDRQ==", "dev": true, "requires": { "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.34", - "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" + "web3-core-helpers": "1.0.0-beta.35" }, "dependencies": { - "websocket": { - "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", - "from": "websocket@git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", - "dev": true, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", "requires": { - "debug": "^2.2.0", - "nan": "^2.3.3", - "typedarray-to-buffer": "^3.1.2", - "yaeti": "^0.0.6" + "ms": "2.0.0" } } } }, "web3-shh": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.34.tgz", - "integrity": "sha1-l1Bh1x6uxCzO5Xb3vY9w8DhEr+A=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-shh/-/web3-shh-1.0.0-beta.35.tgz", + "integrity": "sha512-8qSonk/x0xabERS9Sr6AIADN/Ty+5KwARkkGIfSYHKqFpdMDz+76F7cUCxtoCZoS8K04xgZlDKYe0TJXLYA0Fw==", "dev": true, + "optional": true, "requires": { - "web3-core": "1.0.0-beta.34", - "web3-core-method": "1.0.0-beta.34", - "web3-core-subscriptions": "1.0.0-beta.34", - "web3-net": "1.0.0-beta.34" + "web3-core": "1.0.0-beta.35", + "web3-core-method": "1.0.0-beta.35", + "web3-core-subscriptions": "1.0.0-beta.35", + "web3-net": "1.0.0-beta.35" } }, "web3-utils": { - "version": "1.0.0-beta.34", - "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.34.tgz", - "integrity": "sha1-lBH8OarvOcpOBhafdiKX2f8CCXA=", + "version": "1.0.0-beta.35", + "resolved": "https://registry.npmjs.org/web3-utils/-/web3-utils-1.0.0-beta.35.tgz", + "integrity": "sha512-Dq6f0SOKj3BDFRgOPnE6ALbzBDCKVIW8mKWVf7tGVhTDHf+wQaWwQSC3aArFSqdExB75BPBPyDpuMTNszhljpA==", "dev": true, "requires": { "bn.js": "4.11.6", @@ -18435,9 +18254,15 @@ "utf8": "2.1.1" }, "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, "utf8": { "version": "2.1.1", - "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", + "resolved": "http://registry.npmjs.org/utf8/-/utf8-2.1.1.tgz", "integrity": "sha1-LgHbAvfY0JRPdxBPFgnrDDBM92g=", "dev": true } @@ -18453,11 +18278,22 @@ "nan": "^2.3.3", "typedarray-to-buffer": "^3.1.2", "yaeti": "^0.0.6" + }, + "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" + } + } } }, "whatwg-fetch": { "version": "2.0.4", - "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", + "resolved": "http://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==", "dev": true }, @@ -18475,7 +18311,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "dev": true, "requires": { @@ -18535,11 +18371,14 @@ "xhr-request": "^1.0.1" } }, - "xhr2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", - "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=", - "dev": true + "xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "dev": true, + "requires": { + "cookiejar": "^2.1.1" + } }, "xtend": { "version": "4.0.1", @@ -18560,40 +18399,30 @@ "dev": true }, "yargs": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", - "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "version": "4.8.1", + "resolved": "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "dev": true, "requires": { - "camelcase": "^3.0.0", "cliui": "^3.2.0", "decamelize": "^1.1.1", "get-caller-file": "^1.0.1", + "lodash.assign": "^4.0.3", "os-locale": "^1.4.0", "read-pkg-up": "^1.0.1", "require-directory": "^2.1.1", "require-main-filename": "^1.0.1", "set-blocking": "^2.0.0", - "string-width": "^1.0.2", + "string-width": "^1.0.1", "which-module": "^1.0.0", + "window-size": "^0.2.0", "y18n": "^3.2.1", - "yargs-parser": "^5.0.0" - }, - "dependencies": { - "yargs-parser": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", - "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", - "dev": true, - "requires": { - "camelcase": "^3.0.0" - } - } + "yargs-parser": "^2.4.1" } }, "yargs-parser": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "dev": true, "requires": { @@ -18602,13 +18431,14 @@ } }, "yauzl": { - "version": "2.9.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.9.1.tgz", - "integrity": "sha1-qBmB6nCleUYTOIPwKcWCGok1mn8=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "dev": true, + "optional": true, "requires": { "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.0.1" + "fd-slicer": "~1.1.0" } } } diff --git a/package.json b/package.json index 5600b5f37ed7..c3b38a994a5e 100644 --- a/package.json +++ b/package.json @@ -268,7 +268,7 @@ "fs-extra": "^6.0.1", "fs-promise": "^2.0.3", "ganache-cli": "^6.1.0", - "ganache-core": "^2.2.1", + "ganache-core": "^2.3.1", "geckodriver": "^1.14.1", "gh-pages": "^1.2.0", "gifencoder": "^1.1.0", From d7c8a3048f6f3a22a26e0da61a83cfa6a74b382b Mon Sep 17 00:00:00 2001 From: Whymarrh Whitby Date: Thu, 6 Dec 2018 12:14:32 -0330 Subject: [PATCH 56/64] Deduplicate package.json file From `npm install`: > npm WARN The package css-loader is included as both a dev and production dependency. > npm WARN The package eslint-plugin-react is included as both a dev and production dependency. > npm WARN The package file-loader is included as both a dev and production dependency. > npm WARN The package gulp is included as both a dev and production dependency. It's also worth noting that the Gulp version we were using was inconsistent and there is a published v4 release on GitHub. --- package-lock.json | 1350 ++++++++++++++++++++++++++++++++++----------- package.json | 14 +- 2 files changed, 1042 insertions(+), 322 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4decb301d10a..e145c424db34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1894,6 +1894,7 @@ "version": "3.0.1", "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", + "dev": true, "requires": { "acorn": "^3.0.4" }, @@ -1901,7 +1902,8 @@ "acorn": { "version": "3.3.0", "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", - "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=" + "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", + "dev": true } } }, @@ -2770,7 +2772,8 @@ "ajv-keywords": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz", - "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=" + "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I=", + "dev": true }, "ajv-merge-patch": { "version": "4.1.0", @@ -2795,7 +2798,8 @@ "alphanum-sort": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", - "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=" + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true }, "amdefine": { "version": "1.0.1", @@ -2806,6 +2810,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-1.0.1.tgz", "integrity": "sha512-yopkAU0ZD/WQ56Tms3xLn6jRuX3SyUMAVi0FdmDIbmmnHW3jHiI1sQFdUl3gfVddjnrsP3Y6ywFKvCRopvoVIA==", + "dev": true, "requires": { "ansi-wrap": "^0.1.0" } @@ -2822,12 +2827,14 @@ "ansi-escapes": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.0.0.tgz", - "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==" + "integrity": "sha512-O/klc27mWNUigtv0F8NJWbLF00OcegQalkqKURWdosW08YZKi4m6CnSUSvIZG1otNJbTWhN01Hhz389DW7mvDQ==", + "dev": true }, "ansi-gray": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz", "integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=", + "dev": true, "requires": { "ansi-wrap": "0.1.0" } @@ -2860,7 +2867,8 @@ "ansi-wrap": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz", - "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=" + "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=", + "dev": true }, "ansicolors": { "version": "0.3.2", @@ -2886,6 +2894,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, "requires": { "buffer-equal": "^1.0.0" } @@ -2904,7 +2913,8 @@ "archy": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=" + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true }, "are-we-there-yet": { "version": "1.1.4", @@ -2919,6 +2929,7 @@ "version": "1.0.9", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz", "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=", + "dev": true, "requires": { "sprintf-js": "~1.0.2" } @@ -2935,6 +2946,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/arr-filter/-/arr-filter-1.1.2.tgz", "integrity": "sha1-Q/3d0JHo7xGqTEXZzcGOLf8XEe4=", + "dev": true, "requires": { "make-iterator": "^1.0.0" } @@ -2948,6 +2960,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/arr-map/-/arr-map-2.0.2.tgz", "integrity": "sha1-Onc0X/wc814qkYJWAfnljy4kysQ=", + "dev": true, "requires": { "make-iterator": "^1.0.0" } @@ -2955,17 +2968,20 @@ "arr-union": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=" + "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=" + "integrity": "sha1-7/UuN1gknTO+QCuLuOVkuytdQDE=", + "dev": true }, "array-each": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/array-each/-/array-each-1.0.1.tgz", - "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=" + "integrity": "sha1-p5SvDAWrF1KEbudTofIRoFugxE8=", + "dev": true }, "array-equal": { "version": "1.0.0", @@ -2988,7 +3004,8 @@ "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=" + "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E=", + "dev": true }, "array-flatten": { "version": "1.1.1", @@ -3005,6 +3022,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, "requires": { "define-properties": "^1.1.2", "es-abstract": "^1.7.0" @@ -3014,6 +3032,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-initial/-/array-initial-1.1.0.tgz", "integrity": "sha1-L6dLJnOTccOUe9enrcc74zSz15U=", + "dev": true, "requires": { "array-slice": "^1.0.0", "is-number": "^4.0.0" @@ -3022,7 +3041,8 @@ "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } } }, @@ -3030,6 +3050,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/array-last/-/array-last-1.3.0.tgz", "integrity": "sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==", + "dev": true, "requires": { "is-number": "^4.0.0" }, @@ -3037,7 +3058,8 @@ "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } } }, @@ -3056,12 +3078,14 @@ "array-slice": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz", - "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==" + "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==", + "dev": true }, "array-sort": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-sort/-/array-sort-1.0.0.tgz", "integrity": "sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==", + "dev": true, "requires": { "default-compare": "^1.0.0", "get-value": "^2.0.6", @@ -3071,7 +3095,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -3079,6 +3104,7 @@ "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" } @@ -3086,7 +3112,8 @@ "array-uniq": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=" + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true }, "array-unique": { "version": "0.2.1", @@ -3135,7 +3162,8 @@ "arrify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=" + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true }, "asap": { "version": "2.0.6", @@ -3183,7 +3211,8 @@ "assign-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=" + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true }, "ast-types": { "version": "0.9.6", @@ -3202,6 +3231,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/async-done/-/async-done-1.3.1.tgz", "integrity": "sha512-R1BaUeJ4PMoLNJuk+0tLJgjmEqVsdN118+Z8O+alhnQDQgy0kmD5Mqi0DNEmMx2LM0Ed5yekKu+ZXYvIHceicg==", + "dev": true, "requires": { "end-of-stream": "^1.1.0", "once": "^1.3.2", @@ -3225,7 +3255,8 @@ "async-foreach": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/async-foreach/-/async-foreach-0.1.3.tgz", - "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=" + "integrity": "sha1-NhIfhFwFeBct5Bmpfb6x0W7DRUI=", + "dev": true }, "async-limiter": { "version": "1.0.0", @@ -3242,6 +3273,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/async-settle/-/async-settle-1.0.0.tgz", "integrity": "sha1-HQqRS7Aldb7IqPOnTlCA9yssDGs=", + "dev": true, "requires": { "async-done": "^1.2.2" } @@ -3313,12 +3345,14 @@ "atob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz", - "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=" + "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=", + "dev": true }, "autoprefixer": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-8.1.0.tgz", "integrity": "sha512-b6mjq6VZ0guW6evRkKXL5sSSvIXICAE9dyWReZ3l/riidU7bVaJMe5cQ512SmaLA4Pvgnhi5MFsMs/Mvyh9//Q==", + "dev": true, "requires": { "browserslist": "^3.1.1", "caniuse-lite": "^1.0.30000810", @@ -3332,6 +3366,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.1.2.tgz", "integrity": "sha512-iO5MiK7MZXejqfnCK8onktxxb+mcW+KMiL/5gGF/UCWvVgPzbgbkA5cyYfqj/IIHHo7X1z0znrSHPw9AIfpvrw==", + "dev": true, "requires": { "caniuse-lite": "^1.0.30000813", "electron-to-chromium": "^1.3.36" @@ -3340,12 +3375,14 @@ "caniuse-lite": { "version": "1.0.30000813", "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000813.tgz", - "integrity": "sha512-A8ITSmH5SFdMFdC704ggjg+x2z5PzQmVlG8tavwnfvbC33Q1UYrj0+G+Xm0SNAnd4He36fwUE/KEWytOEchw+A==" + "integrity": "sha512-A8ITSmH5SFdMFdC704ggjg+x2z5PzQmVlG8tavwnfvbC33Q1UYrj0+G+Xm0SNAnd4He36fwUE/KEWytOEchw+A==", + "dev": true }, "electron-to-chromium": { "version": "1.3.37", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.37.tgz", - "integrity": "sha1-SpJzTgBEyM8LFVO+V+riGkxuX6s=" + "integrity": "sha1-SpJzTgBEyM8LFVO+V+riGkxuX6s=", + "dev": true } } }, @@ -4653,6 +4690,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/bach/-/bach-1.2.0.tgz", "integrity": "sha1-Szzpa/JxNPeaG0FKUcFONMO9mIA=", + "dev": true, "requires": { "arr-filter": "^1.1.1", "arr-flatten": "^1.0.1", @@ -4702,6 +4740,7 @@ "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", @@ -4715,7 +4754,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -4758,7 +4798,8 @@ "beeper": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz", - "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=" + "integrity": "sha1-5tXqjF2tABMEpwsiY4RH9pyy+Ak=", + "dev": true }, "better-assert": { "version": "1.0.2", @@ -4833,6 +4874,7 @@ "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" } @@ -5397,7 +5439,8 @@ "buffer-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=" + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true }, "buffer-fill": { "version": "1.0.0", @@ -5477,6 +5520,7 @@ "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", @@ -5492,7 +5536,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -5506,6 +5551,7 @@ "version": "0.1.0", "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz", "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=", + "dev": true, "requires": { "callsites": "^0.2.0" } @@ -5519,7 +5565,8 @@ "callsites": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz", - "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=" + "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo=", + "dev": true }, "camel-case": { "version": "3.0.0", @@ -5540,6 +5587,7 @@ "version": "2.1.0", "resolved": "http://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" @@ -5548,7 +5596,8 @@ "camelcase": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz", - "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=" + "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=", + "dev": true } } }, @@ -5556,6 +5605,7 @@ "version": "1.6.1", "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz", "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=", + "dev": true, "requires": { "browserslist": "^1.3.6", "caniuse-db": "^1.0.30000529", @@ -5567,6 +5617,7 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, "requires": { "caniuse-db": "^1.0.30000639", "electron-to-chromium": "^1.2.7" @@ -5577,7 +5628,8 @@ "caniuse-db": { "version": "1.0.30000808", "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000808.tgz", - "integrity": "sha1-MN/YMAnVcE8C3/s3clBo7RKjZrs=" + "integrity": "sha1-MN/YMAnVcE8C3/s3clBo7RKjZrs=", + "dev": true }, "caniuse-lite": { "version": "1.0.30000865", @@ -5680,7 +5732,8 @@ "chardet": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=" + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true }, "charm": { "version": "1.0.2", @@ -5765,12 +5818,14 @@ "circular-json": { "version": "0.3.3", "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz", - "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==" + "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A==", + "dev": true }, "clap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/clap/-/clap-1.2.3.tgz", "integrity": "sha512-4CoL/A3hf90V3VIEjeuhSvlGFEHKzOz+Wfc2IVZc+FaUgU0ZQafJTP49fvnULipOPcAfqhyI2duwQyns6xqjYA==", + "dev": true, "requires": { "chalk": "^1.1.3" } @@ -5779,6 +5834,7 @@ "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", @@ -5790,6 +5846,7 @@ "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" } @@ -5798,6 +5855,7 @@ "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" }, @@ -5806,6 +5864,7 @@ "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" } @@ -5816,6 +5875,7 @@ "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" }, @@ -5824,6 +5884,7 @@ "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" } @@ -5834,6 +5895,7 @@ "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", @@ -5843,12 +5905,14 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -5888,6 +5952,7 @@ "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" } @@ -5895,7 +5960,8 @@ "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", - "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=" + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true }, "clipboardy": { "version": "1.2.3", @@ -5942,7 +6008,8 @@ "clone-buffer": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=" + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true }, "clone-deep": { "version": "2.0.2", @@ -5986,12 +6053,14 @@ "clone-stats": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=" + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true }, "cloneable-readable": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.0.0.tgz", "integrity": "sha1-pikNQT8hemEjL5XkWP84QYz7ARc=", + "dev": true, "requires": { "inherits": "^2.0.1", "process-nextick-args": "^1.0.6", @@ -6007,6 +6076,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz", "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=", + "dev": true, "requires": { "q": "^1.1.2" } @@ -6041,6 +6111,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-map/-/collection-map-1.0.0.tgz", "integrity": "sha1-rqDwb40mx4DCt1SUOFVEsiVa8Yw=", + "dev": true, "requires": { "arr-map": "^2.0.2", "for-own": "^1.0.0", @@ -6051,6 +6122,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, "requires": { "for-in": "^1.0.1" } @@ -6061,6 +6133,7 @@ "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" @@ -6113,7 +6186,8 @@ "color-support": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==" + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true }, "colorguard": { "version": "1.2.1", @@ -6190,6 +6264,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz", "integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=", + "dev": true, "requires": { "color": "^0.11.0", "css-color-names": "0.0.4", @@ -6199,7 +6274,8 @@ "css-color-names": { "version": "0.0.4", "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", - "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=" + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true } } }, @@ -6320,7 +6396,8 @@ "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", - "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=" + "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY=", + "dev": true }, "component-inherit": { "version": "0.0.3", @@ -6484,12 +6561,14 @@ "copy-descriptor": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=" + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true }, "copy-props": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/copy-props/-/copy-props-2.0.4.tgz", "integrity": "sha512-7cjuUME+p+S3HZlbllgsn2CDwS+5eCCX16qBgNC4jgSTf49qR1VKy/Zhl400m0IQXl/bPGEVqncgUUMjrr4s8A==", + "dev": true, "requires": { "each-props": "^1.3.0", "is-plain-object": "^2.0.1" @@ -6613,6 +6692,7 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", + "dev": true, "requires": { "lru-cache": "^4.0.1", "shebang-command": "^1.2.0", @@ -6714,6 +6794,7 @@ "version": "0.28.11", "resolved": "http://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz", "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==", + "dev": true, "requires": { "babel-code-frame": "^6.26.0", "css-selector-tokenizer": "^0.7.0", @@ -6734,12 +6815,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "loader-utils": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, "requires": { "big.js": "^3.1.3", "emojis-list": "^2.0.0", @@ -6750,6 +6833,7 @@ "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -6760,12 +6844,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -6836,6 +6922,7 @@ "version": "0.7.0", "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz", "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=", + "dev": true, "requires": { "cssesc": "^0.1.0", "fastparse": "^1.1.1", @@ -6846,6 +6933,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz", "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=", + "dev": true, "requires": { "regenerate": "^1.2.1", "regjsgen": "^0.2.0", @@ -6907,12 +6995,14 @@ "cssesc": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-0.1.0.tgz", - "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=" + "integrity": "sha1-yBSQPkViM3GgR3tAEJqq++6t27Q=", + "dev": true }, "cssnano": { "version": "3.10.0", "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", + "dev": true, "requires": { "autoprefixer": "^6.3.1", "decamelize": "^1.1.2", @@ -6952,6 +7042,7 @@ "version": "6.7.7", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz", "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=", + "dev": true, "requires": { "browserslist": "^1.7.6", "caniuse-db": "^1.0.30000634", @@ -6965,6 +7056,7 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, "requires": { "caniuse-db": "^1.0.30000639", "electron-to-chromium": "^1.2.7" @@ -6973,12 +7065,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -6989,12 +7083,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -7005,6 +7101,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz", "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=", + "dev": true, "requires": { "clap": "^1.0.9", "source-map": "^0.5.3" @@ -7013,7 +7110,8 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -7051,6 +7149,7 @@ "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" } @@ -7373,7 +7472,8 @@ "dateformat": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-2.2.0.tgz", - "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=" + "integrity": "sha1-QGXiATz5+5Ft39gu+1Bq1MZ2kGI=", + "dev": true }, "debounce": { "version": "1.1.0", @@ -7428,7 +7528,8 @@ "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=" + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true }, "deep-diff": { "version": "0.3.8", @@ -7463,7 +7564,8 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true }, "deepmerge": { "version": "0.2.10", @@ -7475,6 +7577,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/default-compare/-/default-compare-1.0.0.tgz", "integrity": "sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==", + "dev": true, "requires": { "kind-of": "^5.0.2" }, @@ -7482,14 +7585,16 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, "default-resolution": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/default-resolution/-/default-resolution-2.0.0.tgz", - "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=" + "integrity": "sha1-vLgrqnKtebQmp2cy8aga1t8m1oQ=", + "dev": true }, "defaults": { "version": "1.0.3", @@ -7529,6 +7634,7 @@ "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" } @@ -7656,7 +7762,8 @@ "detect-file": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=" + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true }, "detect-indent": { "version": "4.0.0", @@ -8148,6 +8255,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz", "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==", + "dev": true, "requires": { "esutils": "^2.0.2" } @@ -8430,6 +8538,7 @@ "version": "0.0.2", "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.0.2.tgz", "integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=", + "dev": true, "requires": { "readable-stream": "~1.1.9" }, @@ -8437,12 +8546,14 @@ "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", + "dev": true }, "readable-stream": { "version": "1.1.14", "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", + "dev": true, "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.1", @@ -8453,7 +8564,8 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", + "dev": true } } }, @@ -8472,6 +8584,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/each-props/-/each-props-1.3.2.tgz", "integrity": "sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==", + "dev": true, "requires": { "is-plain-object": "^2.0.1", "object.defaults": "^1.1.0" @@ -8538,12 +8651,14 @@ "electron-releases": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/electron-releases/-/electron-releases-2.1.0.tgz", - "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==" + "integrity": "sha512-cyKFD1bTE/UgULXfaueIN1k5EPFzs+FRc/rvCY5tIynefAPqopQEgjr0EzY+U3Dqrk/G4m9tXSPuZ77v6dL/Rw==", + "dev": true }, "electron-to-chromium": { "version": "1.3.30", "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.30.tgz", "integrity": "sha512-zx1Prv7kYLfc4OA60FhxGbSo4qrEjgSzpo1/37i7l9ltXPYOoQBtjQxY9KmsgfHnBxHlBGXwLlsbt/gub1w5lw==", + "dev": true, "requires": { "electron-releases": "^2.1.0" } @@ -9015,6 +9130,7 @@ "version": "4.14.0", "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.14.0.tgz", "integrity": "sha512-Ul6CSGRjKscEyg0X/EeNs7o2XdnbTEOD1OM8cTjmx85RPcBJQrEhZLevhuJZNAE/vS2iVl5Uhgiqf3h5uLMCJQ==", + "dev": true, "requires": { "ajv": "^5.3.0", "babel-code-frame": "^6.22.0", @@ -9058,12 +9174,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "ansi-styles": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -9072,6 +9190,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, "requires": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", @@ -9082,6 +9201,7 @@ "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" } @@ -9089,12 +9209,14 @@ "globals": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globals/-/globals-11.1.0.tgz", - "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==" + "integrity": "sha512-uEuWt9mqTlPDwSqi+sHjD4nWU/1N+q0fiWI9T1mZpD2UENqX20CFD5T/ziLZvztPaBKl7ZylUi1q6Qfm7E2CiQ==", + "dev": true }, "strip-ansi": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, "requires": { "ansi-regex": "^3.0.0" } @@ -9103,6 +9225,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "^2.0.0" } @@ -9374,6 +9497,7 @@ "version": "7.5.1", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.5.1.tgz", "integrity": "sha512-YGSjB9Qu6QbVTroUZi66pYky3DfoIPLdHQ/wmrBGyBRnwxQsBXAov9j2rpXt/55i8nyMv6IRWJv2s4d4YnduzQ==", + "dev": true, "requires": { "doctrine": "^2.0.0", "has": "^1.0.1", @@ -9385,6 +9509,7 @@ "version": "3.7.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz", "integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=", + "dev": true, "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" @@ -9393,12 +9518,14 @@ "eslint-visitor-keys": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", - "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==" + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true }, "espree": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz", "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==", + "dev": true, "requires": { "acorn": "^5.2.1", "acorn-jsx": "^3.0.0" @@ -9407,19 +9534,22 @@ "acorn": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.3.0.tgz", - "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==" + "integrity": "sha512-Yej+zOJ1Dm/IMZzzj78OntP/r3zHEaKcyNoU2lAaxPtrseM6rF0xwqoz5Q5ysAiED9hTjI2hgtvLXitlCN1/Ug==", + "dev": true } } }, "esprima": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz", - "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==" + "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==", + "dev": true }, "esquery": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz", "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=", + "dev": true, "requires": { "estraverse": "^4.0.0" } @@ -9579,13 +9709,12 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9660,13 +9789,12 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9815,14 +9943,12 @@ "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", - "dev": true, + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10413,13 +10539,12 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { - "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -11431,6 +11556,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, "requires": { "homedir-polyfill": "^1.0.1" } @@ -11481,6 +11607,7 @@ "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" } @@ -11548,6 +11675,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.1.0.tgz", "integrity": "sha512-E44iT5QVOUJBKij4IIV3uvxuNlbKS38Tw1HiupxEIHPv9qtC2PrDYohbXV5U+1jnfIXttny8gUhj+oZvflFlzA==", + "dev": true, "requires": { "chardet": "^0.4.0", "iconv-lite": "^0.4.17", @@ -11643,6 +11771,7 @@ "version": "1.3.2", "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz", "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=", + "dev": true, "requires": { "ansi-gray": "^0.1.1", "color-support": "^1.1.3", @@ -11699,7 +11828,8 @@ "fastparse": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.1.tgz", - "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=" + "integrity": "sha1-0eJkOzipTXWDtHkGDmxK/8lAcfg=", + "dev": true }, "faye-websocket": { "version": "0.10.0", @@ -11771,6 +11901,7 @@ "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" } @@ -11779,6 +11910,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz", "integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=", + "dev": true, "requires": { "flat-cache": "^1.2.1", "object-assign": "^4.0.1" @@ -11788,6 +11920,7 @@ "version": "1.1.11", "resolved": "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", + "dev": true, "requires": { "loader-utils": "^1.0.2", "schema-utils": "^0.4.5" @@ -11797,6 +11930,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz", "integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=", + "dev": true, "requires": { "big.js": "^3.1.3", "emojis-list": "^2.0.0", @@ -11931,6 +12065,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-2.0.0.tgz", "integrity": "sha1-kyaxSIwi0aYIhlCoaQGy2akKLLw=", + "dev": true, "requires": { "detect-file": "^1.0.0", "is-glob": "^3.1.0", @@ -11941,17 +12076,20 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "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=" + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "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", @@ -11969,6 +12107,7 @@ "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" } @@ -11979,6 +12118,7 @@ "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" @@ -11988,6 +12128,7 @@ "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", @@ -12002,6 +12143,7 @@ "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" } @@ -12010,6 +12152,7 @@ "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" } @@ -12018,6 +12161,7 @@ "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", @@ -12027,7 +12171,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -12035,6 +12180,7 @@ "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" @@ -12044,6 +12190,7 @@ "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" } @@ -12054,6 +12201,7 @@ "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", @@ -12069,6 +12217,7 @@ "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" } @@ -12077,6 +12226,7 @@ "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" } @@ -12087,6 +12237,7 @@ "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", @@ -12098,6 +12249,7 @@ "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" } @@ -12108,6 +12260,7 @@ "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" }, @@ -12116,6 +12269,7 @@ "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" } @@ -12126,6 +12280,7 @@ "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" }, @@ -12134,6 +12289,7 @@ "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" } @@ -12143,12 +12299,14 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "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" } @@ -12157,6 +12315,7 @@ "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" }, @@ -12165,6 +12324,7 @@ "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" } @@ -12174,17 +12334,20 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -12205,6 +12368,7 @@ "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", @@ -12216,6 +12380,7 @@ "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" @@ -12229,6 +12394,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/fined/-/fined-1.1.0.tgz", "integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=", + "dev": true, "requires": { "expand-tilde": "^2.0.2", "is-plain-object": "^2.0.3", @@ -12279,7 +12445,8 @@ "flagged-respawn": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz", - "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=" + "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=", + "dev": true }, "flat": { "version": "1.0.0", @@ -12290,6 +12457,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz", "integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=", + "dev": true, "requires": { "circular-json": "^0.3.1", "del": "^2.0.2", @@ -12301,6 +12469,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz", "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=", + "dev": true, "requires": { "globby": "^5.0.0", "is-path-cwd": "^1.0.0", @@ -12314,7 +12483,8 @@ "pify": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } } } @@ -12341,6 +12511,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.3.tgz", "integrity": "sha512-calZMC10u0FMUqoiunI2AiGIIUtUIvifNwkHhNupZH4cbNnW1Itkoh/Nf5HFYmDrwWPjrUxpkZT0KhuCq0jmGw==", + "dev": true, "requires": { "inherits": "^2.0.1", "readable-stream": "^2.0.4" @@ -12435,6 +12606,7 @@ "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" } @@ -12510,6 +12682,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, "requires": { "graceful-fs": "^4.1.11", "through2": "^2.0.3" @@ -12584,6 +12757,7 @@ "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", @@ -12796,7 +12970,6 @@ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", "dev": true, - "optional": true, "requires": { "bn.js": "^4.0.0", "inherits": "^2.0.1", @@ -13586,7 +13759,6 @@ "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", "dev": true, - "optional": true, "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" @@ -13700,7 +13872,6 @@ "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "dev": true, - "optional": true, "requires": { "bn.js": "^4.1.0", "randombytes": "^2.0.1" @@ -13779,7 +13950,6 @@ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz", "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==", "dev": true, - "optional": true, "requires": { "buffer-alloc-unsafe": "^1.1.0", "buffer-fill": "^1.0.0" @@ -13789,8 +13959,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz", "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==", - "dev": true, - "optional": true + "dev": true }, "buffer-crc32": { "version": "0.2.13", @@ -13803,8 +13972,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz", "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=", - "dev": true, - "optional": true + "dev": true }, "buffer-from": { "version": "1.1.1", @@ -13981,7 +14149,6 @@ "resolved": "http://registry.npmjs.org/commander/-/commander-2.8.1.tgz", "integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=", "dev": true, - "optional": true, "requires": { "graceful-readlink": ">= 1.0.0" } @@ -14200,7 +14367,6 @@ "resolved": "https://registry.npmjs.org/decompress-tar/-/decompress-tar-4.1.1.tgz", "integrity": "sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ==", "dev": true, - "optional": true, "requires": { "file-type": "^5.2.0", "is-stream": "^1.1.0", @@ -14738,6 +14904,14 @@ "integrity": "sha512-XOnAR/3rntJgbCdGhqdaLIxDLWKLmsZOGhHdBKadEr6gEnJLH52k93Ou+TUdFaPN3hJc3isBZBal3U/XZ15abA==", "dev": true }, + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + }, "ethereumjs-block": { "version": "1.7.1", "resolved": "http://registry.npmjs.org/ethereumjs-block/-/ethereumjs-block-1.7.1.tgz", @@ -15251,15 +15425,13 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "dev": true, - "optional": true + "dev": true }, "fs-extra": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0" @@ -15288,7 +15460,6 @@ "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.11.tgz", "integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=", "dev": true, - "optional": true, "requires": { "graceful-fs": "^4.1.2", "inherits": "~2.0.0", @@ -15389,8 +15560,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/graceful-readlink/-/graceful-readlink-1.0.1.tgz", "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", - "dev": true, - "optional": true + "dev": true }, "har-schema": { "version": "2.0.0", @@ -15551,8 +15721,7 @@ "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, - "optional": true + "dev": true }, "immediate": { "version": "3.2.3", @@ -15709,8 +15878,7 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" }, "is-utf8": { "version": "0.2.1", @@ -16541,7 +16709,6 @@ "resolved": "http://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz", "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==", "dev": true, - "optional": true, "requires": { "asn1.js": "^4.0.0", "browserify-aes": "^1.0.0", @@ -17549,7 +17716,6 @@ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz", "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==", "dev": true, - "optional": true, "requires": { "bl": "^1.0.0", "buffer-alloc": "^1.2.0", @@ -17588,7 +17754,6 @@ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", "integrity": "sha1-5p44obq+lpsBCCB5eLn2K4hgSDk=", "dev": true, - "optional": true, "requires": { "any-promise": "^1.0.0" } @@ -17598,7 +17763,6 @@ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz", "integrity": "sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY=", "dev": true, - "optional": true, "requires": { "thenify": ">= 3.1.0 < 4" } @@ -17638,8 +17802,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz", "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==", - "dev": true, - "optional": true + "dev": true }, "to-fast-properties": { "version": "1.0.3", @@ -17718,7 +17881,6 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -18174,6 +18336,14 @@ } } }, + "ethereumjs-abi": { + "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "requires": { + "bn.js": "^4.10.0", + "ethereumjs-util": "^5.0.0" + } + }, "ws": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz", @@ -18223,6 +18393,16 @@ "requires": { "ms": "2.0.0" } + }, + "websocket": { + "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", + "from": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", + "requires": { + "debug": "^2.2.0", + "nan": "^2.3.3", + "typedarray-to-buffer": "^3.1.2", + "yaeti": "^0.0.6" + } } } }, @@ -18395,8 +18575,7 @@ "yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", - "dev": true + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" }, "yargs": { "version": "4.8.1", @@ -18468,6 +18647,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz", "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=", + "dev": true, "requires": { "globule": "^1.0.0" } @@ -18547,7 +18727,8 @@ "get-own-enumerable-property-symbols": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/get-own-enumerable-property-symbols/-/get-own-enumerable-property-symbols-2.0.1.tgz", - "integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==" + "integrity": "sha512-TtY/sbOemiMKPRUDDanGCSgBYe7Mf0vbRsWnBZ+9yghpZ1MvcpSpuZFjHdEeY/LZjZy0vdLjS77L6HosisFiug==", + "dev": true }, "get-stdin": { "version": "3.0.2", @@ -18578,7 +18759,8 @@ "get-value": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=" + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true }, "getpass": { "version": "0.1.7", @@ -18774,6 +18956,7 @@ "version": "6.1.0", "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", "integrity": "sha1-cEXJlBOz65SIjYOrRtC0BMx73eQ=", + "dev": true, "requires": { "extend": "^3.0.0", "glob": "^7.1.1", @@ -18791,6 +18974,7 @@ "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" @@ -18799,12 +18983,14 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "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" } @@ -18821,6 +19007,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/glob-watcher/-/glob-watcher-5.0.1.tgz", "integrity": "sha512-fK92r2COMC199WCyGUblrZKhjra3cyVMDiypDdqg1vsSDmexnbYivK1kNR4QItiNXLKmGlqan469ks67RtNa2g==", + "dev": true, "requires": { "async-done": "^1.2.0", "chokidar": "^2.0.0", @@ -18832,6 +19019,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, "requires": { "micromatch": "^3.1.4", "normalize-path": "^2.1.1" @@ -18840,17 +19028,20 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "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=" + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "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", @@ -18868,6 +19059,7 @@ "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" } @@ -18878,6 +19070,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.4.tgz", "integrity": "sha512-z9n7yt9rOvIJrMhvDtDictKrkFHeihkNl6uWMmZlmL6tJtX9Cs+87oK+teBx+JIgzvbX3yZHT3eF8vpbDxHJXQ==", + "dev": true, "requires": { "anymatch": "^2.0.0", "async-each": "^1.0.0", @@ -18898,6 +19091,7 @@ "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" @@ -18907,6 +19101,7 @@ "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", @@ -18921,6 +19116,7 @@ "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" } @@ -18929,6 +19125,7 @@ "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" } @@ -18937,6 +19134,7 @@ "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", @@ -18946,7 +19144,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -18954,6 +19153,7 @@ "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" @@ -18963,6 +19163,7 @@ "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" } @@ -18973,6 +19174,7 @@ "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", @@ -18988,6 +19190,7 @@ "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" } @@ -18996,6 +19199,7 @@ "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" } @@ -19006,6 +19210,7 @@ "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", @@ -19017,6 +19222,7 @@ "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" } @@ -19027,6 +19233,7 @@ "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" @@ -19036,6 +19243,7 @@ "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" } @@ -19046,6 +19254,7 @@ "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" }, @@ -19054,6 +19263,7 @@ "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" } @@ -19064,6 +19274,7 @@ "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" }, @@ -19072,6 +19283,7 @@ "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" } @@ -19081,12 +19293,14 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true }, "is-glob": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz", "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=", + "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -19095,6 +19309,7 @@ "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" }, @@ -19103,6 +19318,7 @@ "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" } @@ -19112,17 +19328,20 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -19143,6 +19362,7 @@ "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", @@ -19154,6 +19374,7 @@ "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" @@ -19164,7 +19385,8 @@ "upath": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz", - "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==" + "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==", + "dev": true } } }, @@ -19181,6 +19403,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, "requires": { "global-prefix": "^1.0.1", "is-windows": "^1.0.1", @@ -19191,6 +19414,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, "requires": { "expand-tilde": "^2.0.2", "homedir-polyfill": "^1.0.1", @@ -19208,6 +19432,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz", "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=", + "dev": true, "requires": { "array-union": "^1.0.1", "arrify": "^1.0.0", @@ -19220,7 +19445,8 @@ "pify": { "version": "2.3.0", "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true } } }, @@ -19234,6 +19460,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.0.tgz", "integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=", + "dev": true, "requires": { "glob": "~7.1.1", "lodash": "~4.17.4", @@ -19244,6 +19471,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz", "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=", + "dev": true, "requires": { "sparkles": "^1.0.0" } @@ -19316,8 +19544,9 @@ "dev": true }, "gulp": { - "version": "github:gulpjs/gulp#55eb23a268dcc7340bb40808600fd4802848c06f", - "from": "github:gulpjs/gulp#v4.0.0", + "version": "4.0.0", + "resolved": "github:gulpjs/gulp#55eb23a268dcc7340bb40808600fd4802848c06f", + "dev": true, "requires": { "glob-watcher": "^5.0.0", "gulp-cli": "^2.0.0", @@ -19329,6 +19558,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/gulp-cli/-/gulp-cli-2.0.1.tgz", "integrity": "sha512-RxujJJdN8/O6IW2nPugl7YazhmrIEjmiVfPKrWt68r71UCaLKS71Hp0gpKT+F6qOUFtr7KqtifDKaAJPRVvMYQ==", + "dev": true, "requires": { "ansi-colors": "^1.0.1", "archy": "^1.0.0", @@ -19353,12 +19583,14 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "yargs": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, "requires": { "camelcase": "^3.0.0", "cliui": "^3.2.0", @@ -19379,6 +19611,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, "requires": { "camelcase": "^3.0.0" } @@ -19389,6 +19622,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/gulp-autoprefixer/-/gulp-autoprefixer-5.0.0.tgz", "integrity": "sha1-gjfCeKaXdScKHK/n1vEBz81YVUQ=", + "dev": true, "requires": { "autoprefixer": "^8.0.0", "fancy-log": "^1.3.2", @@ -19401,12 +19635,14 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "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" @@ -19416,6 +19652,7 @@ "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" } @@ -19424,6 +19661,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, "requires": { "ansi-colors": "^1.0.1", "arr-diff": "^4.0.0", @@ -19494,6 +19732,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/gulp-debug/-/gulp-debug-3.2.0.tgz", "integrity": "sha512-2LZzP+ydczqz1rhqq/NYxvVvYTmOa0IgBl2B1sQTdkQgku9ayOUM/KHuGPjF4QA5aO1VcG+Sskw7iCcRUqHKkA==", + "dev": true, "requires": { "chalk": "^2.3.0", "fancy-log": "^1.3.2", @@ -19507,6 +19746,7 @@ "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" } @@ -19515,6 +19755,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -19524,12 +19765,14 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "supports-color": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -19540,6 +19783,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/gulp-eslint/-/gulp-eslint-4.0.0.tgz", "integrity": "sha512-+qsePo04v1O3JshpNvww9+bOgZEJ6Cc2/w3mEktfKz0NL0zsh1SWzjyIL2FIM2zzy6IYQYv+j8REZORF8dKX4g==", + "dev": true, "requires": { "eslint": "^4.0.0", "gulp-util": "^3.0.8" @@ -19725,6 +19969,7 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/gulp-sass/-/gulp-sass-4.0.1.tgz", "integrity": "sha512-OMQEgWNggpog8Tc5v1MuI6eo+5iiPkVeLL76iBhDoEEScLUPfZlpvzmgTnLkpcqdrNodZxpz5qcv6mS2rulk3g==", + "dev": true, "requires": { "chalk": "^2.3.0", "lodash.clonedeep": "^4.3.2", @@ -19740,6 +19985,7 @@ "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" } @@ -19747,12 +19993,14 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true }, "chalk": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -19763,6 +20011,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-3.0.1.tgz", "integrity": "sha1-ElYDfsufDF9549bvE14wdwGEuYI=", + "dev": true, "requires": { "lru-cache": "^4.0.1", "which": "^1.2.9" @@ -19772,6 +20021,7 @@ "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" @@ -19780,17 +20030,20 @@ "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true }, "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true }, "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" } @@ -19798,12 +20051,14 @@ "nan": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz", - "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==" + "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==", + "dev": true }, "node-sass": { "version": "4.9.2", "resolved": "https://registry.npmjs.org/node-sass/-/node-sass-4.9.2.tgz", "integrity": "sha512-LdxoJLZutx0aQXHtWIYwJKMj+9pTjneTcLWJgzf2XbGu0q5pRNqW5QvFCEdm3mc5rJOdru/mzln5d0EZLacf6g==", + "dev": true, "requires": { "async-foreach": "^0.1.3", "chalk": "^1.1.1", @@ -19829,12 +20084,14 @@ "ansi-styles": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" + "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", @@ -19847,6 +20104,7 @@ "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" } @@ -19854,7 +20112,8 @@ "supports-color": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true } } }, @@ -19862,6 +20121,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/plugin-error/-/plugin-error-1.0.1.tgz", "integrity": "sha512-L1zP0dk7vGweZME2i+EeakvUNqSrdiI3F91TwEoYiGrAfUXmVv6fJIq4g82PAXxNsWOp0J7ZqQy/3Szz0ajTxA==", + "dev": true, "requires": { "ansi-colors": "^1.0.1", "arr-diff": "^4.0.0", @@ -19873,6 +20133,7 @@ "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" }, @@ -19880,7 +20141,8 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true } } }, @@ -19888,6 +20150,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -20207,6 +20470,7 @@ "version": "3.0.8", "resolved": "https://registry.npmjs.org/gulp-util/-/gulp-util-3.0.8.tgz", "integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=", + "dev": true, "requires": { "array-differ": "^1.0.0", "array-uniq": "^1.0.2", @@ -20231,27 +20495,32 @@ "clone": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.3.tgz", - "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=" + "integrity": "sha1-KY1+IjFmD0DAA8LtMUDezz9TCF8=", + "dev": true }, "clone-stats": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-0.0.1.tgz", - "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=" + "integrity": "sha1-uI+UqCzzi4eR1YBG6kAprYjKmdE=", + "dev": true }, "object-assign": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-3.0.0.tgz", - "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=" + "integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=", + "dev": true }, "replace-ext": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-0.0.1.tgz", - "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=" + "integrity": "sha1-KbvZIHinOfC8zitO5B6DeVNSKSQ=", + "dev": true }, "vinyl": { "version": "0.5.3", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-0.5.3.tgz", "integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=", + "dev": true, "requires": { "clone": "^1.0.0", "clone-stats": "^0.0.1", @@ -20676,6 +20945,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/gulplog/-/gulplog-1.0.0.tgz", "integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=", + "dev": true, "requires": { "glogg": "^1.0.0" } @@ -20751,12 +21021,14 @@ "has-flag": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", - "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=", + "dev": true }, "has-gulplog": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/has-gulplog/-/has-gulplog-0.1.0.tgz", "integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=", + "dev": true, "requires": { "sparkles": "^1.0.0" } @@ -20764,7 +21036,8 @@ "has-symbols": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=" + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true }, "has-unicode": { "version": "2.0.1", @@ -20775,6 +21048,7 @@ "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", @@ -20784,7 +21058,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -20792,6 +21067,7 @@ "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" @@ -20801,6 +21077,7 @@ "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" }, @@ -20809,6 +21086,7 @@ "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" } @@ -20819,6 +21097,7 @@ "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" } @@ -20930,6 +21209,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz", "integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=", + "dev": true, "requires": { "parse-passwd": "^1.0.0" } @@ -20942,7 +21222,8 @@ "html-comment-regex": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz", - "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=" + "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=", + "dev": true }, "html-element-attributes": { "version": "1.3.1", @@ -21290,12 +21571,14 @@ "icss-replace-symbols": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", - "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=" + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true }, "icss-utils": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, "requires": { "postcss": "^6.0.1" } @@ -21393,7 +21676,8 @@ "ignore": { "version": "3.3.7", "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.7.tgz", - "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==" + "integrity": "sha512-YGG3ejvBNHRqu0559EOxxNFihD0AjpvHlC/pdGKd3X3ofe+CoJkYazwNJYTNebqpPKN+VVQbh4ZFn1DivMNuHA==", + "dev": true }, "ignore-walk": { "version": "3.0.1", @@ -21424,12 +21708,14 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true }, "in-publish": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/in-publish/-/in-publish-2.0.0.tgz", - "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=" + "integrity": "sha1-4g/146KvwmkDILbcVSaCqcf631E=", + "dev": true }, "indefinite-observable": { "version": "1.0.1", @@ -21450,6 +21736,7 @@ "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" } @@ -21457,7 +21744,8 @@ "indexes-of": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=" + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true }, "indexof": { "version": "0.0.1", @@ -21520,6 +21808,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz", "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==", + "dev": true, "requires": { "ansi-escapes": "^3.0.0", "chalk": "^2.0.0", @@ -21540,12 +21829,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "ansi-styles": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -21554,6 +21845,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, "requires": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", @@ -21563,12 +21855,14 @@ "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=" + "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" @@ -21578,6 +21872,7 @@ "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" } @@ -21586,6 +21881,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "^2.0.0" } @@ -21701,12 +21997,14 @@ "irregular-plurals": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/irregular-plurals/-/irregular-plurals-1.4.0.tgz", - "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=" + "integrity": "sha1-LKmwM2UREYVUEvFr5dd8YqRYp2Y=", + "dev": true }, "is-absolute": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, "requires": { "is-relative": "^1.0.0", "is-windows": "^1.0.1" @@ -21715,12 +22013,14 @@ "is-absolute-url": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", - "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=" + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true }, "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" }, @@ -21728,7 +22028,8 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, @@ -21787,6 +22088,7 @@ "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" }, @@ -21794,7 +22096,8 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, @@ -21812,6 +22115,7 @@ "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", @@ -21821,7 +22125,8 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, @@ -21936,7 +22241,8 @@ "is-negated-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=" + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true }, "is-number": { "version": "2.1.0", @@ -21955,7 +22261,8 @@ "is-obj": { "version": "1.0.1", "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", - "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=" + "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", + "dev": true }, "is-object": { "version": "1.0.1", @@ -21967,6 +22274,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz", "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==", + "dev": true, "requires": { "is-number": "^4.0.0" }, @@ -21974,19 +22282,22 @@ "is-number": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz", - "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==" + "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==", + "dev": true } } }, "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=" + "integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0=", + "dev": true }, "is-path-in-cwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.0.tgz", "integrity": "sha1-ZHdYK4IU1gI0YJRWcAO+ip6sBNw=", + "dev": true, "requires": { "is-path-inside": "^1.0.0" } @@ -21995,6 +22306,7 @@ "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" } @@ -22032,7 +22344,8 @@ "is-promise": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", - "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=" + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true }, "is-property": { "version": "1.0.2", @@ -22057,12 +22370,14 @@ "is-regexp": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=" + "integrity": "sha1-/S2INUXEa6xaYz57mgnof6LLUGk=", + "dev": true }, "is-relative": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, "requires": { "is-unc-path": "^1.0.0" } @@ -22070,7 +22385,8 @@ "is-resolvable": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.1.tgz", - "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==" + "integrity": "sha512-y5CXYbzvB3jTnWAZH1Nl7ykUWb6T3BcTs56HUruwBf8MhF56n1HWqhDWnVFo8GHrUPDgvUUNVhrc2U8W7iqz5g==", + "dev": true }, "is-retry-allowed": { "version": "1.1.0", @@ -22111,6 +22427,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz", "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=", + "dev": true, "requires": { "html-comment-regex": "^1.1.0" } @@ -22138,6 +22455,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, "requires": { "unc-path-regex": "^0.1.2" } @@ -22150,7 +22468,8 @@ "is-valid-glob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=" + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true }, "is-whitespace-character": { "version": "1.0.1", @@ -22160,7 +22479,8 @@ "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==" + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true }, "is-word-character": { "version": "1.0.1", @@ -22190,7 +22510,8 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true }, "isobject": { "version": "2.1.0", @@ -22363,7 +22684,8 @@ "js-base64": { "version": "2.4.3", "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.3.tgz", - "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==" + "integrity": "sha512-H7ErYLM34CvDMto3GbD6xD0JLUGYXR3QTcH6B/tr4Hi/QpSThnCsIp+Sy5FRTw3B0d6py4HcNkW7nO/wdtGWEw==", + "dev": true }, "js-beautify": { "version": "1.5.10", @@ -22396,6 +22718,7 @@ "version": "3.10.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz", "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==", + "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -22806,7 +23129,8 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true }, "json-stringify-safe": { "version": "5.0.1", @@ -23070,6 +23394,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.0.1.tgz", "integrity": "sha1-6AGxs5mF4g//yHtA43SAgOLcrH8=", + "dev": true, "requires": { "array-includes": "^3.0.3" } @@ -23124,7 +23449,8 @@ "just-debounce": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/just-debounce/-/just-debounce-1.0.0.tgz", - "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=" + "integrity": "sha1-h/zPrv/AtozRnVX2cilD+SnqNeo=", + "dev": true }, "just-extend": { "version": "1.1.27", @@ -23677,6 +24003,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/last-run/-/last-run-1.1.1.tgz", "integrity": "sha1-RblpQsF7HHnHchmCWbqUO+v4yls=", + "dev": true, "requires": { "default-resolution": "^2.0.0", "es6-weak-map": "^2.0.1" @@ -23692,6 +24019,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=", + "dev": true, "requires": { "readable-stream": "^2.0.5" } @@ -23760,6 +24088,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, "requires": { "flush-write-stream": "^1.0.2" } @@ -23880,6 +24209,7 @@ "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, "requires": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" @@ -23906,6 +24236,7 @@ "version": "2.5.0", "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.5.0.tgz", "integrity": "sha1-IAkpG7Mc6oYbvxCnwVooyvdcMew=", + "dev": true, "requires": { "extend": "^3.0.0", "findup-sync": "^2.0.0", @@ -24004,7 +24335,8 @@ "lodash._basecopy": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz", - "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=" + "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=", + "dev": true }, "lodash._baseflatten": { "version": "3.1.4", @@ -24019,12 +24351,14 @@ "lodash._basetostring": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz", - "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=" + "integrity": "sha1-0YYdh3+CSlL2aYMtyvPuFVZqB9U=", + "dev": true }, "lodash._basevalues": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._basevalues/-/lodash._basevalues-3.0.0.tgz", - "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=" + "integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=", + "dev": true }, "lodash._bindcallback": { "version": "3.0.1", @@ -24046,32 +24380,38 @@ "lodash._getnative": { "version": "3.9.1", "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz", - "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=" + "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=", + "dev": true }, "lodash._isiterateecall": { "version": "3.0.9", "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz", - "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=" + "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=", + "dev": true }, "lodash._reescape": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reescape/-/lodash._reescape-3.0.0.tgz", - "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=" + "integrity": "sha1-Kx1vXf4HyKNVdT5fJ/rH8c3hYWo=", + "dev": true }, "lodash._reevaluate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reevaluate/-/lodash._reevaluate-3.0.0.tgz", - "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=" + "integrity": "sha1-WLx0xAZklTrgsSTYBpltrKQx4u0=", + "dev": true }, "lodash._reinterpolate": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", - "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" + "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=", + "dev": true }, "lodash._root": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/lodash._root/-/lodash._root-3.0.1.tgz", - "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=" + "integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=", + "dev": true }, "lodash.assign": { "version": "4.2.0", @@ -24087,7 +24427,8 @@ "lodash.camelcase": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz", - "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=" + "integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=", + "dev": true }, "lodash.castarray": { "version": "4.4.0", @@ -24098,7 +24439,8 @@ "lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", - "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=", + "dev": true }, "lodash.debounce": { "version": "4.0.8", @@ -24115,6 +24457,7 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/lodash.escape/-/lodash.escape-3.2.0.tgz", "integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=", + "dev": true, "requires": { "lodash._root": "^3.0.0" } @@ -24155,12 +24498,14 @@ "lodash.isarguments": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz", - "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=" + "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=", + "dev": true }, "lodash.isarray": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz", - "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=" + "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=", + "dev": true }, "lodash.isequal": { "version": "4.5.0", @@ -24178,6 +24523,7 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz", "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=", + "dev": true, "requires": { "lodash._getnative": "^3.0.0", "lodash.isarguments": "^3.0.0", @@ -24192,7 +24538,8 @@ "lodash.mergewith": { "version": "4.6.1", "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.1.tgz", - "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==" + "integrity": "sha512-eWw5r+PYICtEBgrBE5hhlT6aAa75f411bgDz/ZL2KZqYV03USvucsxcHUIlGTDTECs1eunpI7HOV7U+WLDvNdQ==", + "dev": true }, "lodash.pick": { "version": "4.4.0", @@ -24203,7 +24550,8 @@ "lodash.restparam": { "version": "3.6.1", "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz", - "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=" + "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=", + "dev": true }, "lodash.set": { "version": "4.3.2", @@ -24238,6 +24586,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/lodash.template/-/lodash.template-3.6.2.tgz", "integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=", + "dev": true, "requires": { "lodash._basecopy": "^3.0.0", "lodash._basetostring": "^3.0.0", @@ -24254,6 +24603,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/lodash.templatesettings/-/lodash.templatesettings-3.1.1.tgz", "integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=", + "dev": true, "requires": { "lodash._reinterpolate": "^3.0.0", "lodash.escape": "^3.0.0" @@ -24268,7 +24618,8 @@ "lodash.uniq": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true }, "lodash.uniqby": { "version": "4.7.0", @@ -24354,6 +24705,7 @@ "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" @@ -24375,6 +24727,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz", "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==", + "dev": true, "requires": { "pseudomap": "^1.0.2", "yallist": "^2.1.2" @@ -24437,6 +24790,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/make-iterator/-/make-iterator-1.0.1.tgz", "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==", + "dev": true, "requires": { "kind-of": "^6.0.2" }, @@ -24444,7 +24798,8 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, @@ -24465,12 +24820,14 @@ "map-cache": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=" + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true }, "map-obj": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" + "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=", + "dev": true }, "map-stream": { "version": "0.1.0", @@ -24482,6 +24839,7 @@ "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" } @@ -24535,6 +24893,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/matchdep/-/matchdep-2.0.0.tgz", "integrity": "sha1-xvNINKDY28OzfCfui7yyfHd1WC4=", + "dev": true, "requires": { "findup-sync": "^2.0.0", "micromatch": "^3.0.4", @@ -24545,17 +24904,20 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "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=" + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "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", @@ -24573,6 +24935,7 @@ "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" } @@ -24583,6 +24946,7 @@ "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" @@ -24592,6 +24956,7 @@ "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", @@ -24606,6 +24971,7 @@ "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" } @@ -24614,6 +24980,7 @@ "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" } @@ -24622,6 +24989,7 @@ "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", @@ -24631,7 +24999,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -24639,6 +25008,7 @@ "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" @@ -24648,6 +25018,7 @@ "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" } @@ -24658,6 +25029,7 @@ "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", @@ -24673,6 +25045,7 @@ "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" } @@ -24681,6 +25054,7 @@ "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" } @@ -24691,6 +25065,7 @@ "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", @@ -24702,6 +25077,7 @@ "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" } @@ -24712,6 +25088,7 @@ "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" }, @@ -24720,6 +25097,7 @@ "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" } @@ -24730,6 +25108,7 @@ "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" }, @@ -24738,6 +25117,7 @@ "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" } @@ -24748,6 +25128,7 @@ "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" }, @@ -24756,6 +25137,7 @@ "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" } @@ -24765,17 +25147,20 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true }, "micromatch": { "version": "3.1.10", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -24796,6 +25181,7 @@ "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", @@ -24807,6 +25193,7 @@ "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" @@ -24834,7 +25221,8 @@ "math-expression-evaluator": { "version": "1.2.17", "resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.17.tgz", - "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=" + "integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=", + "dev": true }, "math-random": { "version": "1.0.1", @@ -24938,6 +25326,7 @@ "version": "3.7.0", "resolved": "http://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", @@ -25254,7 +25643,8 @@ "mimic-fn": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz", - "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=" + "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg=", + "dev": true }, "min-document": { "version": "2.19.0", @@ -25345,6 +25735,7 @@ "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" @@ -25354,6 +25745,7 @@ "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" } @@ -25585,6 +25977,7 @@ "version": "0.1.2", "resolved": "https://registry.npmjs.org/multipipe/-/multipipe-0.1.2.tgz", "integrity": "sha1-Ko8t33Du1WTf8tV/HhoTfZ8FB4s=", + "dev": true, "requires": { "duplexer2": "0.0.2" } @@ -25610,12 +26003,14 @@ "mute-stdout": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/mute-stdout/-/mute-stdout-1.0.1.tgz", - "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==" + "integrity": "sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==", + "dev": true }, "mute-stream": { "version": "0.0.7", "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=" + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true }, "mz": { "version": "2.7.0", @@ -25645,6 +26040,7 @@ "version": "1.2.9", "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz", "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==", + "dev": true, "requires": { "arr-diff": "^4.0.0", "array-unique": "^0.3.2", @@ -25663,17 +26059,20 @@ "arr-diff": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=" + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "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=" + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true }, "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" @@ -25683,6 +26082,7 @@ "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" @@ -25692,6 +26092,7 @@ "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" } @@ -25699,19 +26100,22 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true }, "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true }, "natural-compare-lite": { "version": "1.4.0", @@ -25935,6 +26339,7 @@ "version": "3.6.2", "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-3.6.2.tgz", "integrity": "sha1-m/vlRWIoYoSDjnUOrAUpWFP6HGA=", + "dev": true, "requires": { "fstream": "^1.0.0", "glob": "^7.0.3", @@ -25954,7 +26359,8 @@ "semver": { "version": "5.3.0", "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", - "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=" + "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", + "dev": true } } }, @@ -26167,6 +26573,7 @@ "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" } @@ -26193,7 +26600,8 @@ "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=" + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true }, "normalize-scroll-left": { "version": "0.1.2", @@ -26210,6 +26618,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.0.tgz", "integrity": "sha1-vGHLtFbXnLMiB85HygUTb/Ln1u4=", + "dev": true, "requires": { "once": "^1.3.2" } @@ -26268,7 +26677,8 @@ "num2fraction": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=" + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true }, "number-is-nan": { "version": "1.0.1", @@ -27575,6 +27985,7 @@ "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", @@ -27585,6 +27996,7 @@ "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" } @@ -27593,6 +28005,7 @@ "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" } @@ -27601,6 +28014,7 @@ "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" } @@ -27609,6 +28023,7 @@ "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", @@ -27618,7 +28033,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } } @@ -27650,6 +28066,7 @@ "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" }, @@ -27657,7 +28074,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -27665,6 +28083,7 @@ "version": "4.1.0", "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, "requires": { "define-properties": "^1.1.2", "function-bind": "^1.1.1", @@ -27676,6 +28095,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/object.defaults/-/object.defaults-1.1.0.tgz", "integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=", + "dev": true, "requires": { "array-each": "^1.0.1", "array-slice": "^1.0.0", @@ -27687,6 +28107,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, "requires": { "for-in": "^1.0.1" } @@ -27694,7 +28115,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -27724,6 +28146,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.map/-/object.map-1.0.1.tgz", "integrity": "sha1-z4Plncj8wK1fQlDh94s7gb2AHTc=", + "dev": true, "requires": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" @@ -27733,6 +28156,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, "requires": { "for-in": "^1.0.1" } @@ -27752,6 +28176,7 @@ "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" }, @@ -27759,7 +28184,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -27767,6 +28193,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/object.reduce/-/object.reduce-1.0.1.tgz", "integrity": "sha1-b+NI8qx/oPlcpiEiZZkJaCW7A60=", + "dev": true, "requires": { "for-own": "^1.0.0", "make-iterator": "^1.0.0" @@ -27776,6 +28203,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/for-own/-/for-own-1.0.0.tgz", "integrity": "sha1-xjMy9BXO3EsE2/5wz4NklMU8tEs=", + "dev": true, "requires": { "for-in": "^1.0.1" } @@ -27849,6 +28277,7 @@ "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" } @@ -27887,6 +28316,7 @@ "version": "0.8.2", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, "requires": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.4", @@ -27899,7 +28329,8 @@ "wordwrap": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", - "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=" + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true } } }, @@ -27907,6 +28338,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, "requires": { "readable-stream": "^2.0.1" } @@ -28122,6 +28554,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", "integrity": "sha1-pjISf1Oq89FYdvWHLz/6x2PWyJE=", + "dev": true, "requires": { "is-absolute": "^1.0.0", "map-cache": "^0.2.0", @@ -28159,7 +28592,8 @@ "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=" + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true }, "parse5": { "version": "3.0.3", @@ -28196,7 +28630,8 @@ "pascalcase": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=" + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true }, "path": { "version": "0.12.7", @@ -28224,7 +28659,8 @@ "path-dirname": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=" + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true }, "path-exists": { "version": "2.1.0", @@ -28242,7 +28678,8 @@ "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=" + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true }, "path-key": { "version": "2.0.1", @@ -28265,6 +28702,7 @@ "version": "0.1.1", "resolved": "https://registry.npmjs.org/path-root/-/path-root-0.1.1.tgz", "integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=", + "dev": true, "requires": { "path-root-regex": "^0.1.0" } @@ -28272,7 +28710,8 @@ "path-root-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/path-root-regex/-/path-root-regex-0.1.2.tgz", - "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=" + "integrity": "sha1-v8zcjfWxLcUsi0PsONGNcsBLqW0=", + "dev": true }, "path-to-regexp": { "version": "0.1.7", @@ -28575,6 +29014,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/plur/-/plur-2.1.2.tgz", "integrity": "sha1-dIJFLBoPUI4+NE6uwxLJHCncZVo=", + "dev": true, "requires": { "irregular-plurals": "^1.0.0" } @@ -28582,7 +29022,8 @@ "pluralize": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz", - "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==" + "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow==", + "dev": true }, "pn": { "version": "1.1.0", @@ -28730,7 +29171,8 @@ "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=" + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true }, "post-message-stream": { "version": "3.0.0", @@ -28744,6 +29186,7 @@ "version": "6.0.19", "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.19.tgz", "integrity": "sha512-f13HRz0HtVwVaEuW6J6cOUCBLFtymhgyLPV7t4QEk2UD3twRI9IluDcQNdzQdBpiixkXj2OmzejhhTbSbDxNTg==", + "dev": true, "requires": { "chalk": "^2.3.1", "source-map": "^0.6.1", @@ -28754,6 +29197,7 @@ "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" } @@ -28762,6 +29206,7 @@ "version": "2.3.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.2.tgz", "integrity": "sha512-ZM4j2/ld/YZDc3Ma8PgN7gyAk+kHMMMyzLNryCPGhWrsfAuDVeuid5bpRFTDgMH9JBK2lA4dyyAkkZYF/WcqDQ==", + "dev": true, "requires": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -28771,17 +29216,20 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "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==" + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true }, "supports-color": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.3.0.tgz", "integrity": "sha512-0aP01LLIskjKs3lq52EC0aGBAJhLq7B2Rd8HC/DR/PtNNpcLilNmHC12O+hu0usQpo7wtHNRqtrhBwtDb0+dNg==", + "dev": true, "requires": { "has-flag": "^3.0.0" } @@ -28792,6 +29240,7 @@ "version": "5.3.1", "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", + "dev": true, "requires": { "postcss": "^5.0.2", "postcss-message-helpers": "^2.0.0", @@ -28801,12 +29250,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -28817,12 +29268,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -28833,6 +29286,7 @@ "version": "2.2.2", "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz", "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=", + "dev": true, "requires": { "colormin": "^1.0.5", "postcss": "^5.0.13", @@ -28842,12 +29296,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -28858,12 +29314,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -28874,6 +29332,7 @@ "version": "2.6.1", "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-2.6.1.tgz", "integrity": "sha1-u9hZPFwf0uPRwyK7kl3K6Nrk1i0=", + "dev": true, "requires": { "postcss": "^5.0.11", "postcss-value-parser": "^3.1.2" @@ -28882,12 +29341,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -28898,12 +29359,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -28914,6 +29377,7 @@ "version": "2.0.4", "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", + "dev": true, "requires": { "postcss": "^5.0.14" }, @@ -28921,12 +29385,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -28937,12 +29403,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -28953,6 +29421,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-2.1.0.tgz", "integrity": "sha1-uavye4isGIFYpesSq8riAmO5GTI=", + "dev": true, "requires": { "postcss": "^5.0.4" }, @@ -28960,12 +29429,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -28976,12 +29447,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -28992,6 +29465,7 @@ "version": "2.1.0", "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", + "dev": true, "requires": { "postcss": "^5.0.14" }, @@ -28999,12 +29473,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29015,12 +29491,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29031,6 +29509,7 @@ "version": "0.1.1", "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", + "dev": true, "requires": { "postcss": "^5.0.16" }, @@ -29038,12 +29517,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29054,12 +29535,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29070,6 +29553,7 @@ "version": "2.2.3", "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", + "dev": true, "requires": { "postcss": "^5.0.14", "uniqs": "^2.0.0" @@ -29078,12 +29562,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29094,12 +29580,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29110,6 +29598,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.3.tgz", "integrity": "sha512-T53GVFsdinJhgwm7rg1BzbeBRomOg9y5MBVhGcsV0CxurUdVj1UlPdKtn7aqYA/c/QVkzKMjq2bSV5dKG5+AwQ==", + "dev": true, "requires": { "postcss": "^5.0.4" }, @@ -29117,12 +29606,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29133,12 +29624,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29265,6 +29758,7 @@ "version": "2.1.7", "resolved": "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", + "dev": true, "requires": { "has": "^1.0.1", "postcss": "^5.0.10", @@ -29274,12 +29768,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29290,12 +29786,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29306,6 +29804,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-2.0.2.tgz", "integrity": "sha1-I9kM0Sewp3mUkVMyc5A0oaTz1lg=", + "dev": true, "requires": { "postcss": "^5.0.4" }, @@ -29313,12 +29812,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29329,12 +29830,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29345,6 +29848,7 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-2.1.2.tgz", "integrity": "sha1-0d9d+qexrMO+VT8OnhDofGG19yE=", + "dev": true, "requires": { "browserslist": "^1.5.2", "caniuse-api": "^1.5.2", @@ -29357,6 +29861,7 @@ "version": "1.7.7", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz", "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=", + "dev": true, "requires": { "caniuse-db": "^1.0.30000639", "electron-to-chromium": "^1.2.7" @@ -29365,12 +29870,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29381,12 +29888,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29396,12 +29905,14 @@ "postcss-message-helpers": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/postcss-message-helpers/-/postcss-message-helpers-2.0.0.tgz", - "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=" + "integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=", + "dev": true }, "postcss-minify-font-values": { "version": "1.0.5", "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", + "dev": true, "requires": { "object-assign": "^4.0.1", "postcss": "^5.0.4", @@ -29411,12 +29922,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29427,12 +29940,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29443,6 +29958,7 @@ "version": "1.0.5", "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", + "dev": true, "requires": { "postcss": "^5.0.12", "postcss-value-parser": "^3.3.0" @@ -29451,12 +29967,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29467,12 +29985,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29483,6 +30003,7 @@ "version": "1.2.2", "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", + "dev": true, "requires": { "alphanum-sort": "^1.0.1", "postcss": "^5.0.2", @@ -29493,12 +30014,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29509,12 +30032,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29525,6 +30050,7 @@ "version": "2.1.1", "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", + "dev": true, "requires": { "alphanum-sort": "^1.0.2", "has": "^1.0.1", @@ -29535,12 +30061,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29551,12 +30079,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29567,6 +30097,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.0.tgz", "integrity": "sha1-ZhQOzs447wa/DT41XWm/WdFB6oU=", + "dev": true, "requires": { "postcss": "^6.0.1" } @@ -29575,6 +30106,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, "requires": { "css-selector-tokenizer": "^0.7.0", "postcss": "^6.0.1" @@ -29584,6 +30116,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, "requires": { "css-selector-tokenizer": "^0.7.0", "postcss": "^6.0.1" @@ -29593,6 +30126,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, "requires": { "icss-replace-symbols": "^1.1.0", "postcss": "^6.0.1" @@ -29602,6 +30136,7 @@ "version": "1.1.1", "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", + "dev": true, "requires": { "postcss": "^5.0.5" }, @@ -29609,12 +30144,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29625,12 +30162,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29641,6 +30180,7 @@ "version": "3.0.8", "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", + "dev": true, "requires": { "is-absolute-url": "^2.0.0", "normalize-url": "^1.4.0", @@ -29651,12 +30191,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "normalize-url": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-1.9.1.tgz", "integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=", + "dev": true, "requires": { "object-assign": "^4.0.1", "prepend-http": "^1.0.0", @@ -29668,6 +30210,7 @@ "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29678,12 +30221,14 @@ "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", - "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=" + "integrity": "sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw=", + "dev": true }, "query-string": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/query-string/-/query-string-4.3.4.tgz", "integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=", + "dev": true, "requires": { "object-assign": "^4.1.0", "strict-uri-encode": "^1.0.0" @@ -29693,6 +30238,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", "integrity": "sha1-RBttTTRnmPG05J6JIK37oOVD+a0=", + "dev": true, "requires": { "is-plain-obj": "^1.0.0" } @@ -29700,12 +30246,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29716,6 +30264,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-2.2.3.tgz", "integrity": "sha1-7sbCpntsQSqNsgQud/6NpD+VwR0=", + "dev": true, "requires": { "postcss": "^5.0.4", "postcss-value-parser": "^3.0.1" @@ -29724,12 +30273,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29740,12 +30291,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29756,6 +30309,7 @@ "version": "2.4.0", "resolved": "http://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", + "dev": true, "requires": { "postcss": "^5.0.4", "postcss-value-parser": "^3.0.2" @@ -29764,12 +30318,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29780,12 +30336,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29796,6 +30354,7 @@ "version": "1.0.1", "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", + "dev": true, "requires": { "postcss": "^5.0.4" }, @@ -29803,12 +30362,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29819,12 +30380,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29835,6 +30398,7 @@ "version": "1.0.4", "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", + "dev": true, "requires": { "has": "^1.0.1", "postcss": "^5.0.8", @@ -29844,12 +30408,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -29860,12 +30426,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -29973,6 +30541,7 @@ "version": "2.2.3", "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz", "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=", + "dev": true, "requires": { "flatten": "^1.0.2", "indexes-of": "^1.0.1", @@ -29982,7 +30551,8 @@ "flatten": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz", - "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=" + "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=", + "dev": true } } }, @@ -30035,6 +30605,7 @@ "version": "2.1.6", "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", + "dev": true, "requires": { "is-svg": "^2.0.0", "postcss": "^5.0.14", @@ -30045,12 +30616,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -30061,12 +30634,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -30077,6 +30652,7 @@ "version": "2.0.2", "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", + "dev": true, "requires": { "alphanum-sort": "^1.0.1", "postcss": "^5.0.4", @@ -30086,12 +30662,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -30102,12 +30680,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -30117,12 +30697,14 @@ "postcss-value-parser": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz", - "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=" + "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=", + "dev": true }, "postcss-zindex": { "version": "2.2.0", "resolved": "http://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", + "dev": true, "requires": { "has": "^1.0.1", "postcss": "^5.0.4", @@ -30132,12 +30714,14 @@ "has-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz", - "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=" + "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=", + "dev": true }, "postcss": { "version": "5.2.18", "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz", "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==", + "dev": true, "requires": { "chalk": "^1.1.3", "js-base64": "^2.1.9", @@ -30148,12 +30732,14 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "supports-color": { "version": "3.2.3", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz", "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=", + "dev": true, "requires": { "has-flag": "^1.0.0" } @@ -30163,7 +30749,8 @@ "prelude-ls": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=" + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true }, "prepend-file": { "version": "1.3.1", @@ -30209,7 +30796,8 @@ "pretty-hrtime": { "version": "1.0.3", "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", - "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=" + "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", + "dev": true }, "printf": { "version": "0.3.0", @@ -30263,7 +30851,8 @@ "progress": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz", - "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=" + "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=", + "dev": true }, "promise": { "version": "7.3.1", @@ -30405,7 +30994,8 @@ "pseudomap": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=" + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true }, "psl": { "version": "1.1.29", @@ -31509,6 +32099,7 @@ "version": "0.6.2", "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.6.2.tgz", "integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=", + "dev": true, "requires": { "resolve": "^1.1.6" } @@ -31548,6 +32139,7 @@ "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" @@ -31557,6 +32149,7 @@ "version": "1.3.0", "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", + "dev": true, "requires": { "balanced-match": "^0.4.2", "math-expression-evaluator": "^1.2.14", @@ -31566,7 +32159,8 @@ "balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true } } }, @@ -31574,6 +32168,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.2.tgz", "integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=", + "dev": true, "requires": { "balanced-match": "^0.4.2" }, @@ -31581,7 +32176,8 @@ "balanced-match": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz", - "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=" + "integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg=", + "dev": true } } }, @@ -31656,6 +32252,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.0.tgz", "integrity": "sha1-Qvg+OXcWIt+CawKvF2Ul1qXxV/k=", + "dev": true, "requires": { "extend-shallow": "^2.0.1" } @@ -31753,6 +32350,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, "requires": { "is-buffer": "^1.1.5", "is-utf8": "^0.2.1" @@ -31762,6 +32360,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, "requires": { "remove-bom-buffer": "^3.0.0", "safe-buffer": "^5.1.0", @@ -31875,6 +32474,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/replace-homedir/-/replace-homedir-1.0.0.tgz", "integrity": "sha1-6H9tUTuSjd6AgmDBK+f+xv9ueYw=", + "dev": true, "requires": { "homedir-polyfill": "^1.0.1", "is-absolute": "^1.0.0", @@ -31991,6 +32591,7 @@ "version": "1.0.3", "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", + "dev": true, "requires": { "caller-path": "^0.1.0", "resolve-from": "^1.0.0" @@ -32036,6 +32637,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, "requires": { "expand-tilde": "^2.0.0", "global-modules": "^1.0.0" @@ -32044,12 +32646,14 @@ "resolve-from": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz", - "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=" + "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY=", + "dev": true }, "resolve-options": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, "requires": { "value-or-function": "^3.0.0" } @@ -32062,7 +32666,8 @@ "resolve-url": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=" + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true }, "resolve-url-loader": { "version": "2.3.0", @@ -32116,6 +32721,7 @@ "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" @@ -32132,7 +32738,8 @@ "ret": { "version": "0.1.15", "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true }, "revalidator": { "version": "0.1.8", @@ -32222,6 +32829,7 @@ "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" } @@ -32248,12 +32856,14 @@ "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", - "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=" + "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=", + "dev": true }, "rx-lite-aggregates": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz", "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=", + "dev": true, "requires": { "rx-lite": "*" } @@ -32305,6 +32915,7 @@ "version": "1.1.0", "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, "requires": { "ret": "~0.1.10" } @@ -32362,6 +32973,7 @@ "version": "2.2.4", "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", + "dev": true, "requires": { "glob": "^7.0.0", "lodash": "^4.0.0", @@ -32373,6 +32985,7 @@ "version": "7.1.0", "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz", "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=", + "dev": true, "requires": { "camelcase": "^3.0.0", "cliui": "^3.2.0", @@ -32393,6 +33006,7 @@ "version": "5.0.0", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "dev": true, "requires": { "camelcase": "^3.0.0" } @@ -32434,6 +33048,7 @@ "version": "0.4.5", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz", "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==", + "dev": true, "requires": { "ajv": "^6.1.0", "ajv-keywords": "^3.1.0" @@ -32443,6 +33058,7 @@ "version": "6.4.0", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.4.0.tgz", "integrity": "sha1-06/3jpJ3VJdx2vAWTP9ISCt1T8Y=", + "dev": true, "requires": { "fast-deep-equal": "^1.0.0", "fast-json-stable-stringify": "^2.0.0", @@ -32453,7 +33069,8 @@ "ajv-keywords": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz", - "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=" + "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=", + "dev": true } } }, @@ -32494,6 +33111,7 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/scss-tokenizer/-/scss-tokenizer-0.2.3.tgz", "integrity": "sha1-jrBtualyMzOCTT9VMGQRSYR85dE=", + "dev": true, "requires": { "js-base64": "^2.1.8", "source-map": "^0.4.2" @@ -32503,6 +33121,7 @@ "version": "0.4.4", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz", "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=", + "dev": true, "requires": { "amdefine": ">=0.0.4" } @@ -32572,6 +33191,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/semver-greatest-satisfied-range/-/semver-greatest-satisfied-range-1.1.0.tgz", "integrity": "sha1-E+jCZYq5aRywzXEJMkAoDTb3els=", + "dev": true, "requires": { "sver-compat": "^1.5.0" } @@ -32648,6 +33268,7 @@ "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", @@ -32740,6 +33361,7 @@ "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" } @@ -32747,7 +33369,8 @@ "shebang-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=" + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true }, "shell-parallel": { "version": "1.0.3", @@ -32963,6 +33586,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz", "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==", + "dev": true, "requires": { "is-fullwidth-code-point": "^2.0.0" }, @@ -32970,7 +33594,8 @@ "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=" + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true } } }, @@ -32984,6 +33609,7 @@ "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", @@ -32999,6 +33625,7 @@ "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" } @@ -33007,6 +33634,7 @@ "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" }, @@ -33015,6 +33643,7 @@ "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" } @@ -33025,6 +33654,7 @@ "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" }, @@ -33033,6 +33663,7 @@ "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" } @@ -33043,6 +33674,7 @@ "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", @@ -33052,17 +33684,20 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true }, "use": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/use/-/use-3.1.0.tgz", "integrity": "sha512-6UJEQM/L+mzC3ZJNM56Q4DFGLX/evKGRg15UJHGB9X5j5Z3AFbgZvjUh2yq/UJUY4U5dh7Fal++XbNg1uzpRAw==", + "dev": true, "requires": { "kind-of": "^6.0.2" }, @@ -33070,7 +33705,8 @@ "kind-of": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==" + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true } } } @@ -33080,6 +33716,7 @@ "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", @@ -33089,7 +33726,8 @@ "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -33097,6 +33735,7 @@ "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" } @@ -33876,6 +34515,7 @@ "version": "0.5.1", "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.1.tgz", "integrity": "sha512-0KW2wvzfxm8NCTb30z0LMNyPqWCdDGE2viwzUaucqJdkTRXtZiSY3I+2A6nVAjmdOy0I4gU8DwnVVGsk9jvP2A==", + "dev": true, "requires": { "atob": "^2.0.0", "decode-uri-component": "^0.2.0", @@ -33902,12 +34542,14 @@ "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=" + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true }, "sparkles": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.0.tgz", - "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=" + "integrity": "sha1-Gsu/tZJDbRC76PeFt8xvgoFQEsM=", + "dev": true }, "spawn-args": { "version": "0.2.0", @@ -33952,6 +34594,7 @@ "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" }, @@ -33960,6 +34603,7 @@ "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" @@ -33969,6 +34613,7 @@ "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" } @@ -34023,7 +34668,8 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, "sshpk": { "version": "1.14.1", @@ -34052,7 +34698,8 @@ "stack-trace": { "version": "0.0.10", "resolved": "https://registry.npmjs.org/stack-trace/-/stack-trace-0.0.10.tgz", - "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=" + "integrity": "sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=", + "dev": true }, "state-toggle": { "version": "1.0.0", @@ -34072,6 +34719,7 @@ "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" @@ -34081,6 +34729,7 @@ "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" } @@ -34089,6 +34738,7 @@ "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" }, @@ -34097,6 +34747,7 @@ "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" } @@ -34107,6 +34758,7 @@ "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" }, @@ -34115,6 +34767,7 @@ "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" } @@ -34125,6 +34778,7 @@ "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", @@ -34134,7 +34788,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -34262,6 +34917,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/stdout-stream/-/stdout-stream-1.4.0.tgz", "integrity": "sha1-osfIWH5U2UJ+qe2zrD8s1SLfN4s=", + "dev": true, "requires": { "readable-stream": "^2.0.1" } @@ -34328,7 +34984,8 @@ "stream-exhaust": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/stream-exhaust/-/stream-exhaust-1.0.2.tgz", - "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==" + "integrity": "sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==", + "dev": true }, "stream-http": { "version": "2.7.2", @@ -34388,7 +35045,8 @@ "strict-uri-encode": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz", - "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=" + "integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=", + "dev": true }, "string-convert": { "version": "0.2.1", @@ -34477,6 +35135,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/stringify-object/-/stringify-object-3.2.2.tgz", "integrity": "sha512-O696NF21oLiDy8PhpWu8AEqoZHw++QW6mUv0UvKZe8gWSdSvMXkiLufK7OmnP27Dro4GU5kb9U7JIO0mBuCRQg==", + "dev": true, "requires": { "get-own-enumerable-property-symbols": "^2.0.1", "is-obj": "^1.0.1", @@ -34542,6 +35201,7 @@ "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" }, @@ -34549,7 +35209,8 @@ "get-stdin": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz", - "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=" + "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4=", + "dev": true } } }, @@ -35120,6 +35781,7 @@ "version": "1.5.0", "resolved": "https://registry.npmjs.org/sver-compat/-/sver-compat-1.5.0.tgz", "integrity": "sha1-PPh9/rTQe0o/FIJ7wYaz/QxkXNg=", + "dev": true, "requires": { "es6-iterator": "^2.0.1", "es6-symbol": "^3.1.1" @@ -35141,6 +35803,7 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz", "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=", + "dev": true, "requires": { "coa": "~1.0.1", "colors": "~1.1.2", @@ -35154,17 +35817,20 @@ "colors": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=" + "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", + "dev": true }, "esprima": { "version": "2.7.3", "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz", - "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=" + "integrity": "sha1-luO3DVd59q1JzQMmc9HDEnZ7pYE=", + "dev": true }, "js-yaml": { "version": "3.7.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.7.0.tgz", "integrity": "sha1-XJZ93YN6m/3KXy3oQlOr6KHAO4A=", + "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^2.6.0" @@ -35273,6 +35939,7 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz", "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==", + "dev": true, "requires": { "ajv": "^5.2.3", "ajv-keywords": "^2.1.0", @@ -35285,12 +35952,14 @@ "ansi-regex": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=" + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true }, "ansi-styles": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz", "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==", + "dev": true, "requires": { "color-convert": "^1.9.0" } @@ -35299,6 +35968,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz", "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==", + "dev": true, "requires": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", @@ -35308,12 +35978,14 @@ "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=" + "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" @@ -35323,6 +35995,7 @@ "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" } @@ -35331,6 +36004,7 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz", "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=", + "dev": true, "requires": { "has-flag": "^2.0.0" } @@ -35383,6 +36057,7 @@ "version": "2.2.1", "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", + "dev": true, "requires": { "block-stream": "*", "fstream": "^1.0.2", @@ -35553,7 +36228,8 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true }, "textarea-caret": { "version": "3.0.2", @@ -35637,6 +36313,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-2.0.0.tgz", "integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=", + "dev": true, "requires": { "through2": "~2.0.0", "xtend": "~4.0.0" @@ -35652,6 +36329,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/tildify/-/tildify-1.2.0.tgz", "integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=", + "dev": true, "requires": { "os-homedir": "^1.0.0" } @@ -35659,7 +36337,8 @@ "time-stamp": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/time-stamp/-/time-stamp-1.1.0.tgz", - "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=" + "integrity": "sha1-dkpaEa9QVhkhsTPztE5hhofg9cM=", + "dev": true }, "timed-out": { "version": "2.0.0", @@ -35735,6 +36414,7 @@ "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" } @@ -35743,6 +36423,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, "requires": { "is-absolute": "^1.0.0", "is-negated-glob": "^1.0.0" @@ -35768,6 +36449,7 @@ "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" } @@ -35776,6 +36458,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.1.tgz", "integrity": "sha1-FTWL7kosg712N3uh3ASdDxiDeq4=", + "dev": true, "requires": { "define-property": "^0.2.5", "extend-shallow": "^2.0.1", @@ -35786,6 +36469,7 @@ "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" } @@ -35794,6 +36478,7 @@ "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" }, @@ -35802,6 +36487,7 @@ "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" } @@ -35812,6 +36498,7 @@ "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" }, @@ -35820,6 +36507,7 @@ "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" } @@ -35830,6 +36518,7 @@ "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", @@ -35839,7 +36528,8 @@ "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==" + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true } } }, @@ -35847,6 +36537,7 @@ "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" @@ -35856,6 +36547,7 @@ "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" } @@ -35866,6 +36558,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, "requires": { "through2": "^2.0.3" } @@ -35953,7 +36646,8 @@ "trim-newlines": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz", - "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" + "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=", + "dev": true }, "trim-repeated": { "version": "1.0.0", @@ -35983,6 +36677,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/true-case-path/-/true-case-path-1.0.2.tgz", "integrity": "sha1-fskRMJJHZsf1c74wIMNPj9/QDWI=", + "dev": true, "requires": { "glob": "^6.0.4" }, @@ -35991,6 +36686,7 @@ "version": "6.0.4", "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=", + "dev": true, "requires": { "inflight": "^1.0.4", "inherits": "2", @@ -36035,6 +36731,7 @@ "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, "requires": { "prelude-ls": "~1.1.2" } @@ -36219,7 +36916,8 @@ "unc-path-regex": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=" + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true }, "undeclared-identifiers": { "version": "1.1.2", @@ -36269,6 +36967,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/undertaker/-/undertaker-1.2.0.tgz", "integrity": "sha1-M52kZGJS0ILcN45wgGcpl1DhG0k=", + "dev": true, "requires": { "arr-flatten": "^1.0.1", "arr-map": "^2.0.0", @@ -36284,7 +36983,8 @@ "undertaker-registry": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/undertaker-registry/-/undertaker-registry-1.0.1.tgz", - "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=" + "integrity": "sha1-XkvaMI5KiirlhPm5pDWaSZglzFA=", + "dev": true }, "unherit": { "version": "1.1.0", @@ -36336,6 +37036,7 @@ "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", @@ -36347,6 +37048,7 @@ "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", @@ -36364,7 +37066,8 @@ "uniqs": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", - "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=" + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true }, "unique-filename": { "version": "1.1.0", @@ -36388,6 +37091,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.2.1.tgz", "integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=", + "dev": true, "requires": { "json-stable-stringify": "^1.0.0", "through2-filter": "^2.0.0" @@ -36448,6 +37152,7 @@ "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" @@ -36457,6 +37162,7 @@ "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", @@ -36467,6 +37173,7 @@ "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" } @@ -36476,12 +37183,14 @@ "has-values": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=" + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true }, "isobject": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=" + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true } } }, @@ -36507,6 +37216,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-3.0.2.tgz", "integrity": "sha1-+QuFhQf4HepNz7s8TD2/orVX+qo=", + "dev": true, "requires": { "punycode": "^2.1.0" }, @@ -36514,14 +37224,16 @@ "punycode": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz", - "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=" + "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0=", + "dev": true } } }, "urix": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=" + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true }, "url": { "version": "0.11.0", @@ -36699,6 +37411,7 @@ "version": "3.1.1", "resolved": "https://registry.npmjs.org/v8flags/-/v8flags-3.1.1.tgz", "integrity": "sha512-iw/1ViSEaff8NJ3HLyEjawk/8hjJib3E7pvG4pddVXfUg1983s3VGsiClDjhK64MQVDGqc1Q8r18S4VKQZS9EQ==", + "dev": true, "requires": { "homedir-polyfill": "^1.0.1" } @@ -36725,7 +37438,8 @@ "value-or-function": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=" + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true }, "varint": { "version": "4.0.1", @@ -36766,7 +37480,8 @@ "vendors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz", - "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==" + "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==", + "dev": true }, "verror": { "version": "1.10.0", @@ -36806,6 +37521,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.1.0.tgz", "integrity": "sha1-Ah+cLPlR1rk5lDyJ617lrdT9kkw=", + "dev": true, "requires": { "clone": "^2.1.1", "clone-buffer": "^1.0.0", @@ -36880,6 +37596,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, "requires": { "fs-mkdirp-stream": "^1.0.0", "glob-stream": "^6.1.0", @@ -36914,6 +37631,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, "requires": { "append-buffer": "^1.0.2", "convert-source-map": "^1.5.0", @@ -36928,6 +37646,7 @@ "version": "1.6.0", "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, "requires": { "safe-buffer": "~5.1.1" } @@ -36938,6 +37657,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/vinyl-sourcemaps-apply/-/vinyl-sourcemaps-apply-0.2.1.tgz", "integrity": "sha1-q2VJ1h0XLCsbh75cUI0jnI74dwU=", + "dev": true, "requires": { "source-map": "^0.5.1" }, @@ -36945,7 +37665,8 @@ "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true } } }, @@ -37041,7 +37762,6 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.3.tgz", "integrity": "sha1-yqRDc9yIFayHZ73ba6cwc5ZMqos=", "requires": { - "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2": "*", @@ -37050,7 +37770,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" } } }, @@ -37291,12 +38011,14 @@ "whet.extend": { "version": "0.9.9", "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz", - "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=" + "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=", + "dev": true }, "which": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz", "integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==", + "dev": true, "requires": { "isexe": "^2.0.0" } @@ -37406,6 +38128,7 @@ "version": "0.2.1", "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz", "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=", + "dev": true, "requires": { "mkdirp": "^0.5.1" } @@ -37534,7 +38257,8 @@ "yallist": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=" + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true }, "yargs": { "version": "6.6.0", diff --git a/package.json b/package.json index c3b38a994a5e..d19fb862dc7d 100644 --- a/package.json +++ b/package.json @@ -100,7 +100,6 @@ "classnames": "^2.2.5", "clone": "^2.1.2", "copy-to-clipboard": "^3.0.8", - "css-loader": "^0.28.11", "currency-formatter": "^1.4.2", "d3": "^5.7.0", "debounce": "1.1.0", @@ -112,7 +111,6 @@ "dnode": "^1.2.2", "end-of-stream": "^1.1.0", "ensnare": "^1.0.0", - "eslint-plugin-react": "^7.4.0", "eth-bin-to-ops": "^1.0.1", "eth-block-tracker": "^4.1.0", "eth-contract-metadata": "github:MetaMask/eth-contract-metadata#master", @@ -143,13 +141,7 @@ "extensionizer": "^1.0.1", "fast-json-patch": "^2.0.4", "fast-levenshtein": "^2.0.6", - "file-loader": "^1.1.11", "fuse.js": "^3.2.0", - "gulp": "github:gulpjs/gulp#v4.0.0", - "gulp-autoprefixer": "^5.0.0", - "gulp-debug": "^3.2.0", - "gulp-eslint": "^4.0.0", - "gulp-sass": "^4.0.0", "hat": "0.0.3", "human-standard-token-abi": "^2.0.0", "idb-global": "^2.1.0", @@ -272,12 +264,16 @@ "geckodriver": "^1.14.1", "gh-pages": "^1.2.0", "gifencoder": "^1.1.0", - "gulp": "github:gulpjs/gulp#6d71a658c61edb3090221579d8f97dbe086ba2ed", + "gulp": "^4.0.0", + "gulp-autoprefixer": "^5.0.0", "gulp-babel": "^7.0.0", + "gulp-debug": "^3.2.0", + "gulp-eslint": "^4.0.0", "gulp-json-editor": "^2.2.1", "gulp-livereload": "4.0.0", "gulp-multi-process": "^1.3.1", "gulp-replace": "^0.6.1", + "gulp-sass": "^4.0.0", "gulp-sourcemaps": "^2.6.0", "gulp-stylefmt": "^1.1.0", "gulp-stylelint": "^7.0.0", From 246dcf689c7e14bd9eab997fd81fc7b4a8914007 Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Thu, 6 Dec 2018 16:12:57 -0330 Subject: [PATCH 57/64] Fix race condition in network controller lookup() method. --- app/scripts/controllers/network/network.js | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/app/scripts/controllers/network/network.js b/app/scripts/controllers/network/network.js index b459b8013717..1a251bce1931 100644 --- a/app/scripts/controllers/network/network.js +++ b/app/scripts/controllers/network/network.js @@ -105,12 +105,18 @@ module.exports = class NetworkController extends EventEmitter { if (!this._provider) { return log.warn('NetworkController - lookupNetwork aborted due to missing provider') } - var { type } = this.providerStore.getState() + const { type } = this.providerStore.getState() const ethQuery = new EthQuery(this._provider) + const initialNetwork = this.getNetworkState() ethQuery.sendAsync({ method: 'net_version' }, (err, network) => { - if (err) return this.setNetworkState('loading') - log.info('web3.getNetwork returned ' + network) - this.setNetworkState(network, type) + const currentNetwork = this.getNetworkState() + if (initialNetwork === currentNetwork) { + if (err) { + return this.setNetworkState('loading') + } + log.info('web3.getNetwork returned ' + network) + this.setNetworkState(network, type) + } }) } From d8ab9cc002c10757b7382a174dafff7a0247e307 Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Sun, 9 Dec 2018 12:48:06 -0800 Subject: [PATCH 58/64] Group transactions by nonce (#5886) --- app/_locales/en/messages.json | 36 ++- app/images/icons/cancelled.svg | 3 + app/images/icons/confirm.svg | 3 + app/images/icons/error.svg | 4 + app/images/icons/new.svg | 3 + app/images/icons/retry.svg | 7 + app/images/icons/submitted.svg | 3 + app/scripts/controllers/transactions/enums.js | 2 + app/scripts/controllers/transactions/index.js | 6 +- app/scripts/metamask-controller.js | 14 +- test/integration/lib/confirm-sig-requests.js | 4 +- test/integration/lib/tx-list-items.js | 26 +- ui/app/actions.js | 6 +- .../cancel-transaction.container.js | 16 +- .../confirm-transaction-base.component.js | 2 +- .../components/sender-to-recipient/index.scss | 55 ++++- .../sender-to-recipient.component.js | 23 +- .../sender-to-recipient.constants.js | 1 + .../transaction-activity-log/index.scss | 40 ++- ...transaction-activity-log.component.test.js | 94 +++++-- .../transaction-activity-log.util.test.js | 145 ++++++++++- .../transaction-activity-log-icon/index.js | 1 + ...transaction-activity-log-icon.component.js | 55 +++++ .../transaction-activity-log.component.js | 114 ++++++--- .../transaction-activity-log.constants.js | 13 + .../transaction-activity-log.container.js | 34 ++- .../transaction-activity-log.util.js | 199 ++++++++++++--- .../transaction-breakdown/index.scss | 7 +- .../transaction-breakdown.component.test.js | 4 - .../transaction-breakdown.component.js | 101 ++++---- .../transaction-list-item-details/index.scss | 11 +- ...action-list-item-details.component.test.js | 19 +- ...transaction-list-item-details.component.js | 59 +++-- .../transaction-list-item/index.scss | 6 - .../transaction-list-item.component.js | 58 +++-- .../transaction-list-item.container.js | 47 ++-- .../transaction-list.component.js | 43 ++-- .../transaction-list.container.js | 15 +- .../components/transaction-status/index.scss | 16 +- .../transaction-status.component.test.js | 8 +- .../transaction-status.component.js | 7 +- ui/app/constants/transactions.js | 3 +- ui/app/ducks/gas.duck.js | 14 ++ ui/app/helpers/transactions.util.js | 16 +- ui/app/selectors/transactions.js | 232 +++++++++++++++++- ui/app/util.js | 4 +- ui/lib/tx-helper.js | 2 +- 47 files changed, 1208 insertions(+), 373 deletions(-) create mode 100755 app/images/icons/cancelled.svg create mode 100644 app/images/icons/confirm.svg create mode 100644 app/images/icons/error.svg create mode 100755 app/images/icons/new.svg create mode 100755 app/images/icons/retry.svg create mode 100755 app/images/icons/submitted.svg create mode 100644 ui/app/components/transaction-activity-log/transaction-activity-log-icon/index.js create mode 100644 ui/app/components/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js create mode 100644 ui/app/components/transaction-activity-log/transaction-activity-log.constants.js diff --git a/app/_locales/en/messages.json b/app/_locales/en/messages.json index d23de5fa0237..400633c8c432 100644 --- a/app/_locales/en/messages.json +++ b/app/_locales/en/messages.json @@ -17,6 +17,9 @@ "confirmClear": { "message": "Are you sure you want to clear approved websites?" }, + "contractInteraction": { + "message": "Contract Interaction" + }, "clearApprovalDataSuccess": { "message": "Approved website data cleared successfully." }, @@ -185,6 +188,9 @@ "cancellationGasFee": { "message": "Cancellation Gas Fee" }, + "cancelled": { + "message": "Cancelled" + }, "cancelN": { "message": "Cancel all $1 transactions" }, @@ -1177,6 +1183,12 @@ "speedUpSubtitle": { "message": "Increase your gas price to attempt to overwrite and speed up your transaction" }, + "speedUpCancellation": { + "message": "Speed up this cancellation" + }, + "speedUpTransaction": { + "message": "Speed up this transaction" + }, "status": { "message": "Status" }, @@ -1263,29 +1275,38 @@ "message": "transaction" }, "transactionConfirmed": { - "message": "Transaction confirmed on $2." + "message": "Transaction confirmed at $2." }, "transactionCreated": { - "message": "Transaction created with a value of $1 on $2." + "message": "Transaction created with a value of $1 at $2." }, "transactionWithNonce": { "message": "Transaction $1" }, "transactionDropped": { - "message": "Transaction dropped on $2." + "message": "Transaction dropped at $2." }, "transactionSubmitted": { - "message": "Transaction submitted on $2." + "message": "Transaction submitted with gas fee of $1 at $2." + }, + "transactionResubmitted": { + "message": "Transaction resubmitted with gas fee increased to $1 at $2" }, "transactionUpdated": { - "message": "Transaction updated on $2." + "message": "Transaction updated at $2." }, "transactionUpdatedGas": { - "message": "Transaction updated with a gas price of $1 on $2." + "message": "Transaction updated with a gas fee of $1 at $2." }, "transactionErrored": { "message": "Transaction encountered an error." }, + "transactionCancelAttempted": { + "message": "Transaction cancel attempted with gas fee of $1 at $2" + }, + "transactionCancelSuccess": { + "message": "Transaction successfully cancelled at $2" + }, "transactions": { "message": "transactions" }, @@ -1350,9 +1371,6 @@ "unknown": { "message": "Unknown" }, - "unknownFunction": { - "message": "Unknown Function" - }, "unknownNetwork": { "message": "Unknown Private Network" }, diff --git a/app/images/icons/cancelled.svg b/app/images/icons/cancelled.svg new file mode 100755 index 000000000000..ae4846dde3b9 --- /dev/null +++ b/app/images/icons/cancelled.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/images/icons/confirm.svg b/app/images/icons/confirm.svg new file mode 100644 index 000000000000..3263bf03eb5a --- /dev/null +++ b/app/images/icons/confirm.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/images/icons/error.svg b/app/images/icons/error.svg new file mode 100644 index 000000000000..bf5abf946f8c --- /dev/null +++ b/app/images/icons/error.svg @@ -0,0 +1,4 @@ + + + + diff --git a/app/images/icons/new.svg b/app/images/icons/new.svg new file mode 100755 index 000000000000..f56c43e088a6 --- /dev/null +++ b/app/images/icons/new.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/images/icons/retry.svg b/app/images/icons/retry.svg new file mode 100755 index 000000000000..ddaa198caf57 --- /dev/null +++ b/app/images/icons/retry.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/app/images/icons/submitted.svg b/app/images/icons/submitted.svg new file mode 100755 index 000000000000..b5ced877759c --- /dev/null +++ b/app/images/icons/submitted.svg @@ -0,0 +1,3 @@ + + + diff --git a/app/scripts/controllers/transactions/enums.js b/app/scripts/controllers/transactions/enums.js index be6f16e0d417..d41400b9f9e7 100644 --- a/app/scripts/controllers/transactions/enums.js +++ b/app/scripts/controllers/transactions/enums.js @@ -3,10 +3,12 @@ const TRANSACTION_TYPE_RETRY = 'retry' const TRANSACTION_TYPE_STANDARD = 'standard' const TRANSACTION_STATUS_APPROVED = 'approved' +const TRANSACTION_STATUS_CONFIRMED = 'confirmed' module.exports = { TRANSACTION_TYPE_CANCEL, TRANSACTION_TYPE_RETRY, TRANSACTION_TYPE_STANDARD, TRANSACTION_STATUS_APPROVED, + TRANSACTION_STATUS_CONFIRMED, } diff --git a/app/scripts/controllers/transactions/index.js b/app/scripts/controllers/transactions/index.js index f530fbd22bb7..2ce736beb74e 100644 --- a/app/scripts/controllers/transactions/index.js +++ b/app/scripts/controllers/transactions/index.js @@ -230,13 +230,15 @@ class TransactionController extends EventEmitter { to allow the user to resign the transaction with a higher gas values @param originalTxId {number} - the id of the txMeta that you want to attempt to retry + @param gasPrice {string=} - Optional gas price to be increased to use as the retry + transaction's gas price @return {txMeta} */ - async retryTransaction (originalTxId) { + async retryTransaction (originalTxId, gasPrice) { const originalTxMeta = this.txStateManager.getTx(originalTxId) const { txParams } = originalTxMeta - const lastGasPrice = originalTxMeta.txParams.gasPrice + const lastGasPrice = gasPrice || originalTxMeta.txParams.gasPrice const suggestedGasPriceBN = new ethUtil.BN(ethUtil.stripHexPrefix(this.getGasPrice()), 16) const lastGasPriceBN = new ethUtil.BN(ethUtil.stripHexPrefix(lastGasPrice), 16) // essentially lastGasPrice * 1.1 but diff --git a/app/scripts/metamask-controller.js b/app/scripts/metamask-controller.js index d382b1ad08e2..c7e9cfcc774c 100644 --- a/app/scripts/metamask-controller.js +++ b/app/scripts/metamask-controller.js @@ -1144,8 +1144,8 @@ module.exports = class MetamaskController extends EventEmitter { * @param {string} txId - The ID of the transaction to speed up. * @param {Function} cb - The callback function called with a full state update. */ - async retryTransaction (txId, cb) { - await this.txController.retryTransaction(txId) + async retryTransaction (txId, gasPrice, cb) { + await this.txController.retryTransaction(txId, gasPrice) const state = await this.getState() return state } @@ -1158,9 +1158,13 @@ module.exports = class MetamaskController extends EventEmitter { * @returns {object} MetaMask state */ async createCancelTransaction (originalTxId, customGasPrice, cb) { - await this.txController.createCancelTransaction(originalTxId, customGasPrice) - const state = await this.getState() - return state + try { + await this.txController.createCancelTransaction(originalTxId, customGasPrice) + const state = await this.getState() + return state + } catch (error) { + throw error + } } async createSpeedUpTransaction (originalTxId, customGasPrice, cb) { diff --git a/test/integration/lib/confirm-sig-requests.js b/test/integration/lib/confirm-sig-requests.js index 9c2ad7cf4d95..041a1af341f1 100644 --- a/test/integration/lib/confirm-sig-requests.js +++ b/test/integration/lib/confirm-sig-requests.js @@ -21,8 +21,8 @@ async function runConfirmSigRequestsTest (assert, done) { const pendingRequestItem = $.find('.transaction-list-item .transaction-list-item__grid') - if (pendingRequestItem[0]) { - pendingRequestItem[0].click() + if (pendingRequestItem[2]) { + pendingRequestItem[2].click() } await timeout(1000) diff --git a/test/integration/lib/tx-list-items.js b/test/integration/lib/tx-list-items.js index ed4f820744a2..ff196fac8041 100644 --- a/test/integration/lib/tx-list-items.js +++ b/test/integration/lib/tx-list-items.js @@ -30,35 +30,25 @@ async function runTxListItemsTest (assert, done) { metamaskLogo[0].click() const txListItems = await queryAsync($, '.transaction-list-item') - assert.equal(txListItems.length, 8, 'all tx list items are rendered') + assert.equal(txListItems.length, 7, 'all tx list items are rendered') - const retryTxGrid = await findAsync($(txListItems[2]), '.transaction-list-item__grid') - retryTxGrid[0].click() - const retryTxDetails = await findAsync($, '.transaction-list-item-details') - const headerButtons = await findAsync($(retryTxDetails[0]), '.transaction-list-item-details__header-button') - assert.equal(headerButtons[0].textContent, 'speed up') - - const approvedTx = txListItems[2] + const approvedTx = txListItems[0] const approvedTxRenderedStatus = await findAsync($(approvedTx), '.transaction-list-item__status') assert.equal(approvedTxRenderedStatus[0].textContent, 'pending', 'approvedTx has correct label') - const unapprovedMsg = txListItems[0] + const unapprovedMsg = txListItems[1] const unapprovedMsgDescription = await findAsync($(unapprovedMsg), '.transaction-list-item__action') assert.equal(unapprovedMsgDescription[0].textContent, 'Signature Request', 'unapprovedMsg has correct description') - const failedTx = txListItems[4] - const failedTxRenderedStatus = await findAsync($(failedTx), '.transaction-list-item__status') - assert.equal(failedTxRenderedStatus[0].textContent, 'Failed', 'failedTx has correct label') - - const shapeShiftTx = txListItems[5] + const shapeShiftTx = txListItems[4] const shapeShiftTxStatus = await findAsync($(shapeShiftTx), '.flex-column div:eq(1)') assert.equal(shapeShiftTxStatus[0].textContent, 'No deposits received', 'shapeShiftTx has correct status') + const rejectedTx = txListItems[5] + const rejectedTxRenderedStatus = await findAsync($(rejectedTx), '.transaction-list-item__status') + assert.equal(rejectedTxRenderedStatus[0].textContent, 'Rejected', 'rejectedTx has correct label') + const confirmedTokenTx = txListItems[6] const confirmedTokenTxAddress = await findAsync($(confirmedTokenTx), '.transaction-list-item__status') assert.equal(confirmedTokenTxAddress[0].textContent, 'Confirmed', 'confirmedTokenTx has correct address') - - const rejectedTx = txListItems[7] - const rejectedTxRenderedStatus = await findAsync($(rejectedTx), '.transaction-list-item__status') - assert.equal(rejectedTxRenderedStatus[0].textContent, 'Rejected', 'rejectedTx has correct label') } diff --git a/ui/app/actions.js b/ui/app/actions.js index cd24aed0a9c1..fa175177e78e 100644 --- a/ui/app/actions.js +++ b/ui/app/actions.js @@ -1793,13 +1793,13 @@ function markAccountsFound () { return callBackgroundThenUpdate(background.markAccountsFound) } -function retryTransaction (txId) { +function retryTransaction (txId, gasPrice) { log.debug(`background.retryTransaction`) let newTxId - return (dispatch) => { + return dispatch => { return new Promise((resolve, reject) => { - background.retryTransaction(txId, (err, newState) => { + background.retryTransaction(txId, gasPrice, (err, newState) => { if (err) { dispatch(actions.displayWarning(err.message)) reject(err) diff --git a/ui/app/components/modals/cancel-transaction/cancel-transaction.container.js b/ui/app/components/modals/cancel-transaction/cancel-transaction.container.js index eede8b1ee15a..10931a001039 100644 --- a/ui/app/components/modals/cancel-transaction/cancel-transaction.container.js +++ b/ui/app/components/modals/cancel-transaction/cancel-transaction.container.js @@ -28,31 +28,29 @@ const mapStateToProps = (state, ownProps) => { transactionId, transactionStatus, originalGasPrice, + defaultNewGasPrice, newGasFee, } } const mapDispatchToProps = dispatch => { return { - createCancelTransaction: txId => dispatch(createCancelTransaction(txId)), + createCancelTransaction: (txId, customGasPrice) => { + return dispatch(createCancelTransaction(txId, customGasPrice)) + }, showTransactionConfirmedModal: () => dispatch(showModal({ name: 'TRANSACTION_CONFIRMED' })), } } const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { transactionId, ...restStateProps } = stateProps - const { - createCancelTransaction: dispatchCreateCancelTransaction, - ...restDispatchProps - } = dispatchProps + const { transactionId, defaultNewGasPrice, ...restStateProps } = stateProps + const { createCancelTransaction, ...restDispatchProps } = dispatchProps return { ...restStateProps, ...restDispatchProps, ...ownProps, - createCancelTransaction: newGasPrice => { - return dispatchCreateCancelTransaction(transactionId, newGasPrice) - }, + createCancelTransaction: () => createCancelTransaction(transactionId, defaultNewGasPrice), } } diff --git a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js index e3abde233a85..6bc415781e9e 100644 --- a/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js +++ b/ui/app/components/pages/confirm-transaction-base/confirm-transaction-base.component.js @@ -426,7 +426,7 @@ export default class ConfirmTransactionBase extends Component { toName={toName} toAddress={toAddress} showEdit={onEdit && !isTxReprice} - action={action || name || this.context.t('unknownFunction')} + action={action || name || this.context.t('contractInteraction')} title={title} titleComponent={this.renderTitleComponent()} subtitle={subtitle} diff --git a/ui/app/components/sender-to-recipient/index.scss b/ui/app/components/sender-to-recipient/index.scss index 0ab0413becdc..b21e4e1bbbee 100644 --- a/ui/app/components/sender-to-recipient/index.scss +++ b/ui/app/components/sender-to-recipient/index.scss @@ -1,12 +1,13 @@ .sender-to-recipient { + width: 100%; + display: flex; + flex-direction: row; + justify-content: center; + position: relative; + flex: 0 0 auto; + &--default { - width: 100%; - display: flex; - flex-direction: row; - justify-content: center; border-bottom: 1px solid $geyser; - position: relative; - flex: 0 0 auto; height: 42px; .sender-to-recipient { @@ -74,13 +75,6 @@ } &--cards { - width: 100%; - display: flex; - flex-direction: row; - justify-content: center; - position: relative; - flex: 0 0 auto; - .sender-to-recipient { &__party { display: flex; @@ -117,4 +111,39 @@ } } } + + &--flat { + .sender-to-recipient { + &__party { + display: flex; + flex-direction: row; + align-items: center; + justify-content: center; + flex: 1; + padding: 6px; + cursor: pointer; + min-width: 0; + color: $dusty-gray; + } + + &__tooltip-wrapper { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + &__name { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + font-size: .6875rem; + } + + &__arrow-container { + display: flex; + justify-content: center; + align-items: center; + } + } + } } diff --git a/ui/app/components/sender-to-recipient/sender-to-recipient.component.js b/ui/app/components/sender-to-recipient/sender-to-recipient.component.js index e71bd7406525..89a1a9c08c62 100644 --- a/ui/app/components/sender-to-recipient/sender-to-recipient.component.js +++ b/ui/app/components/sender-to-recipient/sender-to-recipient.component.js @@ -4,12 +4,13 @@ import classnames from 'classnames' import Identicon from '../identicon' import Tooltip from '../tooltip-v2' import copyToClipboard from 'copy-to-clipboard' -import { DEFAULT_VARIANT, CARDS_VARIANT } from './sender-to-recipient.constants' +import { DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT } from './sender-to-recipient.constants' import { checksumAddress } from '../../util' const variantHash = { [DEFAULT_VARIANT]: 'sender-to-recipient--default', [CARDS_VARIANT]: 'sender-to-recipient--cards', + [FLAT_VARIANT]: 'sender-to-recipient--flat', } export default class SenderToRecipient extends PureComponent { @@ -19,7 +20,7 @@ export default class SenderToRecipient extends PureComponent { recipientName: PropTypes.string, recipientAddress: PropTypes.string, t: PropTypes.func, - variant: PropTypes.oneOf([DEFAULT_VARIANT, CARDS_VARIANT]), + variant: PropTypes.oneOf([DEFAULT_VARIANT, CARDS_VARIANT, FLAT_VARIANT]), addressOnly: PropTypes.bool, assetImage: PropTypes.string, } @@ -128,15 +129,8 @@ export default class SenderToRecipient extends PureComponent { } renderArrow () { - return this.props.variant === CARDS_VARIANT + return this.props.variant === DEFAULT_VARIANT ? ( -
- -
- ) : (
+ ) : ( +
+ +
) } @@ -154,7 +155,7 @@ export default class SenderToRecipient extends PureComponent { const checksummedSenderAddress = checksumAddress(senderAddress) return ( -
+
{ diff --git a/ui/app/components/sender-to-recipient/sender-to-recipient.constants.js b/ui/app/components/sender-to-recipient/sender-to-recipient.constants.js index 166228932dcb..f53a5115d4ad 100644 --- a/ui/app/components/sender-to-recipient/sender-to-recipient.constants.js +++ b/ui/app/components/sender-to-recipient/sender-to-recipient.constants.js @@ -1,3 +1,4 @@ // Component design variants export const DEFAULT_VARIANT = 'DEFAULT_VARIANT' export const CARDS_VARIANT = 'CARDS_VARIANT' +export const FLAT_VARIANT = 'FLAT_VARIANT' diff --git a/ui/app/components/transaction-activity-log/index.scss b/ui/app/components/transaction-activity-log/index.scss index 27f3006b3cfa..00c17e6aabe7 100644 --- a/ui/app/components/transaction-activity-log/index.scss +++ b/ui/app/components/transaction-activity-log/index.scss @@ -1,7 +1,8 @@ .transaction-activity-log { - &__card { - background: $white; - height: 100%; + &__title { + border-bottom: 1px solid #d8d8d8; + padding-bottom: 4px; + text-transform: capitalize; } &__activities-container { @@ -21,8 +22,8 @@ left: 0; top: 0; height: 100%; - width: 6px; - border-right: 1px solid $scorpion; + width: 7px; + border-right: 1px solid #909090; } &:first-child::after { @@ -40,22 +41,25 @@ } &__activity-icon { - width: 13px; - height: 13px; + width: 15px; + height: 15px; margin-right: 6px; border-radius: 50%; - background: $scorpion; + background: #909090; flex: 0 0 auto; + display: flex; + justify-content: center; + align-items: center; + z-index: 1; } &__activity-text { - color: $scorpion; + color: $dusty-gray; font-size: .75rem; + cursor: pointer; - @media screen and (min-width: $break-large) { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; + &:hover { + color: $black; } } @@ -64,6 +68,16 @@ font-weight: 500; } + &__entry-container { + min-width: 0; + } + + &__action-link { + font-size: .75rem; + cursor: pointer; + color: $curious-blue; + } + b { font-weight: 500; } diff --git a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.component.test.js b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.component.test.js index 8687dbbc72ac..a2946e53da85 100644 --- a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.component.test.js +++ b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.component.test.js @@ -2,34 +2,100 @@ import React from 'react' import assert from 'assert' import { shallow } from 'enzyme' import TransactionActivityLog from '../transaction-activity-log.component' -import Card from '../../card' describe('TransactionActivityLog Component', () => { it('should render properly', () => { - const transaction = { - history: [], - id: 1, - status: 'confirmed', - txParams: { - from: '0x1', - gas: '0x5208', - gasPrice: '0x3b9aca00', - nonce: '0xa4', - to: '0x2', + const activities = [ + { + eventKey: 'transactionCreated', + hash: '0xe46c7f9b39af2fbf1c53e66f72f80343ab54c2c6dba902d51fb98ada08fe1a63', + id: 2005383477493174, + timestamp: 1543957986150, value: '0x2386f26fc10000', + }, { + eventKey: 'transactionSubmitted', + hash: '0xe46c7f9b39af2fbf1c53e66f72f80343ab54c2c6dba902d51fb98ada08fe1a63', + id: 2005383477493174, + timestamp: 1543957987853, + value: '0x1319718a5000', + }, { + eventKey: 'transactionResubmitted', + hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87', + id: 2005383477493175, + timestamp: 1543957991563, + value: '0x1502634b5800', + }, { + eventKey: 'transactionConfirmed', + hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87', + id: 2005383477493175, + timestamp: 1543958029960, + value: '0x1502634b5800', }, - } + ] const wrapper = shallow( {}} + onRetry={() => {}} + primaryTransactionStatus="confirmed" />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } } ) assert.ok(wrapper.hasClass('transaction-activity-log')) assert.ok(wrapper.hasClass('test-class')) - assert.equal(wrapper.find(Card).length, 1) + }) + + it('should render inline retry and cancel buttons', () => { + const activities = [ + { + eventKey: 'transactionCreated', + hash: '0xa', + id: 1, + timestamp: 1, + value: '0x1', + }, { + eventKey: 'transactionSubmitted', + hash: '0xa', + id: 1, + timestamp: 2, + value: '0x1', + }, { + eventKey: 'transactionResubmitted', + hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87', + id: 2, + timestamp: 3, + value: '0x1', + }, { + eventKey: 'transactionCancelAttempted', + hash: '0x7d09d337fc6f5d6fe2dbf3a6988d69532deb0a82b665f9180b5a20db377eea87', + id: 3, + timestamp: 4, + value: '0x1', + }, + ] + + const wrapper = shallow( + {}} + onRetry={() => {}} + primaryTransactionStatus="pending" + />, + { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } } + ) + + assert.ok(wrapper.hasClass('transaction-activity-log')) + assert.ok(wrapper.hasClass('test-class')) + assert.equal(wrapper.find('.transaction-activity-log__action-link').length, 2) }) }) diff --git a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.util.test.js b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.util.test.js index 58650040885d..d014b88864de 100644 --- a/ui/app/components/transaction-activity-log/tests/transaction-activity-log.util.test.js +++ b/ui/app/components/transaction-activity-log/tests/transaction-activity-log.util.test.js @@ -1,5 +1,130 @@ import assert from 'assert' -import { getActivities } from '../transaction-activity-log.util' +import { combineTransactionHistories, getActivities } from '../transaction-activity-log.util' + +describe('combineTransactionHistories', () => { + it('should return no activites for an empty list of transactions', () => { + assert.deepEqual(combineTransactionHistories([]), []) + }) + + it('should return activities for an array of transactions', () => { + const transactions = [ + { + estimatedGas: '0x5208', + hash: '0xa14f13d36b3901e352ce3a7acb9b47b001e5a3370f06232a0953c6fc6fad91b3', + history: [ + { + 'id': 6400627574331058, + 'time': 1543958845581, + 'status': 'unapproved', + 'metamaskNetworkId': '3', + 'loadingDefaults': true, + 'txParams': { + 'from': '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706', + 'to': '0xc5ae6383e126f901dcb06131d97a88745bfa88d6', + 'value': '0x2386f26fc10000', + 'gas': '0x5208', + 'gasPrice': '0x3b9aca00', + }, + 'type': 'standard', + }, + [{ 'op': 'replace', 'path': '/status', 'value': 'approved', 'note': 'txStateManager: setting status to approved', 'timestamp': 1543958847813 }], + [{ 'op': 'replace', 'path': '/status', 'value': 'submitted', 'note': 'txStateManager: setting status to submitted', 'timestamp': 1543958848147 }], + [{ 'op': 'replace', 'path': '/status', 'value': 'dropped', 'note': 'txStateManager: setting status to dropped', 'timestamp': 1543958897181 }, { 'op': 'add', 'path': '/replacedBy', 'value': '0xecbe181ee67c4291d04a7cb9ffbf1d5d831e4fbaa89994fd06bab5dd4cc79b33' }], + ], + id: 6400627574331058, + loadingDefaults: false, + metamaskNetworkId: '3', + status: 'dropped', + submittedTime: 1543958848135, + time: 1543958845581, + txParams: { + from: '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706', + gas: '0x5208', + gasPrice: '0x3b9aca00', + nonce: '0x32', + to: '0xc5ae6383e126f901dcb06131d97a88745bfa88d6', + value: '0x2386f26fc10000', + }, + type: 'standard', + }, { + hash: '0xecbe181ee67c4291d04a7cb9ffbf1d5d831e4fbaa89994fd06bab5dd4cc79b33', + history: [ + { + 'id': 6400627574331060, + 'time': 1543958857697, + 'status': 'unapproved', + 'metamaskNetworkId': '3', + 'loadingDefaults': false, + 'txParams': { + 'from': '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706', + 'to': '0xc5ae6383e126f901dcb06131d97a88745bfa88d6', + 'value': '0x2386f26fc10000', + 'gas': '0x5208', + 'gasPrice': '0x3b9aca00', + 'nonce': '0x32', + }, + 'lastGasPrice': '0x4190ab00', + 'type': 'retry', + }, + [{ 'op': 'replace', 'path': '/txParams/gasPrice', 'value': '0x481f2280', 'note': 'confTx: user approved transaction', 'timestamp': 1543958859470 }], + [{ 'op': 'replace', 'path': '/status', 'value': 'approved', 'note': 'txStateManager: setting status to approved', 'timestamp': 1543958859485 }], + [{ 'op': 'replace', 'path': '/status', 'value': 'signed', 'note': 'transactions#publishTransaction', 'timestamp': 1543958859889 }], + [{ 'op': 'replace', 'path': '/status', 'value': 'submitted', 'note': 'txStateManager: setting status to submitted', 'timestamp': 1543958860061 }], [{ 'op': 'add', 'path': '/firstRetryBlockNumber', 'value': '0x45a0fd', 'note': 'transactions/pending-tx-tracker#event: tx:block-update', 'timestamp': 1543958896466 }], + [{ 'op': 'replace', 'path': '/status', 'value': 'confirmed', 'timestamp': 1543958897165 }], + ], + id: 6400627574331060, + lastGasPrice: '0x4190ab00', + loadingDefaults: false, + metamaskNetworkId: '3', + status: 'confirmed', + submittedTime: 1543958860054, + time: 1543958857697, + txParams: { + from: '0x50a9d56c2b8ba9a5c7f2c08c3d26e0499f23a706', + gas: '0x5208', + gasPrice: '0x481f2280', + nonce: '0x32', + to: '0xc5ae6383e126f901dcb06131d97a88745bfa88d6', + value: '0x2386f26fc10000', + }, + txReceipt: { + status: '0x1', + }, + type: 'retry', + }, + ] + + const expected = [ + { + id: 6400627574331058, + hash: '0xa14f13d36b3901e352ce3a7acb9b47b001e5a3370f06232a0953c6fc6fad91b3', + eventKey: 'transactionCreated', + timestamp: 1543958845581, + value: '0x2386f26fc10000', + }, { + id: 6400627574331058, + hash: '0xa14f13d36b3901e352ce3a7acb9b47b001e5a3370f06232a0953c6fc6fad91b3', + eventKey: 'transactionSubmitted', + timestamp: 1543958848147, + value: '0x1319718a5000', + }, { + id: 6400627574331060, + hash: '0xecbe181ee67c4291d04a7cb9ffbf1d5d831e4fbaa89994fd06bab5dd4cc79b33', + eventKey: 'transactionResubmitted', + timestamp: 1543958860061, + value: '0x171c3a061400', + }, { + id: 6400627574331060, + hash: '0xecbe181ee67c4291d04a7cb9ffbf1d5d831e4fbaa89994fd06bab5dd4cc79b33', + eventKey: 'transactionConfirmed', + timestamp: 1543958897165, + value: '0x171c3a061400', + }, + ] + + assert.deepEqual(combineTransactionHistories(transactions), expected) + }) +}) describe('getActivities', () => { it('should return no activities for an empty history', () => { @@ -178,6 +303,7 @@ describe('getActivities', () => { to: '0x2', value: '0x2386f26fc10000', }, + hash: '0xabc', } const expectedResult = [ @@ -185,24 +311,25 @@ describe('getActivities', () => { 'eventKey': 'transactionCreated', 'timestamp': 1535507561452, 'value': '0x2386f26fc10000', - }, - { - 'eventKey': 'transactionUpdatedGas', - 'timestamp': 1535664571504, - 'value': '0x77359400', + 'id': 1, + 'hash': '0xabc', }, { 'eventKey': 'transactionSubmitted', 'timestamp': 1535507564665, - 'value': undefined, + 'value': '0x2632e314a000', + 'id': 1, + 'hash': '0xabc', }, { 'eventKey': 'transactionConfirmed', 'timestamp': 1535507615993, - 'value': undefined, + 'value': '0x2632e314a000', + 'id': 1, + 'hash': '0xabc', }, ] - assert.deepEqual(getActivities(transaction), expectedResult) + assert.deepEqual(getActivities(transaction, true), expectedResult) }) }) diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log-icon/index.js b/ui/app/components/transaction-activity-log/transaction-activity-log-icon/index.js new file mode 100644 index 000000000000..86b12360a19b --- /dev/null +++ b/ui/app/components/transaction-activity-log/transaction-activity-log-icon/index.js @@ -0,0 +1 @@ +export { default } from './transaction-activity-log-icon.component' diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js b/ui/app/components/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js new file mode 100644 index 000000000000..871716002bcb --- /dev/null +++ b/ui/app/components/transaction-activity-log/transaction-activity-log-icon/transaction-activity-log-icon.component.js @@ -0,0 +1,55 @@ +import React, { PureComponent } from 'react' +import PropTypes from 'prop-types' +import classnames from 'classnames' + +import { + TRANSACTION_CREATED_EVENT, + TRANSACTION_SUBMITTED_EVENT, + TRANSACTION_RESUBMITTED_EVENT, + TRANSACTION_CONFIRMED_EVENT, + TRANSACTION_DROPPED_EVENT, + TRANSACTION_ERRORED_EVENT, + TRANSACTION_CANCEL_ATTEMPTED_EVENT, + TRANSACTION_CANCEL_SUCCESS_EVENT, +} from '../transaction-activity-log.constants' + +const imageHash = { + [TRANSACTION_CREATED_EVENT]: '/images/icons/new.svg', + [TRANSACTION_SUBMITTED_EVENT]: '/images/icons/submitted.svg', + [TRANSACTION_RESUBMITTED_EVENT]: '/images/icons/retry.svg', + [TRANSACTION_CONFIRMED_EVENT]: '/images/icons/confirm.svg', + [TRANSACTION_DROPPED_EVENT]: '/images/icons/cancelled.svg', + [TRANSACTION_ERRORED_EVENT]: '/images/icons/error.svg', + [TRANSACTION_CANCEL_ATTEMPTED_EVENT]: '/images/icons/cancelled.svg', + [TRANSACTION_CANCEL_SUCCESS_EVENT]: '/images/icons/cancelled.svg', +} + +export default class TransactionActivityLogIcon extends PureComponent { + static contextTypes = { + t: PropTypes.func, + } + + static propTypes = { + className: PropTypes.string, + eventKey: PropTypes.oneOf(Object.keys(imageHash)), + } + + render () { + const { className, eventKey } = this.props + const imagePath = imageHash[eventKey] + + return ( +
+ { + imagePath && ( + + ) + } +
+ ) + } +} diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.component.js b/ui/app/components/transaction-activity-log/transaction-activity-log.component.js index 58d932a0f888..d6f90860a4cb 100644 --- a/ui/app/components/transaction-activity-log/transaction-activity-log.component.js +++ b/ui/app/components/transaction-activity-log/transaction-activity-log.component.js @@ -1,10 +1,11 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' -import { getActivities } from './transaction-activity-log.util' -import Card from '../card' import { getEthConversionFromWeiHex, getValueFromWeiHex } from '../../helpers/conversions.util' import { formatDate } from '../../util' +import TransactionActivityLogIcon from './transaction-activity-log-icon' +import { CONFIRMED_STATUS } from './transaction-activity-log.constants' +import prefixForNetwork from '../../../lib/etherscan-prefix-for-network' export default class TransactionActivityLog extends PureComponent { static contextTypes = { @@ -12,41 +13,64 @@ export default class TransactionActivityLog extends PureComponent { } static propTypes = { - transaction: PropTypes.object, + activities: PropTypes.array, className: PropTypes.string, conversionRate: PropTypes.number, + inlineRetryIndex: PropTypes.number, + inlineCancelIndex: PropTypes.number, nativeCurrency: PropTypes.string, + onCancel: PropTypes.func, + onRetry: PropTypes.func, + primaryTransaction: PropTypes.object, } - state = { - activities: [], - } + handleActivityClick = hash => { + const { primaryTransaction } = this.props + const { metamaskNetworkId } = primaryTransaction + + const prefix = prefixForNetwork(metamaskNetworkId) + const etherscanUrl = `https://${prefix}etherscan.io/tx/${hash}` - componentDidMount () { - this.setActivites() + global.platform.openWindow({ url: etherscanUrl }) } - componentDidUpdate (prevProps) { - const { - transaction: { history: prevHistory = [], txReceipt: { status: prevStatus } = {} } = {}, - } = prevProps - const { - transaction: { history = [], txReceipt: { status } = {} } = {}, - } = this.props + renderInlineRetry (index, activity) { + const { t } = this.context + const { inlineRetryIndex, primaryTransaction = {}, onRetry } = this.props + const { status } = primaryTransaction + const { id } = activity - if (prevHistory.length !== history.length || prevStatus !== status) { - this.setActivites() - } + return status !== CONFIRMED_STATUS && index === inlineRetryIndex + ? ( +
onRetry(id)} + > + { t('speedUpTransaction') } +
+ ) : null } - setActivites () { - const activities = getActivities(this.props.transaction) - this.setState({ activities }) + renderInlineCancel (index, activity) { + const { t } = this.context + const { inlineCancelIndex, primaryTransaction = {}, onCancel } = this.props + const { status } = primaryTransaction + const { id } = activity + + return status !== CONFIRMED_STATUS && index === inlineCancelIndex + ? ( +
onCancel(id)} + > + { t('speedUpCancellation') } +
+ ) : null } renderActivity (activity, index) { const { conversionRate, nativeCurrency } = this.props - const { eventKey, value, timestamp } = activity + const { eventKey, value, timestamp, hash } = activity const ethValue = index === 0 ? `${getValueFromWeiHex({ value, @@ -55,8 +79,13 @@ export default class TransactionActivityLog extends PureComponent { conversionRate, numberOfDecimals: 6, })} ${nativeCurrency}` - : getEthConversionFromWeiHex({ value, fromCurrency: nativeCurrency, conversionRate }) - const formattedTimestamp = formatDate(timestamp) + : getEthConversionFromWeiHex({ + value, + fromCurrency: nativeCurrency, + conversionRate, + numberOfDecimals: 3, + }) + const formattedTimestamp = formatDate(timestamp, '14:30 on 3/16/2014') const activityText = this.context.t(eventKey, [ethValue, formattedTimestamp]) return ( @@ -64,12 +93,20 @@ export default class TransactionActivityLog extends PureComponent { key={index} className="transaction-activity-log__activity" > -
-
- { activityText } + +
+
this.handleActivityClick(hash)} + > + { activityText } +
+ { this.renderInlineRetry(index, activity) } + { this.renderInlineCancel(index, activity) }
) @@ -77,19 +114,16 @@ export default class TransactionActivityLog extends PureComponent { render () { const { t } = this.context - const { className } = this.props - const { activities } = this.state + const { className, activities } = this.props return (
- -
- { activities.map((activity, index) => this.renderActivity(activity, index)) } -
-
+
+ { t('activityLog') } +
+
+ { activities.map((activity, index) => this.renderActivity(activity, index)) } +
) } diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.constants.js b/ui/app/components/transaction-activity-log/transaction-activity-log.constants.js new file mode 100644 index 000000000000..72e63d85c649 --- /dev/null +++ b/ui/app/components/transaction-activity-log/transaction-activity-log.constants.js @@ -0,0 +1,13 @@ +export const TRANSACTION_CREATED_EVENT = 'transactionCreated' +export const TRANSACTION_SUBMITTED_EVENT = 'transactionSubmitted' +export const TRANSACTION_RESUBMITTED_EVENT = 'transactionResubmitted' +export const TRANSACTION_CONFIRMED_EVENT = 'transactionConfirmed' +export const TRANSACTION_DROPPED_EVENT = 'transactionDropped' +export const TRANSACTION_UPDATED_EVENT = 'transactionUpdated' +export const TRANSACTION_ERRORED_EVENT = 'transactionErrored' +export const TRANSACTION_CANCEL_ATTEMPTED_EVENT = 'transactionCancelAttempted' +export const TRANSACTION_CANCEL_SUCCESS_EVENT = 'transactionCancelSuccess' + +export const SUBMITTED_STATUS = 'submitted' +export const CONFIRMED_STATUS = 'confirmed' +export const DROPPED_STATUS = 'dropped' diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.container.js b/ui/app/components/transaction-activity-log/transaction-activity-log.container.js index 622f77df1312..e4322970805d 100644 --- a/ui/app/components/transaction-activity-log/transaction-activity-log.container.js +++ b/ui/app/components/transaction-activity-log/transaction-activity-log.container.js @@ -1,6 +1,14 @@ import { connect } from 'react-redux' +import R from 'ramda' import TransactionActivityLog from './transaction-activity-log.component' import { conversionRateSelector, getNativeCurrency } from '../../selectors' +import { combineTransactionHistories } from './transaction-activity-log.util' +import { + TRANSACTION_RESUBMITTED_EVENT, + TRANSACTION_CANCEL_ATTEMPTED_EVENT, +} from './transaction-activity-log.constants' + +const matchesEventKey = matchEventKey => ({ eventKey }) => eventKey === matchEventKey const mapStateToProps = state => { return { @@ -9,4 +17,28 @@ const mapStateToProps = state => { } } -export default connect(mapStateToProps)(TransactionActivityLog) +const mergeProps = (stateProps, dispatchProps, ownProps) => { + const { + transactionGroup: { + transactions = [], + primaryTransaction, + } = {}, + ...restOwnProps + } = ownProps + + const activities = combineTransactionHistories(transactions) + const inlineRetryIndex = R.findLastIndex(matchesEventKey(TRANSACTION_RESUBMITTED_EVENT))(activities) + const inlineCancelIndex = R.findLastIndex(matchesEventKey(TRANSACTION_CANCEL_ATTEMPTED_EVENT))(activities) + + return { + ...stateProps, + ...dispatchProps, + ...restOwnProps, + activities, + inlineRetryIndex, + inlineCancelIndex, + primaryTransaction, + } +} + +export default connect(mapStateToProps, null, mergeProps)(TransactionActivityLog) diff --git a/ui/app/components/transaction-activity-log/transaction-activity-log.util.js b/ui/app/components/transaction-activity-log/transaction-activity-log.util.js index 16597ae1ab1f..6206a4678741 100644 --- a/ui/app/components/transaction-activity-log/transaction-activity-log.util.js +++ b/ui/app/components/transaction-activity-log/transaction-activity-log.util.js @@ -1,28 +1,39 @@ +import { getHexGasTotal } from '../../helpers/confirm-transaction/util' + // path constants const STATUS_PATH = '/status' const GAS_PRICE_PATH = '/txParams/gasPrice' - -// status constants -const UNAPPROVED_STATUS = 'unapproved' -const SUBMITTED_STATUS = 'submitted' -const CONFIRMED_STATUS = 'confirmed' -const DROPPED_STATUS = 'dropped' +const GAS_LIMIT_PATH = '/txParams/gas' // op constants const REPLACE_OP = 'replace' -// event constants -const TRANSACTION_CREATED_EVENT = 'transactionCreated' -const TRANSACTION_UPDATED_GAS_EVENT = 'transactionUpdatedGas' -const TRANSACTION_SUBMITTED_EVENT = 'transactionSubmitted' -const TRANSACTION_CONFIRMED_EVENT = 'transactionConfirmed' -const TRANSACTION_DROPPED_EVENT = 'transactionDropped' -const TRANSACTION_UPDATED_EVENT = 'transactionUpdated' -const TRANSACTION_ERRORED_EVENT = 'transactionErrored' +import { + // event constants + TRANSACTION_CREATED_EVENT, + TRANSACTION_SUBMITTED_EVENT, + TRANSACTION_RESUBMITTED_EVENT, + TRANSACTION_CONFIRMED_EVENT, + TRANSACTION_DROPPED_EVENT, + TRANSACTION_UPDATED_EVENT, + TRANSACTION_ERRORED_EVENT, + TRANSACTION_CANCEL_ATTEMPTED_EVENT, + TRANSACTION_CANCEL_SUCCESS_EVENT, + // status constants + SUBMITTED_STATUS, + CONFIRMED_STATUS, + DROPPED_STATUS, +} from './transaction-activity-log.constants' + +import { + TRANSACTION_TYPE_CANCEL, + TRANSACTION_TYPE_RETRY, +} from '../../../../app/scripts/controllers/transactions/enums' const eventPathsHash = { [STATUS_PATH]: true, [GAS_PRICE_PATH]: true, + [GAS_LIMIT_PATH]: true, } const statusHash = { @@ -31,22 +42,39 @@ const statusHash = { [DROPPED_STATUS]: TRANSACTION_DROPPED_EVENT, } -function eventCreator (eventKey, timestamp, value) { - return { - eventKey, - timestamp, - value, - } -} - -export function getActivities (transaction) { - const { history = [], txReceipt: { status } = {} } = transaction - - const historyActivities = history.reduce((acc, base) => { +/** + * @name getActivities + * @param {Object} transaction - txMeta object + * @param {boolean} isFirstTransaction - True if the transaction is the first created transaction + * in the list of transactions with the same nonce. If so, we use this transaction to create the + * transactionCreated activity. + * @returns {Array} + */ +export function getActivities (transaction, isFirstTransaction = false) { + const { id, hash, history = [], txReceipt: { status } = {}, type } = transaction + + let cachedGasLimit = '0x0' + let cachedGasPrice = '0x0' + + const historyActivities = history.reduce((acc, base, index) => { // First history item should be transaction creation - if (!Array.isArray(base) && base.status === UNAPPROVED_STATUS && base.txParams) { - const { time, txParams: { value } = {} } = base - return acc.concat(eventCreator(TRANSACTION_CREATED_EVENT, time, value)) + if (index === 0 && !Array.isArray(base) && base.txParams) { + const { time: timestamp, txParams: { value, gas = '0x0', gasPrice = '0x0' } = {} } = base + // The cached gas limit and gas price are used to display the gas fee in the activity log. We + // need to cache these values because the status update history events don't provide us with + // the latest gas limit and gas price. + cachedGasLimit = gas + cachedGasPrice = gasPrice + + if (isFirstTransaction) { + return acc.concat({ + id, + hash, + eventKey: TRANSACTION_CREATED_EVENT, + timestamp, + value, + }) + } // An entry in the history may be an array of more sub-entries. } else if (Array.isArray(base)) { const events = [] @@ -60,20 +88,69 @@ export function getActivities (transaction) { if (path in eventPathsHash && op === REPLACE_OP) { switch (path) { case STATUS_PATH: { + const gasFee = getHexGasTotal({ gasLimit: cachedGasLimit, gasPrice: cachedGasPrice }) + if (value in statusHash) { - events.push(eventCreator(statusHash[value], timestamp)) + let eventKey = statusHash[value] + + // If the status is 'submitted', we need to determine whether the event is a + // transaction retry or a cancellation attempt. + if (value === SUBMITTED_STATUS) { + if (type === TRANSACTION_TYPE_RETRY) { + eventKey = TRANSACTION_RESUBMITTED_EVENT + } else if (type === TRANSACTION_TYPE_CANCEL) { + eventKey = TRANSACTION_CANCEL_ATTEMPTED_EVENT + } + } else if (value === CONFIRMED_STATUS) { + if (type === TRANSACTION_TYPE_CANCEL) { + eventKey = TRANSACTION_CANCEL_SUCCESS_EVENT + } + } + + events.push({ + id, + hash, + eventKey, + timestamp, + value: gasFee, + }) } break } - case GAS_PRICE_PATH: { - events.push(eventCreator(TRANSACTION_UPDATED_GAS_EVENT, timestamp, value)) + // If the gas price or gas limit has been changed, we update the gasFee of the + // previously submitted event. These events happen when the gas limit and gas price is + // changed at the confirm screen. + case GAS_PRICE_PATH: + case GAS_LIMIT_PATH: { + const lastEvent = events[events.length - 1] || {} + const { lastEventKey } = lastEvent + + if (path === GAS_LIMIT_PATH) { + cachedGasLimit = value + } else if (path === GAS_PRICE_PATH) { + cachedGasPrice = value + } + + if (lastEventKey === TRANSACTION_SUBMITTED_EVENT || + lastEventKey === TRANSACTION_RESUBMITTED_EVENT) { + lastEvent.value = getHexGasTotal({ + gasLimit: cachedGasLimit, + gasPrice: cachedGasPrice, + }) + } + break } default: { - events.push(eventCreator(TRANSACTION_UPDATED_EVENT, timestamp)) + events.push({ + id, + hash, + eventKey: TRANSACTION_UPDATED_EVENT, + timestamp, + }) } } } @@ -88,6 +165,60 @@ export function getActivities (transaction) { // If txReceipt.status is '0x0', that means that an on-chain error occured for the transaction, // so we add an error entry to the Activity Log. return status === '0x0' - ? historyActivities.concat(eventCreator(TRANSACTION_ERRORED_EVENT)) + ? historyActivities.concat({ id, hash, eventKey: TRANSACTION_ERRORED_EVENT }) : historyActivities } + +/** + * @description Removes "Transaction dropped" activities from a list of sorted activities if one of + * the transactions has been confirmed. Typically, if multiple transactions have the same nonce, + * once one transaction is confirmed, the rest are dropped. In this case, we don't want to show + * multiple "Transaction dropped" activities, and instead want to show a single "Transaction + * confirmed". + * @param {Array} activities - List of sorted activities generated from the getActivities function. + * @returns {Array} + */ +function filterSortedActivities (activities) { + const filteredActivities = [] + const hasConfirmedActivity = Boolean(activities.find(({ eventKey }) => ( + eventKey === TRANSACTION_CONFIRMED_EVENT || eventKey === TRANSACTION_CANCEL_SUCCESS_EVENT + ))) + let addedDroppedActivity = false + + activities.forEach(activity => { + if (activity.eventKey === TRANSACTION_DROPPED_EVENT) { + if (!hasConfirmedActivity && !addedDroppedActivity) { + filteredActivities.push(activity) + addedDroppedActivity = true + } + } else { + filteredActivities.push(activity) + } + }) + + return filteredActivities +} + +/** + * Combines the histories of an array of transactions into a single array. + * @param {Array} transactions - Array of txMeta transaction objects. + * @returns {Array} + */ +export function combineTransactionHistories (transactions = []) { + if (!transactions.length) { + return [] + } + + const activities = [] + + transactions.forEach((transaction, index) => { + // The first transaction should be the transaction with the earliest submittedTime. We show the + // 'created' and 'submitted' activities here. All subsequent transactions will use 'resubmitted' + // instead. + const transactionActivities = getActivities(transaction, index === 0) + activities.push(...transactionActivities) + }) + + const sortedActivities = activities.sort((a, b) => a.timestamp - b.timestamp) + return filterSortedActivities(sortedActivities) +} diff --git a/ui/app/components/transaction-breakdown/index.scss b/ui/app/components/transaction-breakdown/index.scss index 1bb108943845..b56cbdd7f722 100644 --- a/ui/app/components/transaction-breakdown/index.scss +++ b/ui/app/components/transaction-breakdown/index.scss @@ -1,9 +1,10 @@ @import './transaction-breakdown-row/index'; .transaction-breakdown { - &__card { - background: $white; - height: 100%; + &__title { + border-bottom: 1px solid #d8d8d8; + padding-bottom: 4px; + text-transform: capitalize; } &__row-title { diff --git a/ui/app/components/transaction-breakdown/tests/transaction-breakdown.component.test.js b/ui/app/components/transaction-breakdown/tests/transaction-breakdown.component.test.js index d18cd420c9b8..4512b84f0db5 100644 --- a/ui/app/components/transaction-breakdown/tests/transaction-breakdown.component.test.js +++ b/ui/app/components/transaction-breakdown/tests/transaction-breakdown.component.test.js @@ -2,8 +2,6 @@ import React from 'react' import assert from 'assert' import { shallow } from 'enzyme' import TransactionBreakdown from '../transaction-breakdown.component' -import TransactionBreakdownRow from '../transaction-breakdown-row' -import Card from '../../card' describe('TransactionBreakdown Component', () => { it('should render properly', () => { @@ -31,7 +29,5 @@ describe('TransactionBreakdown Component', () => { assert.ok(wrapper.hasClass('transaction-breakdown')) assert.ok(wrapper.hasClass('test-class')) - assert.equal(wrapper.find(Card).length, 1) - assert.equal(wrapper.find(Card).find(TransactionBreakdownRow).length, 4) }) }) diff --git a/ui/app/components/transaction-breakdown/transaction-breakdown.component.js b/ui/app/components/transaction-breakdown/transaction-breakdown.component.js index 3a76478737d3..141e16e17c80 100644 --- a/ui/app/components/transaction-breakdown/transaction-breakdown.component.js +++ b/ui/app/components/transaction-breakdown/transaction-breakdown.component.js @@ -2,7 +2,6 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import classnames from 'classnames' import TransactionBreakdownRow from './transaction-breakdown-row' -import Card from '../card' import CurrencyDisplay from '../currency-display' import UserPreferencedCurrencyDisplay from '../user-preferenced-currency-display' import HexToDecimal from '../hex-to-decimal' @@ -37,63 +36,61 @@ export default class TransactionBreakdown extends PureComponent { return (
- + { t('transaction') } +
+ + + + - + + + { + typeof gasUsed === 'string' && ( + + + + ) + } + + + + +
- - - - - { - typeof gasUsed === 'string' && ( - - - - ) - } - - - - -
- - -
-
- +
+
) } diff --git a/ui/app/components/transaction-list-item-details/index.scss b/ui/app/components/transaction-list-item-details/index.scss index 54cf834cc0ac..2e3a06f84855 100644 --- a/ui/app/components/transaction-list-item-details/index.scss +++ b/ui/app/components/transaction-list-item-details/index.scss @@ -1,11 +1,16 @@ .transaction-list-item-details { &__header { - margin-bottom: 8px; + margin: 8px 16px; display: flex; justify-content: space-between; align-items: center; } + &__body { + background: #fafbfc; + padding: 8px 16px; + } + &__header-buttons { display: flex; flex-direction: row; @@ -45,5 +50,9 @@ &__transaction-activity-log { flex: 2; min-width: 0; + + @media screen and (min-width: $break-large) { + padding-left: 12px; + } } } diff --git a/ui/app/components/transaction-list-item-details/tests/transaction-list-item-details.component.test.js b/ui/app/components/transaction-list-item-details/tests/transaction-list-item-details.component.test.js index f2bbe8789268..62fc64db9631 100644 --- a/ui/app/components/transaction-list-item-details/tests/transaction-list-item-details.component.test.js +++ b/ui/app/components/transaction-list-item-details/tests/transaction-list-item-details.component.test.js @@ -23,9 +23,15 @@ describe('TransactionListItemDetails Component', () => { }, } + const transactionGroup = { + transactions: [transaction], + primaryTransaction: transaction, + initialTransaction: transaction, + } + const wrapper = shallow( , { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } } ) @@ -52,9 +58,18 @@ describe('TransactionListItemDetails Component', () => { }, } + const transactionGroup = { + transactions: [transaction], + primaryTransaction: transaction, + initialTransaction: transaction, + nonce: '0xa4', + hasRetried: false, + hasCancelled: false, + } + const wrapper = shallow( , { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } } diff --git a/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js b/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js index a79213ace0b5..cc2c45290bcb 100644 --- a/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js +++ b/ui/app/components/transaction-list-item-details/transaction-list-item-details.component.js @@ -1,7 +1,7 @@ import React, { PureComponent } from 'react' import PropTypes from 'prop-types' import SenderToRecipient from '../sender-to-recipient' -import { CARDS_VARIANT } from '../sender-to-recipient/sender-to-recipient.constants' +import { FLAT_VARIANT } from '../sender-to-recipient/sender-to-recipient.constants' import TransactionActivityLog from '../transaction-activity-log' import TransactionBreakdown from '../transaction-breakdown' import Button from '../button' @@ -18,42 +18,43 @@ export default class TransactionListItemDetails extends PureComponent { onRetry: PropTypes.func, showCancel: PropTypes.bool, showRetry: PropTypes.bool, - transaction: PropTypes.object, + transactionGroup: PropTypes.object, } handleEtherscanClick = () => { - const { hash, metamaskNetworkId } = this.props.transaction + const { transactionGroup: { primaryTransaction } } = this.props + const { hash, metamaskNetworkId } = primaryTransaction const prefix = prefixForNetwork(metamaskNetworkId) const etherscanUrl = `https://${prefix}etherscan.io/tx/${hash}` global.platform.openWindow({ url: etherscanUrl }) - this.setState({ showTransactionDetails: true }) } handleCancel = event => { - const { onCancel } = this.props + const { transactionGroup: { initialTransaction: { id } = {} } = {}, onCancel } = this.props event.stopPropagation() - onCancel() + onCancel(id) } handleRetry = event => { - const { onRetry } = this.props + const { transactionGroup: { initialTransaction: { id } = {} } = {}, onRetry } = this.props event.stopPropagation() - onRetry() + onRetry(id) } render () { const { t } = this.context - const { transaction, showCancel, showRetry } = this.props + const { transactionGroup, showCancel, showRetry, onCancel, onRetry } = this.props + const { primaryTransaction: transaction } = transactionGroup const { txParams: { to, from } = {} } = transaction return (
-
Details
+
{ t('details') }
{ showRetry && ( @@ -88,23 +89,27 @@ export default class TransactionListItemDetails extends PureComponent {
-
- -
-
- - +
+
+ +
+
+ + +
) diff --git a/ui/app/components/transaction-list-item/index.scss b/ui/app/components/transaction-list-item/index.scss index 44997473455e..9e73a546c295 100644 --- a/ui/app/components/transaction-list-item/index.scss +++ b/ui/app/components/transaction-list-item/index.scss @@ -117,12 +117,6 @@ } } - &__details-container { - padding: 8px 16px 16px; - background: #f3f4f7; - width: 100%; - } - &__expander { max-height: 0px; width: 100%; diff --git a/ui/app/components/transaction-list-item/transaction-list-item.component.js b/ui/app/components/transaction-list-item/transaction-list-item.component.js index 5334484dbbbd..ecd8b4cefa88 100644 --- a/ui/app/components/transaction-list-item/transaction-list-item.component.js +++ b/ui/app/components/transaction-list-item/transaction-list-item.component.js @@ -18,6 +18,7 @@ export default class TransactionListItem extends PureComponent { history: PropTypes.object, methodData: PropTypes.object, nonceAndDate: PropTypes.string, + primaryTransaction: PropTypes.object, retryTransaction: PropTypes.func, setSelectedToken: PropTypes.func, showCancelModal: PropTypes.func, @@ -26,6 +27,7 @@ export default class TransactionListItem extends PureComponent { token: PropTypes.object, tokenData: PropTypes.object, transaction: PropTypes.object, + transactionGroup: PropTypes.object, value: PropTypes.string, fetchBasicGasAndTimeEstimates: PropTypes.func, fetchGasEstimates: PropTypes.func, @@ -51,36 +53,48 @@ export default class TransactionListItem extends PureComponent { this.setState({ showTransactionDetails: !showTransactionDetails }) } - handleCancel = () => { - const { transaction: { id, txParams: { gasPrice } } = {}, showCancelModal } = this.props - showCancelModal(id, gasPrice) + handleCancel = id => { + const { + primaryTransaction: { txParams: { gasPrice } } = {}, + transaction: { id: initialTransactionId }, + showCancelModal, + } = this.props + + const cancelId = id || initialTransactionId + showCancelModal(cancelId, gasPrice) } - handleRetry = () => { + /** + * @name handleRetry + * @description Resubmits a transaction. Retrying a transaction within a list of transactions with + * the same nonce requires keeping the original value while increasing the gas price of the latest + * transaction. + * @param {number} id - Transaction id + */ + handleRetry = id => { const { - transaction: { txParams: { to } = {} }, + primaryTransaction: { txParams: { gasPrice } } = {}, + transaction: { txParams: { to } = {}, id: initialTransactionId }, methodData: { name } = {}, setSelectedToken, + retryTransaction, + fetchBasicGasAndTimeEstimates, + fetchGasEstimates, } = this.props if (name === TOKEN_METHOD_TRANSFER) { setSelectedToken(to) } - return this.resubmit() - } + const retryId = id || initialTransactionId - resubmit () { - const { transaction, retryTransaction, fetchBasicGasAndTimeEstimates, fetchGasEstimates } = this.props - fetchBasicGasAndTimeEstimates().then(basicEstimates => { - fetchGasEstimates(basicEstimates.blockTime) - }).then(() => { - retryTransaction(transaction) - }) + return fetchBasicGasAndTimeEstimates() + .then(basicEstimates => fetchGasEstimates(basicEstimates.blockTime)) + .then(retryTransaction(retryId, gasPrice)) } renderPrimaryCurrency () { - const { token, transaction: { txParams: { data } = {} } = {}, value } = this.props + const { token, primaryTransaction: { txParams: { data } = {} } = {}, value } = this.props return token ? ( @@ -118,12 +132,14 @@ export default class TransactionListItem extends PureComponent { render () { const { assetImages, + transaction, methodData, nonceAndDate, + primaryTransaction, showCancel, showRetry, tokenData, - transaction, + transactionGroup, } = this.props const { txParams = {} } = transaction const { showTransactionDetails } = this.state @@ -156,11 +172,11 @@ export default class TransactionListItem extends PureComponent {
{ this.renderPrimaryCurrency() } @@ -173,7 +189,7 @@ export default class TransactionListItem extends PureComponent { showTransactionDetails && (
{ - const { transaction: { txParams: { value, nonce, data } = {}, time } = {} } = ownProps - - const tokenData = data && getTokenData(data) - const nonceAndDate = nonce ? `#${hexToDecimal(nonce)} - ${formatDate(time)}` : formatDate(time) - - return { - value, - nonceAndDate, - tokenData, - } -} - const mapDispatchToProps = dispatch => { return { fetchBasicGasAndTimeEstimates: () => dispatch(fetchBasicGasAndTimeEstimates()), fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), setSelectedToken: tokenAddress => dispatch(setSelectedToken(tokenAddress)), - retryTransaction: (transaction) => { - dispatch(setCustomGasPrice(transaction.txParams.gasPrice)) + retryTransaction: (transaction, gasPrice) => { + dispatch(setCustomGasPrice(gasPrice || transaction.txParams.gasPrice)) dispatch(setCustomGasLimit(transaction.txParams.gas)) dispatch(showSidebar({ transitionName: 'sidebar-left', @@ -47,8 +35,35 @@ const mapDispatchToProps = dispatch => { } } +const mergeProps = (stateProps, dispatchProps, ownProps) => { + const { transactionGroup: { primaryTransaction, initialTransaction } = {} } = ownProps + const { retryTransaction, ...restDispatchProps } = dispatchProps + const { txParams: { nonce, data } = {}, time } = initialTransaction + const { txParams: { value } = {} } = primaryTransaction + + const tokenData = data && getTokenData(data) + const nonceAndDate = nonce ? `#${hexToDecimal(nonce)} - ${formatDate(time)}` : formatDate(time) + + return { + ...stateProps, + ...restDispatchProps, + ...ownProps, + value, + nonceAndDate, + tokenData, + transaction: initialTransaction, + primaryTransaction, + retryTransaction: (transactionId, gasPrice) => { + const { transactionGroup: { transactions = [] } } = ownProps + const transaction = transactions.find(tx => tx.id === transactionId) || {} + const increasedGasPrice = increaseLastGasPrice(gasPrice) + retryTransaction(transaction, increasedGasPrice) + }, + } +} + export default compose( withRouter, - connect(mapStateToProps, mapDispatchToProps), + connect(null, mapDispatchToProps, mergeProps), withMethodData, )(TransactionListItem) diff --git a/ui/app/components/transaction-list/transaction-list.component.js b/ui/app/components/transaction-list/transaction-list.component.js index eef60186d64e..c1e3b3d1c1c2 100644 --- a/ui/app/components/transaction-list/transaction-list.component.js +++ b/ui/app/components/transaction-list/transaction-list.component.js @@ -12,13 +12,11 @@ export default class TransactionList extends PureComponent { static defaultProps = { pendingTransactions: [], completedTransactions: [], - transactionToRetry: {}, } static propTypes = { pendingTransactions: PropTypes.array, completedTransactions: PropTypes.array, - transactionToRetry: PropTypes.object, selectedToken: PropTypes.object, updateNetworkNonce: PropTypes.func, assetImages: PropTypes.object, @@ -37,26 +35,34 @@ export default class TransactionList extends PureComponent { } } - shouldShowRetry = transaction => { - const { transactionToRetry } = this.props - const { id, submittedTime } = transaction - return id === transactionToRetry.id && Date.now() - submittedTime > 30000 + shouldShowRetry = (transactionGroup, isEarliestNonce) => { + const { transactions = [], hasRetried } = transactionGroup + const [earliestTransaction = {}] = transactions + const { submittedTime } = earliestTransaction + return Date.now() - submittedTime > 30000 && isEarliestNonce && !hasRetried + } + + shouldShowCancel (transactionGroup) { + const { hasCancelled } = transactionGroup + return !hasCancelled } renderTransactions () { const { t } = this.context const { pendingTransactions = [], completedTransactions = [] } = this.props + const pendingLength = pendingTransactions.length + return (
{ - pendingTransactions.length > 0 && ( + pendingLength > 0 && (
{ `${t('queue')} (${pendingTransactions.length})` }
{ - pendingTransactions.map((transaction, index) => ( - this.renderTransaction(transaction, index, true) + pendingTransactions.map((transactionGroup, index) => ( + this.renderTransaction(transactionGroup, index, true, index === pendingLength - 1) )) }
@@ -68,8 +74,8 @@ export default class TransactionList extends PureComponent {
{ completedTransactions.length > 0 - ? completedTransactions.map((transaction, index) => ( - this.renderTransaction(transaction, index) + ? completedTransactions.map((transactionGroup, index) => ( + this.renderTransaction(transactionGroup, index) )) : this.renderEmpty() } @@ -78,21 +84,22 @@ export default class TransactionList extends PureComponent { ) } - renderTransaction (transaction, index, showCancel) { + renderTransaction (transactionGroup, index, isPendingTx = false, isEarliestNonce = false) { const { selectedToken, assetImages } = this.props + const { transactions = [] } = transactionGroup - return transaction.key === TRANSACTION_TYPE_SHAPESHIFT + return transactions[0].key === TRANSACTION_TYPE_SHAPESHIFT ? ( ) : ( diff --git a/ui/app/components/transaction-list/transaction-list.container.js b/ui/app/components/transaction-list/transaction-list.container.js index 2e946c67d070..e70ca15c5eba 100644 --- a/ui/app/components/transaction-list/transaction-list.container.js +++ b/ui/app/components/transaction-list/transaction-list.container.js @@ -3,24 +3,17 @@ import { withRouter } from 'react-router-dom' import { compose } from 'recompose' import TransactionList from './transaction-list.component' import { - pendingTransactionsSelector, - submittedPendingTransactionsSelector, - completedTransactionsSelector, + nonceSortedCompletedTransactionsSelector, + nonceSortedPendingTransactionsSelector, } from '../../selectors/transactions' import { getSelectedAddress, getAssetImages } from '../../selectors' import { selectedTokenSelector } from '../../selectors/tokens' -import { getLatestSubmittedTxWithNonce } from '../../helpers/transactions.util' import { updateNetworkNonce } from '../../actions' const mapStateToProps = state => { - const pendingTransactions = pendingTransactionsSelector(state) - const submittedPendingTransactions = submittedPendingTransactionsSelector(state) - const networkNonce = state.appState.networkNonce - return { - completedTransactions: completedTransactionsSelector(state), - pendingTransactions, - transactionToRetry: getLatestSubmittedTxWithNonce(submittedPendingTransactions, networkNonce), + completedTransactions: nonceSortedCompletedTransactionsSelector(state), + pendingTransactions: nonceSortedPendingTransactionsSelector(state), selectedToken: selectedTokenSelector(state), selectedAddress: getSelectedAddress(state), assetImages: getAssetImages(state), diff --git a/ui/app/components/transaction-status/index.scss b/ui/app/components/transaction-status/index.scss index 26a1f5d38a40..e7daafeef079 100644 --- a/ui/app/components/transaction-status/index.scss +++ b/ui/app/components/transaction-status/index.scss @@ -1,6 +1,6 @@ .transaction-status { height: 26px; - width: 81px; + width: 84px; border-radius: 4px; background-color: #f0f0f0; color: #5e6064; @@ -12,22 +12,34 @@ @media screen and (max-width: $break-small) { height: 16px; - width: 70px; + width: 72px; font-size: .5rem; } &--confirmed { background-color: #eafad7; color: #609a1c; + + .transaction-status__transaction-count { + border: 1px solid #609a1c; + } } &--approved, &--submitted { background-color: #FFF2DB; color: #CA810A; + + .transaction-status__transaction-count { + border: 1px solid #CA810A; + } } &--failed { background: lighten($monzo, 56%); color: $monzo; + + .transaction-status__transaction-count { + border: 1px solid $monzo; + } } } diff --git a/ui/app/components/transaction-status/tests/transaction-status.component.test.js b/ui/app/components/transaction-status/tests/transaction-status.component.test.js index 9e3bffe4f982..f4ddc92061b4 100644 --- a/ui/app/components/transaction-status/tests/transaction-status.component.test.js +++ b/ui/app/components/transaction-status/tests/transaction-status.component.test.js @@ -15,9 +15,8 @@ describe('TransactionStatus Component', () => { ) assert.ok(wrapper) - const tooltipProps = wrapper.find(Tooltip).props() - assert.equal(tooltipProps.children, 'APPROVED') - assert.equal(tooltipProps.title, 'test-title') + assert.equal(wrapper.text(), 'APPROVED') + assert.equal(wrapper.find(Tooltip).props().title, 'test-title') }) it('should render SUBMITTED properly', () => { @@ -29,7 +28,6 @@ describe('TransactionStatus Component', () => { ) assert.ok(wrapper) - const tooltipProps = wrapper.find(Tooltip).props() - assert.equal(tooltipProps.children, 'PENDING') + assert.equal(wrapper.text(), 'PENDING') }) }) diff --git a/ui/app/components/transaction-status/transaction-status.component.js b/ui/app/components/transaction-status/transaction-status.component.js index 0d47d7868edd..28544d2cdaf0 100644 --- a/ui/app/components/transaction-status/transaction-status.component.js +++ b/ui/app/components/transaction-status/transaction-status.component.js @@ -11,6 +11,7 @@ import { CONFIRMED_STATUS, FAILED_STATUS, DROPPED_STATUS, + CANCELLED_STATUS, } from '../../constants/transactions' const statusToClassNameHash = { @@ -22,6 +23,7 @@ const statusToClassNameHash = { [CONFIRMED_STATUS]: 'transaction-status--confirmed', [FAILED_STATUS]: 'transaction-status--failed', [DROPPED_STATUS]: 'transaction-status--dropped', + [CANCELLED_STATUS]: 'transaction-status--failed', } const statusToTextHash = { @@ -49,7 +51,10 @@ export default class TransactionStatus extends PureComponent { return (
- + { statusText }
diff --git a/ui/app/constants/transactions.js b/ui/app/constants/transactions.js index 2dc061091ee1..d0a819b9b238 100644 --- a/ui/app/constants/transactions.js +++ b/ui/app/constants/transactions.js @@ -6,6 +6,7 @@ export const SUBMITTED_STATUS = 'submitted' export const CONFIRMED_STATUS = 'confirmed' export const FAILED_STATUS = 'failed' export const DROPPED_STATUS = 'dropped' +export const CANCELLED_STATUS = 'cancelled' export const TOKEN_METHOD_TRANSFER = 'transfer' export const TOKEN_METHOD_APPROVE = 'approve' @@ -17,7 +18,7 @@ export const APPROVE_ACTION_KEY = 'approve' export const SEND_TOKEN_ACTION_KEY = 'sentTokens' export const TRANSFER_FROM_ACTION_KEY = 'transferFrom' export const SIGNATURE_REQUEST_KEY = 'signatureRequest' -export const UNKNOWN_FUNCTION_KEY = 'unknownFunction' +export const CONTRACT_INTERACTION_KEY = 'contractInteraction' export const CANCEL_ATTEMPT_ACTION_KEY = 'cancelAttempt' export const TRANSACTION_TYPE_SHAPESHIFT = 'shapeshift' diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js index 8db24cc837f5..83c236d81b2d 100644 --- a/ui/app/ducks/gas.duck.js +++ b/ui/app/ducks/gas.duck.js @@ -4,6 +4,9 @@ import { loadLocalStorageData, saveLocalStorageData, } from '../../lib/local-storage-helpers' +import { + decGWEIToHexWEI, +} from '../helpers/conversions.util' // Actions const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' @@ -403,6 +406,17 @@ export function fetchGasEstimates (blockTime) { } } +export function setCustomGasPriceForRetry (newPrice) { + return (dispatch) => { + if (newPrice !== '0x0') { + dispatch(setCustomGasPrice(newPrice)) + } else { + const { fast } = loadLocalStorageData('BASIC_PRICE_ESTIMATES') + dispatch(setCustomGasPrice(decGWEIToHexWEI(fast))) + } + } +} + export function setBasicGasEstimateData (basicGasEstimateData) { return { type: SET_BASIC_GAS_ESTIMATE_DATA, diff --git a/ui/app/helpers/transactions.util.js b/ui/app/helpers/transactions.util.js index 2f4b1d0953bb..0f1ed70a31d9 100644 --- a/ui/app/helpers/transactions.util.js +++ b/ui/app/helpers/transactions.util.js @@ -2,6 +2,10 @@ import ethUtil from 'ethereumjs-util' import MethodRegistry from 'eth-method-registry' import abi from 'human-standard-token-abi' import abiDecoder from 'abi-decoder' +import { + TRANSACTION_TYPE_CANCEL, + TRANSACTION_STATUS_CONFIRMED, +} from '../../../app/scripts/controllers/transactions/enums' import { TOKEN_METHOD_TRANSFER, @@ -13,7 +17,7 @@ import { SEND_TOKEN_ACTION_KEY, TRANSFER_FROM_ACTION_KEY, SIGNATURE_REQUEST_KEY, - UNKNOWN_FUNCTION_KEY, + CONTRACT_INTERACTION_KEY, CANCEL_ATTEMPT_ACTION_KEY, } from '../constants/transactions' @@ -87,7 +91,7 @@ export async function getTransactionActionKey (transaction, methodData) { const methodName = name && name.toLowerCase() if (!methodName) { - return UNKNOWN_FUNCTION_KEY + return CONTRACT_INTERACTION_KEY } switch (methodName) { @@ -148,12 +152,16 @@ export function sumHexes (...args) { * @returns {string} */ export function getStatusKey (transaction) { - const { txReceipt: { status } = {} } = transaction + const { txReceipt: { status: receiptStatus } = {}, type, status } = transaction // There was an on-chain failure - if (status === '0x0') { + if (receiptStatus === '0x0') { return 'failed' } + if (status === TRANSACTION_STATUS_CONFIRMED && type === TRANSACTION_TYPE_CANCEL) { + return 'cancelled' + } + return transaction.status } diff --git a/ui/app/selectors/transactions.js b/ui/app/selectors/transactions.js index 479002794ef7..301e8d11fc2c 100644 --- a/ui/app/selectors/transactions.js +++ b/ui/app/selectors/transactions.js @@ -1,16 +1,44 @@ import { createSelector } from 'reselect' -import { valuesFor } from '../util' import { UNAPPROVED_STATUS, APPROVED_STATUS, SUBMITTED_STATUS, + CONFIRMED_STATUS, } from '../constants/transactions' +import { + TRANSACTION_TYPE_CANCEL, + TRANSACTION_TYPE_RETRY, +} from '../../../app/scripts/controllers/transactions/enums' +import { hexToDecimal } from '../helpers/conversions.util' import { selectedTokenAddressSelector } from './tokens' +import txHelper from '../../lib/tx-helper' export const shapeShiftTxListSelector = state => state.metamask.shapeShiftTxList export const unapprovedMsgsSelector = state => state.metamask.unapprovedMsgs export const selectedAddressTxListSelector = state => state.metamask.selectedAddressTxList +export const unapprovedPersonalMsgsSelector = state => state.metamask.unapprovedPersonalMsgs +export const unapprovedTypedMessagesSelector = state => state.metamask.unapprovedTypedMessages +export const networkSelector = state => state.metamask.network + +export const unapprovedMessagesSelector = createSelector( + unapprovedMsgsSelector, + unapprovedPersonalMsgsSelector, + unapprovedTypedMessagesSelector, + networkSelector, + ( + unapprovedMsgs = {}, + unapprovedPersonalMsgs = {}, + unapprovedTypedMessages = {}, + network + ) => txHelper( + {}, + unapprovedMsgs, + unapprovedPersonalMsgs, + unapprovedTypedMessages, + network + ) || [] +) const pendingStatusHash = { [UNAPPROVED_STATUS]: true, @@ -18,14 +46,18 @@ const pendingStatusHash = { [SUBMITTED_STATUS]: true, } +const priorityStatusHash = { + ...pendingStatusHash, + [CONFIRMED_STATUS]: true, +} + export const transactionsSelector = createSelector( selectedTokenAddressSelector, - unapprovedMsgsSelector, + unapprovedMessagesSelector, shapeShiftTxListSelector, selectedAddressTxListSelector, - (selectedTokenAddress, unapprovedMsgs = {}, shapeShiftTxList = [], transactions = []) => { - const unapprovedMsgsList = valuesFor(unapprovedMsgs) - const txsToRender = transactions.concat(unapprovedMsgsList, shapeShiftTxList) + (selectedTokenAddress, unapprovedMessages = [], shapeShiftTxList = [], transactions = []) => { + const txsToRender = transactions.concat(unapprovedMessages, shapeShiftTxList) return selectedTokenAddress ? txsToRender @@ -36,23 +68,199 @@ export const transactionsSelector = createSelector( } ) -export const pendingTransactionsSelector = createSelector( +/** + * @name insertOrderedNonce + * @private + * @description Inserts (mutates) a nonce into an array of ordered nonces, sorted in ascending + * order. + * @param {string[]} nonces - Array of nonce strings in hex + * @param {string} nonceToInsert - Nonce string in hex to be inserted into the array of nonces. + * @returns {string[]} + */ +const insertOrderedNonce = (nonces, nonceToInsert) => { + let insertIndex = nonces.length + + for (let i = 0; i < nonces.length; i++) { + const nonce = nonces[i] + + if (Number(hexToDecimal(nonce)) < Number(hexToDecimal(nonceToInsert))) { + insertIndex = i + break + } + } + + nonces.splice(insertIndex, 0, nonceToInsert) +} + +/** + * @name insertTransactionByTime + * @private + * @description Inserts (mutates) a transaction object into an array of ordered transactions, sorted + * in ascending order by time. + * @param {Object[]} transactions - Array of transaction objects. + * @param {Object} transaction - Transaction object to be inserted into the array of transactions. + * @returns {Object[]} + */ +const insertTransactionByTime = (transactions, transaction) => { + const { time } = transaction + + let insertIndex = transactions.length + + for (let i = 0; i < transactions.length; i++) { + const tx = transactions[i] + + if (tx.time > time) { + insertIndex = i + break + } + } + + transactions.splice(insertIndex, 0, transaction) +} + +/** + * Contains transactions and properties associated with those transactions of the same nonce. + * @typedef {Object} transactionGroup + * @property {string} nonce - The nonce that the transactions within this transactionGroup share. + * @property {Object[]} transactions - An array of transaction (txMeta) objects. + * @property {Object} initialTransaction - The transaction (txMeta) with the lowest "time". + * @property {Object} primaryTransaction - Either the latest transaction or the confirmed + * transaction. + * @property {boolean} hasRetried - True if a transaction in the group was a retry transaction. + * @property {boolean} hasCancelled - True if a transaction in the group was a cancel transaction. + */ + +/** + * @name insertTransactionGroupByTime + * @private + * @description Inserts (mutates) a transactionGroup object into an array of ordered + * transactionGroups, sorted in ascending order by nonce. + * @param {transactionGroup[]} transactionGroups - Array of transactionGroup objects. + * @param {transactionGroup} transactionGroup - transactionGroup object to be inserted into the + * array of transactionGroups. + * @returns {transactionGroup[]} + */ +const insertTransactionGroupByTime = (transactionGroups, transactionGroup) => { + const { primaryTransaction: { time } = {} } = transactionGroup + + let insertIndex = transactionGroups.length + + for (let i = 0; i < transactionGroups.length; i++) { + const txGroup = transactionGroups[i] + + if (txGroup.time > time) { + insertIndex = i + break + } + } + + transactionGroups.splice(insertIndex, 0, transactionGroup) +} + +/** + * @name nonceSortedTransactionsSelector + * @description Returns an array of transactionGroups sorted by nonce in ascending order. + * @returns {transactionGroup[]} + */ +export const nonceSortedTransactionsSelector = createSelector( transactionsSelector, + (transactions = []) => { + const unapprovedTransactionGroups = [] + const orderedNonces = [] + const nonceToTransactionsMap = {} + + transactions.forEach(transaction => { + const { txParams: { nonce } = {}, status, type, time: txTime } = transaction + + if (typeof nonce === 'undefined') { + const transactionGroup = { + transactions: [transaction], + initialTransaction: transaction, + primaryTransaction: transaction, + hasRetried: false, + hasCancelled: false, + } + + insertTransactionGroupByTime(unapprovedTransactionGroups, transactionGroup) + } else if (nonce in nonceToTransactionsMap) { + const nonceProps = nonceToTransactionsMap[nonce] + insertTransactionByTime(nonceProps.transactions, transaction) + + if (status in priorityStatusHash) { + const { primaryTransaction: { time: primaryTxTime = 0 } = {} } = nonceProps + + if (status === CONFIRMED_STATUS || txTime > primaryTxTime) { + nonceProps.primaryTransaction = transaction + } + } + + const { initialTransaction: { time: initialTxTime = 0 } = {} } = nonceProps + + // Used to display the transaction action, since we don't want to overwrite the action if + // it was replaced with a cancel attempt transaction. + if (txTime < initialTxTime) { + nonceProps.initialTransaction = transaction + } + + if (type === TRANSACTION_TYPE_RETRY) { + nonceProps.hasRetried = true + } + + if (type === TRANSACTION_TYPE_CANCEL) { + nonceProps.hasCancelled = true + } + } else { + nonceToTransactionsMap[nonce] = { + nonce, + transactions: [transaction], + initialTransaction: transaction, + primaryTransaction: transaction, + hasRetried: transaction.type === TRANSACTION_TYPE_RETRY, + hasCancelled: transaction.type === TRANSACTION_TYPE_CANCEL, + } + + insertOrderedNonce(orderedNonces, nonce) + } + }) + + const orderedTransactionGroups = orderedNonces.map(nonce => nonceToTransactionsMap[nonce]) + return unapprovedTransactionGroups.concat(orderedTransactionGroups) + } +) + +/** + * @name nonceSortedPendingTransactionsSelector + * @description Returns an array of transactionGroups where transactions are still pending sorted by + * nonce in descending order. + * @returns {transactionGroup[]} + */ +export const nonceSortedPendingTransactionsSelector = createSelector( + nonceSortedTransactionsSelector, (transactions = []) => ( - transactions.filter(transaction => transaction.status in pendingStatusHash).reverse() + transactions + .filter(({ primaryTransaction }) => primaryTransaction.status in pendingStatusHash) + .reverse() ) ) -export const submittedPendingTransactionsSelector = createSelector( - transactionsSelector, +/** + * @name nonceSortedCompletedTransactionsSelector + * @description Returns an array of transactionGroups where transactions are confirmed sorted by + * nonce in descending order. + * @returns {transactionGroup[]} + */ +export const nonceSortedCompletedTransactionsSelector = createSelector( + nonceSortedTransactionsSelector, (transactions = []) => ( - transactions.filter(transaction => transaction.status === SUBMITTED_STATUS) + transactions.filter(({ primaryTransaction }) => { + return !(primaryTransaction.status in pendingStatusHash) + }) ) ) -export const completedTransactionsSelector = createSelector( +export const submittedPendingTransactionsSelector = createSelector( transactionsSelector, (transactions = []) => ( - transactions.filter(transaction => !(transaction.status in pendingStatusHash)) + transactions.filter(transaction => transaction.status === SUBMITTED_STATUS) ) ) diff --git a/ui/app/util.js b/ui/app/util.js index b19a028cc998..28f027e26307 100644 --- a/ui/app/util.js +++ b/ui/app/util.js @@ -8,8 +8,8 @@ const GWEI_FACTOR = new ethUtil.BN(1e9) const MIN_GAS_PRICE_BN = MIN_GAS_PRICE_GWEI_BN.mul(GWEI_FACTOR) // formatData :: ( date: ) -> String -function formatDate (date) { - return vreme.format(new Date(date), '3/16/2014 at 14:30') +function formatDate (date, format = '3/16/2014 at 14:30') { + return vreme.format(new Date(date), format) } var valueTable = { diff --git a/ui/lib/tx-helper.js b/ui/lib/tx-helper.js index 0a6f55a63b93..260dbaa39f24 100644 --- a/ui/lib/tx-helper.js +++ b/ui/lib/tx-helper.js @@ -21,7 +21,7 @@ module.exports = function (unapprovedTxs, unapprovedMsgs, personalMsgs, typedMes allValues = allValues.concat(typedValues) allValues = allValues.sort((a, b) => { - return a.time > b.time + return a.time - b.time }) return allValues From 49971e9ec250888746546f62fa176ed129bf9c74 Mon Sep 17 00:00:00 2001 From: Noah Zinsmeister Date: Mon, 10 Dec 2018 08:17:52 -0500 Subject: [PATCH 59/64] fix formatting of 32-byte strings in personal_sign (#5878) --- CHANGELOG.md | 1 + ui/app/components/signature-request.js | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f8c1937af6f1..fd1348178d39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,7 @@ ## 5.0.4 Thu Nov 29 2018 +- [#5878](https://github.com/MetaMask/metamask-extension/pull/5878): Formats 32-length byte strings passed to personal_sign as hex, rather than UTF8. - [#5840](https://github.com/MetaMask/metamask-extension/pull/5840): transactions/tx-gas-utils - add the acctual response for eth_getCode for NO_CONTRACT_ERROR's && add a debug object to simulationFailed - [#5848](https://github.com/MetaMask/metamask-extension/pull/5848): Soften accusatory language on phishing warning - [#5835](https://github.com/MetaMask/metamask-extension/pull/5835): Open full-screen UI on install diff --git a/ui/app/components/signature-request.js b/ui/app/components/signature-request.js index 85af3b00bdec..715fea13f5d5 100644 --- a/ui/app/components/signature-request.js +++ b/ui/app/components/signature-request.js @@ -164,7 +164,7 @@ SignatureRequest.prototype.msgHexToText = function (hex) { try { const stripped = ethUtil.stripHexPrefix(hex) const buff = Buffer.from(stripped, 'hex') - return buff.toString('utf8') + return buff.length === 32 ? hex : buff.toString('utf8') } catch (e) { return hex } From 0d8fa9290c7146bd068b18af8fb9a476b60975ab Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 10 Dec 2018 10:47:36 -0800 Subject: [PATCH 60/64] Bump json-rpc-engine to v4.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d19fb862dc7d..c3ecb6e571cc 100644 --- a/package.json +++ b/package.json @@ -150,7 +150,7 @@ "iframe-stream": "^3.0.0", "inject-css": "^0.1.1", "jazzicon": "^1.2.0", - "json-rpc-engine": "^3.8.0", + "json-rpc-engine": "^4.0.0", "json-rpc-middleware-stream": "^2.1.0", "jsonschema": "^1.2.4", "lodash.debounce": "^4.0.8", From 14bd5997902fd3129ae00a8da7d43dd3b075e9ff Mon Sep 17 00:00:00 2001 From: Dan Finlay Date: Mon, 10 Dec 2018 10:47:47 -0800 Subject: [PATCH 61/64] Bump package lock, mostly to https links --- package-lock.json | 1512 +++++++++++++++++++++++++++++++-------------- 1 file changed, 1047 insertions(+), 465 deletions(-) diff --git a/package-lock.json b/package-lock.json index e145c424db34..5502ff85cde6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -795,7 +795,7 @@ }, "autoprefixer": { "version": "7.2.6", - "resolved": "http://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-7.2.6.tgz", "integrity": "sha512-Iq8TRIB+/9eQ8rbGhcP7ct5cYb/3qjNYAR2SnzLCEcwF6rvVOax8+9+fccgXk4bEhQGjOZd5TLhsksmAdsbGqQ==", "dev": true, "requires": { @@ -1137,7 +1137,7 @@ }, "style-loader": { "version": "0.20.3", - "resolved": "http://registry.npmjs.org/style-loader/-/style-loader-0.20.3.tgz", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.20.3.tgz", "integrity": "sha512-2I7AVP73MvK33U7B9TKlYZAqdROyMXDYSMvHLX43qy3GCOaJNiV6i0v/sv9idWIaQ42Yn2dNv79Q5mKXbKhAZg==", "dev": true, "requires": { @@ -1282,7 +1282,7 @@ }, "@storybook/podda": { "version": "1.2.3", - "resolved": "http://registry.npmjs.org/@storybook/podda/-/podda-1.2.3.tgz", + "resolved": "https://registry.npmjs.org/@storybook/podda/-/podda-1.2.3.tgz", "integrity": "sha512-g7dsdsn50AhlGZ8iIDKdF8bi7Am++iFOq+QN+hNKz3FvgLuf8Dz+mpC/BFl90eE9bEYxXqXKeMf87399Ec5Qhw==", "dev": true, "requires": { @@ -1646,7 +1646,7 @@ "dependencies": { "hoist-non-react-statics": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=", "dev": true } @@ -1666,7 +1666,7 @@ "dependencies": { "hoist-non-react-statics": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-1.2.0.tgz", "integrity": "sha1-qkSM8JhtVcxAdzsXF0t90GbLfPs=", "dev": true } @@ -1892,7 +1892,7 @@ }, "acorn-jsx": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz", "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=", "dev": true, "requires": { @@ -1901,7 +1901,7 @@ "dependencies": { "acorn": { "version": "3.3.0", - "resolved": "http://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz", "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo=", "dev": true } @@ -2657,7 +2657,7 @@ }, "adjust-sourcemap-loader": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-1.2.0.tgz", "integrity": "sha512-958oaHHVEXMvsY7v7cC5gEkNIcoaAVIhZ4mBReYVZJOTP9IgKmzLjIOhTtzpLMu+qriXvLsVjJ155EeInp45IQ==", "dev": true, "requires": { @@ -2985,7 +2985,7 @@ }, "array-equal": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=", "dev": true }, @@ -3613,7 +3613,7 @@ }, "babel-helper-is-nodes-equiv": { "version": "0.0.1", - "resolved": "http://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", + "resolved": "https://registry.npmjs.org/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz", "integrity": "sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ=", "dev": true }, @@ -3862,7 +3862,7 @@ }, "babel-plugin-react-docgen": { "version": "1.9.0", - "resolved": "http://registry.npmjs.org/babel-plugin-react-docgen/-/babel-plugin-react-docgen-1.9.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-react-docgen/-/babel-plugin-react-docgen-1.9.0.tgz", "integrity": "sha512-8lQ73p4BL+xcgba03NTiHrddl2X8J6PDMQHPpz73sesrRBf6JtAscQPLIjFWQR/abLokdv81HdshpjYGppOXgA==", "dev": true, "requires": { @@ -3873,77 +3873,77 @@ }, "babel-plugin-syntax-async-functions": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" }, "babel-plugin-syntax-async-generators": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz", "integrity": "sha1-a8lj67FuzLrmuStZbrfzXDQqi5o=", "dev": true }, "babel-plugin-syntax-class-constructor-call": { "version": "6.18.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-constructor-call/-/babel-plugin-syntax-class-constructor-call-6.18.0.tgz", "integrity": "sha1-nLnTn+Q8hgC+yBRkVt3L1OGnZBY=", "dev": true }, "babel-plugin-syntax-class-properties": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz", "integrity": "sha1-1+sjt5oxf4VDlixQW4J8fWysJ94=", "dev": true }, "babel-plugin-syntax-decorators": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz", "integrity": "sha1-MSVjtNvePMgGzuPkFszurd0RrAs=", "dev": true }, "babel-plugin-syntax-do-expressions": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-do-expressions/-/babel-plugin-syntax-do-expressions-6.13.0.tgz", "integrity": "sha1-V0d1YTmqJtOQ0JQQsDdEugfkeW0=", "dev": true }, "babel-plugin-syntax-dynamic-import": { "version": "6.18.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz", "integrity": "sha1-jWomIpyDdFqZgqRBBRVyyqF5sdo=", "dev": true }, "babel-plugin-syntax-exponentiation-operator": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" }, "babel-plugin-syntax-export-extensions": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-export-extensions/-/babel-plugin-syntax-export-extensions-6.13.0.tgz", "integrity": "sha1-cKFITw+QiaToStRLrDU8lbmxJyE=", "dev": true }, "babel-plugin-syntax-flow": { "version": "6.18.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=", "dev": true }, "babel-plugin-syntax-function-bind": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-function-bind/-/babel-plugin-syntax-function-bind-6.13.0.tgz", "integrity": "sha1-SMSV8Xe98xqYHnMvVa3AvdJgH0Y=", "dev": true }, "babel-plugin-syntax-jsx": { "version": "6.18.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=", "dev": true }, "babel-plugin-syntax-object-rest-spread": { "version": "6.13.0", - "resolved": "http://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz", "integrity": "sha1-/WU28rzhODb/o6VFjEkDpZe7O/U=", "dev": true }, @@ -4827,7 +4827,7 @@ }, "binaryextensions": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/binaryextensions/-/binaryextensions-1.0.1.tgz", "integrity": "sha1-HmN0iLNbWL2l9HdL+WpSEqjJB1U=", "dev": true }, @@ -5324,7 +5324,7 @@ }, "browserify-rsa": { "version": "4.0.1", - "resolved": "http://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", "requires": { "bn.js": "^4.1.0", @@ -5489,7 +5489,7 @@ }, "cacache": { "version": "10.0.4", - "resolved": "http://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz", "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==", "dev": true, "requires": { @@ -5585,7 +5585,7 @@ }, "camelcase-keys": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz", "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=", "dev": true, "requires": { @@ -5699,7 +5699,7 @@ }, "chalk": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", "requires": { "ansi-styles": "^2.2.1", @@ -6141,7 +6141,7 @@ }, "color": { "version": "0.11.4", - "resolved": "http://registry.npmjs.org/color/-/color-0.11.4.tgz", + "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz", "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=", "requires": { "clone": "^1.0.2", @@ -6254,7 +6254,7 @@ }, "yargs": { "version": "1.3.3", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.3.3.tgz", "integrity": "sha1-BU3oth8i7v23IHBZ6u+da4P7kxo=", "dev": true } @@ -6544,6 +6544,12 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=" }, + "cookiejar": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", + "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", + "dev": true + }, "copy-concurrently": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", @@ -6774,7 +6780,7 @@ }, "css-in-js-utils": { "version": "2.0.1", - "resolved": "http://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", + "resolved": "https://registry.npmjs.org/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz", "integrity": "sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==", "dev": true, "requires": { @@ -6792,7 +6798,7 @@ }, "css-loader": { "version": "0.28.11", - "resolved": "http://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.11.tgz", "integrity": "sha512-wovHgjAx8ZIMGSL8pTys7edA1ClmzxHeY6n/d97gg5odgsxEgKjULPR0viqyC+FWMCL9sfqoC/QCUBo62tLvPg==", "dev": true, "requires": { @@ -6878,7 +6884,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -6896,7 +6902,7 @@ }, "through2": { "version": "0.6.5", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -6908,7 +6914,7 @@ }, "css-select": { "version": "1.2.0", - "resolved": "http://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", "integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=", "dev": true, "requires": { @@ -6960,7 +6966,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -7000,7 +7006,7 @@ }, "cssnano": { "version": "3.10.0", - "resolved": "http://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz", "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=", "dev": true, "requires": { @@ -7174,7 +7180,7 @@ }, "d": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/d/-/d-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz", "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=", "requires": { "es5-ext": "^0.10.9" @@ -8330,7 +8336,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -8366,7 +8372,7 @@ }, "through2": { "version": "0.6.5", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -8382,7 +8388,7 @@ }, "yargs": { "version": "3.32.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz", "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=", "dev": true, "requires": { @@ -8443,7 +8449,7 @@ "dependencies": { "domelementtype": { "version": "1.1.3", - "resolved": "http://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz", "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=", "dev": true } @@ -8506,7 +8512,7 @@ }, "dotenv": { "version": "5.0.1", - "resolved": "http://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-5.0.1.tgz", "integrity": "sha512-4As8uPrjfwb7VXC+WnLCbXK7y+Ueb2B3zgNCePYfhxS1PYeaO1YTeplffTEcbfLhvFNGLAz90VvJs9yomG7bow==", "dev": true }, @@ -8531,7 +8537,7 @@ }, "duplexer": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=" }, "duplexer2": { @@ -8551,7 +8557,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -8701,6 +8707,45 @@ "iconv-lite": "~0.4.13" } }, + "encoding-down": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz", + "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==", + "dev": true, + "requires": { + "abstract-leveldown": "^5.0.0", + "inherits": "^2.0.3", + "level-codec": "^9.0.0", + "level-errors": "^2.0.0", + "xtend": "^4.0.1" + }, + "dependencies": { + "abstract-leveldown": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", + "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", + "dev": true, + "requires": { + "xtend": "~4.0.0" + } + }, + "level-codec": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-9.0.0.tgz", + "integrity": "sha512-OIpVvjCcZNP5SdhcNupnsI1zo5Y9Vpm+k/F1gfG5kXrtctlrwanisakweJtE0uA0OpLukRfOQae+Fg0M5Debhg==", + "dev": true + }, + "level-errors": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/level-errors/-/level-errors-2.0.0.tgz", + "integrity": "sha512-AmY4HCp9h3OiU19uG+3YWkdELgy05OTP/r23aNHaQKWv8DO787yZgsEuGVkoph40uwN+YdUKnANlrxSsoOaaxg==", + "dev": true, + "requires": { + "errno": "~0.1.1" + } + } + } + }, "end-of-stream": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz", @@ -9022,7 +9067,7 @@ }, "es6-promisify": { "version": "5.0.0", - "resolved": "http://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", + "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz", "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=", "dev": true, "requires": { @@ -9291,7 +9336,7 @@ }, "ansi-escapes": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz", "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=", "dev": true }, @@ -9398,7 +9443,7 @@ }, "progress": { "version": "1.1.8", - "resolved": "http://registry.npmjs.org/progress/-/progress-1.1.8.tgz", + "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz", "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=", "dev": true }, @@ -9440,7 +9485,7 @@ }, "slice-ansi": { "version": "0.0.4", - "resolved": "http://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz", "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=", "dev": true }, @@ -9599,6 +9644,15 @@ "safe-event-emitter": "^1.0.1" }, "dependencies": { + "babelify": { + "version": "7.3.0", + "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "requires": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, "cross-fetch": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/cross-fetch/-/cross-fetch-2.2.3.tgz", @@ -9618,6 +9672,21 @@ "json-rpc-engine": "^3.4.0", "json-rpc-error": "^2.0.0", "tape": "^4.8.0" + }, + "dependencies": { + "json-rpc-engine": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + } } }, "eth-json-rpc-middleware": { @@ -9638,6 +9707,21 @@ "json-stable-stringify": "^1.0.1", "promise-to-callback": "^1.0.0", "tape": "^4.6.3" + }, + "dependencies": { + "json-rpc-engine": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + } } }, "ethereumjs-util": { @@ -9672,7 +9756,7 @@ } }, "eth-contract-metadata": { - "version": "github:MetaMask/eth-contract-metadata#05e39ee1be2edaa53b04ff7e215cdd6db16d09c1", + "version": "github:MetaMask/eth-contract-metadata#4d855fea9a5c899059134e03986be9d98e844270", "from": "github:MetaMask/eth-contract-metadata#master" }, "eth-ens-namehash": { @@ -9709,12 +9793,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9759,6 +9844,15 @@ "safe-event-emitter": "^1.0.1" }, "dependencies": { + "babelify": { + "version": "7.3.0", + "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "requires": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, "eth-json-rpc-middleware": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-2.6.0.tgz", @@ -9789,12 +9883,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9842,6 +9937,19 @@ "requires": { "promise-to-callback": "^1.0.0" } + }, + "json-rpc-engine": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } } } }, @@ -9867,7 +9975,7 @@ }, "eth-json-rpc-middleware": { "version": "1.6.0", - "resolved": "http://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", + "resolved": "https://registry.npmjs.org/eth-json-rpc-middleware/-/eth-json-rpc-middleware-1.6.0.tgz", "integrity": "sha512-tDVCTlrUvdqHKqivYMjtFZsdD7TtpNLBCfKAcOpaVs7orBMS/A8HWro6dIzNtTZIR05FAbJ3bioFOnZpuCew9Q==", "requires": { "async": "^2.5.0", @@ -9937,18 +10045,30 @@ "safe-event-emitter": "^1.0.1" }, "dependencies": { + "babelify": { + "version": "7.3.0", + "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "dev": true, + "requires": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, "eth-sig-util": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "dev": true, "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", + "dev": true, "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -9997,6 +10117,20 @@ "safe-buffer": "^5.1.1" } }, + "json-rpc-engine": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "dev": true, + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, "rustbn.js": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/rustbn.js/-/rustbn.js-0.2.0.tgz", @@ -10024,7 +10158,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -10385,7 +10519,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -10517,7 +10651,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -10539,12 +10673,13 @@ "resolved": "https://registry.npmjs.org/eth-sig-util/-/eth-sig-util-1.4.2.tgz", "integrity": "sha1-jZWCAsftuq6Dlwf7pvCf8ydgYhA=", "requires": { + "ethereumjs-abi": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", "ethereumjs-util": "^5.1.1" }, "dependencies": { "ethereumjs-abi": { "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", + "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git", "requires": { "bn.js": "^4.10.0", "ethereumjs-util": "^5.0.0" @@ -10822,7 +10957,7 @@ "dependencies": { "ethereumjs-util": { "version": "4.5.0", - "resolved": "http://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", "requires": { "bn.js": "^4.8.0", @@ -11856,7 +11991,7 @@ "dependencies": { "core-js": { "version": "1.2.7", - "resolved": "http://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz", "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY=" } } @@ -11918,7 +12053,7 @@ }, "file-loader": { "version": "1.1.11", - "resolved": "http://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-1.1.11.tgz", "integrity": "sha512-TGR4HU7HUsGg6GCOPJnFk06RhWgEWFLAGWiT6rcD+GRC2keU3s9RGJ+b3Z6/U73jwwNb2gKLJ7YCrp+jvU4ALg==", "dev": true, "requires": { @@ -12418,7 +12553,7 @@ "dependencies": { "async": { "version": "0.2.10", - "resolved": "http://registry.npmjs.org/async/-/async-0.2.10.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-0.2.10.tgz", "integrity": "sha1-trvgsGdLnXGXCMo43owjfLUmw9E=", "dev": true }, @@ -12634,7 +12769,7 @@ }, "fs-access": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/fs-access/-/fs-access-1.0.1.tgz", "integrity": "sha1-1qh/JiJxzv6+wwxVNAf7mV2od3o=", "dev": true, "requires": { @@ -12783,7 +12918,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -12935,8 +13070,7 @@ "ansi-regex": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", - "dev": true + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" }, "ansi-styles": { "version": "2.2.1", @@ -12950,6 +13084,11 @@ "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8=", "dev": true }, + "argsarray": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/argsarray/-/argsarray-0.0.1.tgz", + "integrity": "sha1-bnIHtOzbObCviDA/pa4ivajfYcs=" + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -12976,12 +13115,35 @@ "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=", + "requires": { + "util": "0.10.3" + } + }, + "assert-match": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/assert-match/-/assert-match-1.1.1.tgz", + "integrity": "sha512-c0QY2kpYVrH/jis6cCq9Mnt4/bIdGALDh1N8HY9ZARZedsMs5LSbgywxkjd5A1uNVLN0L8evANxBPxKiabVoZw==", + "requires": { + "assert": "1.4.1", + "babel-runtime": "6.26.0", + "lodash.merge": "4.6.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==" + }, "async": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz", @@ -13596,24 +13758,12 @@ "lodash": "^4.17.4", "mkdirp": "^0.5.1", "source-map-support": "^0.4.15" - }, - "dependencies": { - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "dev": true, - "requires": { - "source-map": "^0.5.6" - } - } } }, "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" @@ -13758,10 +13908,22 @@ "version": "1.2.2", "resolved": "http://registry.npmjs.org/bl/-/bl-1.2.2.tgz", "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", - "dev": true, "requires": { "readable-stream": "^2.3.5", "safe-buffer": "^5.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3", + "isarray": "0.0.1", + "string_decoder": "0.10.31" + } + } } }, "block-stream": { @@ -13829,6 +13991,11 @@ "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=" }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==" + }, "browserify-aes": { "version": "1.2.0", "resolved": "http://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", @@ -13977,8 +14144,7 @@ "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 + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" }, "buffer-to-arraybuffer": { "version": "0.0.5", @@ -13994,8 +14160,7 @@ "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 + "integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=" }, "bytes": { "version": "3.0.0", @@ -14046,8 +14211,7 @@ "camelcase": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz", - "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=", - "dev": true + "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=" }, "caniuse-lite": { "version": "1.0.30000907", @@ -14061,6 +14225,16 @@ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=", "dev": true }, + "chai": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz", + "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=", + "requires": { + "assertion-error": "1.1.0", + "deep-eql": "0.1.3", + "type-detect": "1.0.0" + } + }, "chalk": { "version": "1.1.3", "resolved": "http://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", @@ -14096,7 +14270,6 @@ "version": "3.2.0", "resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz", "integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=", - "dev": true, "requires": { "string-width": "^1.0.1", "strip-ansi": "^3.0.1", @@ -14109,11 +14282,15 @@ "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", "dev": true }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=" + }, "code-point-at": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, "coinstring": { "version": "2.3.0", @@ -14168,6 +14345,14 @@ "inherits": "^2.0.3", "readable-stream": "^2.2.2", "typedarray": "^0.0.6" + }, + "dependencies": { + "buffer-from": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.0.tgz", + "integrity": "sha512-c5mRlguI/Pe2dSZmpER62rSCu0ryKmWddzRYsuXc50U2/g8jMOulc31VZMa4mYx31U5xsmSOpDCgH88Vl9cDGQ==", + "dev": true + } } }, "content-disposition": { @@ -14203,23 +14388,15 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, - "cookiejar": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.2.tgz", - "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==", - "dev": true - }, "core-js": { "version": "2.5.7", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.7.tgz", - "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==", - "dev": true + "integrity": "sha512-RszJCAxg/PP6uzXVXL6BsxSXx/B05oJAQ2vkJRjyjrEcNVycaqOmNb5OTxZPE3xa5gwZduqza6L9JOCenh/Ecw==" }, "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 + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" }, "cors": { "version": "2.8.5", @@ -14297,6 +14474,11 @@ "randomfill": "^1.0.3" } }, + "d64": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/d64/-/d64-1.0.0.tgz", + "integrity": "sha1-QAKofoUMv8n52XBrYPymE6MzbpA=" + }, "dashdash": { "version": "1.14.1", "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz", @@ -14318,8 +14500,7 @@ "decamelize": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" }, "decode-uri-component": { "version": "0.2.0", @@ -14448,6 +14629,21 @@ } } }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "requires": { + "type-detect": "0.1.1" + }, + "dependencies": { + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=" + } + } + }, "deep-equal": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.0.1.tgz", @@ -14535,6 +14731,11 @@ "repeating": "^2.0.0" } }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==" + }, "diffie-hellman": { "version": "5.0.3", "resolved": "http://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", @@ -14620,30 +14821,6 @@ "iconv-lite": "~0.4.13" } }, - "encoding-down": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-5.0.4.tgz", - "integrity": "sha512-8CIZLDcSKxgzT+zX8ZVfgNbu8Md2wq/iqa1Y7zyVR18QBEAc0Nmzuvj/N5ykSKpfGzjM8qxbaFntLPwnVoUhZw==", - "dev": true, - "requires": { - "abstract-leveldown": "^5.0.0", - "inherits": "^2.0.3", - "level-codec": "^9.0.0", - "level-errors": "^2.0.0", - "xtend": "^4.0.1" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", - "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - } - } - }, "end-of-stream": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", @@ -14657,7 +14834,6 @@ "version": "0.1.7", "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, "requires": { "prr": "~1.0.1" } @@ -14666,7 +14842,6 @@ "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" } @@ -14704,8 +14879,7 @@ "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 + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" }, "esutils": { "version": "2.0.2", @@ -14853,6 +15027,19 @@ "web3-provider-engine": "^13.3.2" }, "dependencies": { + "async-eventemitter": { + "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", + "from": "async-eventemitter@github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", + "dev": true, + "requires": { + "async": "2.6.1" + } + }, + "bn.js": { + "version": "4.11.8", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", + "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==" + }, "eth-block-tracker": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-2.3.1.tgz", @@ -14867,16 +15054,6 @@ "json-rpc-engine": "^3.6.0", "pify": "^2.3.0", "tape": "^4.6.3" - }, - "dependencies": { - "async-eventemitter": { - "version": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "from": "github:ahultgren/async-eventemitter#fa06e39e56786ba541c180061dbf2c0a5bbf951c", - "dev": true, - "requires": { - "async": "^2.4.0" - } - } } }, "eth-sig-util": { @@ -14886,16 +15063,6 @@ "dev": true, "requires": { "ethereumjs-util": "^5.1.1" - }, - "dependencies": { - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - } } }, "ethereum-common": { @@ -14944,18 +15111,6 @@ "safe-buffer": "^5.1.1" } }, - "fs-extra": { - "version": "0.30.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", - "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", - "requires": { - "graceful-fs": "^4.1.2", - "jsonfile": "^2.1.0", - "klaw": "^1.0.0", - "path-is-absolute": "^1.0.0", - "rimraf": "^2.2.8" - } - }, "pify": { "version": "2.3.0", "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", @@ -15073,12 +15228,6 @@ } } }, - "ethereumjs-common": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/ethereumjs-common/-/ethereumjs-common-0.4.1.tgz", - "integrity": "sha512-ywYGsOeGCsMNWso5Y4GhjWI24FJv9FK7+VyVKiQgXg8ZRDPXJ7F/kJ1CnjtkjTvDF4e0yqU+FWswlqR3bmZQ9Q==", - "dev": true - }, "ethereumjs-tx": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/ethereumjs-tx/-/ethereumjs-tx-1.3.7.tgz", @@ -15166,6 +15315,52 @@ "scrypt.js": "^0.2.0", "utf8": "^3.0.0", "uuid": "^3.3.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.6", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.6.tgz", + "integrity": "sha1-UzRK2xRhehP26N0s4okF0cC6MhU=", + "dev": true + }, + "ethereumjs-util": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.5.0.tgz", + "integrity": "sha1-PpQosxfuvaPXJg2FT93alUsfG8Y=", + "dev": true, + "optional": true, + "requires": { + "bn.js": "4.11.6", + "create-hash": "1.2.0", + "keccakjs": "0.2.1", + "rlp": "2.0.0", + "secp256k1": "3.5.0" + } + }, + "rlp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/rlp/-/rlp-2.0.0.tgz", + "integrity": "sha1-nbOE/0uJqPYVY9kjldhiWxjzr7A=", + "dev": true, + "optional": true + }, + "secp256k1": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.5.0.tgz", + "integrity": "sha512-e5QIJl8W7Y4tT6LHffVcZAxJjvpgE5Owawv6/XCYPQljE9aP2NFFddQ8OYMKhdLshNu88FfL3qCN3/xYkXGRsA==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.2.1", + "bip66": "^1.1.3", + "bn.js": "^4.11.3", + "create-hash": "^1.1.2", + "drbg.js": "^1.0.1", + "elliptic": "^6.2.3", + "nan": "^2.2.1", + "safe-buffer": "^5.1.0" + } + } } }, "ethjs-unit": { @@ -15201,12 +15396,6 @@ "integrity": "sha1-R3hr2qCHyvext15zq8XH1UAVjNA=", "dev": true }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, "evp_bytestokey": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", @@ -15254,6 +15443,24 @@ "vary": "~1.1.2" }, "dependencies": { + "body-parser": { + "version": "1.18.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz", + "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "content-type": "1.0.4", + "debug": "2.6.9", + "depd": "1.1.2", + "http-errors": "1.6.3", + "iconv-lite": "0.4.19", + "on-finished": "2.3.0", + "qs": "6.5.1", + "raw-body": "2.3.2", + "type-is": "1.6.16" + } + }, "debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -15263,6 +15470,62 @@ "ms": "2.0.0" } }, + "iconv-lite": { + "version": "0.4.19", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz", + "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ==", + "dev": true + }, + "qs": { + "version": "6.5.1", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz", + "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==", + "dev": true + }, + "raw-body": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz", + "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=", + "dev": true, + "requires": { + "bytes": "3.0.0", + "http-errors": "1.6.2", + "iconv-lite": "0.4.19", + "unpipe": "1.0.0" + }, + "dependencies": { + "depd": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz", + "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k=", + "dev": true + }, + "http-errors": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz", + "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=", + "dev": true, + "requires": { + "depd": "1.1.1", + "inherits": "2.0.3", + "setprototypeof": "1.0.3", + "statuses": "1.4.0" + } + }, + "setprototypeof": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz", + "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ=", + "dev": true + } + } + }, + "safe-buffer": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "dev": true + }, "statuses": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz", @@ -15377,7 +15640,6 @@ "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" @@ -15392,6 +15654,11 @@ "is-callable": "^1.1.3" } }, + "foreach": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz", + "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=" + }, "forever-agent": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz", @@ -15431,7 +15698,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", - "dev": true, "requires": { "graceful-fs": "^4.1.2", "jsonfile": "^2.1.0" @@ -15448,12 +15714,33 @@ "fs-extra": "^2.0.0", "mz": "^2.6.0", "thenify-all": "^1.6.0" + }, + "dependencies": { + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "http://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + } } }, "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true }, "fstream": { "version": "1.0.11", @@ -15479,11 +15766,15 @@ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", "dev": true }, + "generic-pool": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-2.0.4.tgz", + "integrity": "sha1-+XGN7agvoSXtXEPjQcmiFadm2aM=" + }, "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 + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==" }, "get-stream": { "version": "3.0.0", @@ -15504,6 +15795,7 @@ "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", @@ -15562,6 +15854,11 @@ "integrity": "sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=", "dev": true }, + "growl": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", + "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==" + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -15596,18 +15893,22 @@ "ansi-regex": "^2.0.0" } }, + "has-flag": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz", + "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=" + }, + "has-localstorage": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-localstorage/-/has-localstorage-1.0.1.tgz", + "integrity": "sha1-/mJAbEdn+9bXhNrGkFkoEIuClxs=" + }, "has-symbol-support-x": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz", "integrity": "sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw==", "dev": true }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, "has-to-string-tag-x": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz", @@ -15647,6 +15948,11 @@ "secp256k1": "^3.0.1" } }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=" + }, "heap": { "version": "0.2.6", "resolved": "https://registry.npmjs.org/heap/-/heap-0.2.6.tgz", @@ -15676,8 +15982,7 @@ "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 + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==" }, "http-errors": { "version": "1.6.3", @@ -15708,6 +16013,15 @@ "sshpk": "^1.7.0" } }, + "humble-localstorage": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/humble-localstorage/-/humble-localstorage-1.4.2.tgz", + "integrity": "sha1-0Fqw1SbE7b3b98amDfb/WAUoNGk=", + "requires": { + "has-localstorage": "1.0.1", + "localstorage-memory": "1.0.2" + } + }, "iconv-lite": { "version": "0.4.23", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.23.tgz", @@ -15733,6 +16047,7 @@ "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" @@ -15755,8 +16070,7 @@ "invert-kv": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz", - "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=", - "dev": true + "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=" }, "ipaddr.js": { "version": "1.8.0", @@ -15767,14 +16081,12 @@ "is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", - "dev": true + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" }, "is-builtin-module": { "version": "1.0.0", "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", - "dev": true, "requires": { "builtin-modules": "^1.0.0" } @@ -15810,7 +16122,6 @@ "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" } @@ -15878,19 +16189,18 @@ "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=" + "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 + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=" }, "isarray": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=", - "dev": true + "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" }, "isstream": { "version": "0.1.2", @@ -15908,6 +16218,14 @@ "is-object": "^1.0.1" } }, + "js-scrypt": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/js-scrypt/-/js-scrypt-0.2.0.tgz", + "integrity": "sha1-emK3AbRhbnCtDN5URiequ5nX/jk=", + "requires": { + "generic-pool": "2.0.4" + } + }, "js-sha3": { "version": "0.3.1", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz", @@ -16045,6 +16363,7 @@ "version": "1.3.1", "resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz", "integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=", + "dev": true, "requires": { "graceful-fs": "^4.1.9" } @@ -16053,7 +16372,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz", "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=", - "dev": true, "requires": { "invert-kv": "^1.0.0" } @@ -16135,6 +16453,35 @@ "xtend": "~4.0.0" }, "dependencies": { + "abstract-leveldown": { + "version": "0.12.4", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.4.tgz", + "integrity": "sha1-KeGOYy5g5OIh1YECR4UqY9ey5BA=", + "requires": { + "xtend": "3.0.0" + }, + "dependencies": { + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=" + } + } + }, + "deferred-leveldown": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-0.2.0.tgz", + "integrity": "sha1-LO8fER4cV4cNi7uK8mUOWHzS9bQ=", + "requires": { + "abstract-leveldown": "0.12.4" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "level-iterator-stream": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.3.tgz", @@ -16144,6 +16491,43 @@ "inherits": "^2.0.1", "readable-stream": "^2.0.5", "xtend": "^4.0.0" + }, + "dependencies": { + "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" + } + } + } + }, + "levelup": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/levelup/-/levelup-0.19.1.tgz", + "integrity": "sha1-86anIFJyxLXzXkEv8ASgOgrt9Qs=", + "requires": { + "deferred-leveldown": "0.2.0", + "errno": "0.1.7", + "prr": "0.0.0", + "readable-stream": "1.0.34", + "semver": "5.1.1", + "xtend": "3.0.0" + }, + "dependencies": { + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=" + } } }, "ltgt": { @@ -16151,6 +16535,34 @@ "resolved": "https://registry.npmjs.org/ltgt/-/ltgt-2.1.3.tgz", "integrity": "sha1-EIUaBtmWS5cReEQcI8nlJpjuzjQ=", "dev": true + }, + "prr": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz", + "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=" + }, + "readable-stream": { + "version": "1.0.34", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", + "requires": { + "core-util-is": "1.0.2", + "inherits": "2.0.3" + } + }, + "semver": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.1.tgz", + "integrity": "sha1-oykqNz5vPgeY2gsgZBuanFvEfhk=" + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "http://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" + } } } }, @@ -16197,45 +16609,12 @@ "level-errors": "~2.0.0", "level-iterator-stream": "~3.0.0", "xtend": "~4.0.0" - }, - "dependencies": { - "abstract-leveldown": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-5.0.0.tgz", - "integrity": "sha512-5mU5P1gXtsMIXg65/rsYGsi93+MlogXZ9FA8JnwKurHQg64bfXwGYVdVdijNTVNOlAsuIiOwHdvFFD5JqCJQ7A==", - "dev": true, - "requires": { - "xtend": "~4.0.0" - } - }, - "deferred-leveldown": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-4.0.2.tgz", - "integrity": "sha512-5fMC8ek8alH16QiV0lTCis610D1Zt1+LA4MS4d63JgS32lrCjTFDUFz2ao09/j2I4Bqb5jL4FZYwu7Jz0XO1ww==", - "dev": true, - "requires": { - "abstract-leveldown": "~5.0.0", - "inherits": "^2.0.3" - } - }, - "level-iterator-stream": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-3.0.1.tgz", - "integrity": "sha512-nEIQvxEED9yRThxvOrq8Aqziy4EGzrxSZK+QzEFAVuJvQ8glfyZ96GB6BoI4sBbLfjMXm2w4vu3Tkcm9obcY0g==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "xtend": "^4.0.0" - } - } } }, "load-json-file": { "version": "1.1.0", "resolved": "http://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", @@ -16247,11 +16626,43 @@ "pify": { "version": "2.3.0", "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, + "localstorage-down": { + "version": "0.6.7", + "resolved": "https://registry.npmjs.org/localstorage-down/-/localstorage-down-0.6.7.tgz", + "integrity": "sha1-0Hmak7MebF+lGI7AYkLrHM6dbRU=", + "requires": { + "abstract-leveldown": "0.12.3", + "argsarray": "0.0.1", + "d64": "1.0.0", + "humble-localstorage": "1.4.2", + "inherits": "2.0.3", + "tiny-queue": "0.2.0" + }, + "dependencies": { + "abstract-leveldown": { + "version": "0.12.3", + "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-0.12.3.tgz", + "integrity": "sha1-EWsexcdxDvei1XBnaLvbREC+EHA=", + "requires": { + "xtend": "3.0.0" + } + }, + "xtend": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-3.0.0.tgz", + "integrity": "sha1-XM50B7r2Qsunvs2laBEcST9ZZlo=" + } + } + }, + "localstorage-memory": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/localstorage-memory/-/localstorage-memory-1.0.2.tgz", + "integrity": "sha1-zUqPIQ5V3VGckp9LTMgoKbWPmlE=" + }, "lodash": { "version": "4.17.10", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz", @@ -16261,8 +16672,12 @@ "lodash.assign": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz", - "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=", - "dev": true + "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=" + }, + "lodash.merge": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.1.tgz", + "integrity": "sha512-AOYza4+Hf5z1/0Hztxpm2/xiPZgi/cjMqdnKTUWTBSKchJlxXXuUSxCCl8rJlf4g6yww/j6mA8nC8Hw/EZWxKQ==" }, "looper": { "version": "2.0.0", @@ -16308,15 +16723,6 @@ "optional": true, "requires": { "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "optional": true - } } }, "md5.js": { @@ -16500,14 +16906,12 @@ "minimist": { "version": "0.0.8", "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", - "dev": true + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" }, "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" } @@ -16522,6 +16926,46 @@ "mkdirp": "*" } }, + "mocha": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.1.1.tgz", + "integrity": "sha512-kKKs/H1KrMMQIEsWNxGmb4/BGsmj0dkeyotEvbrAuQ01FcWRLssUNXCEUZk6SZtyJBi6EE7SL0zDDtItw1rGhw==", + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.11.0", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "growl": "1.10.3", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "4.4.0" + }, + "dependencies": { + "commander": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", + "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==" + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "requires": { + "ms": "2.0.0" + } + }, + "supports-color": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz", + "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==", + "requires": { + "has-flag": "2.0.0" + } + } + } + }, "mock-fs": { "version": "4.7.0", "resolved": "https://registry.npmjs.org/mock-fs/-/mock-fs-4.7.0.tgz", @@ -16580,7 +17024,6 @@ "version": "2.4.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz", "integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==", - "dev": true, "requires": { "hosted-git-info": "^2.1.4", "is-builtin-module": "^1.0.0", @@ -16591,8 +17034,7 @@ "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 + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" }, "number-to-bn": { "version": "1.7.0", @@ -16658,6 +17100,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, "requires": { "wrappy": "1" } @@ -16672,7 +17115,6 @@ "version": "1.4.0", "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", - "dev": true, "requires": { "lcid": "^1.0.0" } @@ -16680,8 +17122,7 @@ "os-tmpdir": { "version": "1.0.2", "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", - "dev": true + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "p-cancelable": { "version": "0.3.0", @@ -16731,7 +17172,6 @@ "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" } @@ -16746,7 +17186,6 @@ "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" } @@ -16754,7 +17193,8 @@ "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=" + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true }, "path-parse": { "version": "1.0.6", @@ -16772,7 +17212,6 @@ "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", @@ -16782,8 +17221,7 @@ "pify": { "version": "2.3.0", "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", - "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", - "dev": true + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } }, @@ -16813,17 +17251,22 @@ "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, + "optional": true + }, "pinkie": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", - "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", - "dev": true + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=" }, "pinkie-promise": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", - "dev": true, "requires": { "pinkie": "^2.0.0" } @@ -16834,6 +17277,11 @@ "integrity": "sha1-qpWRvKokkj8eD0hJ0kD0fvwQdaw=", "dev": true }, + "prepend-file": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prepend-file/-/prepend-file-1.3.1.tgz", + "integrity": "sha1-g7FuC0rBkB/OiNvZRaIvTMgd9Xk=" + }, "prepend-http": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-1.0.4.tgz", @@ -16881,8 +17329,7 @@ "prr": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=" }, "pseudomap": { "version": "1.0.2", @@ -16890,12 +17337,6 @@ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", "dev": true }, - "psl": { - "version": "1.1.29", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.29.tgz", - "integrity": "sha512-AeUmQ0oLN02flVHXWh9sSJF7mcdFq0ppid/JkErufc3hGIV/AMa8Fo9VgDo/cT2jFdOWoFvHp90qqBH54W+gjQ==", - "dev": true - }, "public-encrypt": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", @@ -17040,7 +17481,6 @@ "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", @@ -17051,7 +17491,6 @@ "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" @@ -17098,8 +17537,7 @@ "regenerator-runtime": { "version": "0.11.1", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==", - "dev": true + "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" }, "regenerator-transform": { "version": "0.10.1", @@ -17173,13 +17611,20 @@ "tough-cookie": "~2.4.3", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "dependencies": { + "uuid": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.2.1.tgz", + "integrity": "sha512-jZnMwlb9Iku/O3smGWvZhauCf6cvvpKi4BKRiliS3cxnI+Gz9j5MEpTz2UFuXiKPJocb7gnsLHwiS05ige5BEA==", + "dev": true + } } }, "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 + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=" }, "require-from-string": { "version": "1.2.1", @@ -17190,8 +17635,7 @@ "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 + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=" }, "resolve": { "version": "1.7.1", @@ -17215,6 +17659,7 @@ "version": "2.6.2", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", + "dev": true, "requires": { "glob": "^7.0.5" } @@ -17247,15 +17692,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, - "safe-event-emitter": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/safe-event-emitter/-/safe-event-emitter-1.0.1.tgz", - "integrity": "sha512-e1wFe99A91XYYxoQbcq2ZJUWurxEyP8vfz7A7vuUe1s95q8r5ebraVaA1BukYJcpM6V16ugWoD9vngi8Ccu5fg==", - "dev": true, - "requires": { - "events": "^3.0.0" - } - }, "safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -17333,8 +17769,7 @@ "semver": { "version": "5.4.1", "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz", - "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==", - "dev": true + "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==" }, "send": { "version": "0.16.2", @@ -17402,8 +17837,7 @@ "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 + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=" }, "set-immediate-shim": { "version": "1.0.1", @@ -17442,6 +17876,11 @@ "nan": "2.10.0" } }, + "shebang-loader": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/shebang-loader/-/shebang-loader-0.0.1.tgz", + "integrity": "sha1-pAAEldRMzu++xjQ157FphWn6Uuw=" + }, "simple-concat": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.0.tgz", @@ -17490,6 +17929,34 @@ "path-is-absolute": "^1.0.0", "rimraf": "^2.2.8" } + }, + "get-caller-file": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.2.tgz", + "integrity": "sha1-9wLmMSfn4jHBYKgMFVSstw1QR+U=", + "dev": true + }, + "yargs": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", + "dev": true, + "requires": { + "cliui": "3.2.0", + "decamelize": "1.2.0", + "get-caller-file": "1.0.2", + "lodash.assign": "4.2.0", + "os-locale": "1.4.0", + "read-pkg-up": "1.0.1", + "require-directory": "2.1.1", + "require-main-filename": "1.0.1", + "set-blocking": "2.0.0", + "string-width": "1.0.2", + "which-module": "1.0.0", + "window-size": "0.2.0", + "y18n": "3.2.1", + "yargs-parser": "2.4.1" + } } } }, @@ -17499,11 +17966,19 @@ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true }, + "source-map-support": { + "version": "0.4.18", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", + "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", + "dev": true, + "requires": { + "source-map": "0.5.7" + } + }, "spdx-correct": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.2.tgz", "integrity": "sha512-q9hedtzyXHr5S0A1vEPoK/7l8NpfkFYTq6iCY+Pno2ZbdZR6WexZFtqeVGkGxW3TEJMN914Z55EnAGMmenlIQQ==", - "dev": true, "requires": { "spdx-expression-parse": "^3.0.0", "spdx-license-ids": "^3.0.0" @@ -17512,14 +17987,12 @@ "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 + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==" }, "spdx-expression-parse": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", - "dev": true, "requires": { "spdx-exceptions": "^2.1.0", "spdx-license-ids": "^3.0.0" @@ -17528,8 +18001,7 @@ "spdx-license-ids": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.2.tgz", - "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==", - "dev": true + "integrity": "sha512-qky9CVt0lVIECkEsYbNILVnPvycuEBkXoMFLRWsREkomQLevYhtRKC+R91a5TOAQ3bCMjikRwhyaRqj1VYatYg==" }, "sshpk": { "version": "1.15.2", @@ -17582,7 +18054,6 @@ "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", @@ -17603,14 +18074,12 @@ "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", - "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=", - "dev": true + "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "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" } @@ -17619,7 +18088,6 @@ "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" } @@ -17668,6 +18136,26 @@ "setimmediate": "^1.0.5", "tar.gz": "^1.0.5", "xhr-request-promise": "^0.1.2" + }, + "dependencies": { + "fs-extra": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz", + "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "4.1.11", + "jsonfile": "2.4.0" + } + }, + "graceful-fs": { + "version": "4.1.11", + "resolved": "http://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz", + "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=", + "dev": true, + "optional": true + } } }, "tape": { @@ -17724,6 +18212,18 @@ "readable-stream": "^2.3.0", "to-buffer": "^1.1.1", "xtend": "^4.0.0" + }, + "dependencies": { + "bl": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz", + "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==", + "dev": true, + "requires": { + "readable-stream": "2.3.6", + "safe-buffer": "5.1.2" + } + } } }, "tar.gz": { @@ -17749,6 +18249,22 @@ } } }, + "temp": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz", + "integrity": "sha1-4Ma8TSa5AxJEEOT+2BEDAU38H1k=", + "requires": { + "os-tmpdir": "1.0.2", + "rimraf": "2.2.8" + }, + "dependencies": { + "rimraf": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.2.8.tgz", + "integrity": "sha1-5Dm+Kq7jJzIZUnMPmaiSnk/FBYI=" + } + } + }, "thenify": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.0.tgz", @@ -17789,6 +18305,11 @@ "integrity": "sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8=", "dev": true }, + "tiny-queue": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/tiny-queue/-/tiny-queue-0.2.0.tgz", + "integrity": "sha1-xJ/LXIdVW+G0pd9+uHEB1beLydw=" + }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -17861,6 +18382,11 @@ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=", "dev": true }, + "type-detect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz", + "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI=" + }, "type-is": { "version": "1.6.16", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz", @@ -17881,6 +18407,7 @@ "version": "3.1.5", "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, "requires": { "is-typedarray": "^1.0.0" } @@ -18006,6 +18533,21 @@ "dev": true, "optional": true }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "requires": { + "inherits": "2.0.1" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=" + } + } + }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -18022,13 +18564,13 @@ "version": "3.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz", "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==", - "dev": true + "dev": true, + "optional": 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" @@ -18324,16 +18866,6 @@ "dev": true, "requires": { "ethereumjs-util": "^5.1.1" - }, - "dependencies": { - "ethereumjs-abi": { - "version": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "from": "git+https://github.com/ethereumjs/ethereumjs-abi.git#2863c40e0982acfc0b7163f0285d4c56427c7799", - "requires": { - "bn.js": "^4.10.0", - "ethereumjs-util": "^5.0.0" - } - } } }, "ethereumjs-abi": { @@ -18383,22 +18915,15 @@ "dev": true, "requires": { "underscore": "1.8.3", - "web3-core-helpers": "1.0.0-beta.35" + "web3-core-helpers": "1.0.0-beta.35", + "websocket": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2" }, "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, "websocket": { "version": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", "from": "git://github.com/frozeman/WebSocket-Node.git#6c72925e3f8aaaea8dc8450f97627e85263999f2", + "dev": true, "requires": { - "debug": "^2.2.0", "nan": "^2.3.3", "typedarray-to-buffer": "^3.1.2", "yaeti": "^0.0.6" @@ -18480,20 +19005,17 @@ "which-module": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz", - "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=", - "dev": true + "integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8=" }, "window-size": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.2.0.tgz", - "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=", - "dev": true + "integrity": "sha1-tDFbtCFKPXBY6+7okuE/ok2YsHU=" }, "wrap-ansi": { "version": "2.1.0", "resolved": "http://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" @@ -18502,7 +19024,8 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true }, "ws": { "version": "3.3.3", @@ -18551,14 +19074,10 @@ "xhr-request": "^1.0.1" } }, - "xhr2-cookies": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", - "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", - "dev": true, - "requires": { - "cookiejar": "^2.1.1" - } + "xhr2": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.4.tgz", + "integrity": "sha1-f4dliEdxbbUCYyOBL4GMras4el8=" }, "xtend": { "version": "4.0.1", @@ -18569,19 +19088,18 @@ "y18n": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz", - "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=", - "dev": true + "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=" }, "yaeti": { "version": "0.0.6", "resolved": "https://registry.npmjs.org/yaeti/-/yaeti-0.0.6.tgz", - "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=" + "integrity": "sha1-8m9ITXJoTPQr7ft2lwqhYI+/lXc=", + "dev": true }, "yargs": { "version": "4.8.1", "resolved": "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", - "dev": true, "requires": { "cliui": "^3.2.0", "decamelize": "^1.1.1", @@ -18597,6 +19115,16 @@ "window-size": "^0.2.0", "y18n": "^3.2.1", "yargs-parser": "^2.4.1" + }, + "dependencies": { + "yargs-parser": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-5.0.0.tgz", + "integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=", + "requires": { + "camelcase": "3.0.0" + } + } } }, "yargs-parser": { @@ -18667,7 +19195,7 @@ "dependencies": { "bluebird": { "version": "3.4.6", - "resolved": "http://registry.npmjs.org/bluebird/-/bluebird-3.4.6.tgz", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.6.tgz", "integrity": "sha1-AdqNgh2HgT0ViWfnQ9X+bGLPjA8=", "dev": true }, @@ -18738,7 +19266,7 @@ }, "get-stream": { "version": "3.0.0", - "resolved": "http://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", "dev": true }, @@ -18772,7 +19300,7 @@ }, "gettext-parser": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/gettext-parser/-/gettext-parser-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/gettext-parser/-/gettext-parser-1.1.0.tgz", "integrity": "sha1-LFpmONiTk0ubVQN9CtgstwBLJnk=", "dev": true, "requires": { @@ -18805,7 +19333,7 @@ }, "commander": { "version": "2.15.1", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", "dev": true }, @@ -18920,13 +19448,13 @@ "dependencies": { "minimist": { "version": "0.1.0", - "resolved": "http://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.1.0.tgz", "integrity": "sha1-md9lelJXTCHJBXSX33QnkLK0wN4=", "dev": true }, "yargs": { "version": "1.2.6", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-1.2.6.tgz", "integrity": "sha1-nHtKgv1dWVsr8Xq23MQxNUMv40s=", "dev": true, "requires": { @@ -19444,7 +19972,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true } @@ -20234,7 +20762,7 @@ }, "gulp-stylelint": { "version": "7.0.0", - "resolved": "http://registry.npmjs.org/gulp-stylelint/-/gulp-stylelint-7.0.0.tgz", + "resolved": "https://registry.npmjs.org/gulp-stylelint/-/gulp-stylelint-7.0.0.tgz", "integrity": "sha512-0PI+tNTzaJz5+qO3i9Jyd04ZPSb+NCN7bZ2GaIArvbQpuyJha9p3lpWxPG+XJtrVT42bIiyLeYKPnLe7uW4dQQ==", "dev": true, "requires": { @@ -21115,7 +21643,7 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true } @@ -21339,7 +21867,7 @@ }, "htmlescape": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/htmlescape/-/htmlescape-1.1.1.tgz", "integrity": "sha1-OgPtwiFLyjtmQko+eVk0lQnLA1E=", "dev": true }, @@ -21439,13 +21967,13 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, "colors": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", "dev": true }, @@ -21505,7 +22033,7 @@ }, "humanize-url": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/humanize-url/-/humanize-url-1.0.1.tgz", "integrity": "sha1-9KuZ4NKIF0yk4eUEB8VfuuRk7/8=", "dev": true, "requires": { @@ -21593,7 +22121,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -22073,7 +22601,7 @@ }, "is-builtin-module": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz", "integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=", "requires": { "builtin-modules": "^1.0.0" @@ -22260,7 +22788,7 @@ }, "is-obj": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz", "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=", "dev": true }, @@ -22657,7 +23185,7 @@ }, "istextorbinary": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/istextorbinary/-/istextorbinary-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/istextorbinary/-/istextorbinary-1.0.2.tgz", "integrity": "sha1-rOGTVNGpoBc+/rEITOD4ewrX3s8=", "dev": true, "requires": { @@ -22889,13 +23417,13 @@ }, "entities": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/entities/-/entities-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz", "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=", "dev": true }, "htmlparser2": { "version": "3.8.3", - "resolved": "http://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz", "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=", "dev": true, "requires": { @@ -22914,7 +23442,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "dev": true, "requires": { @@ -22973,9 +23501,9 @@ "dev": true }, "json-rpc-engine": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", - "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-4.0.0.tgz", + "integrity": "sha512-SvOcy0SFqdMyWH/8muc8G88CvrlzQW4XC0/HA+ukc1nFlj4im3rcwGjivhznBMa5xiEK4EzO404Qi1cB0svU0g==", "requires": { "async": "^2.0.1", "babel-preset-env": "^1.7.0", @@ -23024,6 +23552,15 @@ "async": "^2.4.0" } }, + "babelify": { + "version": "7.3.0", + "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "requires": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, "eth-block-tracker": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/eth-block-tracker/-/eth-block-tracker-2.3.1.tgz", @@ -23096,9 +23633,22 @@ "resolved": "https://registry.npmjs.org/ethjs-schema/-/ethjs-schema-0.1.5.tgz", "integrity": "sha1-WXQOOzl3vNu5sRvDBoIB6Kzquw0=" }, + "json-rpc-engine": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -23153,12 +23703,12 @@ }, "json5": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/json5/-/json5-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" }, "jsonfile": { "version": "2.4.0", - "resolved": "http://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz", "integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=", "requires": { "graceful-fs": "^4.1.6" @@ -23178,7 +23728,7 @@ "dependencies": { "JSONStream": { "version": "0.8.4", - "resolved": "http://registry.npmjs.org/JSONStream/-/JSONStream-0.8.4.tgz", + "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-0.8.4.tgz", "integrity": "sha1-kWV9/m/4V0gwZhMrRhi2Lo9Ih70=", "dev": true, "requires": { @@ -23200,7 +23750,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -23228,7 +23778,7 @@ }, "through2": { "version": "0.6.5", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -23414,19 +23964,19 @@ "dependencies": { "core-js": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.3.0.tgz", "integrity": "sha1-+rg/uwstjchfpjbEudNMdUIMbWU=", "dev": true }, "es6-promise": { "version": "3.0.2", - "resolved": "http://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", + "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-3.0.2.tgz", "integrity": "sha1-AQ1YWEI6XxGJeWZfRkhqlcbuK7Y=", "dev": true }, "readable-stream": { "version": "2.0.6", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.0.6.tgz", "integrity": "sha1-j5A0HmilPMySh4jaz80Rs265t44=", "dev": true, "requires": { @@ -23939,7 +24489,7 @@ }, "kew": { "version": "0.7.0", - "resolved": "http://registry.npmjs.org/kew/-/kew-0.7.0.tgz", + "resolved": "https://registry.npmjs.org/kew/-/kew-0.7.0.tgz", "integrity": "sha1-edk9LTM2PW/dKXCzNdkUGtWR15s=", "dev": true }, @@ -24056,7 +24606,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -24074,7 +24624,7 @@ }, "through2": { "version": "0.6.5", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -24114,7 +24664,7 @@ }, "level-iterator-stream": { "version": "1.3.1", - "resolved": "http://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", + "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz", "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=", "requires": { "inherits": "^2.0.1", @@ -24130,7 +24680,7 @@ }, "readable-stream": { "version": "1.1.14", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", "requires": { "core-util-is": "~1.0.0", @@ -24167,7 +24717,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "requires": { "core-util-is": "~1.0.0", @@ -24256,7 +24806,7 @@ }, "load-json-file": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=", "requires": { "graceful-fs": "^4.1.2", @@ -24268,7 +24818,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -24755,7 +25305,7 @@ }, "magic-string": { "version": "0.22.5", - "resolved": "http://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.22.5.tgz", "integrity": "sha512-oreip9rJZkzvA8Qzk9HFs8fZGF/u7H/gtrE8EN6RjKJ9kh2HlC+yQ2QezifqTZfGyiuAV0dRv5a+y/8gBb1m9w==", "dev": true, "requires": { @@ -24874,7 +25424,7 @@ }, "marked": { "version": "0.3.19", - "resolved": "http://registry.npmjs.org/marked/-/marked-0.3.19.tgz", + "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.19.tgz", "integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==", "dev": true }, @@ -25257,7 +25807,7 @@ }, "media-typer": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=" }, "mem": { @@ -25324,7 +25874,7 @@ }, "meow": { "version": "3.7.0", - "resolved": "http://registry.npmjs.org/meow/-/meow-3.7.0.tgz", + "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz", "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=", "dev": true, "requires": { @@ -25379,7 +25929,7 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, "ethereumjs-util": { @@ -25426,7 +25976,7 @@ }, "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -25544,7 +26094,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" }, "pump": { @@ -25572,6 +26122,28 @@ "safe-event-emitter": "^1.0.1" }, "dependencies": { + "babelify": { + "version": "7.3.0", + "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", + "requires": { + "babel-core": "^6.0.14", + "object-assign": "^4.0.0" + } + }, + "json-rpc-engine": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/json-rpc-engine/-/json-rpc-engine-3.8.0.tgz", + "integrity": "sha512-6QNcvm2gFuuK4TKU1uwfH0Qd/cOSb9c1lls0gbnIhciktIUQJwz6NQNAW4B1KiGPenv7IKu97V222Yo1bNhGuA==", + "requires": { + "async": "^2.0.1", + "babel-preset-env": "^1.7.0", + "babelify": "^7.3.0", + "json-rpc-error": "^2.0.0", + "promise-to-callback": "^1.0.0", + "safe-event-emitter": "^1.0.1" + } + }, "loglevel": { "version": "1.6.1", "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz", @@ -25772,7 +26344,7 @@ }, "mkdirp": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", "requires": { "minimist": "0.0.8" @@ -26137,7 +26709,7 @@ "dependencies": { "async": { "version": "1.5.2", - "resolved": "http://registry.npmjs.org/async/-/async-1.5.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", "dev": true }, @@ -26172,7 +26744,7 @@ }, "ncp": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz", "integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=", "dev": true }, @@ -26224,7 +26796,7 @@ }, "next-tick": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", "dev": true }, @@ -26358,7 +26930,7 @@ "dependencies": { "semver": { "version": "5.3.0", - "resolved": "http://registry.npmjs.org/semver/-/semver-5.3.0.tgz", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.3.0.tgz", "integrity": "sha1-myzl094C0XxgEq0yaqa00M9U+U8=", "dev": true } @@ -26396,7 +26968,7 @@ "dependencies": { "buffer": { "version": "4.9.1", - "resolved": "http://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", "requires": { "base64-js": "^1.0.2", @@ -26555,7 +27127,7 @@ }, "node-status-codes": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/node-status-codes/-/node-status-codes-1.0.0.tgz", "integrity": "sha1-WuVUHQJGRdMqWPzdyc7s6nrjrC8=", "dev": true }, @@ -28236,7 +28808,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -28359,12 +28931,12 @@ }, "os-homedir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" }, "os-locale": { "version": "1.4.0", - "resolved": "http://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz", "integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=", "requires": { "lcid": "^1.0.0" @@ -28382,7 +28954,7 @@ }, "os-tmpdir": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" }, "osenv": { @@ -28672,7 +29244,7 @@ }, "path-is-absolute": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-is-inside": { @@ -28730,7 +29302,7 @@ "dependencies": { "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=" } } @@ -28743,7 +29315,7 @@ }, "pause-stream": { "version": "0.0.11", - "resolved": "http://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", + "resolved": "https://registry.npmjs.org/pause-stream/-/pause-stream-0.0.11.tgz", "integrity": "sha1-/lo0sMvOErWqaitAPuLnO2AvFEU=", "dev": true, "requires": { @@ -29238,7 +29810,7 @@ }, "postcss-calc": { "version": "5.3.1", - "resolved": "http://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz", "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=", "dev": true, "requires": { @@ -29375,7 +29947,7 @@ }, "postcss-discard-comments": { "version": "2.0.4", - "resolved": "http://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz", "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=", "dev": true, "requires": { @@ -29463,7 +30035,7 @@ }, "postcss-discard-empty": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz", "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=", "dev": true, "requires": { @@ -29507,7 +30079,7 @@ }, "postcss-discard-overridden": { "version": "0.1.1", - "resolved": "http://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz", "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=", "dev": true, "requires": { @@ -29551,7 +30123,7 @@ }, "postcss-discard-unused": { "version": "2.2.3", - "resolved": "http://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", + "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz", "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=", "dev": true, "requires": { @@ -29649,7 +30221,7 @@ }, "postcss-less": { "version": "0.14.0", - "resolved": "http://registry.npmjs.org/postcss-less/-/postcss-less-0.14.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-0.14.0.tgz", "integrity": "sha1-xjGwicbM5CK5oQ86lY0r7dOBkyQ=", "dev": true, "requires": { @@ -29756,7 +30328,7 @@ }, "postcss-merge-idents": { "version": "2.1.7", - "resolved": "http://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", + "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz", "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=", "dev": true, "requires": { @@ -29910,7 +30482,7 @@ }, "postcss-minify-font-values": { "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz", "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=", "dev": true, "requires": { @@ -29956,7 +30528,7 @@ }, "postcss-minify-gradients": { "version": "1.0.5", - "resolved": "http://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz", "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=", "dev": true, "requires": { @@ -30001,7 +30573,7 @@ }, "postcss-minify-params": { "version": "1.2.2", - "resolved": "http://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz", "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=", "dev": true, "requires": { @@ -30048,7 +30620,7 @@ }, "postcss-minify-selectors": { "version": "2.1.1", - "resolved": "http://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz", "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=", "dev": true, "requires": { @@ -30134,7 +30706,7 @@ }, "postcss-normalize-charset": { "version": "1.1.1", - "resolved": "http://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz", "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=", "dev": true, "requires": { @@ -30178,7 +30750,7 @@ }, "postcss-normalize-url": { "version": "3.0.8", - "resolved": "http://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz", "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=", "dev": true, "requires": { @@ -30307,7 +30879,7 @@ }, "postcss-reduce-idents": { "version": "2.4.0", - "resolved": "http://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz", "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=", "dev": true, "requires": { @@ -30352,7 +30924,7 @@ }, "postcss-reduce-initial": { "version": "1.0.1", - "resolved": "http://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz", "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=", "dev": true, "requires": { @@ -30396,7 +30968,7 @@ }, "postcss-reduce-transforms": { "version": "1.0.4", - "resolved": "http://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz", "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=", "dev": true, "requires": { @@ -30603,7 +31175,7 @@ }, "postcss-svgo": { "version": "2.1.6", - "resolved": "http://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz", "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=", "dev": true, "requires": { @@ -30650,7 +31222,7 @@ }, "postcss-unique-selectors": { "version": "2.0.2", - "resolved": "http://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz", "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=", "dev": true, "requires": { @@ -30702,7 +31274,7 @@ }, "postcss-zindex": { "version": "2.2.0", - "resolved": "http://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", + "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz", "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=", "dev": true, "requires": { @@ -30795,7 +31367,7 @@ }, "pretty-hrtime": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz", "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=", "dev": true }, @@ -31104,7 +31676,7 @@ "dependencies": { "chokidar": { "version": "1.6.1", - "resolved": "http://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.6.1.tgz", "integrity": "sha1-L0RHq16W5Q+z14n9kNTHLg5McMI=", "dev": true, "requires": { @@ -31121,7 +31693,7 @@ }, "commander": { "version": "2.9.0", - "resolved": "http://registry.npmjs.org/commander/-/commander-2.9.0.tgz", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.9.0.tgz", "integrity": "sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=", "dev": true, "requires": { @@ -31246,7 +31818,7 @@ "dependencies": { "inline-style-prefixer": { "version": "2.0.5", - "resolved": "http://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz", + "resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz", "integrity": "sha1-wVPH6I/YT+9cYC6VqBaLJ3BnH+c=", "dev": true, "requires": { @@ -32147,7 +32719,7 @@ }, "reduce-css-calc": { "version": "1.3.0", - "resolved": "http://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", + "resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz", "integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=", "dev": true, "requires": { @@ -32274,7 +32846,7 @@ }, "regexpp": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz", "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw==", "dev": true }, @@ -32290,7 +32862,7 @@ }, "regjsgen": { "version": "0.2.0", - "resolved": "http://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" }, "regjsparser": { @@ -32589,7 +33161,7 @@ }, "require-uncached": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz", "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=", "dev": true, "requires": { @@ -32759,7 +33331,7 @@ "dependencies": { "convert-source-map": { "version": "0.3.5", - "resolved": "http://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=", "dev": true } @@ -32913,7 +33485,7 @@ }, "safe-regex": { "version": "1.1.0", - "resolved": "http://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", "dev": true, "requires": { @@ -32940,7 +33512,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -33338,7 +33910,7 @@ }, "shasum": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/shasum/-/shasum-1.0.2.tgz", "integrity": "sha1-5wEjENj0F/TetXEhUOVni4euVl8=", "dev": true, "requires": { @@ -34449,7 +35021,7 @@ "dependencies": { "fs-extra": { "version": "0.30.0", - "resolved": "http://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.30.0.tgz", "integrity": "sha1-8jP/zAjU2n1DLapEl3aYnbHfk/A=", "requires": { "graceful-fs": "^4.1.2", @@ -34461,7 +35033,7 @@ }, "yargs": { "version": "4.8.1", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-4.8.1.tgz", "integrity": "sha1-wMQpJMpKqmsObaFznfshZDn53cA=", "requires": { "cliui": "^3.2.0", @@ -34482,7 +35054,7 @@ }, "yargs-parser": { "version": "2.4.1", - "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-2.4.1.tgz", "integrity": "sha1-hVaN488VD/SfpRgl8DqMiA3cxcQ=", "requires": { "camelcase": "^3.0.0", @@ -34583,7 +35155,7 @@ }, "split": { "version": "0.3.3", - "resolved": "http://registry.npmjs.org/split/-/split-0.3.3.tgz", + "resolved": "https://registry.npmjs.org/split/-/split-0.3.3.tgz", "integrity": "sha1-zQ7qXmOiEd//frDwkcQTPi0N0o8=", "dev": true, "requires": { @@ -34637,7 +35209,7 @@ }, "readable-stream": { "version": "1.0.34", - "resolved": "http://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz", "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=", "dev": true, "requires": { @@ -34655,7 +35227,7 @@ }, "through2": { "version": "0.6.5", - "resolved": "http://registry.npmjs.org/through2/-/through2-0.6.5.tgz", + "resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz", "integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=", "dev": true, "requires": { @@ -34853,7 +35425,7 @@ "dependencies": { "ansi-regex": { "version": "0.2.1", - "resolved": "http://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-0.2.1.tgz", "integrity": "sha1-DY6UaWej2BQ/k+JOKYUl/BsiNfk=", "dev": true }, @@ -34865,7 +35437,7 @@ }, "chalk": { "version": "0.5.1", - "resolved": "http://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.5.1.tgz", "integrity": "sha1-Zjs6ZItotV0EaQ1JFnqoN4WPIXQ=", "dev": true, "requires": { @@ -34887,7 +35459,7 @@ }, "strip-ansi": { "version": "0.3.0", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.3.0.tgz", "integrity": "sha1-JfSOoiynkYfzF0pNuHWTR7sSYiA=", "dev": true, "requires": { @@ -35144,7 +35716,7 @@ }, "strip-ansi": { "version": "3.0.1", - "resolved": "http://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", "requires": { "ansi-regex": "^2.0.0" @@ -35185,7 +35757,7 @@ }, "strip-eof": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, @@ -35575,7 +36147,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -35850,7 +36422,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -35875,7 +36447,7 @@ "dependencies": { "babelify": { "version": "7.3.0", - "resolved": "http://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", + "resolved": "https://registry.npmjs.org/babelify/-/babelify-7.3.0.tgz", "integrity": "sha1-qlau3nBn/XvVSWZu4W3ChQh+iOU=", "requires": { "babel-core": "^6.0.14", @@ -35920,7 +36492,7 @@ "dependencies": { "css-color-names": { "version": "0.0.3", - "resolved": "http://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.3.tgz", "integrity": "sha1-3gzvFvTYqoIioyDVttfpu62nufY=", "dev": true } @@ -36055,7 +36627,7 @@ }, "tar": { "version": "2.2.1", - "resolved": "http://registry.npmjs.org/tar/-/tar-2.2.1.tgz", + "resolved": "https://registry.npmjs.org/tar/-/tar-2.2.1.tgz", "integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=", "dev": true, "requires": { @@ -36222,7 +36794,7 @@ }, "text-encoding": { "version": "0.6.4", - "resolved": "http://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", + "resolved": "https://registry.npmjs.org/text-encoding/-/text-encoding-0.6.4.tgz", "integrity": "sha1-45mpgiV6J22uQou5KEXLcb3CbRk=" }, "text-table": { @@ -36238,7 +36810,7 @@ }, "textextensions": { "version": "1.0.2", - "resolved": "http://registry.npmjs.org/textextensions/-/textextensions-1.0.2.tgz", + "resolved": "https://registry.npmjs.org/textextensions/-/textextensions-1.0.2.tgz", "integrity": "sha1-ZUhjk+4fK7A5pgy7oFsLaL2VAdI=", "dev": true }, @@ -36297,12 +36869,12 @@ }, "through": { "version": "2.3.8", - "resolved": "http://registry.npmjs.org/through/-/through-2.3.8.tgz", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=" }, "through2": { "version": "2.0.3", - "resolved": "http://registry.npmjs.org/through2/-/through2-2.0.3.tgz", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz", "integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=", "requires": { "readable-stream": "^2.1.5", @@ -36809,7 +37381,7 @@ }, "yargs": { "version": "3.10.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz", "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=", "dev": true, "requires": { @@ -37340,7 +37912,7 @@ }, "utf8": { "version": "2.1.2", - "resolved": "http://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" }, "util": { @@ -37385,7 +37957,7 @@ "dependencies": { "async": { "version": "0.9.2", - "resolved": "http://registry.npmjs.org/async/-/async-0.9.2.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz", "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0=", "dev": true }, @@ -37569,7 +38141,7 @@ }, "pify": { "version": "2.3.0", - "resolved": "http://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", "dev": true }, @@ -37762,6 +38334,7 @@ "resolved": "https://registry.npmjs.org/web3/-/web3-0.20.3.tgz", "integrity": "sha1-yqRDc9yIFayHZ73ba6cwc5ZMqos=", "requires": { + "bignumber.js": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", "crypto-js": "^3.1.4", "utf8": "^2.1.1", "xhr2": "*", @@ -37770,7 +38343,7 @@ "dependencies": { "bignumber.js": { "version": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934", - "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git#57692b3ecfc98bbdd6b3a516cb2353652ea49934" + "from": "git+https://github.com/frozeman/bignumber.js-nolookahead.git" } } }, @@ -38067,13 +38640,13 @@ "dependencies": { "async": { "version": "1.0.0", - "resolved": "http://registry.npmjs.org/async/-/async-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/async/-/async-1.0.0.tgz", "integrity": "sha1-+PwEyjoTeErenhZBr5hXjPvWR6k=", "dev": true }, "colors": { "version": "1.0.3", - "resolved": "http://registry.npmjs.org/colors/-/colors-1.0.3.tgz", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz", "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=", "dev": true }, @@ -38112,7 +38685,7 @@ }, "wrap-ansi": { "version": "2.1.0", - "resolved": "http://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", "requires": { "string-width": "^1.0.1", @@ -38193,6 +38766,15 @@ "resolved": "https://registry.npmjs.org/xhr2/-/xhr2-0.1.3.tgz", "integrity": "sha1-y/xHWaabSoiOeM9PILBRA4dXvRE=" }, + "xhr2-cookies": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/xhr2-cookies/-/xhr2-cookies-1.1.0.tgz", + "integrity": "sha1-fXdEnQmZGX8VXLc7I99yUF7YnUg=", + "dev": true, + "requires": { + "cookiejar": "^2.1.1" + } + }, "xml-name-validator": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-2.0.1.tgz", @@ -38211,7 +38793,7 @@ }, "xmlbuilder": { "version": "9.0.7", - "resolved": "http://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz", "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0=", "dev": true }, @@ -38262,7 +38844,7 @@ }, "yargs": { "version": "6.6.0", - "resolved": "http://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-6.6.0.tgz", "integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=", "requires": { "camelcase": "^3.0.0", @@ -38282,7 +38864,7 @@ }, "yargs-parser": { "version": "4.2.1", - "resolved": "http://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-4.2.1.tgz", "integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=", "requires": { "camelcase": "^3.0.0" From 1fbdce8916151df2b31eebc5de29a1365e5dadff Mon Sep 17 00:00:00 2001 From: Dan J Miller Date: Mon, 10 Dec 2018 18:21:00 -0330 Subject: [PATCH 62/64] Improve ux for low gas price set (#5862) * Show user warning if they set gas price below safelow minimum, error if 0. * Properly cache basic price estimate data. * Default retry price to recommended price if original price was 0x0 * Use mock fetch in send-new-ui integration tests. --- development/states/send-edit.json | 1 + development/states/send-new-ui.json | 4 +- test/e2e/beta/metamask-beta-ui.spec.js | 3 +- test/integration/lib/send-new-ui.js | 16 ++ .../advanced-tab-content.component.js | 103 +++++++++--- .../advanced-tab-content/index.scss | 14 +- .../advanced-tab-content-component.test.js | 157 ++++++++++++++---- .../gas-modal-page-container.component.js | 10 +- .../gas-modal-page-container.container.js | 5 +- ...gas-modal-page-container-component.test.js | 1 + ...gas-modal-page-container-container.test.js | 4 +- .../transaction-list-item.container.js | 4 +- ui/app/ducks/gas.duck.js | 43 ++++- ui/app/ducks/tests/gas-duck.test.js | 62 ++++++- ui/app/selectors/custom-gas.js | 36 ++++ 15 files changed, 395 insertions(+), 68 deletions(-) diff --git a/development/states/send-edit.json b/development/states/send-edit.json index a519f30b49fc..7951b06cfd05 100644 --- a/development/states/send-edit.json +++ b/development/states/send-edit.json @@ -197,6 +197,7 @@ }, "basicEstimateIsLoading": false, "gasEstimatesLoading": false, + "basicPriceAndTimeEstimates": [], "priceAndTimeEstimates": [ { "expectedTime": "1374.1168296452973076627", diff --git a/development/states/send-new-ui.json b/development/states/send-new-ui.json index 479b6d3e3e25..fd048596c919 100644 --- a/development/states/send-new-ui.json +++ b/development/states/send-new-ui.json @@ -139,7 +139,8 @@ "send": { "fromDropdownOpen": false, "toDropdownOpen": false, - "errors": {} + "errors": {}, + "gasButtonGroupShown": true }, "confirmTransaction": { "txData": {}, @@ -179,6 +180,7 @@ }, "basicEstimateIsLoading": false, "gasEstimatesLoading": false, + "basicPriceAndTimeEstimates": [], "priceAndTimeEstimates": [ { "expectedTime": "1374.1168296452973076627", diff --git a/test/e2e/beta/metamask-beta-ui.spec.js b/test/e2e/beta/metamask-beta-ui.spec.js index c5b7f40e4a43..9980e874f67c 100644 --- a/test/e2e/beta/metamask-beta-ui.spec.js +++ b/test/e2e/beta/metamask-beta-ui.spec.js @@ -69,6 +69,7 @@ describe('MetaMask', function () { beforeEach(async function () { await driver.executeScript( + 'window.origFetch = window.fetch.bind(window);' + 'window.fetch = ' + '(...args) => { ' + 'if (args[0] === "https://ethgasstation.info/json/ethgasAPI.json") { return ' + @@ -77,7 +78,7 @@ describe('MetaMask', function () { 'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.ethGasPredictTable + '\')) }); } else if ' + '(args[0] === "https://dev.blockscale.net/api/gasexpress.json") { return ' + 'Promise.resolve({ json: () => Promise.resolve(JSON.parse(\'' + fetchMockResponses.gasExpress + '\')) }); } ' + - 'return window.fetch(...args); }' + 'return window.origFetch(...args); }' ) }) diff --git a/test/integration/lib/send-new-ui.js b/test/integration/lib/send-new-ui.js index 98e5f549b954..1acd85a3528a 100644 --- a/test/integration/lib/send-new-ui.js +++ b/test/integration/lib/send-new-ui.js @@ -4,6 +4,7 @@ const { queryAsync, findAsync, } = require('../../lib/util') +const fetchMockResponses = require('../../e2e/beta/fetch-mocks.js') QUnit.module('new ui send flow') @@ -22,6 +23,19 @@ global.ethQuery = { global.ethereumProvider = {} async function runSendFlowTest (assert, done) { + const tempFetch = global.fetch + + global.fetch = (...args) => { + if (args[0] === 'https://ethgasstation.info/json/ethgasAPI.json') { + return Promise.resolve({ json: () => Promise.resolve(JSON.parse(fetchMockResponses.ethGasBasic)) }) + } else if (args[0] === 'https://ethgasstation.info/json/predictTable.json') { + return Promise.resolve({ json: () => Promise.resolve(JSON.parse(fetchMockResponses.ethGasPredictTable)) }) + } else if (args[0] === 'https://dev.blockscale.net/api/gasexpress.json') { + return Promise.resolve({ json: () => Promise.resolve(JSON.parse(fetchMockResponses.gasExpress)) }) + } + return window.fetch(...args) + } + console.log('*** start runSendFlowTest') const selectState = await queryAsync($, 'select') selectState.val('send new ui') @@ -129,6 +143,8 @@ async function runSendFlowTest (assert, done) { const cancelButtonInEdit = await queryAsync($, '.btn-default.btn--large.page-container__footer-button') cancelButtonInEdit[0].click() + + global.fetch = tempFetch // sendButtonInEdit[0].click() // // TODO: Need a way to mock background so that we can test correct transition from editing to confirm diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js index ba738ff750f9..7c3142d0d3cb 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/advanced-tab-content.component.js @@ -21,6 +21,8 @@ export default class AdvancedTabContent extends Component { timeRemaining: PropTypes.string, gasChartProps: PropTypes.object, insufficientBalance: PropTypes.bool, + customPriceIsSafe: PropTypes.bool, + isSpeedUp: PropTypes.bool, } constructor (props) { @@ -37,27 +39,62 @@ export default class AdvancedTabContent extends Component { } } - gasInput (value, onChange, min, insufficientBalance, showGWEI) { + gasInputError ({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) { + let errorText + let errorType + let isInError = true + + + if (insufficientBalance) { + errorText = 'Insufficient Balance' + errorType = 'error' + } else if (labelKey === 'gasPrice' && isSpeedUp && value === 0) { + errorText = 'Zero gas price on speed up' + errorType = 'error' + } else if (labelKey === 'gasPrice' && !customPriceIsSafe) { + errorText = 'Gas Price Extremely Low' + errorType = 'warning' + } else { + isInError = false + } + + return { + isInError, + errorText, + errorType, + } + } + + gasInput ({ labelKey, value, onChange, insufficientBalance, showGWEI, customPriceIsSafe, isSpeedUp }) { + const { + isInError, + errorText, + errorType, + } = this.gasInputError({ labelKey, insufficientBalance, customPriceIsSafe, isSpeedUp, value }) + return (
onChange(Number(event.target.value))} />
onChange(value + 1)}>
onChange(value - 1)}>
- {insufficientBalance &&
- Insufficient Balance -
} + { isInError + ?
+ { errorText } +
+ : null }
) } @@ -83,23 +120,45 @@ export default class AdvancedTabContent extends Component { ) } - renderGasEditRow (labelKey, ...gasInputArgs) { + renderGasEditRow (gasInputArgs) { return (
- { this.context.t(labelKey) } + { this.context.t(gasInputArgs.labelKey) } { this.infoButton(() => {}) }
- { this.gasInput(...gasInputArgs) } + { this.gasInput(gasInputArgs) }
) } - renderGasEditRows (customGasPrice, updateCustomGasPrice, customGasLimit, updateCustomGasLimit, insufficientBalance) { + renderGasEditRows ({ + customGasPrice, + updateCustomGasPrice, + customGasLimit, + updateCustomGasLimit, + insufficientBalance, + customPriceIsSafe, + isSpeedUp, + }) { return (
- { this.renderGasEditRow('gasPrice', customGasPrice, updateCustomGasPrice, customGasPrice, insufficientBalance, true) } - { this.renderGasEditRow('gasLimit', customGasLimit, this.onChangeGasLimit, customGasLimit, insufficientBalance) } + { this.renderGasEditRow({ + labelKey: 'gasPrice', + value: customGasPrice, + onChange: updateCustomGasPrice, + insufficientBalance, + customPriceIsSafe, + showGWEI: true, + isSpeedUp, + }) } + { this.renderGasEditRow({ + labelKey: 'gasLimit', + value: customGasLimit, + onChange: this.onChangeGasLimit, + insufficientBalance, + customPriceIsSafe, + }) }
) } @@ -115,19 +174,23 @@ export default class AdvancedTabContent extends Component { totalFee, gasChartProps, gasEstimatesLoading, + customPriceIsSafe, + isSpeedUp, } = this.props return (
{ this.renderDataSummary(totalFee, timeRemaining) }
- { this.renderGasEditRows( - customGasPrice, - updateCustomGasPrice, - customGasLimit, - updateCustomGasLimit, - insufficientBalance - ) } + { this.renderGasEditRows({ + customGasPrice, + updateCustomGasPrice, + customGasLimit, + updateCustomGasLimit, + insufficientBalance, + customPriceIsSafe, + isSpeedUp, + }) }
Live Gas Price Predictions
{!gasEstimatesLoading ? diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss index 88c69faf4dfd..53cb84791633 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/index.scss @@ -102,11 +102,15 @@ } } - &__insufficient-balance { + &__error-text { font-size: 12px; color: red; } + &__warning-text { + font-size: 12px; + color: orange; + } &__input-wrapper { position: relative; @@ -128,6 +132,10 @@ border: 1px solid $red; } + &__input--warning { + border: 1px solid $orange; + } + &__input-arrows { position: absolute; top: 7px; @@ -169,6 +177,10 @@ border: 1px solid $red; } + &__input-arrows--warning { + border: 1px solid $orange; + } + input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; -moz-appearance: none; diff --git a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js index d6920454d06f..00242e4303b8 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/advanced-tab-content/tests/advanced-tab-content-component.test.js @@ -16,6 +16,7 @@ sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRow') sinon.spy(AdvancedTabContent.prototype, 'gasInput') sinon.spy(AdvancedTabContent.prototype, 'renderGasEditRows') sinon.spy(AdvancedTabContent.prototype, 'renderDataSummary') +sinon.spy(AdvancedTabContent.prototype, 'gasInputError') describe('AdvancedTabContent Component', function () { let wrapper @@ -29,6 +30,8 @@ describe('AdvancedTabContent Component', function () { timeRemaining={21500} totalFee={'$0.25'} insufficientBalance={false} + customPriceIsSafe={true} + isSpeedUp={false} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) @@ -86,9 +89,15 @@ describe('AdvancedTabContent Component', function () { it('should call renderGasEditRows with the expected params', () => { assert.equal(AdvancedTabContent.prototype.renderGasEditRows.callCount, 1) const renderGasEditRowArgs = AdvancedTabContent.prototype.renderGasEditRows.getCall(0).args - assert.deepEqual(renderGasEditRowArgs, [ - 11, propsMethodSpies.updateCustomGasPrice, 23456, propsMethodSpies.updateCustomGasLimit, false, - ]) + assert.deepEqual(renderGasEditRowArgs, [{ + customGasPrice: 11, + customGasLimit: 23456, + insufficientBalance: false, + customPriceIsSafe: true, + updateCustomGasPrice: propsMethodSpies.updateCustomGasPrice, + updateCustomGasLimit: propsMethodSpies.updateCustomGasLimit, + isSpeedUp: false, + }]) }) }) @@ -124,9 +133,10 @@ describe('AdvancedTabContent Component', function () { beforeEach(() => { AdvancedTabContent.prototype.gasInput.resetHistory() - gasEditRow = shallow(wrapper.instance().renderGasEditRow( - 'mockLabelKey', 'argA', 'argB' - )) + gasEditRow = shallow(wrapper.instance().renderGasEditRow({ + labelKey: 'mockLabelKey', + someArg: 'argA', + })) }) it('should render the gas-edit-row root node', () => { @@ -149,7 +159,7 @@ describe('AdvancedTabContent Component', function () { it('should call this.gasInput with the correct args', () => { const gasInputSpyArgs = AdvancedTabContent.prototype.gasInput.args - assert.deepEqual(gasInputSpyArgs[0], [ 'argA', 'argB' ]) + assert.deepEqual(gasInputSpyArgs[0], [ { labelKey: 'mockLabelKey', someArg: 'argA' } ]) }) }) @@ -188,12 +198,22 @@ describe('AdvancedTabContent Component', function () { it('should call this.renderGasEditRow twice, with the expected args', () => { const renderGasEditRowSpyArgs = AdvancedTabContent.prototype.renderGasEditRow.args assert.equal(renderGasEditRowSpyArgs.length, 2) - assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [ - 'gasPrice', 'mockGasPrice', () => 'mockUpdateCustomGasPriceReturn', 'mockGasPrice', false, true, - ].map(String)) - assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [ - 'gasLimit', 'mockGasLimit', () => 'mockOnChangeGasLimit', 'mockGasLimit', false, - ].map(String)) + assert.deepEqual(renderGasEditRowSpyArgs[0].map(String), [{ + labelKey: 'gasPrice', + value: 'mockGasLimit', + onChange: () => 'mockOnChangeGasLimit', + insufficientBalance: false, + customPriceIsSafe: true, + showGWEI: true, + }].map(String)) + assert.deepEqual(renderGasEditRowSpyArgs[1].map(String), [{ + labelKey: 'gasPrice', + value: 'mockGasPrice', + onChange: () => 'mockUpdateCustomGasPriceReturn', + insufficientBalance: false, + customPriceIsSafe: true, + showGWEI: true, + }].map(String)) }) }) @@ -219,13 +239,16 @@ describe('AdvancedTabContent Component', function () { beforeEach(() => { AdvancedTabContent.prototype.renderGasEditRow.resetHistory() - gasInput = shallow(wrapper.instance().gasInput( - 321, - value => value + 7, - 0, - false, - 8 - )) + AdvancedTabContent.prototype.gasInputError.resetHistory() + gasInput = shallow(wrapper.instance().gasInput({ + labelKey: 'gasPrice', + value: 321, + onChange: value => value + 7, + insufficientBalance: false, + showGWEI: true, + customPriceIsSafe: true, + isSpeedUp: false, + })) }) it('should render the input-wrapper root node', () => { @@ -237,12 +260,6 @@ describe('AdvancedTabContent Component', function () { assert(gasInput.children().at(0).hasClass('advanced-tab__gas-edit-row__input')) }) - it('should pass the correct value min and precision props to the input', () => { - const inputProps = gasInput.find('input').props() - assert.equal(inputProps.min, 0) - assert.equal(inputProps.value, 321) - }) - it('should call the passed onChange method with the value of the input onChange event', () => { const inputOnChange = gasInput.find('input').props().onChange assert.equal(inputOnChange({ target: { value: 8} }), 15) @@ -256,18 +273,92 @@ describe('AdvancedTabContent Component', function () { }) it('should call onChange with the value incremented decremented when its onchange method is called', () => { - gasInput = shallow(wrapper.instance().gasInput( - 321, - value => value + 7, - 0, - 8, - false - )) const upArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(0) assert.equal(upArrow.props().onClick(), 329) const downArrow = gasInput.find('.advanced-tab__gas-edit-row__input-arrows__i-wrap').at(1) assert.equal(downArrow.props().onClick(), 327) }) + + it('should call gasInputError with the expected params', () => { + assert.equal(AdvancedTabContent.prototype.gasInputError.callCount, 1) + const gasInputErrorArgs = AdvancedTabContent.prototype.gasInputError.getCall(0).args + assert.deepEqual(gasInputErrorArgs, [{ + labelKey: 'gasPrice', + insufficientBalance: false, + customPriceIsSafe: true, + value: 321, + isSpeedUp: false, + }]) + }) + }) + + describe('gasInputError()', () => { + let gasInputError + + beforeEach(() => { + AdvancedTabContent.prototype.renderGasEditRow.resetHistory() + gasInputError = wrapper.instance().gasInputError({ + labelKey: '', + insufficientBalance: false, + customPriceIsSafe: true, + isSpeedUp: false, + }) + }) + + it('should return an insufficientBalance error', () => { + const gasInputError = wrapper.instance().gasInputError({ + labelKey: 'gasPrice', + insufficientBalance: true, + customPriceIsSafe: true, + isSpeedUp: false, + value: 1, + }) + assert.deepEqual(gasInputError, { + isInError: true, + errorText: 'Insufficient Balance', + errorType: 'error', + }) + }) + + it('should return a zero gas on retry error', () => { + const gasInputError = wrapper.instance().gasInputError({ + labelKey: 'gasPrice', + insufficientBalance: false, + customPriceIsSafe: false, + isSpeedUp: true, + value: 0, + }) + assert.deepEqual(gasInputError, { + isInError: true, + errorText: 'Zero gas price on speed up', + errorType: 'error', + }) + }) + + it('should return a low gas warning', () => { + const gasInputError = wrapper.instance().gasInputError({ + labelKey: 'gasPrice', + insufficientBalance: false, + customPriceIsSafe: false, + isSpeedUp: false, + value: 1, + }) + assert.deepEqual(gasInputError, { + isInError: true, + errorText: 'Gas Price Extremely Low', + errorType: 'warning', + }) + }) + + it('should return isInError false if there is no error', () => { + gasInputError = wrapper.instance().gasInputError({ + labelKey: 'gasPrice', + insufficientBalance: false, + customPriceIsSafe: true, + value: 1, + }) + assert.equal(gasInputError.isInError, false) + }) }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js index be91bef0f818..64c2be353fd0 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.component.js @@ -35,6 +35,9 @@ export default class GasModalPageContainer extends Component { PropTypes.string, PropTypes.number, ]), + customPriceIsSafe: PropTypes.bool, + isSpeedUp: PropTypes.bool, + disableSave: PropTypes.bool, } state = {} @@ -69,6 +72,8 @@ export default class GasModalPageContainer extends Component { currentTimeEstimate, insufficientBalance, gasEstimatesLoading, + customPriceIsSafe, + isSpeedUp, }) { const { transactionFee } = this.props return ( @@ -83,6 +88,8 @@ export default class GasModalPageContainer extends Component { gasChartProps={gasChartProps} insufficientBalance={insufficientBalance} gasEstimatesLoading={gasEstimatesLoading} + customPriceIsSafe={customPriceIsSafe} + isSpeedUp={isSpeedUp} /> ) } @@ -153,6 +160,7 @@ export default class GasModalPageContainer extends Component { onSubmit, customModalGasPriceInHex, customModalGasLimitInHex, + disableSave, ...tabProps } = this.props @@ -162,7 +170,7 @@ export default class GasModalPageContainer extends Component { title={this.context.t('customGas')} subtitle={this.context.t('customGasSubTitle')} tabsComponent={this.renderTabs(infoRowProps, tabProps)} - disabled={tabProps.insufficientBalance} + disabled={disableSave} onCancel={() => cancelAndClose()} onClose={() => cancelAndClose()} onSubmit={() => { diff --git a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js index c619a0988088..dde0f2b94e31 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/gas-modal-page-container.container.js @@ -40,6 +40,7 @@ import { getEstimatedGasTimes, getRenderableBasicEstimateData, getBasicGasEstimateBlockTime, + isCustomPriceSafe, } from '../../../selectors/custom-gas' import { submittedPendingTransactionsSelector, @@ -107,6 +108,7 @@ const mapStateToProps = (state, ownProps) => { newTotalFiat, currentTimeEstimate: getRenderableTimeEstimate(customGasPrice, gasPrices, estimatedTimes), blockTime: getBasicGasEstimateBlockTime(state), + customPriceIsSafe: isCustomPriceSafe(state), gasPriceButtonGroupProps: { buttonDataLoading, defaultActiveButtonIndex: getDefaultActiveButtonIndex(gasButtonInfo, customModalGasPriceInHex), @@ -167,7 +169,7 @@ const mapDispatchToProps = dispatch => { } const mergeProps = (stateProps, dispatchProps, ownProps) => { - const { gasPriceButtonGroupProps, isConfirm, isSpeedUp, txId } = stateProps + const { gasPriceButtonGroupProps, isConfirm, txId, isSpeedUp, insufficientBalance, customGasPrice } = stateProps const { updateCustomGasPrice: dispatchUpdateCustomGasPrice, hideGasButtonGroup: dispatchHideGasButtonGroup, @@ -208,6 +210,7 @@ const mergeProps = (stateProps, dispatchProps, ownProps) => { dispatchHideSidebar() } }, + disableSave: insufficientBalance || (isSpeedUp && customGasPrice === 0), } } diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js index 2ba2fa9e7abf..f068c40d0f40 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-component.test.js @@ -78,6 +78,7 @@ describe('GasModalPageContainer Component', function () { customGasPriceInHex={'mockCustomGasPriceInHex'} customGasLimitInHex={'mockCustomGasLimitInHex'} insufficientBalance={false} + disableSave={false} />, { context: { t: (str1, str2) => str2 ? str1 + str2 : str1 } }) }) diff --git a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js index 512832866f9c..077ec471d4ec 100644 --- a/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js +++ b/ui/app/components/gas-customization/gas-modal-page-container/tests/gas-modal-page-container-container.test.js @@ -75,6 +75,7 @@ describe('gas-modal-page-container container', () => { gas: { basicEstimates: { blockTime: 12, + safeLow: 2, }, customData: { limit: 'aaaaaaaa', @@ -107,9 +108,10 @@ describe('gas-modal-page-container container', () => { blockTime: 12, customModalGasLimitInHex: 'aaaaaaaa', customModalGasPriceInHex: 'ffffffff', + customPriceIsSafe: true, gasChartProps: { 'currentPrice': 4.294967295, - estimatedTimes: ['31', '62', '93', '124'], + estimatedTimes: [31, 62, 93, 124], estimatedTimesMax: '31', gasPrices: [3, 4, 5, 6], gasPricesMax: 6, diff --git a/ui/app/components/transaction-list-item/transaction-list-item.container.js b/ui/app/components/transaction-list-item/transaction-list-item.container.js index 73d9d82504b5..e08d3232f91b 100644 --- a/ui/app/components/transaction-list-item/transaction-list-item.container.js +++ b/ui/app/components/transaction-list-item/transaction-list-item.container.js @@ -11,7 +11,7 @@ import { formatDate } from '../../util' import { fetchBasicGasAndTimeEstimates, fetchGasEstimates, - setCustomGasPrice, + setCustomGasPriceForRetry, setCustomGasLimit, } from '../../ducks/gas.duck' @@ -21,7 +21,7 @@ const mapDispatchToProps = dispatch => { fetchGasEstimates: (blockTime) => dispatch(fetchGasEstimates(blockTime)), setSelectedToken: tokenAddress => dispatch(setSelectedToken(tokenAddress)), retryTransaction: (transaction, gasPrice) => { - dispatch(setCustomGasPrice(gasPrice || transaction.txParams.gasPrice)) + dispatch(setCustomGasPriceForRetry(gasPrice || transaction.txParams.gasPrice)) dispatch(setCustomGasLimit(transaction.txParams.gas)) dispatch(showSidebar({ transitionName: 'sidebar-left', diff --git a/ui/app/ducks/gas.duck.js b/ui/app/ducks/gas.duck.js index 83c236d81b2d..ee235a75759b 100644 --- a/ui/app/ducks/gas.duck.js +++ b/ui/app/ducks/gas.duck.js @@ -23,6 +23,7 @@ const SET_CUSTOM_GAS_TOTAL = 'metamask/gas/SET_CUSTOM_GAS_TOTAL' const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' const SET_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' +const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' // TODO: determine if this approach to initState is consistent with conventional ducks pattern const initState = { @@ -49,6 +50,7 @@ const initState = { basicPriceAndTimeEstimates: [], priceAndTimeEstimatesLastRetrieved: 0, basicPriceAndTimeEstimatesLastRetrieved: 0, + basicPriceEstimatesLastRetrieved: 0, errors: {}, } @@ -129,6 +131,11 @@ export default function reducer ({ gas: gasState = initState }, action = {}) { ...newState, basicPriceAndTimeEstimatesLastRetrieved: action.value, } + case SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED: + return { + ...newState, + basicPriceEstimatesLastRetrieved: action.value, + } case RESET_CUSTOM_DATA: return { ...newState, @@ -167,10 +174,17 @@ export function gasEstimatesLoadingFinished () { } export function fetchBasicGasEstimates () { - return (dispatch) => { + return (dispatch, getState) => { + const { + basicPriceEstimatesLastRetrieved, + basicPriceAndTimeEstimates, + } = getState().gas + const timeLastRetrieved = basicPriceEstimatesLastRetrieved || loadLocalStorageData('BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') || 0 + dispatch(basicGasEstimatesLoadingStarted()) - return fetch('https://dev.blockscale.net/api/gasexpress.json', { + const promiseToFetch = Date.now() - timeLastRetrieved > 75000 + ? fetch('https://dev.blockscale.net/api/gasexpress.json', { 'headers': {}, 'referrer': 'https://dev.blockscale.net/api/', 'referrerPolicy': 'no-referrer-when-downgrade', @@ -195,10 +209,24 @@ export function fetchBasicGasEstimates () { blockTime, blockNum, } - dispatch(setBasicGasEstimateData(basicEstimates)) - dispatch(basicGasEstimatesLoadingFinished()) + + const timeRetrieved = Date.now() + dispatch(setBasicPriceEstimatesLastRetrieved(timeRetrieved)) + saveLocalStorageData(timeRetrieved, 'BASIC_PRICE_ESTIMATES_LAST_RETRIEVED') + saveLocalStorageData(basicEstimates, 'BASIC_PRICE_ESTIMATES') + return basicEstimates }) + : Promise.resolve(basicPriceAndTimeEstimates.length + ? basicPriceAndTimeEstimates + : loadLocalStorageData('BASIC_PRICE_ESTIMATES') + ) + + return promiseToFetch.then(basicEstimates => { + dispatch(setBasicGasEstimateData(basicEstimates)) + dispatch(basicGasEstimatesLoadingFinished()) + return basicEstimates + }) } } @@ -473,6 +501,13 @@ export function setBasicApiEstimatesLastRetrieved (retrievalTime) { } } +export function setBasicPriceEstimatesLastRetrieved (retrievalTime) { + return { + type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, + value: retrievalTime, + } +} + export function resetCustomGasState () { return { type: RESET_CUSTOM_GAS_STATE } } diff --git a/ui/app/ducks/tests/gas-duck.test.js b/ui/app/ducks/tests/gas-duck.test.js index bf374c7eca89..3637d8f293aa 100644 --- a/ui/app/ducks/tests/gas-duck.test.js +++ b/ui/app/ducks/tests/gas-duck.test.js @@ -20,6 +20,7 @@ const { setCustomGasErrors, resetCustomGasState, fetchBasicGasAndTimeEstimates, + fetchBasicGasEstimates, gasEstimatesLoadingStarted, gasEstimatesLoadingFinished, setPricesAndTimeEstimates, @@ -43,6 +44,7 @@ describe('Gas Duck', () => { safeLow: 10, safeLowWait: 'mockSafeLowWait', speed: 'mockSpeed', + standard: 20, } const mockPredictTableResponse = [ { expectedTime: 400, expectedWait: 40, gasprice: 0.25, somethingElse: 'foobar' }, @@ -67,7 +69,7 @@ describe('Gas Duck', () => { { expectedTime: 1, expectedWait: 0.5, gasprice: 20, somethingElse: 'foobar' }, ] const fetchStub = sinon.stub().callsFake((url) => new Promise(resolve => { - const dataToResolve = url.match(/ethgasAPI/) + const dataToResolve = url.match(/ethgasAPI|gasexpress/) ? mockEthGasApiResponse : mockPredictTableResponse resolve({ @@ -83,6 +85,7 @@ describe('Gas Duck', () => { }) afterEach(() => { + fetchStub.resetHistory() global.fetch = tempFetch global.Date.now = tempDateNow }) @@ -117,8 +120,7 @@ describe('Gas Duck', () => { priceAndTimeEstimatesLastRetrieved: 0, basicPriceAndTimeEstimates: [], basicPriceAndTimeEstimatesLastRetrieved: 0, - - + basicPriceEstimatesLastRetrieved: 0, } const BASIC_GAS_ESTIMATE_LOADING_FINISHED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_FINISHED' const BASIC_GAS_ESTIMATE_LOADING_STARTED = 'metamask/gas/BASIC_GAS_ESTIMATE_LOADING_STARTED' @@ -133,6 +135,7 @@ describe('Gas Duck', () => { const SET_PRICE_AND_TIME_ESTIMATES = 'metamask/gas/SET_PRICE_AND_TIME_ESTIMATES' const SET_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_API_ESTIMATES_LAST_RETRIEVED' const SET_BASIC_API_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_API_ESTIMATES_LAST_RETRIEVED' + const SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED = 'metamask/gas/SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED' describe('GasReducer()', () => { it('should initialize state', () => { @@ -301,6 +304,59 @@ describe('Gas Duck', () => { }) }) + describe('fetchBasicGasEstimates', () => { + const mockDistpatch = sinon.spy() + it('should call fetch with the expected params', async () => { + await fetchBasicGasEstimates()(mockDistpatch, () => ({ gas: Object.assign( + {}, + initState, + { basicPriceAEstimatesLastRetrieved: 1000000 } + ) })) + assert.deepEqual( + mockDistpatch.getCall(0).args, + [{ type: BASIC_GAS_ESTIMATE_LOADING_STARTED} ] + ) + assert.deepEqual( + global.fetch.getCall(0).args, + [ + 'https://dev.blockscale.net/api/gasexpress.json', + { + 'headers': {}, + 'referrer': 'https://dev.blockscale.net/api/', + 'referrerPolicy': 'no-referrer-when-downgrade', + 'body': null, + 'method': 'GET', + 'mode': 'cors', + }, + ] + ) + + assert.deepEqual( + mockDistpatch.getCall(1).args, + [{ type: SET_BASIC_PRICE_ESTIMATES_LAST_RETRIEVED, value: 2000000 } ] + ) + + assert.deepEqual( + mockDistpatch.getCall(2).args, + [{ + type: SET_BASIC_GAS_ESTIMATE_DATA, + value: { + average: 20, + blockTime: 'mockBlock_time', + blockNum: 'mockBlockNum', + fast: 30, + fastest: 40, + safeLow: 10, + }, + }] + ) + assert.deepEqual( + mockDistpatch.getCall(3).args, + [{ type: BASIC_GAS_ESTIMATE_LOADING_FINISHED }] + ) + }) + }) + describe('fetchBasicGasAndTimeEstimates', () => { const mockDistpatch = sinon.spy() it('should call fetch with the expected params', async () => { diff --git a/ui/app/selectors/custom-gas.js b/ui/app/selectors/custom-gas.js index 59f240f9c635..91c9109a549e 100644 --- a/ui/app/selectors/custom-gas.js +++ b/ui/app/selectors/custom-gas.js @@ -2,6 +2,7 @@ import { pipe, partialRight } from 'ramda' import { conversionUtil, multiplyCurrencies, + conversionGreaterThan, } from '../conversion-util' import { getCurrentCurrency, @@ -38,6 +39,8 @@ const selectors = { getRenderableBasicEstimateData, getRenderableEstimateDataForSmallButtonsFromGWEI, priceEstimateToWei, + getSafeLowEstimate, + isCustomPriceSafe, } module.exports = selectors @@ -96,6 +99,39 @@ function getDefaultActiveButtonIndex (gasButtonInfo, customGasPriceInHex, gasPri }) } +function getSafeLowEstimate (state) { + const { + gas: { + basicEstimates: { + safeLow, + }, + }, + } = state + + return safeLow +} + +function isCustomPriceSafe (state) { + const safeLow = getSafeLowEstimate(state) + const customGasPrice = getCustomGasPrice(state) + + if (!customGasPrice) { + return true + } + + const customPriceSafe = conversionGreaterThan( + { + value: customGasPrice, + fromNumericBase: 'hex', + fromDenomination: 'WEI', + toDenomination: 'GWEI', + }, + { value: safeLow, fromNumericBase: 'dec' } + ) + + return customPriceSafe +} + function getBasicGasEstimateBlockTime (state) { return state.gas.basicEstimates.blockTime } From dde239797b6cd4248b7ac48d5b97ad03ab69255e Mon Sep 17 00:00:00 2001 From: Alexander Tseung Date: Mon, 10 Dec 2018 18:02:26 -0800 Subject: [PATCH 63/64] Show Failed transaction in the browser notification for on-chain failures (#5904) --- app/scripts/platforms/extension.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/app/scripts/platforms/extension.js b/app/scripts/platforms/extension.js index 9ef0d22c9354..3f1cb0f271a7 100644 --- a/app/scripts/platforms/extension.js +++ b/app/scripts/platforms/extension.js @@ -48,10 +48,13 @@ class ExtensionPlatform { } showTransactionNotification (txMeta) { + const { status, txReceipt: { status: receiptStatus } = {} } = txMeta - const status = txMeta.status if (status === 'confirmed') { - this._showConfirmedTransaction(txMeta) + // There was an on-chain failure + receiptStatus === '0x0' + ? this._showFailedTransaction(txMeta, 'Transaction encountered an error.') + : this._showConfirmedTransaction(txMeta) } else if (status === 'failed') { this._showFailedTransaction(txMeta) } @@ -81,11 +84,11 @@ class ExtensionPlatform { this._showNotification(title, message, url) } - _showFailedTransaction (txMeta) { + _showFailedTransaction (txMeta, errorMessage) { const nonce = parseInt(txMeta.txParams.nonce, 16) const title = 'Failed transaction' - const message = `Transaction ${nonce} failed! ${txMeta.err.message}` + const message = `Transaction ${nonce} failed! ${errorMessage || txMeta.err.message}` this._showNotification(title, message) } From 5ab3f5bb20ca5b8775a786a771b124840c307d2d Mon Sep 17 00:00:00 2001 From: Dan Miller Date: Tue, 11 Dec 2018 13:51:19 -0330 Subject: [PATCH 64/64] Changelog and version bump for 5.2.0 --- CHANGELOG.md | 9 ++++++++- app/manifest.json | 2 +- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fd1348178d39..7a7d586cd7a7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,13 @@ ## Current Develop Branch +## 5.2.0 Mon Dec 11 2018 + +- [#5704] Implements new gas customization features for sending, confirming and speeding up transactions +- [#5886] Groups transactions - speed up, cancel and original - by nonce in the transaction history list +- [#5892] bugfix: eliminates infinite spinner issues caused by switching quickly from a loading network that ultimately fails to resolve +- [$5902] bugfix: provider crashes caused caching issues in `json-rpc-engine`. Fixed in (https://github.com/MetaMask/json-rpc-engine/commit/6de511afbd03ccef4550ea43ff4010b7d7a84039) + ## 5.1.0 Mon Dec 03 2018 - [#5860](https://github.com/MetaMask/metamask-extension/pull/5860): Fixed an infinite spinner bug. @@ -17,7 +24,7 @@ - [#5835](https://github.com/MetaMask/metamask-extension/pull/5835): Open full-screen UI on install - Locked versions for some dependencies to avoid possible issues from event-stream hack. - [#5831](https://github.com/MetaMask/metamask-extension/pull/5831): Hide app-header when provider request pending -- [#5786](https://github.com/MetaMask/metamask-extension/pull/5786): * transactions - autofill gasPrice for retry attempts with either the recomened gasprice or a %10 bump +- [#5786](https://github.com/MetaMask/metamask-extension/pull/5786): * transactions - autofill gasPrice for retry attempts with either the recomened gasprice or a %10 bump - [#5801](https://github.com/MetaMask/metamask-extension/pull/5801): transactions - ensure err is defined when setting tx failed - [#5792](https://github.com/MetaMask/metamask-extension/pull/5792): Consider HW Wallets for signTypedMessage - [#5829](https://github.com/MetaMask/metamask-extension/pull/5829): Show disabled cursor in .network-disabled state diff --git a/app/manifest.json b/app/manifest.json index 07b3a3c48860..8d4e738a6246 100644 --- a/app/manifest.json +++ b/app/manifest.json @@ -1,7 +1,7 @@ { "name": "__MSG_appName__", "short_name": "__MSG_appName__", - "version": "5.1.0", + "version": "5.2.0", "manifest_version": 2, "author": "https://metamask.io", "description": "__MSG_appDescription__",