diff --git a/.npmrc b/.npmrc
index e77c744f1b3..0e33a9703c0 100644
--- a/.npmrc
+++ b/.npmrc
@@ -1,7 +1,7 @@
runtime = electron
target_arch = x64
-brave_electron_version = 5.0.2
-chromedriver_version = 2.33
-target = v5.0.2
+brave_electron_version = 6.0.12
+chromedriver_version = 2.36
+target = v6.0.12
disturl=https://brave-laptop-binaries.s3.amazonaws.com/atom-shell/dist/
build_from_source = true
diff --git a/.travis.yml b/.travis.yml
index 90095b2dd4c..316aa6788c3 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -21,18 +21,35 @@ notifications:
slack:
secure: bDwO2uce5JAZvjrvWj4+/+yEXJAIK4O0RcgUWvZ2IMbi7Q9I89Mw40JmkLWL6x2gWZwxr8+FoLtErJA7RVrsfImjrX+NmMyAB7AydLdrBJtkLozNnuacnhcnBRyp1gGCa1ymxCEXGbgC6onAD3kiJJhggr70T+2lu3IuJYXENhc=
env:
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=lint
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=unit
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=codecov
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=about
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=app
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=bookmark-components
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=bravery-components
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=contents
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=misc-components
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=navbar-components
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=tab-components
- - CXX=g++-4.8 NODE_ENV=test TEST_DIR=performance ARTIFACTS_REGION=us-east-1
+ global:
+ - CXX=g++-4.8
+ - NODE_ENV=test
+ matrix:
+ - TEST_DIR=lint
+ - TEST_DIR=unit
+ - TEST_DIR=codecov
+ - TEST_DIR=security
+ - TEST_DIR=about
+ - TEST_DIR=app
+ - TEST_DIR=bookmark-components
+ - TEST_DIR=bravery-components
+ - TEST_DIR=contents
+ - TEST_DIR=misc-components
+ - TEST_DIR=navbar-components
+ - TEST_DIR=tab-components
+ - TEST_DIR=performance ARTIFACTS_REGION=us-east-1
+matrix:
+ fast_finish: true
+ allow_failures:
+ - env: TEST_DIR=about
+ - env: TEST_DIR=app
+ - env: TEST_DIR=bookmark-components
+ - env: TEST_DIR=bravery-components
+ - env: TEST_DIR=contents
+ - env: TEST_DIR=misc-components
+ - env: TEST_DIR=navbar-components
+ - env: TEST_DIR=tab-components
+ - env: TEST_DIR=performance ARTIFACTS_REGION=us-east-1
addons:
apt:
sources:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 86a44e2a242..42aed62ad89 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,161 @@
# Changelog
+## [0.22.721](https://github.com/brave/browser-laptop/releases/tag/v0.22.721dev)
+
+ - Fixed partner subscription page no longer active tab on initial launch. ([#14220](https://github.com/brave/browser-laptop/issues/14220))
+ - Fixed tabs opened via links with target attribute not always rendering. ([#14159](https://github.com/brave/browser-laptop/issues/14159))
+ - Fixed fingerprinting protection breaks the Uphold verification process. ([#14152](https://github.com/brave/browser-laptop/issues/14152))
+ - Fixed toggling shields breaks the security indicator on URLs that include a hash. ([#14231](https://github.com/brave/browser-laptop/issues/14231))
+ - Fixed opening extension background pages from the URL bar causes Brave to crash. ([#14079](https://github.com/brave/browser-laptop/issues/14079))
+ - Fixed tabs becoming unresponsive when detaching into separate window. ([#14031](https://github.com/brave/browser-laptop/issues/14031))
+ - Fixed disabling TorrentViewer doesn't disable torrent handling. ([#10767](https://github.com/brave/browser-laptop/issues/10767))
+ - Upgraded to muon 6.0.12. ([#14154](https://github.com/brave/browser-laptop/issues/14154))
+ - Upgraded to Chromium 66.0.3359.170. ([#14125](https://github.com/brave/browser-laptop/issues/14125))
+
+## [0.22.714](https://github.com/brave/browser-laptop/releases/tag/v0.22.714dev)
+
+ - Improved performance for browser startup and general UI, especially with a high number of tabs opened. ([#13216](https://github.com/brave/browser-laptop/issues/13216))
+ - Added "Include site in Brave Payments" right-click item for history and bookmarks. ([#6547](https://github.com/brave/browser-laptop/issues/6547))
+ - Added notification when contribution is pushed back due to minimum 30min browsing time not being met. ([#14000](https://github.com/brave/browser-laptop/issues/14000))
+ - Added an option to disable WebRTC. ([#13668](https://github.com/brave/browser-laptop/issues/13668))
+ - Added a reminder notification to backup Payments wallet when funds are added for the first time. ([#13425](https://github.com/brave/browser-laptop/issues/13425))
+ - Added HSTS fingerprinting mitigation. ([#12223](https://github.com/brave/browser-laptop/issues/12223))
+ - Added error under Payments when connection to the ledger server fails. ([#13972](https://github.com/brave/browser-laptop/issues/13972))
+ - Fixed performance issues when closing tab towards the beginning of a tab strip. ([#14081](https://github.com/brave/browser-laptop/issues/14081))
+ - Fixed bookmark bar staying visible after all bookmarks have been removed. ([#14047](https://github.com/brave/browser-laptop/issues/14047))
+ - Fixed crash on macOS when selecting "Share" under the file menu when there's no windows opened. ([#13928](https://github.com/brave/browser-laptop/issues/13928))
+ - Fixed several broken cases when adding websites via the publisher toggle button. ([#13879](https://github.com/brave/browser-laptop/issues/13879))
+ - Fixed ledger table sort based on contribution percentage. ([#13721](https://github.com/brave/browser-laptop/issues/13721))
+ - Fixed active tabs sometimes appearing white and not loading during startup. ([#13679](https://github.com/brave/browser-laptop/issues/13679))
+ - Fixed bookmark search. ([#13322](https://github.com/brave/browser-laptop/issues/13322))
+ - Fixed background process not correctly terminating when closing Brave after importing data. ([#13422](https://github.com/brave/browser-laptop/issues/13422))
+ - Fixed background process not correctly terminating when closing Brave using titlebar after bookmarking. ([#13277](https://github.com/brave/browser-laptop/issues/13277))
+ - Fixed PDFs not being added into Payments. ([#12792](https://github.com/brave/browser-laptop/issues/12792))
+ - Fixed large balances not being displayed correctly under Payments. ([#12220](https://github.com/brave/browser-laptop/issues/12220))
+ - Fixed loading icon being displayed in ad slots where ads have been removed on Marketwatch. ([#11730](https://github.com/brave/browser-laptop/issues/11730))
+ - Fixed crash when using "Mute other tabs" with large profiles. ([#14058](https://github.com/brave/browser-laptop/issues/14058))
+ - Fixed tabs become unmuted when dragged to a new window. ([#13979](https://github.com/brave/browser-laptop/issues/13979))
+ - Fixed unable to open private tab using keyboard shortcut from a PDF tab. ([#4024](https://github.com/brave/browser-laptop/issues/4024))
+ - Fixed escape key not closing the add funds dialog under Payments. ([#3800](https://github.com/brave/browser-laptop/issues/3800))
+
+## [0.22.669](https://github.com/brave/browser-laptop/releases/tag/v0.22.669dev)
+
+ - Fixed crashing when submitting online forms. ([#13947](https://github.com/brave/browser-laptop/issues/13947))
+ - Improved accuracy of recorded time in Brave Payments when watching Twitch. ([#13828](https://github.com/brave/browser-laptop/issues/13828))
+ - Fixed updates sometimes failing on macOS. ([#2184](https://github.com/brave/browser-laptop/issues/2184))
+ - Fixed transactions not being recorded in ledger-state.json. ([#13544](https://github.com/brave/browser-laptop/issues/13544))
+ - Fixed tabs and windows opening in minimized state when using Brave menu items while all windows have been minimized. ([#13865](https://github.com/brave/browser-laptop/issues/13865))
+ - Fixed inability to open windows using the dock on macOS when there are no Brave windows opened. ([#13860](https://github.com/brave/browser-laptop/issues/13860))
+ - Fixed inability to open hyperlinks on macOS when there are no Brave windows opened. ([#13859](https://github.com/brave/browser-laptop/issues/13859))
+ - Fixed inability to open new tabs using the file menu on macOS when there are no Brave windows opened. ([#13689](https://github.com/brave/browser-laptop/issues/13689))
+ - Upgraded to muon 5.2.7. ([#13964](https://github.com/brave/browser-laptop/issues/13964))
+ - Upgraded to Chromium 66.0.3359.117. ([#13912](https://github.com/brave/browser-laptop/issues/13912))
+
+## [0.22.22](https://github.com/brave/browser-laptop/releases/tag/v0.22.22dev)
+
+ - Fixed missing static variable on macOS for first-run referral program installs. ([#13853](https://github.com/brave/browser-laptop/issues/13853))
+
+## [0.22.21](https://github.com/brave/browser-laptop/releases/tag/v0.22.21dev)
+
+ - Improvements to the referral program. ([#13754](https://github.com/brave/browser-laptop/issues/13754))
+ - Reverted quarantine feature for macOS. ([#13826](https://github.com/brave/browser-laptop/issues/13826))
+
+## [0.22.13](https://github.com/brave/browser-laptop/releases/tag/v0.22.13dev)
+
+ - Added a new recovery dialog with information when detecting corrupted seed. ([#13424](https://github.com/brave/browser-laptop/issues/13424))
+ - Added U2F support for various websites. ([#518](https://github.com/brave/browser-laptop/issues/518))
+ - Added "no thanks" to Brave Payment notifications. ([#12758](https://github.com/brave/browser-laptop/issues/12758))
+ - Added "always block" option to autoplay. ([#9755](https://github.com/brave/browser-laptop/issues/9755))
+ - Added "in progress" status under Brave Payments when contribution in progress. ([#13423](https://github.com/brave/browser-laptop/issues/13423))
+ - Added keyboard shortcuts to re-order tabs. ([#11310](https://github.com/brave/browser-laptop/issues/11310))
+ - Added EV certificate status in URL bar. ([#791](https://github.com/brave/browser-laptop/issues/791))
+ - Added new look for tab previews when hovering. ([#12454](https://github.com/brave/browser-laptop/issues/12454))
+ - Optimized opening new windows. ([#12437](https://github.com/brave/browser-laptop/issues/12437))
+ - Updated HTTPS Everywhere. ([#11598](https://github.com/brave/browser-laptop/issues/11598))
+ - Disabled WebUSB API. ([#13374](https://github.com/brave/browser-laptop/issues/13374))
+ - Fixed printing issues under Windows. ([#13546](https://github.com/brave/browser-laptop/issues/13546))
+ - Fixed scrolling sometimes becoming stuck. ([#13580](https://github.com/brave/browser-laptop/issues/13580))
+ - Fixed pinned site contributions so they are excluded from statistical voting. ([#13431](https://github.com/brave/browser-laptop/issues/13431))
+ - Fixed Twitch not being added into the ledger table. ([#13597](https://github.com/brave/browser-laptop/issues/13597))
+ - Fixed Twitch not being added into the ledger table when resuming after pausing a video. ([#13257](https://github.com/brave/browser-laptop/issues/13257))
+ - Fixed adding remaining time into the ledger table when closing Twitch media. ([#13259](https://github.com/brave/browser-laptop/issues/13259))
+ - Fixed downloaded files on macOS not being quarantined by default. ([#13088](https://github.com/brave/browser-laptop/issues/13088))
+ - Fixed tab preview animation under Windows. ([#2869](https://github.com/brave/browser-laptop/issues/2869))
+ - Fixed tab content should be discarded when memory usage is too high. ([#13210](https://github.com/brave/browser-laptop/issues/13210))
+ - Fixed backing up wallet to file creates recovery file in AppData. ([#11419](https://github.com/brave/browser-laptop/issues/11419))
+ - Fixed print dialog not being displayed when printing recovery keys. ([#7512](https://github.com/brave/browser-laptop/issues/7512))
+ - Fixed save recovery file opens new tab. ([#7511](https://github.com/brave/browser-laptop/issues/7511))
+ - Fixed crash when using overrides in developer tools. ([#13521](https://github.com/brave/browser-laptop/issues/13521))
+ - Fixed incorrect origin being displayed on external application permission requests when using invalid URL protocols. ([#13471](https://github.com/brave/browser-laptop/issues/13471))
+ - Fixed issues when resizing "Save Download As..." dialog under macOS. ([#13470](https://github.com/brave/browser-laptop/issues/13470))
+ - Fixed save dialog causing lockup on macOS. ([#3313](https://github.com/brave/browser-laptop/issues/3313))
+ - Fixed "Save Page..." dialog under macOS. ([#12628](https://github.com/brave/browser-laptop/issues/12628))
+ - Fixed "Save As..." dialog appearing twice when offline. ([#3784](https://github.com/brave/browser-laptop/issues/3784))
+ - Fixed "Save As..." dialog can't be closed with ESC key. ([#3864](https://github.com/brave/browser-laptop/issues/3864))
+ - Fixed "Save As..." field not scrollable when downloading long filenames. ([#10924](https://github.com/brave/browser-laptop/issues/10924))
+ - Fixed "Save Image..." randomly crashes the browser. ([#10653](https://github.com/brave/browser-laptop/issues/10653))
+ - Fixed file picker not working under Windows. ([#9409](https://github.com/brave/browser-laptop/issues/9409))
+ - Fixed file uploader not showing any image previews under Linux. ([#8854](https://github.com/brave/browser-laptop/issues/8854))
+ - Fixed set file type filter when presenting a save dialog. ([#8096](https://github.com/brave/browser-laptop/issues/8096))
+ - Fixed contribution notification displaying again after toggle payments off/on. ([#13287](https://github.com/brave/browser-laptop/issues/13287))
+ - Fixed bad session state can result in permanently corrupted profile. ([#13261](https://github.com/brave/browser-laptop/issues/13261))
+ - Fixed issues displaying long publisher names in the ledger table. ([#13195](https://github.com/brave/browser-laptop/issues/13195))
+ - Fixed publishers should not make requests to Youtube, Twitch, etc in the main process. ([#13114](https://github.com/brave/browser-laptop/issues/13114))
+ - Fixed top site tiles not being populated when updating profile from an older version of Brave. ([#12941](https://github.com/brave/browser-laptop/issues/12941))
+ - Fixed theme color being incorrectly displayed due to transparency. ([#12803](https://github.com/brave/browser-laptop/issues/12803))
+ - Fixed favicons being distorted. ([#12722](https://github.com/brave/browser-laptop/issues/12722))
+ - Fixed tab background gradient visible when switching tabs. ([#12721](https://github.com/brave/browser-laptop/issues/12721))
+ - Fixed network requests should use non-persistent session by default, ([#12469](https://github.com/brave/browser-laptop/issues/12469))
+ - Fixed closing tab switches to second tab from root tab. ([#11981](https://github.com/brave/browser-laptop/issues/11981))
+ - Fixed tabs settings options not working after the 0.19.48 update. ([#11526](https://github.com/brave/browser-laptop/issues/11526))
+ - Fixed tab animations run again when tab is being moved. ([#11470](https://github.com/brave/browser-laptop/issues/11470))
+ - Fixed "Save Torrent" button. ([#11452](https://github.com/brave/browser-laptop/issues/11452))
+ - Fixed autocomplete search results displaying incorrect results when typing non-ASCII characters. ([#11297](https://github.com/brave/browser-laptop/issues/11297))
+ - Fixed tab colour has weird fade in paint effect when switching. ([#11249](https://github.com/brave/browser-laptop/issues/11249))
+ - Fixed default download path not working. ([#10260](https://github.com/brave/browser-laptop/issues/10260))
+ - Fixed default download path should be set to the downloads folder. ([#9822](https://github.com/brave/browser-laptop/issues/9822))
+ - Fixed IME results are shown before selection is made. ([#9139](https://github.com/brave/browser-laptop/issues/9139))
+ - Fixed pinned tabs losing order after re-launch. ([#8543](https://github.com/brave/browser-laptop/issues/8543))
+ - Fixed file download hangs if Brave does not have write permission to target directory. ([#7747](https://github.com/brave/browser-laptop/issues/7747))
+ - Fixed file extensions not auto added to some downloads. ([#1985](https://github.com/brave/browser-laptop/issues/1985))
+ - Upgraded to muon 5.1.2. ([#12429](https://github.com/brave/browser-laptop/issues/12429))
+ - Upgraded to Chromium 65.0.3325.181. ([#13572](https://github.com/brave/browser-laptop/issues/13572))
+
+## [0.21.24](https://github.com/brave/browser-laptop/releases/tag/v0.21.24dev)
+
+ - Fixed bugs with ledger session corruption. ([#13330](https://github.com/brave/browser-laptop/issues/13330))
+ - Fixed possible error when trying to save password. ([#13408](https://github.com/brave/browser-laptop/issues/13408))
+ - Fixed tab refresh not releasing memory. ([#13273](https://github.com/brave/browser-laptop/issues/13273))
+ - Upgraded to muon 4.9.3. ([#13357](https://github.com/brave/browser-laptop/issues/13357))
+ - Upgraded to Chromium 65.0.3325.162. ([#13358](https://github.com/brave/browser-laptop/issues/13358))
+
+## [0.21.18](https://github.com/brave/browser-laptop/releases/tag/v0.21.18dev)
+
+ - Added the ability to pay Twitch publishers with BAT. ([#13139](https://github.com/brave/browser-laptop/issues/13139))
+ - There are three things related to Twitch that will be fixed or improved later: i) Paused videos are currently counted for watch time, ii) favicons associated with streams are not shown in the payments panel when watching live video, iii) calculating watch time will be improved when seeking.
+ - Added the ability to sort publishers using the verified publisher column under payments. ([#10752](https://github.com/brave/browser-laptop/issues/10752))
+ - Moved publishers that have been deleted from payments into a new dialog. ([#12833](https://github.com/brave/browser-laptop/issues/12833))
+ - Fixed localization issue when backing up recovery key. ([#13311](https://github.com/brave/browser-laptop/issues/13311))
+ - Fixed favicons not being consistently displayed under payments. ([#13281](https://github.com/brave/browser-laptop/issues/13281))
+ - Fixed publisher pinning issue when brave profile has been corrupted. ([#13134](https://github.com/brave/browser-laptop/issues/13134))
+ - Fixed the actions column under payments being clickable as it's not sortable. ([#13074](https://github.com/brave/browser-laptop/issues/13074))
+ - Fixed token promotions notifying users who have disabled promotion notifications in the advanced settings. ([#13021](https://github.com/brave/browser-laptop/issues/13021))
+ - Fixed "show notifications" under advanced settings being re-enabled when disabling/enabling payments. ([#12817](https://github.com/brave/browser-laptop/issues/12817))
+ - Fixed publishers being auto included under payments even though "show only included sites" has been disabled. ([#12766](https://github.com/brave/browser-laptop/issues/12766))
+ - Fixed incorrect decimal value being displayed when balance under payments is below a certain amount. ([#12666](https://github.com/brave/browser-laptop/issues/12666))
+ - Fixed pinned publishers not always being displayed under payments. ([#12584](https://github.com/brave/browser-laptop/issues/12584))
+ - Fixed "never include" wording under context menu when right clicking on publishers under payments. ([#12296](https://github.com/brave/browser-laptop/issues/12296))
+ - Fixed incorrect amount being deducted from wallet during payment processing. ([#12183](https://github.com/brave/browser-laptop/issues/12183))
+ - Fixed manually entered values for publishers under payments not being retained. ([#11238](https://github.com/brave/browser-laptop/issues/11238))
+
+## [0.20.46](https://github.com/brave/browser-laptop/releases/tag/v0.20.46dev)
+
+ - Fixed YouTube videos lagging while playing. ([#13079](https://github.com/brave/browser-laptop/issues/13079))
+ - Fixed several performance issues. ([#13087](https://github.com/brave/browser-laptop/issues/13087))
+ - Fixed about: pages not working after long usage. ([#12828](https://github.com/brave/browser-laptop/issues/12828))
+ - Fixed back button not working after long usage. ([#13157](https://github.com/brave/browser-laptop/issues/13157))
+ - Fixed reload button not working after long usage. ([#12333](https://github.com/brave/browser-laptop/issues/12333))
+
## [0.20.42](https://github.com/brave/browser-laptop/releases/tag/v0.20.42dev)
- Fixed websites randomly being unpinned under Payments. ([#13102](https://github.com/brave/browser-laptop/issues/13102))
diff --git a/README.md b/README.md
index 37a8389ec3a..b0e8c45f9e3 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,13 @@ dnf install rpm-build
dnf group install "Development Tools" "C Development Tools and Libraries"
````
+#### On Solus
+
+````
+sudo eopkg it -c system.devel gconf
+````
+
+
### Installation
After installing the prerequisites:
@@ -108,12 +115,12 @@ Some platforms are available as pre-configured VMs. See the [readme](https://git
### Running Brave
-To run a development version of the browser requires a few steps. The easiest way is just to use two
-terminals. One terminal can be used just to watch for changes to the code
+Running a development version of the browser requires two steps. The easiest way is just to use two
+terminals (or one terminal with two tabs). First, you'll need to start the watch process (which runs webpack and watches for changes to the code)
npm run watch
-Now actually run Brave in another terminal
+Second, you can start the actual Brave process (in another terminal or tab)
npm start
diff --git a/app/browser/activeTabHistory.js b/app/browser/activeTabHistory.js
index a3650face01..9569c9a5197 100644
--- a/app/browser/activeTabHistory.js
+++ b/app/browser/activeTabHistory.js
@@ -55,6 +55,18 @@ const api = {
*/
clearTabbedWindow: function (windowId) {
activeTabsByWindow.delete(windowId)
+ },
+
+ /**
+ * Replace all intances of `oldTabId` with `newTabId` in
+ * active tab history for each window
+ */
+ tabIdChanged: function (oldTabId, newTabId) {
+ for (const [windowId, windowActiveTabs] of activeTabsByWindow) {
+ if (windowActiveTabs && windowActiveTabs.length) {
+ activeTabsByWindow.set(windowId, windowActiveTabs.map(previousTabId => (previousTabId === oldTabId) ? newTabId : previousTabId))
+ }
+ }
}
}
diff --git a/app/browser/api/ledger.js b/app/browser/api/ledger.js
index 1c24e2e3f97..358de7e1b88 100644
--- a/app/browser/api/ledger.js
+++ b/app/browser/api/ledger.js
@@ -24,21 +24,22 @@ const BigNumber = require('bignumber.js')
const appActions = require('../../../js/actions/appActions')
// State
+const aboutPreferencesState = require('../../common/state/aboutPreferencesState')
const ledgerState = require('../../common/state/ledgerState')
const pageDataState = require('../../common/state/pageDataState')
-const migrationState = require('../../common/state/migrationState')
const updateState = require('../../common/state/updateState')
// Constants
const settings = require('../../../js/constants/settings')
const messages = require('../../../js/constants/messages')
+const ledgerStatuses = require('../../common/constants/ledgerStatuses')
// Utils
const config = require('../../../js/constants/buildConfig')
const tabs = require('../../browser/tabs')
const locale = require('../../locale')
const getSetting = require('../../../js/settings').getSetting
-const {fileUrl, getSourceAboutUrl, isSourceAboutUrl} = require('../../../js/lib/appUrlUtil')
+const {getSourceAboutUrl, isSourceAboutUrl} = require('../../../js/lib/appUrlUtil')
const urlParse = require('../../common/urlParse')
const ruleSolver = require('../../extensions/brave/content/scripts/pageInformation')
const request = require('../../../js/lib/request')
@@ -49,6 +50,13 @@ const ledgerNotifications = require('./ledgerNotifications')
const ledgerVideoCache = require('../../common/cache/ledgerVideoCache')
const updater = require('../../updater')
const promoCodeFirstRunStorage = require('../../promoCodeFirstRunStorage')
+const appUrlUtil = require('../../../js/lib/appUrlUtil')
+const urlutil = require('../../../js/lib/urlutil')
+const windowState = require('../../common/state/windowState')
+const {makeImmutable, makeJS, isList, isImmutable} = require('../../common/state/immutableUtil')
+const siteHacks = require('../../siteHacks')
+const UrlUtil = require('../../../js/lib/urlutil')
+const promotionStatuses = require('../../common/constants/promotionStatuses')
// Caching
let locationDefault = 'NOOP'
@@ -85,7 +93,6 @@ let verifiedTimeoutId = false
let v2RulesetDB
const v2RulesetPath = 'ledger-rulesV2.leveldb'
const statePath = 'ledger-state.json'
-const newClientPath = 'ledger-newstate.json'
// Definitions
const clientOptions = {
@@ -99,7 +106,7 @@ const clientOptions = {
environment: process.env.LEDGER_ENVIRONMENT || 'production'
}
-var platforms = {
+const platforms = {
'darwin': 'osx',
'win32x64': 'winx64',
'win32ia32': 'winia32',
@@ -136,7 +143,7 @@ signatureMax = Math.ceil(signatureMax * 1.5)
if (ipc) {
ipc.on(messages.LEDGER_PUBLISHER, (event, location) => {
- if (!synopsis || event.sender.session === electron.session.fromPartition('default') || !tldjs.isValid(location)) {
+ if (!synopsis || event.sender.session === electron.session.fromPartition('default') || !tldjs.isValid(tldjs.getDomain(location))) {
event.returnValue = {}
return
}
@@ -180,11 +187,30 @@ const paymentPresent = (state, tabId, present) => {
}
appActions.onPromotionGet()
+
+ state = checkSeed(state)
getPublisherTimestamp(true)
} else if (balanceTimeoutId) {
clearTimeout(balanceTimeoutId)
balanceTimeoutId = false
}
+
+ return state
+}
+
+const checkSeed = (state) => {
+ const seed = ledgerState.getInfoProp(state, 'passphrase')
+ let localClient = client
+
+ if (!localClient) {
+ localClient = require('bat-client')
+ }
+
+ if (seed && localClient && !localClient.isValidPassPhrase(seed)) {
+ state = ledgerState.setAboutProp(state, 'status', ledgerStatuses.CORRUPTED_SEED)
+ }
+
+ return state
}
const getPublisherTimestamp = (updateList) => {
@@ -241,7 +267,7 @@ const onBootStateFile = (state) => {
}
if (client.sync(callback) === true) {
- run(random.randomInt({min: ledgerUtil.milliseconds.minute, max: 10 * ledgerUtil.milliseconds.minute}))
+ run(state, random.randomInt({min: ledgerUtil.milliseconds.minute, max: 5 * ledgerUtil.milliseconds.minute}))
}
module.exports.getBalance(state)
@@ -252,7 +278,7 @@ const onBootStateFile = (state) => {
}
const promptForRecoveryKeyFile = () => {
- const defaultRecoveryKeyFilePath = path.join(electron.app.getPath('userData'), '/brave_wallet_recovery.txt')
+ const defaultRecoveryKeyFilePath = path.join(electron.app.getPath('downloads'), '/brave_wallet_recovery.txt')
if (process.env.SPECTRON) {
// skip the dialog for tests
console.log(`for test, trying to recover keys from path: ${defaultRecoveryKeyFilePath}`)
@@ -266,7 +292,7 @@ const promptForRecoveryKeyFile = () => {
extensions: [['txt']],
includeAllFiles: false
}, (files) => {
- return (files && files.length ? files[0] : null)
+ appActions.onFileRecoveryKeys((files && files.length ? files[0] : null))
})
}
}
@@ -317,6 +343,7 @@ const getPublisherData = (result, scorekeeper) => {
verified: result.options.verified || false,
exclude: result.options.exclude || false,
publisherKey: result.publisherKey,
+ providerName: result.providerName,
siteName: result.publisherKey,
views: result.visits,
duration: duration,
@@ -325,7 +352,7 @@ const getPublisherData = (result, scorekeeper) => {
minutesSpent: 0,
secondsSpent: 0,
faviconURL: result.faviconURL,
- score: result.scores[scorekeeper],
+ score: result.scores ? result.scores[scorekeeper] : 0,
pinPercentage: result.pinPercentage,
weight: result.pinPercentage
}
@@ -437,7 +464,7 @@ const synopsisNormalizer = (state, changedPublisher, returnState = true, prune =
dataPinned.push(getPublisherData(publisher, scorekeeper))
} else if (ledgerUtil.stickyP(state, publisher.publisherKey)) {
// unpinned
- unPinnedTotal += publisher.scores[scorekeeper]
+ unPinnedTotal += publisher.scores ? publisher.scores[scorekeeper] : 0
dataUnPinned.push(publisher)
} else {
// excluded
@@ -490,9 +517,6 @@ const synopsisNormalizer = (state, changedPublisher, returnState = true, prune =
publisher.weight = 0
return publisher
})
-
- // sync app store
- state = ledgerState.changePinnedValues(state, dataPinned)
} else if (dataUnPinned.length === 0 && pinnedTotal < 100) {
// when you don't have any unpinned sites and pinned total is less then 100 %
let changedObject = dataPinned.find(publisher => publisher.publisherKey === changedPublisher)
@@ -507,9 +531,6 @@ const synopsisNormalizer = (state, changedPublisher, returnState = true, prune =
dataPinned = module.exports.normalizePinned(dataPinned, pinnedTotal, 100, false)
dataPinned = module.exports.roundToTarget(dataPinned, 100, 'pinPercentage')
}
-
- // sync app store
- state = ledgerState.changePinnedValues(state, dataPinned)
} else {
// unpinned publishers
dataUnPinned = dataUnPinned.map((result) => {
@@ -587,7 +608,7 @@ const inspectP = (db, path, publisher, property, key, callback) => {
}
// TODO rename function name
-const verifiedP = (state, publisherKey, callback) => {
+const verifiedP = (state, publisherKey, callback, lastUpdate) => {
const clientCallback = (err, result) => {
if (err) {
console.error(`Error verifying publisher ${publisherKey}: `, err.toString())
@@ -596,7 +617,7 @@ const verifiedP = (state, publisherKey, callback) => {
if (callback) {
if (result) {
- callback(null, result)
+ callback(null, result, lastUpdate)
} else {
callback(err, {})
}
@@ -681,14 +702,17 @@ const excludeP = (publisherKey, callback) => {
})
}
-const addSiteVisit = (state, timestamp, location, tabId) => {
- if (!synopsis) {
+const addSiteVisit = (state, timestamp, location, tabId, manualAdd = false) => {
+ if (!synopsis || location == null) {
return state
}
location = pageDataUtil.getInfoKey(location)
- const locationData = ledgerState.getLocation(state, location)
- const duration = new Date().getTime() - timestamp
+
+ const minimumVisitTime = getSetting(settings.PAYMENTS_MINIMUM_VISIT_TIME)
+ const duration = manualAdd ? parseInt(minimumVisitTime) : new Date().getTime() - timestamp
+ const locationData = manualAdd ? Immutable.fromJS({ publisher: tldjs.getDomain(location) }) : ledgerState.getLocation(state, location)
+
if (_internal.verboseP) {
console.log(
`locations[${location}]=${JSON.stringify(locationData, null, 2)} ` +
@@ -703,7 +727,7 @@ const addSiteVisit = (state, timestamp, location, tabId) => {
let publisherKey = locationData.get('publisher')
let revisitP = false
- if (duration >= getSetting(settings.PAYMENTS_MINIMUM_VISIT_TIME)) {
+ if (duration >= minimumVisitTime) {
if (!visitsByPublisher[publisherKey]) {
visitsByPublisher[publisherKey] = {}
}
@@ -714,13 +738,13 @@ const addSiteVisit = (state, timestamp, location, tabId) => {
}
}
- revisitP = visitsByPublisher[publisherKey][location].tabIds.indexOf(tabId) !== -1
+ revisitP = manualAdd ? false : visitsByPublisher[publisherKey][location].tabIds.indexOf(tabId) !== -1
if (!revisitP) {
visitsByPublisher[publisherKey][location].tabIds.push(tabId)
}
}
- return saveVisit(state, publisherKey, {
+ return module.exports.saveVisit(state, publisherKey, {
duration,
revisited: revisitP
})
@@ -747,6 +771,47 @@ const saveVisit = (state, publisherKey, options) => {
return state
}
+const onVerifiedPStatus = (error, result, lastUpdate) => {
+ if (error || result == null) {
+ return
+ }
+
+ if (!Array.isArray(result)) {
+ result = [result]
+ }
+
+ if (result.length === 0) {
+ return
+ }
+
+ const data = result.reduce((publishers, item) => {
+ if (item.err) {
+ return publishers
+ }
+
+ const publisherKey = item.publisher
+ let verified = false
+ if (item && item.properties) {
+ verified = !!item.properties.verified
+ savePublisherOption(publisherKey, 'verified', verified)
+ }
+
+ savePublisherOption(publisherKey, 'verifiedTimestamp', lastUpdate)
+
+ publishers.push({
+ publisherKey,
+ verified,
+ verifiedTimestamp: lastUpdate
+ })
+
+ return publishers
+ }, [])
+
+ if (data && data.length > 0) {
+ appActions.onPublishersOptionUpdate(data)
+ }
+}
+
const checkVerifiedStatus = (state, publisherKeys, publisherTimestamp) => {
if (publisherKeys == null) {
return state
@@ -756,35 +821,22 @@ const checkVerifiedStatus = (state, publisherKeys, publisherTimestamp) => {
publisherKeys = [publisherKeys]
}
- const checkKeys = []
const lastUpdate = parseInt(publisherTimestamp || ledgerState.getLedgerValue(state, 'publisherTimestamp'))
-
- publisherKeys.forEach(key => {
+ const checkKeys = publisherKeys.reduce((init, key) => {
const lastPublisherUpdate = parseInt(ledgerState.getPublisherOption(state, key, 'verifiedTimestamp') || 0)
if (lastUpdate > lastPublisherUpdate) {
- checkKeys.push(key)
+ init.push(key)
}
- })
+
+ return init
+ }, [])
if (checkKeys.length === 0) {
return state
}
- state = module.exports.verifiedP(state, checkKeys, (error, result) => {
- if (!error) {
- const publisherKey = result.publisher
-
- if (result && result.properties && result.properties) {
- const verified = !!result.properties.verified
- appActions.onPublisherOptionUpdate(publisherKey, 'verified', verified)
- savePublisherOption(publisherKey, 'verified', verified)
- }
-
- appActions.onPublisherOptionUpdate(publisherKey, 'verifiedTimestamp', lastUpdate)
- savePublisherOption(publisherKey, 'verifiedTimestamp', lastUpdate)
- }
- })
+ state = module.exports.verifiedP(state, checkKeys, onVerifiedPStatus, lastUpdate)
return state
}
@@ -798,19 +850,27 @@ const shouldTrackTab = (state, tabId) => {
return !isPrivate && !tabFromState.isEmpty() && ledgerUtil.shouldTrackView(tabFromState)
}
-const addNewLocation = (state, location, tabId = tabState.TAB_ID_NONE, keepInfo = false) => {
+const addNewLocation = (state, location, tabId = tabState.TAB_ID_NONE, keepInfo = false, manualAdd = false) => {
// We always want to have the latest active tabId
- const currentTabId = pageDataState.getLastActiveTabId(state)
+ const currentTabId = manualAdd ? tabId : pageDataState.getLastActiveTabId(state)
state = pageDataState.setLastActiveTabId(state, tabId)
- if (location === currentUrl) {
+ if (location === currentUrl && !manualAdd) {
return state
}
// Save previous recorder page
- if (currentUrl !== locationDefault && currentTabId != null && currentTabId !== tabState.TAB_ID_NONE) {
- if (shouldTrackTab(state, currentTabId)) {
- state = addSiteVisit(state, currentTimestamp, currentUrl, currentTabId)
+ if (currentUrl !== locationDefault && currentTabId != null && currentTabId !== tabState.TAB_ID_NONE && !manualAdd) {
+ if (module.exports.shouldTrackTab(state, currentTabId)) {
+ state = module.exports.addSiteVisit(state, currentTimestamp, currentUrl, currentTabId)
+ }
+ }
+
+ if (manualAdd) {
+ const minimumVisits = getSetting(settings.PAYMENTS_MINIMUM_VISITS)
+ for (let v = 0; v < minimumVisits; v++) {
+ state = module.exports.addSiteVisit(state, currentTimestamp, location, currentTabId, manualAdd)
}
+ return state
}
if (location === locationDefault && !keepInfo) {
@@ -823,6 +883,17 @@ const addNewLocation = (state, location, tabId = tabState.TAB_ID_NONE, keepInfo
return state
}
+const onFavIconReceived = (state, publisherKey, blob) => {
+ if (publisherKey == null) {
+ return state
+ }
+
+ state = ledgerState.setPublishersProp(state, publisherKey, 'faviconURL', blob)
+ module.exports.savePublisherData(publisherKey, 'faviconURL', blob)
+
+ return state
+}
+
const getFavIcon = (state, publisherKey, page) => {
let publisher = ledgerState.getPublisher(state, publisherKey)
const protocol = page.get('protocol')
@@ -894,7 +965,7 @@ const fetchFavIcon = (publisherKey, url, redirects) => {
underscore.keys(fileTypes).forEach((fileType) => {
if (matchP) return
if (
- prefix.length >= fileTypes[fileType].length ||
+ prefix.length < fileTypes[fileType].length ||
fileTypes[fileType].compare(prefix, 0, fileTypes[fileType].length) !== 0
) {
return
@@ -909,10 +980,6 @@ const fetchFavIcon = (publisherKey, url, redirects) => {
} else if (tail > 0 && (tail + 8 >= blob.length)) return
appActions.onFavIconReceived(publisherKey, blob)
-
- if (synopsis.publishers && synopsis.publishers[publisherKey]) {
- synopsis.publishers[publisherKey].faviconURL = blob
- }
})
}
@@ -923,13 +990,21 @@ const pageDataChanged = (state, viewData = {}, keepInfo = false) => {
let info = pageDataState.getLastInfo(state)
const tabId = viewData.tabId || pageDataState.getLastActiveTabId(state)
- const location = viewData.location || locationDefault
+ let location = viewData.location || locationDefault
if (!synopsis) {
state = addNewLocation(state, locationDefault, tabId)
return state
}
+ if (UrlUtil.isUrlPDF(location)) {
+ location = UrlUtil.getLocationIfPDF(location)
+ info = Immutable.fromJS({
+ key: location,
+ location: location
+ })
+ }
+
const realUrl = getSourceAboutUrl(location) || location
if (
info.isEmpty() &&
@@ -1022,37 +1097,59 @@ const backupKeys = (state, backupAction) => {
]
const message = messageLines.join(os.EOL)
- const filePath = path.join(electron.app.getPath('userData'), '/brave_wallet_recovery.txt')
+ const defaultFilePath = path.join(electron.app.getPath('downloads'), '/brave_wallet_recovery.txt')
const fs = require('fs')
- fs.writeFile(filePath, message, (err) => {
- if (err) {
- console.error(err)
- } else {
- tabs.create({url: fileUrl(filePath)}, (webContents) => {
- if (backupAction === 'print') {
- webContents.print({silent: false, printBackground: false})
- } else {
- webContents.downloadURL(fileUrl(filePath), true)
- }
- })
+
+ if (backupAction === 'print') {
+ tabs.create({url: appUrlUtil.aboutUrls.get('about:printkeys')})
+
+ // we do not check whether the user actually printed the backup word list
+ return aboutPreferencesState.setBackupStatus(state, true)
+ }
+
+ const dialog = electron.dialog
+ const BrowserWindow = electron.BrowserWindow
+
+ dialog.showDialog(BrowserWindow.getFocusedWindow(), {
+ type: 'select-saveas-file',
+ defaultPath: defaultFilePath,
+ extensions: [['txt']],
+ includeAllFiles: false
+ }, (files) => {
+ const file = files && files.length ? files[0] : null
+ if (file) {
+ try {
+ fs.writeFileSync(file, message)
+ appActions.onLedgerBackupSuccess()
+ } catch (e) {
+ console.error('Problem saving backup keys')
+ }
}
})
+ return state
+}
+
+const fileRecoveryKeys = (state, recoveryKeyFile) => {
+ if (!recoveryKeyFile) {
+ // user canceled from dialog, we abort without error
+ return state
+ }
+
+ state = aboutPreferencesState.setRecoveryInProgress(state, true)
+ const result = loadKeysFromBackupFile(state, recoveryKeyFile)
+ const recoveryKey = result.recoveryKey || ''
+ state = result.state
+
+ return recoverKeys(state, false, recoveryKey)
}
const recoverKeys = (state, useRecoveryKeyFile, key) => {
let recoveryKey
if (useRecoveryKeyFile) {
- let recoveryKeyFile = promptForRecoveryKeyFile()
- if (!recoveryKeyFile) {
- // user canceled from dialog, we abort without error
- return state
- }
-
- const result = loadKeysFromBackupFile(state, recoveryKeyFile)
- recoveryKey = result.recoveryKey || ''
- state = result.state
+ promptForRecoveryKeyFile()
+ return state
}
if (!recoveryKey) {
@@ -1062,10 +1159,11 @@ const recoverKeys = (state, useRecoveryKeyFile, key) => {
if (typeof recoveryKey !== 'string') {
// calling logError sets the error object
state = logError(state, true, 'recoverKeys')
- state = ledgerState.setRecoveryStatus(state, false)
+ state = aboutPreferencesState.setRecoveryStatus(state, false)
return state
}
+ state = aboutPreferencesState.setRecoveryBalanceRecalculated(state, false)
client.recoverWallet(null, recoveryKey, (err, result) => {
appActions.onWalletRecovery(err, result)
appActions.onPromotionRemoval()
@@ -1081,7 +1179,7 @@ const onWalletRecovery = (state, error, result) => {
// if ledgerInfo.error is not null, the wallet info will not display in UI
// logError sets ledgerInfo.error, so we must we clear it or UI will show an error
state = logError(state, error.toString(), 'recoveryWallet')
- state = ledgerState.setRecoveryStatus(state, false)
+ state = aboutPreferencesState.setRecoveryStatus(state, false)
} else {
// convert buffer to Uint8Array
let seed = result && result.getIn(['properties', 'wallet', 'keyinfo', 'seed'])
@@ -1093,24 +1191,37 @@ const onWalletRecovery = (state, error, result) => {
state = ledgerState.setInfoProp(state, 'walletQR', Immutable.Map())
state = ledgerState.setInfoProp(state, 'addresses', Immutable.Map())
+ const status = ledgerState.getAboutProp(state, 'status')
+
+ if (status === ledgerStatuses.CORRUPTED_SEED) {
+ state = ledgerState.setAboutProp(state, 'status', '')
+ }
+
callback(error, result)
if (balanceTimeoutId) {
clearTimeout(balanceTimeoutId)
}
module.exports.getBalance(state)
- state = ledgerState.setRecoveryStatus(state, true)
+ state = aboutPreferencesState.setRecoveryStatus(state, true)
}
return state
}
+const resetPublishers = (state) => {
+ state = ledgerState.resetPublishers(state)
+ synopsis.publishers = {}
+
+ return state
+}
+
const quit = (state) => {
quitP = true
state = addNewLocation(state, locationDefault)
- if (!getSetting(settings.PAYMENTS_ENABLED) && getSetting(settings.SHUTDOWN_CLEAR_HISTORY)) {
- state = ledgerState.resetSynopsis(state, true)
+ if (!getSetting(settings.PAYMENTS_ENABLED) && getSetting(settings.SHUTDOWN_CLEAR_PUBLISHERS)) {
+ resetPublishers(state)
}
return state
@@ -1162,12 +1273,17 @@ const initSynopsis = (state) => {
}
const publishers = ledgerState.getPublishers(state)
+
for (let item of publishers) {
const publisherKey = item[0]
- excludeP(publisherKey, (unused, exclude) => {
- appActions.onPublisherOptionUpdate(publisherKey, 'exclude', exclude)
- savePublisherOption(publisherKey, 'exclude', exclude)
- })
+ const publisher = item[1] || Immutable.Map()
+
+ if (!publisher.getIn(['options', 'exclude'])) {
+ excludeP(publisherKey, (unused, exclude) => {
+ appActions.onPublisherOptionUpdate(publisherKey, 'exclude', exclude)
+ savePublisherOption(publisherKey, 'exclude', exclude)
+ })
+ }
}
state = updatePublisherInfo(state)
@@ -1190,8 +1306,6 @@ const checkPromotions = () => {
const enable = (state, paymentsEnabled) => {
if (paymentsEnabled) {
- state = checkBtcBatMigrated(state, paymentsEnabled)
-
if (!getSetting(settings.PAYMENTS_NOTIFICATION_TRY_PAYMENTS_DISMISSED)) {
appActions.changeSetting(settings.PAYMENTS_NOTIFICATION_TRY_PAYMENTS_DISMISSED, true)
}
@@ -1199,7 +1313,6 @@ const enable = (state, paymentsEnabled) => {
if (paymentsEnabled === getSetting(settings.PAYMENTS_ENABLED)) {
// on start
-
if (togglePromotionTimeoutId) {
clearTimeout(togglePromotionTimeoutId)
}
@@ -1208,7 +1321,7 @@ const enable = (state, paymentsEnabled) => {
checkPromotions()
}, random.randomInt({min: 10 * ledgerUtil.milliseconds.second, max: 15 * ledgerUtil.milliseconds.second}))
} else if (paymentsEnabled) {
- // on toggle
+ // toggle on
if (togglePromotionTimeoutId) {
clearTimeout(togglePromotionTimeoutId)
}
@@ -1220,6 +1333,9 @@ const enable = (state, paymentsEnabled) => {
state = ledgerState.setActivePromotion(state, paymentsEnabled)
getPromotion(state)
+ } else {
+ // toggle off
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', null)
}
if (synopsis) {
@@ -1353,12 +1469,84 @@ const clientprep = () => {
_internal.verboseP = ledgerClient.prototype.boolion(process.env.LEDGER_PUBLISHER_VERBOSE)
}
+/**
+ * This callback that we do it in roundtrips
+ *
+ * @callback roundtripCallback
+ * @param {Error|null} error - error when doing a request, null if no errors
+ * @param {object} response - response object that we get from request.request
+ * @param {any} payload - data that we get from the request
+ */
+
+/**
+ * Round trip for fetching data (scrap data from html) inside window process
+ * @param {object} params - contains params from roundtrip
+ * @param {string} params.url - url of the site that we want to scrap
+ * @param {string} params.verboseP - tells us if we want to log the process or not
+ * @param {roundtripCallback} callback - The callback that handles the response
+ */
+const roundTripFromWindow = (params, callback) => {
+ if (!callback) {
+ return
+ }
+
+ if (!params || !params.url) {
+ if (params && params.verboseP) {
+ console.log(`We are missing url. Params ${JSON.stringify(params)}`)
+ }
+
+ callback(new Error('Url is missing'))
+ return
+ }
+
+ request.fetchPublisherInfo(params.url, {
+ method: 'GET',
+ responseType: 'text',
+ headers: {
+ 'content-type': 'application/json; charset=utf-8'
+ }
+ }, (error, body) => {
+ if (error) {
+ if (params.verboseP) {
+ console.log(`roundTripFromWindow error: ${error.toString()}`)
+ }
+ return callback(error)
+ }
+
+ if (params.verboseP) {
+ console.log(`roundTripFromWindow success: ${JSON.stringify(body)}`)
+ }
+
+ return callback(null, null, body)
+ })
+}
+
+/**
+ * Round trip function for executing actions
+ * from the bat libraries (mostly server calls)
+ * @param {object} params - params that are directly tied to request.request
+ * @param {string} params.server - server url
+ * @param {string} params.method - HTTP method (GET, PUT, etc)
+ * @param {object} params.payload - payload that we want to send to the server
+ * @param {object} params.headers - HTTP headers
+ * @param {string} params.path - relative path to requested url
+ * @param {boolean} params.binaryP - are we receiving raw payload back
+ * @param {object} options
+ * @param {boolean} options.verboseP - tells us if we want to log the process or not
+ * @param {object} options.headers - headers that are used in the request.request
+ * @param {string} options.server - server url
+ * @param {boolean} options.binaryP - are we receiving binary payload back
+ * @param {boolean} options.rawP - are we receiving raw payload back
+ * @param {boolean} options.scrapeP - are we doping scraping
+ * @param {boolean} options.windowP - do we want to run this request in the window process
+ * @param {roundtripCallback} callback - The callback that handles the response
+ */
const roundtrip = (params, options, callback) => {
let parts = typeof params.server === 'string' ? urlParse(params.server)
: typeof params.server !== 'undefined' ? params.server
: typeof options.server === 'string' ? urlParse(options.server) : options.server
- const binaryP = options.binaryP
- const rawP = binaryP || options.rawP
+ const binaryP = options.binaryP || params.binaryP
+ const rawP = binaryP || options.rawP || options.scrapeP
if (!params.method) params.method = 'GET'
parts = underscore.extend(underscore.pick(parts, ['protocol', 'hostname', 'port']),
@@ -1381,6 +1569,11 @@ const roundtrip = (params, options, callback) => {
parts.pathname = parts.path
}
+ if (options.windowP) {
+ roundTripFromWindow({url: urlFormat(parts), verboseP: options.verboseP}, callback)
+ return
+ }
+
options = {
url: urlFormat(parts),
method: params.method,
@@ -1444,12 +1637,12 @@ const roundtrip = (params, options, callback) => {
const observeTransactions = (state, transactions) => {
if (!transactions) {
- return
+ return state
}
const current = ledgerState.getInfoProp(state, 'transactions')
if (current && current.size === transactions.length) {
- return
+ return state
}
// Notify the user of new transactions.
@@ -1457,10 +1650,13 @@ const observeTransactions = (state, transactions) => {
if (transactions.length > 0) {
const newestTransaction = transactions[0]
if (newestTransaction && newestTransaction.contribution) {
+ state = ledgerState.setAboutProp(state, 'status', '')
ledgerNotifications.showPaymentDone(newestTransaction.contribution.fiat)
}
}
}
+
+ return state
}
// TODO convert this function and related ones to immutable
@@ -1472,7 +1668,7 @@ const getStateInfo = (state, parsedData) => {
const info = parsedData.paymentInfo
const then = new Date().getTime() - ledgerUtil.milliseconds.year
- if (!parsedData.properties.wallet) {
+ if (!parsedData.properties || !parsedData.properties.wallet) {
return state
}
@@ -1481,12 +1677,7 @@ const getStateInfo = (state, parsedData) => {
}
if (parsedData.properties && parsedData.properties.wallet && parsedData.properties.wallet.keyinfo) {
- let seed = parsedData.properties.wallet.keyinfo.seed
- if (!(seed instanceof Uint8Array)) {
- seed = new Uint8Array(Object.values(seed))
- }
-
- parsedData.properties.wallet.keyinfo.seed = seed
+ parsedData.properties.wallet.keyinfo.seed = uintKeySeed(parsedData.properties.wallet.keyinfo.seed)
}
const newInfo = {
@@ -1497,9 +1688,14 @@ const getStateInfo = (state, parsedData) => {
reconcileStamp: parsedData.reconcileStamp
}
- let passphrase = ledgerClient.prototype.getWalletPassphrase(parsedData)
- if (passphrase) {
- newInfo.passphrase = passphrase.join(' ')
+ try {
+ let passphrase = ledgerClient.prototype.getWalletPassphrase(parsedData)
+ if (passphrase) {
+ newInfo.passphrase = passphrase.join(' ')
+ }
+ } catch (e) {
+ console.error(e)
+ state = ledgerState.setAboutProp(state, 'status', ledgerStatuses.CORRUPTED_SEED)
}
state = ledgerState.mergeInfoProp(state, newInfo)
@@ -1533,7 +1729,7 @@ const getStateInfo = (state, parsedData) => {
{ballots: ballots}))
}
- observeTransactions(state, transactions)
+ state = observeTransactions(state, transactions)
return ledgerState.setInfoProp(state, 'transactions', Immutable.fromJS(transactions))
}
@@ -1597,7 +1793,12 @@ const getPaymentInfo = (state) => {
client.getWalletProperties(amount, currency, function (err, body) {
if (err) {
- console.error('getWalletProperties error: ' + err.toString())
+ if (err.message) {
+ console.error('getWalletProperties error: ' + err.message)
+ } else {
+ console.error('getWalletProperties error: ' + err.toString())
+ }
+ appActions.onWalletPropertiesError()
return
}
@@ -1623,7 +1824,24 @@ const lockInContributionAmount = (state, balance) => {
}
}
+const setNewTimeUntilReconcile = (newReconcileTime = null) => {
+ client.setTimeUntilReconcile(newReconcileTime, (err, stateResult) => {
+ if (err) return console.error('ledger setTimeUntilReconcile error: ' + err.toString())
+
+ if (!stateResult) {
+ return
+ }
+
+ appActions.onTimeUntilReconcile(stateResult)
+ })
+}
+
const onWalletProperties = (state, body) => {
+ const currentStatus = ledgerState.getAboutProp(state, 'status')
+ if (currentStatus === ledgerStatuses.SERVER_PROBLEM) {
+ state = ledgerState.setAboutProp(state, 'status', '')
+ }
+
if (body == null) {
return state
}
@@ -1646,6 +1864,9 @@ const onWalletProperties = (state, body) => {
const balance = parseFloat(body.get('balance'))
if (balance >= 0) {
state = ledgerState.setInfoProp(state, 'balance', balance)
+ if (balance > 0) {
+ state = ledgerState.setInfoProp(state, 'userHasFunded', true)
+ }
lockInContributionAmount(state, balance)
}
@@ -1668,15 +1889,33 @@ const onWalletProperties = (state, body) => {
state = ledgerState.setInfoProp(state, 'currentRate', rate)
}
+ // Grants
+ let probi = parseFloat(body.get('probi'))
+ let userFunded = null
+ if (!isNaN(probi)) {
+ userFunded = probi
+ let grants = body.get('grants') || Immutable.List()
+ if (!grants.isEmpty()) {
+ let grantTotal = 0
+ grants = grants.map(grant => {
+ grantTotal += parseFloat(grant.get('probi'))
+ return {
+ amount: new BigNumber(grant.get('probi').toString()).dividedBy('1e18').toNumber(),
+ expirationDate: grant.get('expiryTime')
+ }
+ })
+ state = ledgerState.setInfoProp(state, 'grants', grants)
+ userFunded = probi - grantTotal
+ }
+
+ state = ledgerState.setInfoProp(state, 'userFunded', new BigNumber(userFunded.toString()).dividedBy('1e18').toNumber())
+ }
+
// Probi
- const probi = parseFloat(body.get('probi'))
if (probi >= 0) {
state = ledgerState.setInfoProp(state, 'probi', probi)
-
- const amount = info.get('balance')
-
- if (amount != null && rate) {
- const bigProbi = new BigNumber(probi.toString()).dividedBy('1e18')
+ if (userFunded != null && rate) {
+ const bigProbi = new BigNumber(userFunded.toString()).dividedBy('1e18')
const bigRate = new BigNumber(rate.toString())
const converted = bigProbi.times(bigRate).toNumber()
@@ -1710,7 +1949,9 @@ const onWalletProperties = (state, body) => {
}
state = module.exports.generatePaymentData(state)
-
+ if (state.getIn(['about', 'preferences']) != null && aboutPreferencesState.getRecoveryBalanceRecalulated(state) === false) {
+ state = aboutPreferencesState.setRecoveryBalanceRecalculated(state, true)
+ }
return state
}
@@ -1774,10 +2015,13 @@ const uintKeySeed = (currentSeed) => {
return currentSeed
}
+ if (currentSeed instanceof Object) {
+ return new Uint8Array(Object.values(currentSeed))
+ }
+
try {
currentSeed.toJSON()
- const seed = new Uint8Array(Object.values(currentSeed))
- currentSeed = seed
+ return new Uint8Array(Object.values(currentSeed))
} catch (err) { }
return currentSeed
@@ -1802,7 +2046,7 @@ const callback = (err, result, delayTime) => {
if (!client) return
if (typeof delayTime === 'undefined') {
- delayTime = random.randomInt({min: ledgerUtil.milliseconds.minute, max: 10 * ledgerUtil.milliseconds.minute})
+ delayTime = random.randomInt({min: ledgerUtil.milliseconds.minute, max: 5 * ledgerUtil.milliseconds.minute})
}
}
@@ -1818,6 +2062,10 @@ const onCallback = (state, result, delayTime) => {
return state
}
+ if (result.getIn(['currentReconcile', 'timestamp']) === 0) {
+ state = ledgerState.setAboutProp(state, 'status', ledgerStatuses.IN_PROGRESS)
+ }
+
const newAddress = result.getIn(['properties', 'wallet', 'addresses', 'BAT'])
const oldAddress = ledgerState.getInfoProps(state).getIn(['addresses', 'BAT'])
@@ -1884,19 +2132,6 @@ const onCallback = (state, result, delayTime) => {
// persist the new ledger state
muonWriter(statePath, regularResults)
- // delete the temp file used during transition (if it still exists)
- if (client && client.options && client.options.version === 'v2') {
- const fs = require('fs')
- fs.access(pathName(newClientPath), fs.FF_OK, (err) => {
- if (err) {
- return
- }
- fs.unlink(pathName(newClientPath), (err) => {
- if (err) console.error('unlink error: ' + err.toString())
- })
- })
- }
-
run(state, delayTime)
return state
@@ -1904,6 +2139,7 @@ const onCallback = (state, result, delayTime) => {
const onReferralCodeRead = (code) => {
if (!code) {
+ fetchReferralHeaders()
return
}
@@ -1932,7 +2168,7 @@ const onReferralInit = (err, response, body) => {
}
if (body && body.download_id) {
- appActions.onReferralCodeRead(body.download_id, body.referral_code)
+ appActions.onReferralCodeRead(body)
promoCodeFirstRunStorage
.removePromoCode()
.catch(error => {
@@ -1948,6 +2184,63 @@ const onReferralInit = (err, response, body) => {
}
}
+const onReferralRead = (state, body, activeWindowId) => {
+ body = makeImmutable(body)
+
+ if (body.has('offer_page_url')) {
+ const url = body.get('offer_page_url')
+ if (urlutil.isURL(url)) {
+ if (activeWindowId === windowState.WINDOW_ID_NONE || !state.get('windowReady')) {
+ // write referralPage to state if initial window is not created/visible yet
+ state = updateState.setUpdateProp(state, 'referralPage', url)
+ } else {
+ // initial window exists and should be ready; create tab directly
+ appActions.createTabRequested({
+ url,
+ windowId: activeWindowId,
+ active: true
+ })
+ state = updateState.setUpdateProp(state, 'referralPage', null)
+ }
+ }
+ }
+
+ if (body.has('headers')) {
+ const headers = body.get('headers')
+ state = updateState.setUpdateProp(state, 'referralHeaders', headers)
+ siteHacks.setReferralHeaders(headers)
+ }
+
+ state = updateState.setUpdateProp(state, 'referralDownloadId', body.get('download_id'))
+ state = updateState.setUpdateProp(state, 'referralPromoCode', body.get('referral_code'))
+
+ return state
+}
+
+const fetchReferralHeaders = () => {
+ module.exports.roundtrip({
+ server: referralServer,
+ method: 'GET',
+ path: '/promo/custom-headers'
+ }, {}, appActions.onFetchReferralHeaders)
+}
+
+const onFetchReferralHeaders = (state, err, response, body) => {
+ if (err) {
+ if (clientOptions.verboseP) {
+ console.error(makeJS(err))
+ }
+ return state
+ }
+
+ if (body && isList(body)) {
+ state = updateState.setUpdateProp(state, 'referralHeaders', body)
+ siteHacks.setReferralHeaders(body)
+ }
+
+ return state
+}
+
const initialize = (state, paymentsEnabled) => {
let fs
@@ -1983,12 +2276,17 @@ const initialize = (state, paymentsEnabled) => {
if (clientOptions.verboseP) {
console.error('read error: ' + error.toString())
}
+ fetchReferralHeaders()
})
+ } else {
+ fetchReferralHeaders()
}
+ // Get referral headers every day
+ setInterval(() => fetchReferralHeaders, (24 * ledgerUtil.milliseconds.hour))
+
if (!paymentsEnabled) {
client = null
- newClient = false
return ledgerState.resetInfo(state, true)
}
@@ -2044,6 +2342,22 @@ const getContributionAmount = (state) => {
}
const onInitRead = (state, parsedData) => {
+ const isBTC = parsedData &&
+ parsedData.properties &&
+ parsedData.properties.wallet &&
+ parsedData.properties.wallet.keychains
+
+ if (isBTC) {
+ const fs = require('fs')
+ fs.renameSync(pathName(statePath), pathName('ledger-state-btc.json'))
+ state = ledgerState.resetInfo(state)
+ clientprep()
+ client = ledgerClient(null, underscore.extend({roundtrip: roundtrip}, clientOptions), null)
+ parsedData = client.state
+ getPaymentInfo(state)
+ muonWriter(statePath, parsedData)
+ }
+
if (Array.isArray(parsedData.transactions)) {
parsedData.transactions.sort((transaction1, transaction2) => {
return transaction1.submissionStamp - transaction2.submissionStamp
@@ -2073,20 +2387,12 @@ const onInitRead = (state, parsedData) => {
// enables it again -> reconcileStamp is in the past.
// In this case reset reconcileStamp to the future.
try {
- timeUntilReconcile = client.timeUntilReconcile(synopsis)
+ timeUntilReconcile = client.timeUntilReconcile(synopsis, onFuzzing)
} catch (ex) {}
let ledgerWindow = (ledgerState.getSynopsisOption(state, 'numFrames') - 1) * ledgerState.getSynopsisOption(state, 'frameSize')
if (typeof timeUntilReconcile === 'number' && timeUntilReconcile < -ledgerWindow) {
- client.setTimeUntilReconcile(null, (err, stateResult) => {
- if (err) return console.error('ledger setTimeUntilReconcile error: ' + err.toString())
-
- if (!stateResult) {
- return
- }
-
- appActions.onTimeUntilReconcile(stateResult)
- })
+ setNewTimeUntilReconcile()
}
} catch (ex) {
console.error('ledger client creation error(1): ', ex)
@@ -2112,12 +2418,15 @@ const onInitRead = (state, parsedData) => {
module.exports.setPaymentInfo(contributionAmount)
module.exports.getBalance(state)
- // Show relevant browser notifications on launch
- state = ledgerNotifications.onLaunch(state)
-
return state
}
+const onFuzzing = () => {
+ if (client && client.state) {
+ appActions.onLedgerFuzzing(client.state.reconcileStamp)
+ }
+}
+
const onTimeUntilReconcile = (state, stateResult) => {
state = getStateInfo(state, stateResult.toJS()) // TODO optimize
muonWriter(statePath, stateResult)
@@ -2127,7 +2436,7 @@ const onTimeUntilReconcile = (state, stateResult) => {
const onLedgerFirstSync = (state, parsedData) => {
if (client.sync(callback) === true) {
- run(state, random.randomInt({min: ledgerUtil.milliseconds.minute, max: 10 * ledgerUtil.milliseconds.minute}))
+ run(state, random.randomInt({min: ledgerUtil.milliseconds.minute, max: 5 * ledgerUtil.milliseconds.minute}))
}
return cacheRuleSet(state, parsedData.ruleset)
@@ -2150,7 +2459,11 @@ const run = (state, delayTime) => {
let result = ''
fields.forEach((field) => {
- const max = (result.length > 0) ? 9 : 19
+ const max = (result.length > 0) ? 45 : 19
+
+ if (!field) {
+ return
+ }
if (typeof field !== 'string') field = field.toString()
if (field.length < max) {
@@ -2159,6 +2472,7 @@ const run = (state, delayTime) => {
} else {
field = field.substr(0, max)
}
+
result += ' ' + field
})
@@ -2184,20 +2498,50 @@ const run = (state, delayTime) => {
})
}
- if (typeof delayTime === 'undefined' || !client) {
+ if (state == null || typeof delayTime === 'undefined' || !client) {
return
}
+ const publishers = ledgerState.getAboutProp(state, 'synopsis') || Immutable.List()
+ if (isList(publishers) && publishers.isEmpty() && client.isReadyToReconcile(synopsis, onFuzzing)) {
+ setNewTimeUntilReconcile()
+ }
+
let winners
const ballots = client.ballots()
const data = (synopsis) && (ballots > 0) && synopsisNormalizer(state, null, false, true)
+ let map = null
+
if (data) {
let weights = []
+ map = {}
+
data.forEach((datum) => {
- weights.push({publisher: datum.publisherKey, weight: datum.weight / 100.0})
+ map[datum.publisherKey] = {
+ verified: datum.verified,
+ exclude: datum.exclude,
+ score: datum.score,
+ pinPercentage: datum.pinPercentage,
+ percentage: datum.percentage,
+ votes: 0,
+ weight: datum.weight
+ }
+
+ weights.push({
+ publisher: datum.publisherKey,
+ pinPercentage: datum.pinPercentage,
+ weight: datum.weight / 100.0
+ })
+ })
+
+ winners = synopsis.winners(ballots, weights) || []
+
+ winners.forEach((winner) => {
+ if (map[winner]) map[winner].votes++
})
- winners = synopsis.winners(ballots, weights)
+
+ client.memo('run:ballots', Object.values(map))
}
if (!winners) winners = []
@@ -2210,6 +2554,9 @@ const run = (state, delayTime) => {
const result = client.vote(winner)
if (result) stateData = result
})
+ if (!stateData && map) {
+ stateData = client.state
+ }
if (stateData) muonWriter(statePath, stateData)
} catch (ex) {
console.error('ledger client error(2): ' + ex.toString() + (ex.stack ? ('\n' + ex.stack) : ''))
@@ -2217,12 +2564,12 @@ const run = (state, delayTime) => {
if (delayTime === 0) {
try {
- delayTime = client.timeUntilReconcile(synopsis)
+ delayTime = client.timeUntilReconcile(synopsis, onFuzzing)
} catch (ex) {
delayTime = false
}
if (delayTime === false) {
- delayTime = random.randomInt({min: ledgerUtil.milliseconds.minute, max: 10 * ledgerUtil.milliseconds.minute})
+ delayTime = random.randomInt({min: ledgerUtil.milliseconds.minute, max: 5 * ledgerUtil.milliseconds.minute})
}
}
@@ -2251,7 +2598,7 @@ const run = (state, delayTime) => {
return
}
- if (client.isReadyToReconcile(synopsis)) {
+ if (client.isReadyToReconcile(synopsis, onFuzzing)) {
client.reconcile(uuid.v4().toLowerCase(), callback)
}
}
@@ -2271,7 +2618,7 @@ const onNetworkConnected = (state) => {
}
if (client.sync(callback) === true) {
- const delayTime = random.randomInt({min: ledgerUtil.milliseconds.minute, max: 10 * ledgerUtil.milliseconds.minute})
+ const delayTime = random.randomInt({min: ledgerUtil.milliseconds.minute, max: 5 * ledgerUtil.milliseconds.minute})
run(state, delayTime)
}
@@ -2337,6 +2684,31 @@ const migration = (state) => {
return state
}
+const setPublishersOptions = (state, publishersArray) => {
+ if (!publishersArray || publishersArray.size === 0) {
+ return state
+ }
+
+ publishersArray.forEach(publisherData => {
+ const publisherKey = publisherData.get('publisherKey')
+
+ if (publisherKey == null) {
+ return state
+ }
+
+ for (const data of publisherData) {
+ const prop = data[0]
+ const value = data[1]
+ if (prop !== 'publisherKey') {
+ state = ledgerState.setPublisherOption(state, publisherKey, prop, value)
+ module.exports.savePublisherOption(publisherKey, prop, value)
+ }
+ }
+ })
+
+ return state
+}
+
// for synopsis variable handling only
const deleteSynopsisPublisher = (publisherKey) => {
delete synopsis.publishers[publisherKey]
@@ -2347,174 +2719,77 @@ const saveOptionSynopsis = (prop, value) => {
}
const savePublisherOption = (publisherKey, prop, value) => {
- if (synopsis && synopsis.publishers && synopsis.publishers[publisherKey] && synopsis.publishers[publisherKey].options) {
- synopsis.publishers[publisherKey].options[prop] = value
- }
-}
-
-const savePublisherData = (publisherKey, prop, value) => {
- if (synopsis && synopsis.publishers && synopsis.publishers[publisherKey]) {
- synopsis.publishers[publisherKey][prop] = value
- }
-}
-
-const deleteSynopsis = () => {
- synopsis.publishers = {}
-}
-
-// fix for incorrectly persisted state (see #11585)
-const yoDawg = (stateState) => {
- while (stateState.hasOwnProperty('state') && stateState.state.persona) {
- stateState = stateState.state
+ if (!synopsis || !synopsis.publishers || !publisherKey) {
+ return
}
- return stateState
-}
-const checkBtcBatMigrated = (state, paymentsEnabled) => {
- if (!paymentsEnabled) {
- return state
+ if (!synopsis.publishers[publisherKey]) {
+ synopsis.publishers[publisherKey] = {}
}
- // One time conversion of wallet
- const isNewInstall = migrationState.isNewInstall(state)
- const hasUpgradedWallet = migrationState.hasUpgradedWallet(state)
- if (!isNewInstall && !hasUpgradedWallet) {
- state = migrationState.setTransitionStatus(state, true)
- module.exports.transitionWalletToBat()
- } else {
- state = migrationState.setTransitionStatus(state, false)
+ if (!synopsis.publishers[publisherKey].options) {
+ synopsis.publishers[publisherKey].options = {}
}
- return state
-}
-
-let newClient = null
-const getNewClient = () => {
- return newClient
+ synopsis.publishers[publisherKey].options[prop] = value
}
-let busyRetryCount = 0
-
-const transitionWalletToBat = () => {
- let newPaymentId, result
-
- if (newClient === true) return
- clientprep()
-
- if (!client) {
- console.log('Client is not initialized, will try again')
+const savePublisherData = (publisherKey, prop, value) => {
+ if (!synopsis || !synopsis.publishers || !publisherKey) {
return
}
- // only attempt this transition if the wallet is v1
- if (client.options && client.options.version !== 'v1') {
- // older versions incorrectly marked this for transition
- // this will clean them up (no more bouncy ball)
- appActions.onBitcoinToBatTransitioned()
- return
+ if (!synopsis.publishers[publisherKey]) {
+ synopsis.publishers[publisherKey] = {}
}
- // Restore newClient from the file (if one exists)
- if (!newClient) {
- const fs = require('fs')
- try {
- fs.accessSync(pathName(newClientPath), fs.FF_OK)
- fs.readFile(pathName(newClientPath), (error, data) => {
- if (error) {
- console.error(`ledger client: can't read ${newClientPath} to restore newClient`)
- return
- }
- const parsedData = JSON.parse(data)
- const state = yoDawg(parsedData)
- newClient = ledgerClient(state.personaId,
- underscore.extend(state.options, {roundtrip: module.exports.roundtrip}, clientOptions),
- state)
- transitionWalletToBat()
- })
- return
- } catch (err) {}
- }
+ synopsis.publishers[publisherKey][prop] = value
+}
- // Create new client
- if (!newClient) {
- try {
- newClient = ledgerClient(null, underscore.extend({roundtrip: module.exports.roundtrip}, clientOptions), null)
- muonWriter(newClientPath, newClient.state)
- } catch (ex) {
- console.error('ledger client creation error(2): ', ex)
- return
- }
+let currentMediaKey = null
+const onMediaRequest = (state, xhr, type, details) => {
+ if (!xhr || type == null) {
+ return state
}
- newPaymentId = newClient.getPaymentId()
- if (!newPaymentId) {
- newClient.sync((err, result, delayTime) => {
- if (err) {
- return console.error('ledger client error(3): ' + JSON.stringify(err, null, 2) + (err.stack ? ('\n' + err.stack) : ''))
- }
-
- if (typeof delayTime === 'undefined') delayTime = random.randomInt({ min: 1, max: 500 })
+ const parsed = ledgerUtil.getMediaData(xhr, type, details)
+ if (parsed == null) {
+ return state
+ }
- if (newClient) {
- muonWriter(newClientPath, newClient.state)
+ if (Array.isArray(parsed)) {
+ parsed.forEach(data => {
+ if (data) {
+ state = module.exports.processMediaData(state, data, type, details)
}
-
- setTimeout(() => transitionWalletToBat(), delayTime)
})
- return
+ } else {
+ state = module.exports.processMediaData(state, parsed, type, details)
}
- if (client.busyP()) {
- if (++busyRetryCount > 3) {
- console.log('ledger client is currently busy; transition will be retried on next launch')
- return
- }
- const delayTime = random.randomInt({
- min: ledgerUtil.milliseconds.minute,
- max: 10 * ledgerUtil.milliseconds.minute
- })
- console.log('ledger client is currently busy; transition will be retried shortly (this was attempt ' + busyRetryCount + ')')
- setTimeout(() => transitionWalletToBat(), delayTime)
- return
+ return state
+}
+
+const processMediaData = (state, parsed, type, details) => {
+ let tabId = tabState.TAB_ID_NONE
+ if (details) {
+ tabId = details.get('tabId')
}
- appActions.onBitcoinToBatBeginTransition()
+ const mediaId = ledgerUtil.getMediaId(parsed, type)
- try {
- client.transition(newPaymentId, (err, properties) => {
- if (err || !newClient) {
- console.error('ledger client transition error: ', err)
- } else {
- result = newClient.transitioned(properties)
- client = newClient
- newClient = true
- // NOTE: onLedgerCallback will save latest client to disk as ledger-state.json
- appActions.onLedgerCallback(result, random.randomInt({
- min: ledgerUtil.milliseconds.minute,
- max: 10 * ledgerUtil.milliseconds.minute
- }))
- appActions.onBitcoinToBatTransitioned()
- ledgerNotifications.showBraveWalletUpdated()
- getPublisherTimestamp()
- }
- })
- } catch (ex) {
- console.error('exception during ledger client transition: ', ex)
+ if (clientOptions.loggingP) {
+ console.log('Media request', parsed, `Media id: ${mediaId}`)
}
-}
-let currentMediaKey = null
-const onMediaRequest = (state, xhr, type, tabId) => {
- if (!xhr || type == null) {
+ if (mediaId == null) {
return state
}
- const parsed = ledgerUtil.getMediaData(xhr, type)
- const mediaId = ledgerUtil.getMediaId(parsed, type)
const mediaKey = ledgerUtil.getMediaKey(mediaId, type)
- let duration = ledgerUtil.getMediaDuration(parsed, type)
+ let duration = ledgerUtil.getMediaDuration(state, parsed, mediaKey, type)
- if (mediaId == null || duration == null || mediaKey == null) {
+ if (duration == null || mediaKey == null) {
return state
}
@@ -2526,6 +2801,9 @@ const onMediaRequest = (state, xhr, type, tabId) => {
if (!ledgerPublisher) {
ledgerPublisher = require('bat-publisher')
}
+ if (clientOptions.loggingP) {
+ console.log('LOGGED EVENT', parsed, `Media id: ${mediaId}`, `Media key: ${mediaKey}`, `Duration: ${duration}ms (${duration / 1000}s)`)
+ }
let revisited = true
const activeTabId = tabState.getActiveTabId(state)
@@ -2534,9 +2812,17 @@ const onMediaRequest = (state, xhr, type, tabId) => {
currentMediaKey = mediaKey
}
+ const stateData = ledgerUtil.generateMediaCacheData(state, parsed, type, mediaKey)
const cache = ledgerVideoCache.getDataByVideoId(state, mediaKey)
+ if (clientOptions.loggingP) {
+ console.log('Media cache data: ', stateData.toJS())
+ }
if (!cache.isEmpty()) {
+ if (!stateData.isEmpty()) {
+ state = ledgerVideoCache.mergeCacheByVideoId(state, mediaKey, stateData)
+ }
+
const publisherKey = cache.get('publisher')
const publisher = ledgerState.getPublisher(state, publisherKey)
if (!publisher.isEmpty() && publisher.has('providerName')) {
@@ -2548,6 +2834,10 @@ const onMediaRequest = (state, xhr, type, tabId) => {
}
}
+ if (!stateData.isEmpty()) {
+ state = ledgerVideoCache.setCacheByVideoId(state, mediaKey, stateData)
+ }
+
const options = underscore.extend({roundtrip: module.exports.roundtrip}, clientOptions)
const mediaProps = {
mediaId,
@@ -2567,7 +2857,7 @@ const onMediaRequest = (state, xhr, type, tabId) => {
if (_internal.verboseP) {
console.log('\ngetPublisherFromMediaProps mediaProps=' + JSON.stringify(mediaProps, null, 2) + '\nresponse=' +
- JSON.stringify(response, null, 2))
+ JSON.stringify(response, null, 2))
}
appActions.onLedgerMediaPublisher(mediaKey, response, duration, revisited)
@@ -2608,10 +2898,10 @@ const onMediaPublisher = (state, mediaKey, response, duration, revisited) => {
}
}
- synopsis.publishers[publisherKey].faviconName = faviconName
- synopsis.publishers[publisherKey].faviconURL = faviconURL
- synopsis.publishers[publisherKey].publisherURL = publisherURL
- synopsis.publishers[publisherKey].providerName = providerName
+ savePublisherData(publisherKey, 'faviconName', faviconName)
+ savePublisherData(publisherKey, 'faviconURL', faviconURL)
+ savePublisherData(publisherKey, 'publisherURL', publisherURL)
+ savePublisherData(publisherKey, 'providerName', providerName)
state = ledgerState.setPublishersProp(state, publisherKey, 'faviconName', faviconName)
state = ledgerState.setPublishersProp(state, publisherKey, 'faviconURL', faviconURL)
state = ledgerState.setPublishersProp(state, publisherKey, 'publisherURL', publisherURL)
@@ -2625,7 +2915,7 @@ const onMediaPublisher = (state, mediaKey, response, duration, revisited) => {
.set('publisher', publisherKey)
// Add to cache
- state = ledgerVideoCache.setCacheByVideoId(state, mediaKey, cacheObject)
+ state = ledgerVideoCache.mergeCacheByVideoId(state, mediaKey, cacheObject)
state = module.exports.saveVisit(state, publisherKey, {
duration,
@@ -2663,7 +2953,45 @@ const getPromotion = (state) => {
})
}
-const claimPromotion = (state) => {
+const getCaptcha = (state) => {
+ if (!client) {
+ return
+ }
+
+ const promotion = ledgerState.getPromotion(state)
+ if (promotion.isEmpty()) {
+ return
+ }
+
+ client.getPromotionCaptcha(promotion.get('promotionId'), (err, body) => {
+ if (err) {
+ console.error(`Problem getting promotion captcha ${err.toString()}`)
+ appActions.onCaptchaResponse(null)
+ }
+
+ appActions.onCaptchaResponse(body)
+ })
+}
+
+const onCaptchaResponse = (state, body) => {
+ if (body == null) {
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', promotionStatuses.CAPTCHA_ERROR)
+ return state
+ }
+
+ const image = `data:image/jpeg;base64,${Buffer.from(body).toString('base64')}`
+
+ state = ledgerState.setPromotionProp(state, 'captcha', image)
+ const currentStatus = ledgerState.getPromotionProp(state, 'promotionStatus')
+
+ if (currentStatus !== promotionStatuses.CAPTCHA_ERROR) {
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', promotionStatuses.CAPTCHA_CHECK)
+ }
+
+ return state
+}
+
+const claimPromotion = (state, x, y) => {
if (!client) {
return
}
@@ -2673,7 +3001,7 @@ const claimPromotion = (state) => {
return
}
- client.setPromotion(promotion.get('promotionId'), (err, _, status) => {
+ client.setPromotion(promotion.get('promotionId'), {x, y}, (err, _, status) => {
let param = null
if (err) {
console.error(`Problem claiming promotion ${err.toString()}`)
@@ -2685,17 +3013,30 @@ const claimPromotion = (state) => {
}
const onPromotionResponse = (state, status) => {
- if (status) {
+ if (status && isImmutable(status)) {
if (status.get('statusCode') === 422) {
// promotion already claimed
- state = ledgerState.setPromotionProp(state, 'promotionStatus', 'expiredError')
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', promotionStatuses.PROMO_EXPIRED)
+ } else if (status.get('statusCode') === 403) {
+ // captcha verification failed
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', promotionStatuses.CAPTCHA_ERROR)
+ module.exports.getCaptcha(state)
} else {
// general error
- state = ledgerState.setPromotionProp(state, 'promotionStatus', 'generalError')
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', promotionStatuses.GENERAL_ERROR)
}
return state
}
+ const currentStatus = ledgerState.getPromotionProp(state, 'promotionStatus')
+
+ if (
+ currentStatus === promotionStatuses.CAPTCHA_ERROR ||
+ currentStatus === promotionStatuses.CAPTCHA_CHECK
+ ) {
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', null)
+ }
+
ledgerNotifications.removePromotionNotification(state)
state = ledgerState.setPromotionProp(state, 'claimedTimestamp', new Date().getTime())
@@ -2703,15 +3044,7 @@ const onPromotionResponse = (state, status) => {
const minTimestamp = ledgerState.getPromotionProp(state, 'minimumReconcileTimestamp')
if (minTimestamp > currentTimestamp) {
- client.setTimeUntilReconcile(minTimestamp, (err, stateResult) => {
- if (err) return console.error('ledger setTimeUntilReconcile error: ' + err.toString())
-
- if (!stateResult) {
- return
- }
-
- appActions.onTimeUntilReconcile(stateResult)
- })
+ setNewTimeUntilReconcile(minTimestamp)
}
if (togglePromotionTimeoutId) {
@@ -2733,9 +3066,7 @@ const onPublisherTimestamp = (state, oldTimestamp, newTimestamp) => {
return
}
- publishers.forEach((publisher, key) => {
- module.exports.checkVerifiedStatus(state, key, newTimestamp)
- })
+ module.exports.checkVerifiedStatus(state, Array.from(publishers.keys()), newTimestamp)
}
const checkReferralActivity = (state) => {
@@ -2813,6 +3144,53 @@ const activityRoundTrip = (err, response, body) => {
updater.checkForUpdate(false, true)
}
+const deleteWallet = (state) => {
+ state = ledgerState.deleteSynopsis(state)
+ state = state.setIn(['settings', settings.PAYMENTS_ENABLED], false)
+
+ client = null
+ synopsis = null
+
+ const fs = require('fs')
+ fs.access(pathName(statePath), fs.constants.F_OK, (err) => {
+ if (err) {
+ return
+ }
+
+ fs.unlink(pathName(statePath), (err) => {
+ if (err) {
+ return console.error('read error: ' + err.toString())
+ }
+ })
+ })
+
+ return state
+}
+
+const clearPaymentHistory = (state) => {
+ state = ledgerState.setInfoProp(state, 'transactions', Immutable.List())
+ state = ledgerState.setInfoProp(state, 'ballots', Immutable.List())
+ state = ledgerState.setInfoProp(state, 'batch', Immutable.Map())
+
+ const fs = require('fs')
+ const path = pathName(statePath)
+ try {
+ fs.accessSync(path, fs.constants.W_OK)
+ let data = fs.readFileSync(path)
+ data = JSON.parse(data)
+ if (data) {
+ data.transactions = []
+ data.ballots = []
+ data.batch = {}
+ muonWriter(statePath, data)
+ }
+ } catch (err) {
+ console.error(`Problem reading ${path} when clearing payment history`)
+ }
+
+ return state
+}
+
const getMethods = () => {
const publicMethods = {
backupKeys,
@@ -2842,14 +3220,11 @@ const getMethods = () => {
onNetworkConnected,
migration,
onInitRead,
- deleteSynopsis,
- transitionWalletToBat,
- getNewClient,
normalizePinned,
roundToTarget,
+ onFavIconReceived,
savePublisherData,
pruneSynopsis,
- checkBtcBatMigrated,
onMediaRequest,
onMediaPublisher,
saveVisit,
@@ -2857,12 +3232,25 @@ const getMethods = () => {
claimPromotion,
onPromotionResponse,
getBalance,
+ fileRecoveryKeys,
getPromotion,
onPublisherTimestamp,
checkVerifiedStatus,
checkReferralActivity,
+ setPublishersOptions,
referralCheck,
- roundtrip
+ roundtrip,
+ onFetchReferralHeaders,
+ onReferralRead,
+ processMediaData,
+ addNewLocation,
+ addSiteVisit,
+ getCaptcha,
+ onCaptchaResponse,
+ shouldTrackTab,
+ deleteWallet,
+ resetPublishers,
+ clearPaymentHistory
}
let privateMethods = {}
@@ -2871,7 +3259,6 @@ const getMethods = () => {
privateMethods = {
enable,
addSiteVisit,
- checkBtcBatMigrated,
clearVisitsByPublisher: function () {
visitsByPublisher = {}
},
@@ -2882,9 +3269,6 @@ const getMethods = () => {
setSynopsis: (data) => {
synopsis = data
},
- resetNewClient: () => {
- newClient = false
- },
getClient: () => {
return client
},
@@ -2906,7 +3290,11 @@ const getMethods = () => {
activityRoundTrip,
pathName,
onReferralInit,
- onReferralCodeRead
+ roundTripFromWindow,
+ onReferralCodeRead,
+ onVerifiedPStatus,
+ checkSeed,
+ shouldTrackTab
}
}
diff --git a/app/browser/api/ledgerNotifications.js b/app/browser/api/ledgerNotifications.js
index 3fdf8f78a01..5696aa5da48 100644
--- a/app/browser/api/ledgerNotifications.js
+++ b/app/browser/api/ledgerNotifications.js
@@ -11,8 +11,8 @@ const messages = require('../../../js/constants/messages')
const settings = require('../../../js/constants/settings')
// State
+const aboutPreferencesState = require('../../common/state/aboutPreferencesState')
const ledgerState = require('../../common/state/ledgerState')
-const migrationState = require('../../common/state/migrationState')
// Actions
const appActions = require('../../../js/actions/appActions')
@@ -28,16 +28,17 @@ const text = {
addFunds: locale.translation('addFundsNotification'),
tryPayments: locale.translation('notificationTryPayments'),
reconciliation: locale.translation('reconciliationNotification'),
- walletConvertedToBat: locale.translation('walletConvertedToBat')
+ backupKeys: locale.translation('backupKeys')
}
-const pollingInterval = 15 * ledgerUtil.milliseconds.minute // 15 * minutes
+const pollingInterval = process.env.LEDGER_NOTIFICATION ? ledgerUtil.milliseconds.second * 5 : 15 * ledgerUtil.milliseconds.minute // 15 * minute default production
let intervalTimeout
const displayOptions = {
style: 'greetingStyle',
persist: false
}
const nextAddFundsTime = 3 * ledgerUtil.milliseconds.day
+let backupNotifyInterval = process.env.LEDGER_NOTIFICATION ? [2 * ledgerUtil.milliseconds.minute, 5 * ledgerUtil.milliseconds.minute] : [7 * ledgerUtil.milliseconds.day, 14 * ledgerUtil.milliseconds.day]
const sufficientBalanceToReconcile = (state) => {
const balance = Number(ledgerState.getInfoProp(state, 'balance') || 0)
@@ -45,11 +46,11 @@ const sufficientBalanceToReconcile = (state) => {
const budget = ledgerState.getContributionAmount(state)
return balance + unconfirmed >= budget
}
-const hasFunds = (state) => {
- const balance = getSetting(settings.PAYMENTS_ENABLED)
- ? Number(ledgerState.getInfoProp(state, 'balance') || 0)
- : 0
- return balance > 0
+
+const hasFunded = (state) => {
+ return getSetting(settings.PAYMENTS_ENABLED)
+ ? ledgerState.getInfoProp(state, 'userHasFunded') || false
+ : false
}
const shouldShowNotificationReviewPublishers = () => {
const nextTime = getSetting(settings.PAYMENTS_NOTIFICATION_RECONCILE_SOON_TIMESTAMP)
@@ -70,43 +71,13 @@ const init = () => {
}, pollingInterval)
}
-const onLaunch = (state) => {
- const enabled = getSetting(settings.PAYMENTS_ENABLED)
- if (!enabled) {
- return state
- }
-
- const ledger = require('./ledger')
- state = ledger.checkBtcBatMigrated(state, enabled)
-
- if (hasFunds(state)) {
- // Don't bother processing the rest, which are only
- if (!getSetting(settings.PAYMENTS_NOTIFICATIONS)) {
- return state
- }
-
- // Show one-time BAT conversion message:
- // - if payments are enabled
- // - user has a positive balance
- // - this is an existing profile (new profiles will have firstRunTimestamp matching batMercuryTimestamp)
- // - wallet has been transitioned
- // - notification has not already been shown yet
- // (see https://github.com/brave/browser-laptop/issues/11021)
- const isNewInstall = migrationState.isNewInstall(state)
- const hasUpgradedWallet = migrationState.hasUpgradedWallet(state)
- const hasBeenNotified = migrationState.hasBeenNotified(state)
- if (!isNewInstall && hasUpgradedWallet && !hasBeenNotified) {
- module.exports.showBraveWalletUpdated()
- }
- }
-
- return state
-}
-
const onInterval = (state) => {
+ if (process.env.LEDGER_NOTIFICATION) {
+ runDebugCounter()
+ }
if (getSetting(settings.PAYMENTS_ENABLED)) {
if (getSetting(settings.PAYMENTS_NOTIFICATIONS)) {
- module.exports.showEnabledNotifications(state)
+ state = module.exports.showEnabledNotifications(state)
}
} else {
module.exports.showDisabledNotifications(state)
@@ -147,7 +118,7 @@ const onResponse = (message, buttonIndex, activeWindow) => {
} else if (buttonIndex === 2 && activeWindow) {
// Add funds: Open payments panel
appActions.createTabRequested({
- url: 'about:preferences#payments',
+ url: 'about:preferences#payments?addFundsOverlayVisible',
windowId: activeWindow.id
})
}
@@ -181,16 +152,16 @@ const onResponse = (message, buttonIndex, activeWindow) => {
appActions.changeSetting(settings.PAYMENTS_NOTIFICATION_TRY_PAYMENTS_DISMISSED, true)
break
- case text.walletConvertedToBat:
+ case text.backupKeys:
if (buttonIndex === 0) {
- // Open backup modal
+ appActions.changeSetting(settings.PAYMENTS_NOTIFICATIONS, false)
+ } else if (buttonIndex === 2 && activeWindow) {
appActions.createTabRequested({
url: 'about:preferences#payments?ledgerBackupOverlayVisible',
windowId: activeWindow.id
})
}
break
-
default:
return
}
@@ -219,6 +190,11 @@ const onDynamicResponse = (message, actionId, activeWindow) => {
appActions.onPromotionRemind()
break
}
+ case 'noThanks':
+ {
+ appActions.changeSetting(settings.PAYMENTS_ALLOW_PROMOTIONS, false)
+ break
+ }
}
appActions.hideNotification(message)
@@ -229,14 +205,17 @@ const onDynamicResponse = (message, actionId, activeWindow) => {
* a day in the future and balance is too low.
* 24 hours prior to reconciliation, show message asking user to review
* their votes.
+ *
+ * If not time to reconcile, check to show backup notification ()
*/
const showEnabledNotifications = (state) => {
+ const now = new Date().getTime()
+ let bootStamp = ledgerState.getInfoProp(state, 'bootStamp')
const reconcileStamp = ledgerState.getInfoProp(state, 'reconcileStamp')
if (!reconcileStamp) {
- return
+ return state
}
-
- if (reconcileStamp - new Date().getTime() < ledgerUtil.milliseconds.day) {
+ if (reconcileStamp - now < ledgerUtil.milliseconds.day) {
if (sufficientBalanceToReconcile(state)) {
if (shouldShowNotificationReviewPublishers()) {
const reconcileFrequency = ledgerState.getInfoProp(state, 'reconcileFrequency')
@@ -245,11 +224,38 @@ const showEnabledNotifications = (state) => {
} else if (shouldShowNotificationAddFunds()) {
showAddFunds()
}
- } else if (reconcileStamp - new Date().getTime() < 2 * ledgerUtil.milliseconds.day) {
+ } else if (reconcileStamp - now < 2 * ledgerUtil.milliseconds.day) {
if (sufficientBalanceToReconcile(state) && (shouldShowNotificationReviewPublishers())) {
- showReviewPublishers(new Date().getTime() + ledgerUtil.milliseconds.day)
+ showReviewPublishers(now + ledgerUtil.milliseconds.day)
+ }
+ } else if (hasFunded(state) && !aboutPreferencesState.hasBeenBackedUp(state)) {
+ const backupNotifyCount = aboutPreferencesState.getPreferencesProp(state, 'backupNotifyCount') || 0
+ const backupNotifyTimestamp = aboutPreferencesState.getPreferencesProp(state, 'backupNotifyTimestamp') || backupNotifyInterval[0]
+ if (!bootStamp) {
+ bootStamp = now
+ state = ledgerState.setInfoProp(state, 'bootStamp', bootStamp)
+ }
+ if (now - bootStamp > backupNotifyTimestamp) {
+ const nextTime = backupNotifyTimestamp + getNextBackupNotification(state, backupNotifyCount + 1, backupNotifyInterval) // set next time to notify case for remind later
+ state = aboutPreferencesState.setPreferencesProp(state, 'backupNotifyCount', (backupNotifyCount + 1))
+ state = aboutPreferencesState.setPreferencesProp(state, 'backupNotifyTimestamp', nextTime)
+ module.exports.showBackupKeys(nextTime)
+ }
+ if (process.env.LEDGER_NOTIFICATION) {
+ watchNotificationTimers(now, bootStamp, backupNotifyCount, backupNotifyTimestamp)
+ }
+ }
+ return state
+}
+
+const getNextBackupNotification = (state, count, interval) => {
+ if (count >= (interval && interval.constructor === Array ? interval.length : 0)) {
+ if (process.env.LEDGER_NOTIFICATION) {
+ return ledgerUtil.milliseconds.minute
}
+ return ledgerUtil.milliseconds.month
}
+ return interval[count]
}
const showDisabledNotifications = (state) => {
@@ -272,6 +278,20 @@ const showDisabledNotifications = (state) => {
}
}
+const showBackupKeys = (nextTime) => {
+ appActions.showNotification({
+ position: 'global',
+ greeting: text.hello,
+ message: text.backupKeys,
+ buttons: [
+ {text: locale.translation('turnOffNotifications')},
+ {text: locale.translation('updateLater')},
+ {text: locale.translation('backupKeysNow'), className: 'primaryButton'}
+ ],
+ options: displayOptions
+ })
+}
+
const showReviewPublishers = (nextTime) => {
appActions.changeSetting(settings.PAYMENTS_NOTIFICATION_RECONCILE_SOON_TIMESTAMP, nextTime)
@@ -324,27 +344,6 @@ const showPaymentDone = (transactionContributionFiat) => {
})
}
-const showBraveWalletUpdated = () => {
- appActions.onBitcoinToBatNotified()
-
- appActions.showNotification({
- position: 'global',
- greeting: text.hello,
- message: text.walletConvertedToBat,
- // Learn More.
- buttons: [
- {text: locale.translation('walletConvertedBackup')},
- {text: locale.translation('walletConvertedDismiss')}
- ],
- options: {
- style: 'greetingStyle',
- persist: false,
- advancedLink: 'https://brave.com/faq-payments/#brave-payments',
- advancedText: locale.translation('walletConvertedLearnMore')
- }
- })
-}
-
const onPromotionReceived = (state) => {
const promotion = ledgerState.getPromotionNotification(state)
@@ -373,6 +372,13 @@ const showPromotionNotification = (state) => {
const data = notification.toJS()
data.position = 'global'
+ if (data.buttons) {
+ data.buttons.unshift({
+ text: locale.translation('noThanks'),
+ buttonActionId: 'noThanks'
+ })
+ }
+
appActions.showNotification(data)
}
@@ -386,6 +392,16 @@ const removePromotionNotification = (state) => {
appActions.hideNotification(notification.get('message'))
}
+const watchNotificationTimers = (now, bootStamp, backupNotifyCount, backupNotifyTimestamp) => { // for testing
+ console.log('now - bootstamp: ' + (now - bootStamp))
+ console.log('count: ' + backupNotifyCount)
+ console.log('backupNotifyTimestamp: ' + backupNotifyTimestamp)
+}
+
+const runDebugCounter = () => {
+ console.log(new Date().getTime() / ledgerUtil.milliseconds.second)
+}
+
if (ipc) {
ipc.on(messages.NOTIFICATION_RESPONSE, (e, message, buttonIndex, checkbox, index, buttonActionId) => {
if (buttonActionId) {
@@ -409,15 +425,16 @@ const getMethods = () => {
const publicMethods = {
showPaymentDone,
init,
- onLaunch,
- showBraveWalletUpdated,
onInterval,
onPromotionReceived,
removePromotionNotification,
showDisabledNotifications,
showEnabledNotifications,
onIntervalDynamic,
- showPromotionNotification
+ showPromotionNotification,
+ showBackupKeys,
+ hasFunded,
+ getNextBackupNotification
}
let privateMethods = {}
diff --git a/app/browser/api/textCalc.js b/app/browser/api/textCalc.js
deleted file mode 100644
index 7525acca8f4..00000000000
--- a/app/browser/api/textCalc.js
+++ /dev/null
@@ -1,147 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Immutable = require('immutable')
-
-// Actions
-const appActions = require('../../../js/actions/appActions')
-
-// Constant
-const siteTags = require('../../../js/constants/siteTags')
-
-// Utils
-const tabs = require('../../browser/tabs')
-const {makeImmutable} = require('../../common/state/immutableUtil')
-
-// Styles
-const globalStyles = require('../../renderer/components/styles/global')
-
-const fontSize = globalStyles.spacing.bookmarksItemFontSize
-const fontFamily = globalStyles.typography.default.family
-
-const calcText = (item, type) => {
- let title = type === siteTags.BOOKMARK
- ? item.get('title') || item.get('location')
- : item.get('title')
-
- if (title && title.length === 0) {
- return
- }
-
- title = title
- .replace(/'/g, '!')
- .replace(/\\"/g, '!')
- .replace(/\\\\/g, '//')
-
- const param = `
- (function() {
- let ctx = document.createElement('canvas').getContext('2d')
- ctx.font = '${fontSize} ${fontFamily}'
- const width = ctx.measureText('${title}').width
-
- return width
- })()
- `
-
- tabs.executeScriptInBackground(param, (err, url, result) => {
- if (err) {
- throw err
- }
-
- if (type === siteTags.BOOKMARK) {
- appActions.onBookmarkWidthChanged(Immutable.fromJS([
- {
- key: item.get('key'),
- parentFolderId: item.get('parentFolderId'),
- width: result[0]
- }
- ]))
- } else {
- appActions.onBookmarkFolderWidthChanged(Immutable.fromJS([
- {
- key: item.get('key'),
- parentFolderId: item.get('parentFolderId'),
- width: result[0]
- }
- ]))
- }
- })
-}
-
-const calcTextList = (list) => {
- const take = 500
- list = makeImmutable(list)
-
- if (list.size === 0) {
- return
- }
-
- let paramList = JSON.stringify(list.take(take))
- .replace(/'/g, '!')
- .replace(/\\"/g, '!')
- .replace(/\\\\/g, '//')
-
- const param = `
- (function() {
- const ctx = document.createElement('canvas').getContext('2d')
- ctx.font = '${fontSize} ${fontFamily}'
- const bookmarks = []
- const folders = []
- const list = JSON.parse('${paramList}')
-
- list.forEach(item => {
- if (item.type === '${siteTags.BOOKMARK}') {
- bookmarks.push({
- key: item.key,
- parentFolderId: item.parentFolderId,
- width: ctx.measureText(item.title || item.location).width
- })
- } else {
- folders.push({
- key: item.key,
- parentFolderId: item.parentFolderId,
- width: ctx.measureText(item.title).width
- })
- }
- })
-
- const result = {
- bookmarks: bookmarks,
- folders: folders
- }
-
- return JSON.stringify(result)
- })()
- `
-
- tabs.executeScriptInBackground(param, (err, url, result) => {
- if (err) {
- console.error('Error in executeScriptInBackground (textCalcUtil.js)')
- }
-
- if (result[0]) {
- const data = JSON.parse(result[0])
- if (data.bookmarks.length > 0) {
- appActions.onBookmarkWidthChanged(Immutable.fromJS(data.bookmarks))
- }
-
- if (data.folders.length > 0) {
- appActions.onBookmarkFolderWidthChanged(Immutable.fromJS(data.folders))
- }
- } else {
- console.error('Error, cant parse bookmarks in executeScriptInBackground')
- }
-
- list = list.skip(take)
-
- if (list.size > 0) {
- calcTextList(list)
- }
- })
-}
-
-module.exports = {
- calcText,
- calcTextList
-}
diff --git a/app/browser/bookmarksExporter.js b/app/browser/bookmarksExporter.js
index 6923549207e..0d5a676eaec 100644
--- a/app/browser/bookmarksExporter.js
+++ b/app/browser/bookmarksExporter.js
@@ -43,7 +43,7 @@ const showDialog = (state) => {
personal = createBookmarkArray(state)
other = createBookmarkArray(state, -1, false)
try {
- fs.writeFileSync(fileName, createBookmarkHTML(personal, other))
+ fs.writeFileSync(fileNames[0], createBookmarkHTML(personal, other))
} catch (e) {
console.log('Error exporting bookmarks: ', e)
}
diff --git a/app/browser/isThirdPartyHost.js b/app/browser/isThirdPartyHost.js
index 89e473ba82f..dc4957cde28 100644
--- a/app/browser/isThirdPartyHost.js
+++ b/app/browser/isThirdPartyHost.js
@@ -3,22 +3,28 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const getBaseDomain = require('../../js/lib/baseDomain').getBaseDomain
+const ip = require('ip')
/**
- * baseContextHost {string} - The base host to check against
- * testHost {string} - The host to check
+ * Checks if two hosts are third party. Subdomains count as first-party to the
+ * parent domain. Uses hostname (no port).
+ * @param {host1} string - First hostname to compare
+ * @param {host2} string - Second hostname to compare
*/
-const isThirdPartyHost = (baseContextHost, testHost) => {
- // TODO: Always return true if these are IP addresses that aren't the same
- if (!testHost || !baseContextHost) {
+const isThirdPartyHost = (host1, host2) => {
+ if (!host1 || !host2) {
return true
}
- const documentDomain = getBaseDomain(baseContextHost)
- if (testHost.length > documentDomain.length) {
- return (testHost.substr(testHost.length - documentDomain.length - 1) !== '.' + documentDomain)
- } else {
- return (testHost !== documentDomain)
+ if (host1 === host2) {
+ return false
}
+
+ if (ip.isV4Format(host1) || ip.isV4Format(host2)) {
+ // '127.0.0.1' and '::7f00:1' are actually equal, but ignore such cases for now
+ return host1 !== host2
+ }
+
+ return getBaseDomain(host1) !== getBaseDomain(host2)
}
module.exports = isThirdPartyHost
diff --git a/app/browser/menu.js b/app/browser/menu.js
index c532c7dd322..a148be6858f 100644
--- a/app/browser/menu.js
+++ b/app/browser/menu.js
@@ -39,6 +39,8 @@ const bookmarkUtil = require('../common/lib/bookmarkUtil')
const isDarwin = platformUtil.isDarwin()
const isLinux = platformUtil.isLinux()
const isWindows = platformUtil.isWindows()
+const {templateUrls} = require('./share')
+const {getAllRendererWindows} = require('./windows')
let appMenu = null
let closedFrames = new Immutable.OrderedMap()
@@ -215,19 +217,6 @@ const createViewSubmenu = () => {
}
},
CommonMenu.separatorMenuItem,
- /*
- {
- label: locale.translation('toolbars'),
- visible: false
- submenu: [
- {label: 'Favorites Bar', accelerator: 'Alt+CmdOrCtrl+B'},
- {label: 'Tab Bar'},
- {label: 'Address Bar', accelerator: 'Alt+CmdOrCtrl+A'},
- {label: 'Tab Previews', accelerator: 'Alt+CmdOrCtrl+P'}
- ]
- },
- CommonMenu.separatorMenuItem,
- */
{
label: locale.translation('stop'),
accelerator: isDarwin ? 'Cmd+.' : 'Esc',
@@ -238,31 +227,6 @@ const createViewSubmenu = () => {
CommonMenu.reloadPageMenuItem(),
CommonMenu.cleanReloadMenuItem(),
CommonMenu.separatorMenuItem,
- /*
- {
- label: locale.translation('readingView'),
- visible: false,
- accelerator: 'Alt+CmdOrCtrl+R'
- }, {
- label: locale.translation('tabManager'),
- visible: false,
- accelerator: 'Alt+CmdOrCtrl+M'
- },
- CommonMenu.separatorMenuItem,
- {
- label: locale.translation('textEncoding'),
- visible: false
- submenu: [
- {label: 'Autodetect', submenu: []},
- CommonMenu.separatorMenuItem,
- {label: 'Unicode'},
- {label: 'Western'},
- CommonMenu.separatorMenuItem,
- {label: 'etc...'}
- ]
- },
- CommonMenu.separatorMenuItem,
- */
{
label: locale.translation('toggleDeveloperTools'),
accelerator: isDarwin ? 'Cmd+Alt+I' : 'Ctrl+Shift+I',
@@ -330,14 +294,6 @@ const createHistorySubmenu = () => {
}
},
CommonMenu.separatorMenuItem,
- /*
- {
- label: locale.translation('showAllHistory'),
- accelerator: 'CmdOrCtrl+Y',
- visible: false
- },
- CommonMenu.separatorMenuItem,
- */
{
label: locale.translation('clearBrowsingData'),
accelerator: 'Shift+CmdOrCtrl+Delete',
@@ -414,6 +370,15 @@ const createBookmarksSubmenu = (state) => {
submenu = submenu.concat(bookmarks)
}
+ const otherBookmarks = menuUtil.createOtherBookmarkTemplateItems(state)
+ if (otherBookmarks.length > 0) {
+ submenu.push(CommonMenu.separatorMenuItem)
+ submenu.push({
+ label: locale.translation('otherBookmarks'),
+ submenu: otherBookmarks
+ })
+ }
+
return submenu
}
@@ -540,6 +505,13 @@ const createDebugSubmenu = (state) => {
click: function (menuItem, browserWindow, e) {
appActions.changeSetting(settings.DEBUG_ALLOW_MANUAL_TAB_DISCARD, menuItem.checked)
}
+ }, {
+ label: 'Display tab identifiers',
+ type: 'checkbox',
+ checked: !!getSetting(settings.DEBUG_VERBOSE_TAB_INFO),
+ click: function (menuItem, browserWindow, e) {
+ appActions.changeSetting(settings.DEBUG_VERBOSE_TAB_INFO, menuItem.checked)
+ }
}
]
}
@@ -633,21 +605,29 @@ const createMenu = (state) => {
}
}
-const setMenuItemChecked = (state, label, checked) => {
- // Update electron menu (Mac / Linux)
+const setMenuItemAttribute = (state, label, key, value) => {
const systemMenuItem = menuUtil.getMenuItem(appMenu, label)
- systemMenuItem.checked = checked
+ systemMenuItem[key] = value
// Update in-memory menu template (Windows)
if (isWindows) {
const oldTemplate = state.getIn(['menu', 'template'])
- const newTemplate = menuUtil.setTemplateItemChecked(oldTemplate, label, checked)
+ const newTemplate = menuUtil.setTemplateItemAttribute(oldTemplate, label, key, value)
if (newTemplate) {
appActions.setMenubarTemplate(newTemplate)
}
}
}
+const updateShareMenuItems = (state, enabled) => {
+ for (let key of Object.keys(templateUrls)) {
+ const siteName = menuUtil.extractSiteName(key)
+ const l10nId = key === 'email' ? 'emailPageLink' : 'sharePageLink'
+ const label = locale.translation(l10nId, {siteName: siteName})
+ setMenuItemAttribute(state, label, 'enabled', enabled)
+ }
+}
+
const doAction = (state, action) => {
switch (action.actionType) {
case appConstants.APP_SET_STATE:
@@ -659,17 +639,31 @@ const doAction = (state, action) => {
const frame = frameStateUtil.getFrameByTabId(state, action.tabId)
if (frame) {
currentLocation = frame.location
- setMenuItemChecked(state, locale.translation('bookmarkPage'), isCurrentLocationBookmarked(state))
+ setMenuItemAttribute(state, locale.translation('bookmarkPage'), 'checked', isCurrentLocationBookmarked(state))
+ }
+ break
+ }
+ case appConstants.APP_WINDOW_CLOSED:
+ case appConstants.APP_WINDOW_CREATED:
+ {
+ const windowCount = getAllRendererWindows().length
+ if (action.actionType === appConstants.APP_WINDOW_CLOSED && windowCount === 0) {
+ updateShareMenuItems(state, false)
+ } else if (action.actionType === appConstants.APP_WINDOW_CREATED && windowCount === 1) {
+ updateShareMenuItems(state, true)
}
break
}
case appConstants.APP_CHANGE_SETTING:
if (action.key === settings.SHOW_BOOKMARKS_TOOLBAR) {
// Update the checkbox next to "Bookmarks Toolbar" (Bookmarks menu)
- setMenuItemChecked(state, locale.translation('bookmarksToolbar'), action.value)
+ setMenuItemAttribute(state, locale.translation('bookmarksToolbar'), 'checked', action.value)
}
if (action.key === settings.DEBUG_ALLOW_MANUAL_TAB_DISCARD) {
- setMenuItemChecked(state, 'Allow manual tab discarding', action.value)
+ setMenuItemAttribute(state, 'Allow manual tab discarding', 'checked', action.value)
+ }
+ if (action.key === settings.DEBUG_VERBOSE_TAB_INFO) {
+ setMenuItemAttribute(state, 'Display tab identifiers', 'checked', action.value)
}
break
case windowConstants.WINDOW_UNDO_CLOSED_FRAME:
diff --git a/app/browser/reducers/autoplayReducer.js b/app/browser/reducers/autoplayReducer.js
index 9e256db5bfe..ae99ded28c8 100644
--- a/app/browser/reducers/autoplayReducer.js
+++ b/app/browser/reducers/autoplayReducer.js
@@ -36,8 +36,8 @@ const showAutoplayMessageBox = (state, tabId) => {
appActions.showNotification({
buttons: [
- {text: locale.translation('allow')},
- {text: locale.translation('deny')}
+ {text: locale.translation('deny')},
+ {text: locale.translation('allow')}
],
message,
frameOrigin: origin,
@@ -50,7 +50,7 @@ const showAutoplayMessageBox = (state, tabId) => {
notificationCallbacks[tabId] = (e, msg, buttonIndex, persist) => {
if (msg === message) {
appActions.hideNotification(message)
- if (buttonIndex === 0) {
+ if (buttonIndex === 1) {
appActions.changeSiteSetting(origin, 'autoplay', true)
if (tab && !tab.isDestroyed()) {
tab.reload()
diff --git a/app/browser/reducers/bookmarkFoldersReducer.js b/app/browser/reducers/bookmarkFoldersReducer.js
index 9bc48632343..3c728b3e5e4 100644
--- a/app/browser/reducers/bookmarkFoldersReducer.js
+++ b/app/browser/reducers/bookmarkFoldersReducer.js
@@ -7,17 +7,15 @@ const Immutable = require('immutable')
// State
const bookmarksState = require('../../common/state/bookmarksState')
const bookmarkFoldersState = require('../../common/state/bookmarkFoldersState')
-const bookmarkToolbarState = require('../../common/state/bookmarkToolbarState')
// Constants
const appConstants = require('../../../js/constants/appConstants')
-const siteTags = require('../../../js/constants/siteTags')
const {STATE_SITES} = require('../../../js/constants/stateConstants')
// Utils
const {makeImmutable} = require('../../common/state/immutableUtil')
const syncUtil = require('../../../js/state/syncUtil')
-const textCalc = require('../../browser/api/textCalc')
+const bookmarkUtil = require('../../common/lib/bookmarkUtil')
const bookmarkFolderUtil = require('../../common/lib/bookmarkFoldersUtil')
const bookmarkFoldersReducer = (state, action, immutableAction) => {
@@ -40,12 +38,10 @@ const bookmarkFoldersReducer = (state, action, immutableAction) => {
state = syncUtil.updateObjectCache(state, folderDetails, STATE_SITES.BOOKMARK_FOLDERS)
folderList = folderList.push(folderDetails)
})
- textCalc.calcTextList(folderList)
} else {
const folderDetails = bookmarkFolderUtil.buildFolder(folder, bookmarkFoldersState.getFolders(state))
state = bookmarkFoldersState.addFolder(state, folderDetails, closestKey)
state = syncUtil.updateObjectCache(state, folderDetails, STATE_SITES.BOOKMARK_FOLDERS)
- textCalc.calcText(folderDetails, siteTags.BOOKMARK_FOLDER)
}
break
}
@@ -66,12 +62,6 @@ const bookmarkFoldersReducer = (state, action, immutableAction) => {
state = bookmarkFoldersState.editFolder(state, key, oldFolder, folder)
state = syncUtil.updateObjectCache(state, folder, STATE_SITES.BOOKMARK_FOLDERS)
- const folderDetails = bookmarkFoldersState.getFolder(state, key)
- textCalc.calcText(folderDetails, siteTags.BOOKMARK_FOLDER)
-
- if (folder.has('parentFolderId') && oldFolder.get('parentFolderId') !== folder.get('parentFolderId')) {
- state = bookmarkToolbarState.setToolbars(state)
- }
break
}
@@ -83,8 +73,6 @@ const bookmarkFoldersReducer = (state, action, immutableAction) => {
break
}
- const oldFolder = bookmarkFoldersState.getFolder(state, key)
-
state = bookmarkFoldersState.moveFolder(
state,
key,
@@ -95,13 +83,7 @@ const bookmarkFoldersReducer = (state, action, immutableAction) => {
const destinationDetail = bookmarksState.findBookmark(state, action.get('destinationKey'))
state = syncUtil.updateObjectCache(state, destinationDetail, STATE_SITES.BOOKMARK_FOLDERS)
- if (
- destinationDetail.get('parentFolderId') === 0 ||
- action.get('destinationKey') === 0 ||
- oldFolder.get('parentFolderId') === 0
- ) {
- state = bookmarkToolbarState.setToolbars(state)
- }
+ bookmarkUtil.closeToolbarIfEmpty(state)
break
}
case appConstants.APP_REMOVE_BOOKMARK_FOLDER:
@@ -118,34 +100,12 @@ const bookmarkFoldersReducer = (state, action, immutableAction) => {
state = bookmarkFoldersState.removeFolder(state, key)
state = syncUtil.updateObjectCache(state, folder, STATE_SITES.BOOKMARK_FOLDERS)
})
- state = bookmarkToolbarState.setToolbars(state)
} else {
const folder = bookmarkFoldersState.getFolder(state, folderKey)
state = bookmarkFoldersState.removeFolder(state, folderKey)
state = syncUtil.updateObjectCache(state, folder, STATE_SITES.BOOKMARK_FOLDERS)
- if (folder.get('parentFolderId') === 0) {
- state = bookmarkToolbarState.setToolbars(state)
- }
- }
- break
- }
- case appConstants.APP_ON_BOOKMARK_FOLDER_WIDTH_CHANGED:
- {
- if (action.get('folderList', Immutable.List()).isEmpty()) {
- break
- }
-
- let updateToolbar = false
- action.get('folderList').forEach(item => {
- state = bookmarkFoldersState.setWidth(state, item.get('key'), item.get('width'))
- if (item.get('parentFolderId') === 0) {
- updateToolbar = true
- }
- })
-
- if (updateToolbar) {
- state = bookmarkToolbarState.setToolbars(state)
}
+ bookmarkUtil.closeToolbarIfEmpty(state)
break
}
}
diff --git a/app/browser/reducers/bookmarkToolbarReducer.js b/app/browser/reducers/bookmarkToolbarReducer.js
deleted file mode 100644
index cc75a48dcd8..00000000000
--- a/app/browser/reducers/bookmarkToolbarReducer.js
+++ /dev/null
@@ -1,44 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Immutable = require('immutable')
-
-// Constants
-const appConstants = require('../../../js/constants/appConstants')
-
-// State
-const bookmarksState = require('../../common/state/bookmarksState')
-const bookmarkFoldersState = require('../../common/state/bookmarkFoldersState')
-
-// Util
-const {makeImmutable} = require('../../common/state/immutableUtil')
-const textCalc = require('../../browser/api/textCalc')
-
-const bookmarkToolbarReducer = (state, action, immutableAction) => {
- action = immutableAction || makeImmutable(action)
- switch (action.get('actionType')) {
- case appConstants.APP_SET_STATE:
- {
- // update session for 0.21.x version
- const bookmarks = bookmarksState.getBookmarks(state)
- let list = Immutable.List()
- if (bookmarks.first() && !bookmarks.first().has('width')) {
- list = bookmarks.toList()
- }
-
- const bookmarkFolders = bookmarkFoldersState.getFolders(state)
- if (bookmarkFolders.first() && !bookmarkFolders.first().has('width')) {
- list = list.concat(bookmarkFolders.toList())
- }
-
- if (!list.isEmpty()) {
- textCalc.calcTextList(list)
- }
- }
- break
- }
- return state
-}
-
-module.exports = bookmarkToolbarReducer
diff --git a/app/browser/reducers/bookmarksReducer.js b/app/browser/reducers/bookmarksReducer.js
index aed8d035b84..135bfed90be 100644
--- a/app/browser/reducers/bookmarksReducer.js
+++ b/app/browser/reducers/bookmarksReducer.js
@@ -6,11 +6,9 @@ const Immutable = require('immutable')
// State
const bookmarksState = require('../../common/state/bookmarksState')
-const bookmarkToolbarState = require('../../common/state/bookmarkToolbarState')
// Constants
const appConstants = require('../../../js/constants/appConstants')
-const siteTags = require('../../../js/constants/siteTags')
const {STATE_SITES} = require('../../../js/constants/stateConstants')
// Utils
@@ -18,7 +16,6 @@ const {makeImmutable} = require('../../common/state/immutableUtil')
const syncUtil = require('../../../js/state/syncUtil')
const bookmarkUtil = require('../../common/lib/bookmarkUtil')
const bookmarkLocationCache = require('../../common/cache/bookmarkLocationCache')
-const textCalc = require('../../browser/api/textCalc')
const bookmarksReducer = (state, action, immutableAction) => {
action = immutableAction || makeImmutable(action)
@@ -44,12 +41,10 @@ const bookmarksReducer = (state, action, immutableAction) => {
state = syncUtil.updateObjectCache(state, bookmarkDetail, STATE_SITES.BOOKMARKS)
bookmarkList = bookmarkList.push(bookmarkDetail)
})
- textCalc.calcTextList(bookmarkList)
} else {
const bookmarkDetail = bookmarkUtil.buildBookmark(state, bookmark)
state = bookmarksState.addBookmark(state, bookmarkDetail, closestKey, !isLeftSide)
state = syncUtil.updateObjectCache(state, bookmarkDetail, STATE_SITES.BOOKMARKS)
- textCalc.calcText(bookmarkDetail, siteTags.BOOKMARK)
}
state = bookmarkUtil.updateActiveTabBookmarked(state)
@@ -72,12 +67,8 @@ const bookmarksReducer = (state, action, immutableAction) => {
const bookmarkDetail = bookmarkUtil.buildEditBookmark(oldBookmark, bookmark)
state = bookmarksState.editBookmark(state, oldBookmark, bookmarkDetail)
state = syncUtil.updateObjectCache(state, bookmark, STATE_SITES.BOOKMARKS)
- textCalc.calcText(bookmarkDetail, siteTags.BOOKMARK)
state = bookmarkUtil.updateActiveTabBookmarked(state)
- if (oldBookmark.get('parentFolderId') !== bookmarkDetail.get('parentFolderId')) {
- state = bookmarkToolbarState.setToolbars(state)
- }
break
}
case appConstants.APP_MOVE_BOOKMARK:
@@ -88,8 +79,6 @@ const bookmarksReducer = (state, action, immutableAction) => {
break
}
- const oldBookmark = bookmarksState.getBookmark(state, key)
-
state = bookmarksState.moveBookmark(
state,
key,
@@ -100,14 +89,7 @@ const bookmarksReducer = (state, action, immutableAction) => {
const destinationDetail = bookmarksState.findBookmark(state, action.get('destinationKey'))
state = syncUtil.updateObjectCache(state, destinationDetail, STATE_SITES.BOOKMARKS)
-
- if (
- destinationDetail.get('parentFolderId') === 0 ||
- action.get('destinationKey') === 0 ||
- oldBookmark.get('parentFolderId') === 0
- ) {
- state = bookmarkToolbarState.setToolbars(state)
- }
+ bookmarkUtil.closeToolbarIfEmpty(state)
break
}
case appConstants.APP_REMOVE_BOOKMARK:
@@ -121,34 +103,11 @@ const bookmarksReducer = (state, action, immutableAction) => {
action.get('bookmarkKey', Immutable.List()).forEach((key) => {
state = bookmarksState.removeBookmark(state, key)
})
- state = bookmarkToolbarState.setToolbars(state)
} else {
- const bookmark = bookmarksState.getBookmark(state, bookmarkKey)
state = bookmarksState.removeBookmark(state, bookmarkKey)
- if (bookmark.get('parentFolderId') === 0) {
- state = bookmarkToolbarState.setToolbars(state)
- }
}
state = bookmarkUtil.updateActiveTabBookmarked(state)
- break
- }
- case appConstants.APP_ON_BOOKMARK_WIDTH_CHANGED:
- {
- if (action.get('bookmarkList', Immutable.List()).isEmpty()) {
- break
- }
-
- let updateToolbar = false
- action.get('bookmarkList').forEach(item => {
- state = bookmarksState.setWidth(state, item.get('key'), item.get('width'))
- if (item.get('parentFolderId') === 0) {
- updateToolbar = true
- }
- })
-
- if (updateToolbar) {
- state = bookmarkToolbarState.setToolbars(state)
- }
+ bookmarkUtil.closeToolbarIfEmpty(state)
break
}
}
diff --git a/app/browser/reducers/historyReducer.js b/app/browser/reducers/historyReducer.js
index 9802f702f5d..8f53dc5a841 100644
--- a/app/browser/reducers/historyReducer.js
+++ b/app/browser/reducers/historyReducer.js
@@ -19,6 +19,7 @@ const messages = require('../../../js/constants/messages')
const settings = require('../../../js/constants/settings')
// Utils
+const urlParse = require('../../common/urlParse')
const {makeImmutable} = require('../../common/state/immutableUtil')
const {remove} = require('../../common/lib/siteSuggestions')
const syncUtil = require('../../../js/state/syncUtil')
@@ -126,6 +127,24 @@ const historyReducer = (state, action, immutableAction) => {
break
}
+ case appConstants.APP_REMOVE_HISTORY_DOMAIN: {
+ const domain = action.get('domain')
+
+ if (!domain) {
+ break
+ }
+
+ historyState.getSites(state).forEach(historySite => {
+ if (urlParse(historySite.get('location')).hostname === domain) {
+ state = historyState.removeSite(state, historySite.get('key'))
+ }
+ })
+
+ state = aboutHistoryState.setHistory(state, historyState.getSites(state))
+
+ break
+ }
+
case appConstants.APP_POPULATE_HISTORY:
{
state = aboutHistoryState.setHistory(state, historyState.getSites(state))
diff --git a/app/browser/reducers/ledgerReducer.js b/app/browser/reducers/ledgerReducer.js
index 31bc8045074..9e8c611f0df 100644
--- a/app/browser/reducers/ledgerReducer.js
+++ b/app/browser/reducers/ledgerReducer.js
@@ -4,22 +4,27 @@
const Immutable = require('immutable')
const {BrowserWindow} = require('electron')
+const {getWebContents} = require('../webContentsCache')
// Constants
const appConstants = require('../../../js/constants/appConstants')
const windowConstants = require('../../../js/constants/windowConstants')
const settings = require('../../../js/constants/settings')
+const tabActionConstants = require('../../common/constants/tabAction')
+const ledgerStatuses = require('../../common/constants/ledgerStatuses')
// State
const ledgerState = require('../../common/state/ledgerState')
const pageDataState = require('../../common/state/pageDataState')
-const migrationState = require('../../common/state/migrationState')
const updateState = require('../../common/state/updateState')
+const aboutPreferencesState = require('../../common/state/aboutPreferencesState')
+const tabState = require('../../common/state/tabState')
// Utils
+const windows = require('../windows')
const ledgerApi = require('../../browser/api/ledger')
const ledgerNotifications = require('../../browser/api/ledgerNotifications')
-const {makeImmutable} = require('../../common/state/immutableUtil')
+const {makeImmutable, makeJS} = require('../../common/state/immutableUtil')
const getSetting = require('../../../js/settings').getSetting
const ledgerReducer = (state, action, immutableAction) => {
@@ -43,16 +48,24 @@ const ledgerReducer = (state, action, immutableAction) => {
}
case appConstants.APP_BACKUP_KEYS:
{
- ledgerApi.backupKeys(state, action.get('backupAction'))
+ state = ledgerApi.backupKeys(state, action.get('backupAction'))
break
}
case appConstants.APP_RECOVER_WALLET:
{
- state = ledgerApi.recoverKeys(
- state,
- action.get('useRecoveryKeyFile'),
- action.get('recoveryKey')
- )
+ const recoveryKey = action.get('recoveryKey')
+ const useRecoveryKeyFile = action.get('useRecoveryKeyFile')
+
+ if (!useRecoveryKeyFile) {
+ state = aboutPreferencesState.setRecoveryInProgress(state, true)
+ }
+
+ state = ledgerApi.recoverKeys(state, useRecoveryKeyFile, recoveryKey)
+ break
+ }
+ case appConstants.APP_ON_FILE_RECOVERY_KEYS:
+ {
+ state = ledgerApi.fileRecoveryKeys(state, action.get('file'))
break
}
case appConstants.APP_SHUTTING_DOWN:
@@ -62,12 +75,15 @@ const ledgerReducer = (state, action, immutableAction) => {
}
case appConstants.APP_ON_CLEAR_BROWSING_DATA:
{
- const defaults = state.get('clearBrowsingDataDefaults')
+ const defaults = state.get('clearBrowsingDataDefaults') || Immutable.Map()
const temp = state.get('tempClearBrowsingData', Immutable.Map())
const clearData = defaults ? defaults.merge(temp) : temp
- if (clearData.get('browserHistory') && !getSetting(settings.PAYMENTS_ENABLED)) {
- state = ledgerState.resetSynopsis(state)
- ledgerApi.deleteSynopsis()
+ if (clearData.get('publishersClear')) {
+ state = ledgerApi.resetPublishers(state)
+ }
+
+ if (clearData.get('paymentHistory')) {
+ state = ledgerApi.clearPaymentHistory(state)
}
break
}
@@ -146,21 +162,39 @@ const ledgerReducer = (state, action, immutableAction) => {
state = ledgerApi.verifiedP(state, publisherKey)
break
}
- case 'ledgerPinPercentage':
- {
- const value = action.get('value')
- const publisher = ledgerState.getPublisher(state, publisherKey)
- if (publisher.isEmpty() || publisher.get('pinPercentage') === value) {
- break
- }
- state = ledgerState.setPublishersProp(state, publisherKey, 'pinPercentage', value)
- ledgerApi.savePublisherData(publisherKey, 'pinPercentage', value)
- state = ledgerApi.updatePublisherInfo(state, publisherKey)
- break
- }
}
break
}
+ case appConstants.APP_ON_LEDGER_PIN_PUBLISHER:
+ {
+ const value = action.get('value')
+ const publisherKey = action.get('publisherKey')
+ const publisher = ledgerState.getPublisher(state, publisherKey)
+
+ if (publisher.isEmpty() || publisher.get('pinPercentage') === value) {
+ break
+ }
+
+ state = ledgerState.setPublishersProp(state, publisherKey, 'pinPercentage', value)
+ ledgerApi.savePublisherData(publisherKey, 'pinPercentage', value)
+ state = ledgerApi.updatePublisherInfo(state, publisherKey)
+ break
+ }
+ case appConstants.APP_ADD_PUBLISHER_TO_LEDGER:
+ {
+ const tabId = action.get('tabId')
+ const location = action.get('location')
+
+ if (!location) {
+ break
+ }
+
+ const passedTabId = tabId || tabState.TAB_ID_NONE
+
+ state = ledgerApi.addNewLocation(state, location, passedTabId, false, true)
+ state = ledgerApi.pageDataChanged(state, {}, true)
+ break
+ }
case appConstants.APP_REMOVE_SITE_SETTING:
{
const pattern = action.get('hostPattern')
@@ -201,7 +235,7 @@ const ledgerReducer = (state, action, immutableAction) => {
}
case appConstants.APP_ON_FAVICON_RECEIVED:
{
- state = ledgerState.setPublishersProp(state, action.get('publisherKey'), 'faviconURL', action.get('blob'))
+ state = ledgerApi.onFavIconReceived(state, action.get('publisherKey'), action.get('blob'))
state = ledgerApi.updatePublisherInfo(state)
break
}
@@ -222,13 +256,14 @@ const ledgerReducer = (state, action, immutableAction) => {
state = ledgerState.setPublisherOption(state, key, prop, value)
break
}
+ case appConstants.APP_ON_PUBLISHERS_OPTION_UPDATE:
+ {
+ state = ledgerApi.setPublishersOptions(state, action.get('publishersArray'))
+ break
+ }
case appConstants.APP_ON_LEDGER_WALLET_CREATE:
{
ledgerApi.boot()
- if (ledgerApi.getNewClient() === null) {
- state = migrationState.setConversionTimestamp(state, new Date().getTime())
- state = migrationState.setTransitionStatus(state, false)
- }
break
}
case appConstants.APP_ON_BOOT_STATE_FILE:
@@ -243,7 +278,7 @@ const ledgerReducer = (state, action, immutableAction) => {
}
case appConstants.APP_LEDGER_PAYMENTS_PRESENT:
{
- ledgerApi.paymentPresent(state, action.get('tabId'), action.get('present'))
+ state = ledgerApi.paymentPresent(state, action.get('tabId'), action.get('present'))
break
}
case appConstants.APP_ON_ADD_FUNDS_CLOSED:
@@ -293,7 +328,7 @@ const ledgerReducer = (state, action, immutableAction) => {
}
case appConstants.APP_ON_RESET_RECOVERY_STATUS:
{
- state = ledgerState.setRecoveryStatus(state, null)
+ state = aboutPreferencesState.setRecoveryStatus(state, null)
state = ledgerState.setInfoProp(state, 'error', null)
break
}
@@ -302,22 +337,6 @@ const ledgerReducer = (state, action, immutableAction) => {
state = ledgerApi.onInitRead(state, action.parsedData)
break
}
- case appConstants.APP_ON_BTC_TO_BAT_NOTIFIED:
- {
- state = migrationState.setNotifiedTimestamp(state, new Date().getTime())
- break
- }
- case appConstants.APP_ON_BTC_TO_BAT_BEGIN_TRANSITION:
- {
- state = migrationState.setTransitionStatus(state, true)
- break
- }
- case appConstants.APP_ON_BTC_TO_BAT_TRANSITIONED:
- {
- state = migrationState.setConversionTimestamp(state, new Date().getTime())
- state = migrationState.setTransitionStatus(state, false)
- break
- }
case appConstants.APP_ON_LEDGER_QR_GENERATED:
{
state = ledgerState.saveQRCode(state, action.get('currency'), action.get('image'))
@@ -380,22 +399,20 @@ const ledgerReducer = (state, action, immutableAction) => {
state = ledgerApi.pageDataChanged(state)
break
}
- case windowConstants.WINDOW_GOT_RESPONSE_DETAILS:
+ case tabActionConstants.FINISH_NAVIGATION:
{
if (!getSetting(settings.PAYMENTS_ENABLED)) {
break
}
- // Only capture response for the page (not sub resources, like images, JavaScript, etc)
- if (action.getIn(['details', 'resourceType']) === 'mainFrame') {
- const pageUrl = action.getIn(['details', 'newURL'])
-
- // create a page view event if this is a page load on the active tabId
- const lastActiveTabId = pageDataState.getLastActiveTabId(state)
- const tabId = action.get('tabId')
+ // create a page view event if this is a page load on the active tabId
+ const lastActiveTabId = pageDataState.getLastActiveTabId(state)
+ const tabId = action.get('tabId')
+ const tab = getWebContents(tabId)
+ if (tab && !tab.isDestroyed()) {
if (!lastActiveTabId || tabId === lastActiveTabId) {
state = ledgerApi.pageDataChanged(state, {
- location: pageUrl,
+ location: tab.getURL(),
tabId
})
}
@@ -417,9 +434,24 @@ const ledgerReducer = (state, action, immutableAction) => {
state = ledgerNotifications.onPromotionReceived(state)
break
}
+ case appConstants.APP_ON_PROMOTION_CLICK:
+ {
+ ledgerApi.getCaptcha(state)
+ break
+ }
+ case appConstants.APP_ON_CAPTCHA_RESPONSE:
+ {
+ state = ledgerApi.onCaptchaResponse(state, action.get('body'))
+ break
+ }
+ case appConstants.APP_ON_CAPTCHA_CLOSE:
+ {
+ state = ledgerState.setPromotionProp(state, 'promotionStatus', null)
+ break
+ }
case appConstants.APP_ON_PROMOTION_CLAIM:
{
- ledgerApi.claimPromotion(state)
+ ledgerApi.claimPromotion(state, action.get('x'), action.get('y'))
break
}
case appConstants.APP_ON_PROMOTION_REMIND:
@@ -429,7 +461,7 @@ const ledgerReducer = (state, action, immutableAction) => {
}
case appConstants.APP_ON_LEDGER_MEDIA_DATA:
{
- state = ledgerApi.onMediaRequest(state, action.get('url'), action.get('type'), action.get('tabId'))
+ state = ledgerApi.onMediaRequest(state, action.get('url'), action.get('type'), action.get('details'))
break
}
case appConstants.APP_ON_PRUNE_SYNOPSIS:
@@ -471,8 +503,7 @@ const ledgerReducer = (state, action, immutableAction) => {
}
case appConstants.APP_ON_REFERRAL_CODE_READ:
{
- state = updateState.setUpdateProp(state, 'referralDownloadId', action.get('downloadId'))
- state = updateState.setUpdateProp(state, 'referralPromoCode', action.get('promoCode'))
+ state = ledgerApi.onReferralRead(state, action.get('body'), windows.getActiveWindowId())
break
}
case appConstants.APP_ON_REFERRAL_CODE_FAIL:
@@ -485,6 +516,20 @@ const ledgerReducer = (state, action, immutableAction) => {
state = ledgerApi.checkReferralActivity(state)
break
}
+ case appConstants.APP_ON_FETCH_REFERRAL_HEADERS:
+ {
+ state = ledgerApi.onFetchReferralHeaders(state, action.get('error'), action.get('response'), action.get('body'))
+ break
+ }
+ case appConstants.APP_ON_LEDGER_FUZZING:
+ {
+ state = ledgerState.setAboutProp(state, 'status', ledgerStatuses.FUZZING)
+ const newStamp = parseInt(action.get('newStamp'))
+ if (!isNaN(newStamp) && newStamp > 0) {
+ state = ledgerState.setInfoProp(state, 'reconcileStamp', newStamp)
+ }
+ break
+ }
case appConstants.APP_ON_REFERRAL_ACTIVITY:
{
state = updateState.setUpdateProp(state, 'referralTimestamp', new Date().getTime())
@@ -503,6 +548,28 @@ const ledgerReducer = (state, action, immutableAction) => {
)
break
}
+ case appConstants.APP_ON_WALLET_PROPERTIES_ERROR:
+ {
+ state = ledgerState.setAboutProp(state, 'status', ledgerStatuses.SERVER_PROBLEM)
+ break
+ }
+ case appConstants.APP_ON_LEDGER_BACKUP_SUCCESS:
+ {
+ state = aboutPreferencesState.setBackupStatus(state, true)
+ break
+ }
+ case appConstants.APP_ON_WALLET_DELETE:
+ {
+ state = ledgerApi.deleteWallet(state)
+ break
+ }
+ case appConstants.APP_ON_PUBLISHER_TOGGLE_UPDATE:
+ {
+ const viewData = makeJS(action.get('viewData'))
+ state = ledgerApi.pageDataChanged(state, {}, true)
+ state = ledgerApi.pageDataChanged(state, viewData, true)
+ break
+ }
}
return state
}
diff --git a/app/browser/reducers/passwordManagerReducer.js b/app/browser/reducers/passwordManagerReducer.js
index 00ac942e89e..6b2d3a0edf3 100644
--- a/app/browser/reducers/passwordManagerReducer.js
+++ b/app/browser/reducers/passwordManagerReducer.js
@@ -50,9 +50,9 @@ const savePassword = (username, origin, tabId) => {
})
}
- const webContents = getWebContents(tabId)
-
passwordCallbacks[message] = (buttonIndex) => {
+ const webContents = getWebContents(tabId)
+
delete passwordCallbacks[message]
appActions.hideNotification(message)
@@ -61,13 +61,17 @@ const savePassword = (username, origin, tabId) => {
return
}
if (buttonIndex === 2) {
- // never save
- webContents.neverSavePassword()
+ if (webContents && !webContents.isDestroyed()) {
+ // never save
+ webContents.neverSavePassword()
+ }
return
}
- // save password
- webContents.savePassword()
+ if (webContents && !webContents.isDestroyed()) {
+ // save password
+ webContents.savePassword()
+ }
}
}
@@ -96,18 +100,22 @@ const updatePassword = (username, origin, tabId) => {
})
}
- const webContents = getWebContents(tabId)
-
passwordCallbacks[message] = (buttonIndex) => {
+ const webContents = getWebContents(tabId)
+
delete passwordCallbacks[message]
appActions.hideNotification(message)
if (buttonIndex === 0) {
- webContents.updatePassword()
+ if (webContents && !webContents.isDestroyed()) {
+ webContents.updatePassword()
+ }
return
}
- // never save
- webContents.noUpdatePassword()
+ if (webContents && !webContents.isDestroyed()) {
+ // never save
+ webContents.noUpdatePassword()
+ }
}
}
diff --git a/app/browser/reducers/pinnedSitesReducer.js b/app/browser/reducers/pinnedSitesReducer.js
index e717dfe23eb..7ff2c57bb69 100644
--- a/app/browser/reducers/pinnedSitesReducer.js
+++ b/app/browser/reducers/pinnedSitesReducer.js
@@ -16,15 +16,17 @@ const {STATE_SITES} = require('../../../js/constants/stateConstants')
const {makeImmutable} = require('../../common/state/immutableUtil')
const syncUtil = require('../../../js/state/syncUtil')
const pinnedSitesUtil = require('../../common/lib/pinnedSitesUtil')
+const {shouldDebugTabEvents} = require('../../cmdLine')
const pinnedSitesReducer = (state, action, immutableAction) => {
action = immutableAction || makeImmutable(action)
switch (action.get('actionType')) {
case appConstants.APP_TAB_UPDATED:
{
+ const tabId = action.getIn(['tabValue', 'tabId'])
+ // has this tab just been pinned or un-pinned?
if (action.getIn(['changeInfo', 'pinned']) != null) {
const pinned = action.getIn(['changeInfo', 'pinned'])
- const tabId = action.getIn(['tabValue', 'tabId'])
const tab = tabState.getByTabId(state, tabId)
if (!tab) {
console.warn('Trying to pin a tabId which does not exist:', tabId, 'tabs: ', state.get('tabs').toJS())
@@ -38,6 +40,39 @@ const pinnedSitesReducer = (state, action, immutableAction) => {
state = pinnedSitesState.removePinnedSite(state, siteDetail)
}
state = syncUtil.updateObjectCache(state, siteDetail, STATE_SITES.PINNED_SITES)
+ } else if (action.getIn(['changeInfo', 'index']) != null && tabState.isTabPinned(state, tabId)) {
+ // The tab index changed and tab is already pinned.
+ // We cannot rely on the index reported by muon as pinned tabs may not always start at 0,
+ // and each window may have a different index for each pinned tab,
+ // but we want the 'order' in pinnedSites to be sequential starting at 0.
+ // So, focus on the order of the tabs, and make our own index.
+ const windowId = tabState.getWindowId(state, tabId)
+ if (windowId == null || windowId === -1) {
+ break
+ }
+ let windowPinnedTabs = tabState.getPinnedTabsByWindowId(state, windowId)
+ if (!windowPinnedTabs) {
+ break
+ }
+ windowPinnedTabs = windowPinnedTabs.sort((a, b) => a.get('index') - b.get('index'))
+ const tab = tabState.getByTabId(state, tabId)
+ const windowPinnedTabIndex = windowPinnedTabs.findIndex(pinnedTab => pinnedTab === tab)
+ if (windowPinnedTabIndex === -1) {
+ console.error(`pinnedSitesReducer:APP_TAB_UPDATED: could not find tab ${tabId} as a pinned tab in tabState!`)
+ }
+ const siteKey = pinnedSitesUtil.getKey(pinnedSitesUtil.getDetailsFromTab(pinnedSitesState.getSites(state), tab))
+ // update state for new order so pinned tabs order is persisted on restart
+ if (shouldDebugTabEvents) {
+ console.log(`Moving pinned site '${siteKey}' to order: ${windowPinnedTabIndex}`)
+ }
+ const newState = pinnedSitesState.moveSiteToNewOrder(state, siteKey, windowPinnedTabIndex, shouldDebugTabEvents)
+ // did anything change?
+ if (newState !== state) {
+ state = newState
+ // make sure it's synced
+ const newSite = pinnedSitesState.getSite(state, siteKey)
+ state = syncUtil.updateObjectCache(state, newSite, STATE_SITES.PINNED_SITES)
+ }
}
break
}
@@ -49,25 +84,6 @@ const pinnedSitesReducer = (state, action, immutableAction) => {
}
break
}
- case appConstants.APP_ON_PINNED_TAB_REORDER:
- {
- const siteKey = action.get('siteKey')
-
- if (siteKey == null) {
- break
- }
-
- state = pinnedSitesState.reOrderSite(
- state,
- siteKey,
- action.get('destinationKey'),
- action.get('prepend')
- )
-
- const newSite = pinnedSitesState.getSite(state, siteKey)
- state = syncUtil.updateObjectCache(state, newSite, STATE_SITES.PINNED_SITES)
- break
- }
}
return state
diff --git a/app/browser/reducers/siteSettingsReducer.js b/app/browser/reducers/siteSettingsReducer.js
index e0a7be29800..eb69de0267a 100644
--- a/app/browser/reducers/siteSettingsReducer.js
+++ b/app/browser/reducers/siteSettingsReducer.js
@@ -57,6 +57,9 @@ const siteSettingsReducer = (state, action, immutableAction) => {
if (action.get('skipSync')) {
newEntry = newEntry.set('skipSync', true)
}
+ if (action.get('key') === 'ledgerPaymentsShown') {
+ newEntry = newEntry.delete('ledgerPayments')
+ }
newSiteSettings = newSiteSettings.set(hostPattern, newEntry)
})
state = state.set(propertyName, newSiteSettings)
diff --git a/app/browser/reducers/tabsReducer.js b/app/browser/reducers/tabsReducer.js
index b2935dbffba..596995be691 100644
--- a/app/browser/reducers/tabsReducer.js
+++ b/app/browser/reducers/tabsReducer.js
@@ -4,44 +4,93 @@
'use strict'
-const appConfig = require('../../../js/constants/appConfig')
-const appConstants = require('../../../js/constants/appConstants')
-const tabs = require('../tabs')
-const windows = require('../windows')
-const {getWebContents} = require('../webContentsCache')
const {BrowserWindow} = require('electron')
+const Immutable = require('immutable')
+
+// Actions
+const windowActions = require('../../../js/actions/windowActions')
+
+// State
const tabState = require('../../common/state/tabState')
+const windowState = require('../../common/state/windowState')
const siteSettings = require('../../../js/state/siteSettings')
const siteSettingsState = require('../../common/state/siteSettingsState')
+const {frameOptsFromFrame} = require('../../../js/state/frameStateUtil')
+const updateState = require('../../common/state/updateState')
+
+// Constants
+const appConfig = require('../../../js/constants/appConfig')
+const appConstants = require('../../../js/constants/appConstants')
const windowConstants = require('../../../js/constants/windowConstants')
-const windowActions = require('../../../js/actions/windowActions')
+const webrtcConstants = require('../../../js/constants/webrtcConstants')
+const dragTypes = require('../../../js/constants/dragTypes')
+const tabActionConsts = require('../../common/constants/tabAction')
+const appActions = require('../../../js/actions/appActions')
+const settings = require('../../../js/constants/settings')
+
+// Utils
+const tabs = require('../tabs')
+const windows = require('../windows')
+const {getWebContents} = require('../webContentsCache')
const {makeImmutable} = require('../../common/state/immutableUtil')
const {getFlashResourceId} = require('../../../js/flash')
const {l10nErrorText} = require('../../common/lib/httpUtil')
-const Immutable = require('immutable')
-const dragTypes = require('../../../js/constants/dragTypes')
-const tabActionConsts = require('../../common/constants/tabAction')
const flash = require('../../../js/flash')
-const {frameOptsFromFrame} = require('../../../js/state/frameStateUtil')
const {isSourceAboutUrl, isTargetAboutUrl, isNavigatableAboutPage} = require('../../../js/lib/appUrlUtil')
-
-const WEBRTC_DEFAULT = 'default'
-const WEBRTC_DISABLE_NON_PROXY = 'disable_non_proxied_udp'
+const {shouldDebugTabEvents} = require('../../cmdLine')
const getWebRTCPolicy = (state, tabId) => {
+ const webrtcSetting = state.getIn(['settings', settings.WEBRTC_POLICY])
+ if (webrtcSetting && webrtcSetting !== webrtcConstants.default) {
+ // Global webrtc setting overrides fingerprinting shield setting
+ return webrtcSetting
+ }
+
const tabValue = tabState.getByTabId(state, tabId)
if (tabValue == null) {
- return WEBRTC_DEFAULT
+ return webrtcConstants.default
}
+
const allSiteSettings = siteSettingsState.getAllSiteSettings(state, tabValue.get('incognito') === true)
const tabSiteSettings =
siteSettings.getSiteSettingsForURL(allSiteSettings, tabValue.get('url'))
const activeSiteSettings = siteSettings.activeSettings(tabSiteSettings, state, appConfig)
if (!activeSiteSettings || activeSiteSettings.fingerprintingProtection !== true) {
- return WEBRTC_DEFAULT
+ return webrtcConstants.default
} else {
- return WEBRTC_DISABLE_NON_PROXY
+ return webrtcConstants.disableNonProxiedUdp
+ }
+}
+
+function expireContentSettings (state, tabId, origin) {
+ // Expired Flash settings should be deleted when the webview is
+ // navigated or closed. Same for NoScript's allow-once option.
+ const tabValue = tabState.getByTabId(state, tabId)
+ const isPrivate = tabValue.get('incognito') === true
+ const allSiteSettings = siteSettingsState.getAllSiteSettings(state, isPrivate)
+ const tabSiteSettings =
+ siteSettings.getSiteSettingsForURL(allSiteSettings, tabValue.get('url'))
+ if (!tabSiteSettings) {
+ return
+ }
+ const originFlashEnabled = tabSiteSettings.get('flash')
+ const originWidevineEnabled = tabSiteSettings.get('widevine')
+ const originNoScriptEnabled = tabSiteSettings.get('noScript')
+ const originNoScriptExceptions = tabSiteSettings.get('noScriptExceptions')
+ if (typeof originFlashEnabled === 'number') {
+ if (originFlashEnabled < Date.now()) {
+ appActions.removeSiteSetting(origin, 'flash', isPrivate)
+ }
+ }
+ if (originWidevineEnabled === 0) {
+ appActions.removeSiteSetting(origin, 'widevine', isPrivate)
+ }
+ if (originNoScriptEnabled === 0) {
+ appActions.removeSiteSetting(origin, 'noScript', isPrivate)
+ }
+ if (originNoScriptExceptions) {
+ appActions.noScriptExceptionsAdded(origin, originNoScriptExceptions.map(value => value === 0 ? false : value))
}
}
@@ -52,7 +101,13 @@ const tabsReducer = (state, action, immutableAction) => {
case tabActionConsts.START_NAVIGATION:
{
const tabId = action.get('tabId')
+ const originalOrigin = tabState.getVisibleOrigin(state, tabId)
state = tabState.setNavigationState(state, tabId, action.get('navigationState'))
+ const newOrigin = tabState.getVisibleOrigin(state, tabId)
+ // For cross-origin navigation, clear temp approvals
+ if (originalOrigin !== newOrigin) {
+ expireContentSettings(state, tabId, originalOrigin)
+ }
setImmediate(() => {
tabs.setWebRTCIPHandlingPolicy(tabId, getWebRTCPolicy(state, tabId))
})
@@ -66,28 +121,62 @@ const tabsReducer = (state, action, immutableAction) => {
})
break
}
+ case tabActionConsts.FIND_IN_PAGE_REQUEST:
+ {
+ const tabId = tabState.resolveTabId(state, action.get('tabId'))
+ setImmediate(() => {
+ tabs.findInPage(
+ tabId,
+ action.get('searchString'),
+ action.get('caseSensitivity'),
+ action.get('forward'),
+ action.get('findNext')
+ )
+ })
+ break
+ }
+ case tabActionConsts.STOP_FIND_IN_PAGE_REQUEST:
+ {
+ const tabId = tabState.resolveTabId(state, action.get('tabId'))
+ setImmediate(() => {
+ tabs.stopFindInPage(tabId)
+ })
+ break
+ }
+ case tabActionConsts.ZOOM_CHANGED:
+ {
+ const tabId = tabState.resolveTabId(state, action.get('tabId'))
+ const zoomPercent = action.get('zoomPercent')
+ state = tabState.setZoomPercent(state, tabId, zoomPercent)
+ break
+ }
case appConstants.APP_SET_STATE:
state = tabs.init(state, action)
break
case appConstants.APP_TAB_CREATED:
state = tabState.maybeCreateTab(state, action)
break
- case appConstants.APP_TAB_ATTACHED:
+ case appConstants.APP_TAB_MOVED:
state = tabs.updateTabsStateForAttachedTab(state, action.get('tabId'))
break
- case appConstants.APP_TAB_WILL_ATTACH: {
- const tabId = action.get('tabId')
- const tabValue = tabState.getByTabId(state, tabId)
- if (!tabValue) {
+ case appConstants.APP_TAB_INSERTED_TO_TAB_STRIP: {
+ const windowId = action.get('windowId')
+ if (windowId == null) {
break
}
- const oldWindowId = tabState.getWindowId(state, tabId)
- state = tabs.updateTabsStateForWindow(state, oldWindowId)
+ const tabId = action.get('tabId')
+ state = tabState.setTabStripWindowId(state, tabId, windowId)
+ state = tabs.updateTabIndexesForWindow(state, windowId)
break
}
- case appConstants.APP_TAB_MOVED:
- state = tabs.updateTabsStateForAttachedTab(state, action.get('tabId'))
+ case appConstants.APP_TAB_DETACHED_FROM_TAB_STRIP: {
+ const windowId = action.get('windowId')
+ if (windowId == null) {
+ break
+ }
+ state = tabs.updateTabIndexesForWindow(state, windowId)
break
+ }
case appConstants.APP_TAB_DETACH_MENU_ITEM_CLICKED: {
setImmediate(() => {
const tabId = action.get('tabId')
@@ -131,11 +220,24 @@ const tabsReducer = (state, action, immutableAction) => {
const senderWindowId = action.getIn(['senderWindowId'])
if (senderWindowId != null) {
action = action.setIn(['createProperties', 'windowId'], senderWindowId)
- } else if (BrowserWindow.getActiveWindow()) {
- action = action.setIn(['createProperties', 'windowId'], BrowserWindow.getActiveWindow().id)
+ } else {
+ // no specified window, so use active one, or create one
+ const activeWindowId = windows.getActiveWindowId()
+ if (activeWindowId === windowState.WINDOW_ID_NONE) {
+ setImmediate(() => appActions.newWindow(action.get('createProperties')))
+ // this action will get dispatched again
+ // once the new window is ready to have tabs
+ break
+ }
+ action = action.setIn(['createProperties', 'windowId'], activeWindowId)
}
}
-
+ // option to focus the window the tab is being created in
+ const windowId = action.getIn(['createProperties', 'windowId'])
+ const shouldFocusWindow = action.get('focusWindow')
+ if (shouldFocusWindow && windowId) {
+ windows.focus(windowId)
+ }
const url = action.getIn(['createProperties', 'url'])
setImmediate(() => {
if (action.get('activateIfOpen') ||
@@ -150,6 +252,19 @@ const tabsReducer = (state, action, immutableAction) => {
state = tabState.maybeCreateTab(state, action)
// tabs.debugTabs(state)
break
+ case appConstants.APP_TAB_REPLACED:
+ if (action.get('isPermanent')) {
+ if (shouldDebugTabEvents) {
+ console.log('APP_TAB_REPLACED before')
+ tabs.debugTabs(state)
+ }
+ state = tabState.replaceTabValue(state, action.get('oldTabId'), action.get('newTabValue'))
+ if (shouldDebugTabEvents) {
+ console.log('APP_TAB_REPLACED after')
+ tabs.debugTabs(state)
+ }
+ }
+ break
case appConstants.APP_TAB_CLOSE_REQUESTED:
{
let tabId = action.get('tabId')
@@ -212,8 +327,10 @@ const tabsReducer = (state, action, immutableAction) => {
// But still check for no tabId because on tab detach there's a dummy tabId
const tabValue = tabState.getByTabId(state, tabId)
if (tabValue) {
+ const lastOrigin = tabState.getVisibleOrigin(state, tabId)
+ expireContentSettings(state, tabId, lastOrigin)
const windowIdOfTabBeingRemoved = tabState.getWindowId(state, tabId)
- state = tabs.updateTabsStateForWindow(state, windowIdOfTabBeingRemoved)
+ state = tabs.updateTabIndexesForWindow(state, windowIdOfTabBeingRemoved)
}
state = tabState.removeTabByTabId(state, tabId)
tabs.forgetTab(tabId)
@@ -258,6 +375,14 @@ const tabsReducer = (state, action, immutableAction) => {
tabs.setTabIndex(action.get('tabId'), action.get('index'))
})
break
+ case appConstants.APP_TAB_SET_FULL_SCREEN: {
+ const isFullscreen = action.get('isFullScreen')
+ const tabId = action.get('tabId')
+ if (isFullscreen === true || isFullscreen === false) {
+ tabs.setFullScreen(tabId, isFullscreen)
+ }
+ break
+ }
case appConstants.APP_TAB_TOGGLE_DEV_TOOLS:
setImmediate(() => {
tabs.toggleDevTools(action.get('tabId'))
@@ -334,12 +459,19 @@ const tabsReducer = (state, action, immutableAction) => {
}
break
}
- case appConstants.APP_FRAME_CHANGED:
- state = tabState.updateFrame(state, action)
+ case appConstants.APP_FRAMES_CHANGED:
+ for (const frameAction of action.get('frames').valueSeq()) {
+ state = tabState.updateFrame(state, frameAction, shouldDebugTabEvents)
+ }
break
+ // TODO: convert window frame navigation status (load, error, etc)
+ // to browser actions with data on tab state. This reducer responds to
+ // actions from both at the moment (browser-side for certificate errors and
+ // renderer-side for load errors) until all can be refactored.
case windowConstants.WINDOW_SET_FRAME_ERROR:
+ case tabActionConsts.SET_CONTENTS_ERROR:
{
- const tabId = action.getIn(['frameProps', 'tabId'])
+ const tabId = action.getIn(['frameProps', 'tabId']) || action.get('tabId')
const tab = getWebContents(tabId)
if (tab) {
let currentIndex = tab.getCurrentEntryIndex()
@@ -360,24 +492,40 @@ const tabsReducer = (state, action, immutableAction) => {
}
break
case appConstants.APP_WINDOW_READY: {
+ // Get the window's id from the action or the sender
if (!action.getIn(['createProperties', 'windowId'])) {
const senderWindowId = action.getIn(['senderWindowId'])
if (senderWindowId) {
action = action.setIn(['createProperties', 'windowId'], senderWindowId)
}
}
+ // Show welcome tab in first window on first start,
+ // but not in the buffer window.
+ const windowId = action.getIn(['createProperties', 'windowId'])
+ const bufferWindow = windows.getBufferWindow()
+ if (!bufferWindow || bufferWindow.id !== windowId) {
+ const welcomeScreenProperties = {
+ url: 'about:welcome',
+ windowId
+ }
+ const shouldShowWelcomeScreen = state.getIn(['about', 'welcome', 'showOnLoad'])
+ if (shouldShowWelcomeScreen) {
+ setImmediate(() => tabs.create(welcomeScreenProperties))
+ // We only need to run welcome screen once
+ state = state.setIn(['about', 'welcome', 'showOnLoad'], false)
+ }
- const welcomeScreenProperties = {
- 'url': 'about:welcome',
- 'windowId': action.getIn(['createProperties', 'windowId'])
- }
-
- const shouldShowWelcomeScreen = state.getIn(['about', 'welcome', 'showOnLoad'])
- if (shouldShowWelcomeScreen) {
- setImmediate(() => tabs.create(welcomeScreenProperties))
- // We only need to run welcome screen once
- state = state.setIn(['about', 'welcome', 'showOnLoad'], false)
+ // Show promotion
+ const page = updateState.getUpdateProp(state, 'referralPage') || null
+ if (page) {
+ setImmediate(() => tabs.create({
+ url: page,
+ windowId
+ }))
+ state = updateState.setUpdateProp(state, 'referralPage', null)
+ }
}
+ state = state.set('windowReady', true)
break
}
case appConstants.APP_ENABLE_PEPPER_MENU: {
@@ -389,15 +537,21 @@ const tabsReducer = (state, action, immutableAction) => {
if (dragData && dragData.get('type') === dragTypes.TAB) {
const frame = dragData.get('data')
let frameOpts = frameOptsFromFrame(frame)
+ const draggingTabId = frameOpts.get('tabId')
const browserOpts = { positionByMouseCursor: true, checkMaximized: true }
const tabIdForIndex = dragData.getIn(['dragOverData', 'draggingOverKey'])
- const tabForIndex = tabState.getByTabId(state, tabIdForIndex)
+ const tabForIndex = tabIdForIndex !== draggingTabId && tabState.getByTabId(state, tabIdForIndex)
const dropWindowId = dragData.get('dropWindowId')
- if (dropWindowId != null && dropWindowId !== -1 && tabForIndex) {
+ let newIndex = -1
+ // Set new index for new window if last dragged-over tab is in new window.
+ // Otherwise, could be over another tab's tab strip, but most recently dragged-over a tab in another window.
+ if (dropWindowId != null && dropWindowId !== -1 && tabForIndex && tabForIndex.get('windowId') === dropWindowId) {
const prependIndexByTabId = dragData.getIn(['dragOverData', 'draggingOverLeftHalf'])
- frameOpts = frameOpts.set('index', tabForIndex.get('index') + (prependIndexByTabId ? 0 : 1))
+ newIndex = tabForIndex.get('index') + (prependIndexByTabId ? 0 : 1)
}
- tabs.moveTo(state, frame.get('tabId'), frameOpts, browserOpts, dragData.get('dropWindowId'))
+ // ensure the tab never moves window with its original index
+ frameOpts = frameOpts.set('index', newIndex)
+ tabs.moveTo(state, draggingTabId, frameOpts, browserOpts, dragData.get('dropWindowId'))
}
break
}
diff --git a/app/browser/reducers/windowsReducer.js b/app/browser/reducers/windowsReducer.js
index 808a44345db..73abc4e31eb 100644
--- a/app/browser/reducers/windowsReducer.js
+++ b/app/browser/reducers/windowsReducer.js
@@ -158,7 +158,7 @@ function setDefaultWindowSize (state) {
return state
}
-const handleCreateWindowAction = (state, action) => {
+const handleCreateWindowAction = (state, action = Immutable.Map()) => {
const frameOpts = (action.get('frameOpts') || Immutable.Map()).toJS()
let browserOpts = (action.get('browserOpts') || Immutable.Map()).toJS()
let immutableWindowState = action.get('restoredState') || Immutable.Map()
@@ -305,6 +305,14 @@ const windowsReducer = (state, action, immutableAction) => {
})
}
break
+ case appConstants.APP_FOCUS_OR_CREATE_WINDOW:
+ const activeWindowId = windows.getActiveWindowId()
+ if (activeWindowId === windowState.WINDOW_ID_NONE) {
+ state = handleCreateWindowAction(state)
+ } else {
+ windows.focus(activeWindowId)
+ }
+ break
case appConstants.APP_CLOSE_WINDOW:
windows.closeWindow(action.get('windowId'))
break
@@ -316,10 +324,7 @@ const windowsReducer = (state, action, immutableAction) => {
case appConstants.APP_WINDOW_CREATED:
case appConstants.APP_WINDOW_RESIZED:
{
- const bookmarkToolbarState = require('../../common/state/bookmarkToolbarState')
state = windowState.maybeCreateWindow(state, action)
- const windowId = action.getIn(['windowValue', 'windowId'], windowState.WINDOW_ID_NONE)
- state = bookmarkToolbarState.setToolbar(state, windowId)
break
}
case appConstants.APP_TAB_STRIP_EMPTY:
diff --git a/app/browser/share.js b/app/browser/share.js
index 99e0a35164f..4bbc196ea26 100644
--- a/app/browser/share.js
+++ b/app/browser/share.js
@@ -15,7 +15,6 @@ const templateUrls = {
googlePlus: 'https://plus.google.com/share?url={url}',
linkedIn: 'https://www.linkedin.com/shareArticle?url={url}&title={title}',
buffer: 'https://buffer.com/add?text={title}&url={url}',
- digg: 'https://digg.com/submit?url={url}&title={title}',
reddit: 'https://reddit.com/submit?url={url}&title={title}'
}
diff --git a/app/browser/tabMessageBox.js b/app/browser/tabMessageBox.js
index 03c6286851d..fe95a5924a4 100644
--- a/app/browser/tabMessageBox.js
+++ b/app/browser/tabMessageBox.js
@@ -1,6 +1,7 @@
const appActions = require('../../js/actions/appActions')
const tabMessageBoxState = require('../common/state/tabMessageBoxState')
const {makeImmutable} = require('../common/state/immutableUtil')
+const locale = require('../../app/locale')
// callbacks for alert, confirm, etc.
let messageBoxCallbacks = {}
@@ -13,6 +14,23 @@ const cleanupCallback = (tabId) => {
return false
}
+const onWindowPrompt = show => (webContents, extraData, title, message, defaultPromptText,
+ shouldDisplaySuppressCheckbox, isBeforeUnloadDialog, isReload, muonCb) => {
+ const tabId = webContents.getId()
+ const detail = {
+ message,
+ title,
+ buttons: [locale.translation('messageBoxOk'), locale.translation('messageBoxCancel')],
+ cancelId: 1,
+ suppress: false,
+ allowInput: true,
+ defaultPromptText,
+ showSuppress: shouldDisplaySuppressCheckbox
+ }
+
+ show(tabId, detail, muonCb)
+}
+
const tabMessageBox = {
init: (state, action) => {
process.on('window-alert', (webContents, extraData, title, message, defaultPromptText,
@@ -21,7 +39,7 @@ const tabMessageBox = {
const detail = {
message,
title,
- buttons: ['ok'],
+ buttons: [locale.translation('messageBoxOk')],
suppress: false,
showSuppress: shouldDisplaySuppressCheckbox
}
@@ -35,7 +53,7 @@ const tabMessageBox = {
const detail = {
message,
title,
- buttons: ['ok', 'cancel'],
+ buttons: [locale.translation('messageBoxOk'), locale.translation('messageBoxCancel')],
cancelId: 1,
suppress: false,
showSuppress: shouldDisplaySuppressCheckbox
@@ -44,12 +62,7 @@ const tabMessageBox = {
tabMessageBox.show(tabId, detail, muonCb)
})
- process.on('window-prompt', (webContents, extraData, title, message, defaultPromptText,
- shouldDisplaySuppressCheckbox, isBeforeUnloadDialog, isReload, muonCb) => {
- console.warn('window.prompt is not supported yet')
- let suppress = false
- muonCb(null, '', suppress)
- })
+ process.on('window-prompt', onWindowPrompt(tabMessageBox.show))
return state
},
@@ -70,6 +83,7 @@ const tabMessageBox = {
const muonCb = messageBoxCallbacks[tabId]
let suppress = false
let result = true
+ let input = ''
state = tabMessageBoxState.removeDetail(state, action)
if (muonCb) {
cleanupCallback(tabId)
@@ -80,7 +94,10 @@ const tabMessageBox = {
if (detail.has('result')) {
result = detail.get('result')
}
- muonCb(result, '', suppress)
+ if (detail.has('input')) {
+ input = detail.get('input')
+ }
+ muonCb(result, input, suppress)
} else {
muonCb(false, '', false)
}
@@ -130,3 +147,4 @@ const tabMessageBox = {
}
module.exports = tabMessageBox
+module.exports.onWindowPrompt = onWindowPrompt
diff --git a/app/browser/tabs.js b/app/browser/tabs.js
index b5e0da8b6c4..0533ccc862c 100644
--- a/app/browser/tabs.js
+++ b/app/browser/tabs.js
@@ -3,13 +3,11 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const appActions = require('../../js/actions/appActions')
-const windowActions = require('../../js/actions/windowActions')
const tabActions = require('../common/actions/tabActions')
-const config = require('../../js/constants/config')
const Immutable = require('immutable')
const { shouldDebugTabEvents } = require('../cmdLine')
const tabState = require('../common/state/tabState')
-const {app, BrowserWindow, extensions, session, ipcMain} = require('electron')
+const {app, extensions, session, ipcMain} = require('electron')
const {makeImmutable, makeJS} = require('../common/state/immutableUtil')
const {getTargetAboutUrl, getSourceAboutUrl, isSourceAboutUrl, newFrameUrl, isTargetAboutUrl, isIntermediateAboutPage, isTargetMagnetUrl, getSourceMagnetUrl} = require('../../js/lib/appUrlUtil')
const {isURL, getUrlFromInput, toPDFJSLocation, getDefaultFaviconUrl, isHttpOrHttps, getLocationIfPDF} = require('../../js/lib/urlutil')
@@ -25,6 +23,7 @@ const aboutHistoryState = require('../common/state/aboutHistoryState')
const aboutNewTabState = require('../common/state/aboutNewTabState')
const appStore = require('../../js/stores/appStore')
const appConfig = require('../../js/constants/appConfig')
+const config = require('../../js/constants/config')
const {newTabMode} = require('../common/constants/settingsEnums')
const {tabCloseAction} = require('../common/constants/settingsEnums')
const webContentsCache = require('./webContentsCache')
@@ -37,7 +36,7 @@ const historyState = require('../common/state/historyState')
const siteSettingsState = require('../common/state/siteSettingsState')
const bookmarkOrderCache = require('../common/cache/bookmarkOrderCache')
const ledgerState = require('../common/state/ledgerState')
-const {getWindow} = require('./windows')
+const {getWindow, notifyWindowWebContentsAdded} = require('./windows')
const activeTabHistory = require('./activeTabHistory')
let adBlockRegions
@@ -66,6 +65,8 @@ const getTabValue = function (tabId) {
tabValue = tabValue.set('guestInstanceId', tab.guestInstanceId)
tabValue = tabValue.set('partition', tab.session.partition)
tabValue = tabValue.set('partitionNumber', getPartitionNumber(tab.session.partition))
+ tabValue = tabValue.set('isPlaceholder', tab.isPlaceholder())
+ tabValue = tabValue.set('zoomPercent', tab.getZoomPercent())
return tabValue.set('tabId', tabId)
}
}
@@ -73,8 +74,15 @@ const getTabValue = function (tabId) {
const updateTab = (tabId, changeInfo = {}) => {
let tabValue = getTabValue(tabId)
if (shouldDebugTabEvents) {
- console.log('tab updated from muon', { tabId, changeIndex: changeInfo.index, changeActive: changeInfo.active, newIndex: tabValue && tabValue.get('index'), newActive: tabValue && tabValue.get('active') })
+ console.log(`Tab [${tabId}] updated from muon. changeInfo:`, changeInfo, 'currentValues:', {
+ newIndex: tabValue && tabValue.get('index'),
+ newActive: tabValue && tabValue.get('active'),
+ windowId: tabValue && tabValue.get('windowId'),
+ isPlaceholder: tabValue && tabValue.get('isPlaceholder'),
+ guestInstanceId: tabValue && tabValue.get('guestInstanceId')
+ })
}
+
if (tabValue) {
appActions.tabUpdated(tabValue, makeImmutable(changeInfo))
}
@@ -148,6 +156,10 @@ ipcMain.on(messages.ABOUT_COMPONENT_INITIALIZED, (e) => {
const tabId = tab.getId()
aboutTabs[tabId] = {}
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] ABOUT_COMPONENT_INITIALIZED`)
+ }
+
const url = getSourceAboutUrl(tab.getURL())
const location = getBaseUrl(url)
if (location === 'about:preferences') {
@@ -181,13 +193,17 @@ const getBookmarksData = (state) => {
.set('bookmarkFolders', bookmarkFoldersState.getFolders(state))
.set('bookmarkOrder', bookmarkOrderCache.getOrderCache(state))
}
-
+const shouldDebugAboutData = false
const sendAboutDetails = (tabId, type, value, shared = false) => {
// use a weak map to avoid holding references to large objects that will never be equal to anything
aboutTabs[tabId][type] = aboutTabs[tabId][type] || new WeakMap()
if (aboutTabs[tabId] && !aboutTabs[tabId][type].get(value)) {
const tab = webContentsCache.getWebContents(tabId)
if (tab && !tab.isDestroyed()) {
+ if (shouldDebugAboutData) {
+ console.log(`Tab [${tabId}] sendAboutDetails(${type})`)
+ }
+
if (shared) {
const handle = muon.shared_memory.create(makeJS(value))
tab.sendShared(type, handle)
@@ -196,6 +212,28 @@ const sendAboutDetails = (tabId, type, value, shared = false) => {
}
aboutTabs[tabId][type] = new WeakMap()
aboutTabs[tabId][type].set(value, true)
+ } else {
+ if (shouldDebugAboutData) {
+ const isNull = !tab
+ const isDestroyed = tab && tab.isDestroyed()
+ const reason = isNull
+ ? 'tab is null'
+ : isDestroyed
+ ? 'tab is destroyed'
+ : ''
+ console.log(`Tab [${tabId}] skipping sendAboutDetails(${type}); ${reason}`)
+ }
+ }
+ } else {
+ if (shouldDebugAboutData) {
+ const tabFalsey = !aboutTabs[tabId]
+ const tabHasValue = aboutTabs[tabId] && !!aboutTabs[tabId][type].get(value)
+ const reason = tabFalsey
+ ? 'tab is falsey'
+ : tabHasValue
+ ? 'tab has a value'
+ : ''
+ console.log(`Tab [${tabId}] skipping sendAboutDetails(${type}); ${reason}`)
}
}
}
@@ -204,6 +242,9 @@ const updateAboutDetails = (tabId) => {
const appState = appStore.getState()
const tabValue = tabState.getByTabId(appState, tabId)
if (!tabValue) {
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] updateAboutDetails - unable to get tabValue from tabState`)
+ }
return
}
@@ -230,7 +271,7 @@ const updateAboutDetails = (tabId) => {
if (location === 'about:contributions' || onPaymentsPage) {
const ledgerInfo = ledgerState.getInfoProps(appState)
const preferencesData = appState.getIn(['about', 'preferences'], Immutable.Map())
- const synopsis = appState.getIn(['ledger', 'about'])
+ const synopsis = ledgerState.getAboutData(appState)
const migration = appState.get('migrations')
const wizardData = ledgerState.geWizardData(appState)
const ledgerData = ledgerInfo
@@ -239,6 +280,7 @@ const updateAboutDetails = (tabId) => {
.set('wizardData', wizardData)
.set('migration', migration)
.set('promotion', ledgerState.getAboutPromotion(appState))
+ .set('tabId', tabId)
sendAboutDetails(tabId, messages.LEDGER_UPDATED, ledgerData)
} else if (url === 'about:preferences#sync' || location === 'about:contributions' || onPaymentsPage) {
const sync = appState.get('sync', Immutable.Map())
@@ -274,6 +316,11 @@ const updateAboutDetails = (tabId) => {
sendAboutDetails(tabId, messages.DOWNLOADS_UPDATED, {
downloads: downloads.toJS()
})
+ } else if (location === 'about:printkeys') {
+ const phrase = ledgerState.getInfoProp(appState, 'passphrase')
+ sendAboutDetails(tabId, messages.PRINTKEYS_UPDATED, {
+ passphrase: phrase
+ })
} else if (location === 'about:passwords') {
autofill.getAutofillableLogins((result) => {
sendAboutDetails(tabId, messages.PASSWORD_DETAILS_UPDATED, result)
@@ -400,29 +447,6 @@ const createNavigationState = (navigationHandle, controller) => {
})
}
-let backgroundProcess = null
-let backgroundProcessTimer = null
-/**
- * Execute script in the browser tab
- * @param win{object} - window in which we want to execute script
- * @param debug{boolean} - would you like to close window or not
- * @param script{string} - script that you want to execute
- * @param cb{function} - function that we call after script is completed
- */
-const runScript = (win, debug, script, cb) => {
- win.webContents.executeScriptInTab(config.braveExtensionId, script, {}, (err, url, result) => {
- cb(err, url, result)
- if (!debug) {
- backgroundProcessTimer = setTimeout(() => {
- if (backgroundProcess) {
- win.close()
- backgroundProcess = null
- }
- }, 2 * 60 * 1000) // 2 min
- }
- })
-}
-
const api = {
init: (state, action) => {
process.on('open-url-from-tab', (e, source, targetUrl, disposition) => {
@@ -434,6 +458,9 @@ const api = {
})
process.on('add-new-contents', (e, source, newTab, disposition, size, userGesture) => {
+ if (shouldDebugTabEvents) {
+ console.log(`Contents [${newTab.getId()}] process:add-new-contents`, {userGesture, isBackground: newTab.isBackgroundPage(), disposition})
+ }
if (userGesture === false) {
e.preventDefault()
return
@@ -448,6 +475,10 @@ const api = {
return
}
+ if (!newTab.isTab()) {
+ return
+ }
+
let displayURL = newTab.getURL()
let location = displayURL || 'about:blank'
const openerTabId = !source.isDestroyed() ? source.getId() : -1
@@ -458,7 +489,10 @@ const api = {
}
const tabId = newTab.getId()
+
+ // update our webContents Map with the openerTabId
webContentsCache.updateWebContents(tabId, newTab, openerTabId)
+
let newTabValue = getTabValue(newTab.getId())
let windowId
@@ -495,8 +529,14 @@ const api = {
const windowOpts = makeImmutable(size)
appActions.newWindow(makeImmutable(frameOpts), windowOpts)
} else {
- // TODO(bridiver) - use tabCreated in place of newWebContentsAdded
- appActions.newWebContentsAdded(windowId, frameOpts, newTabValue)
+ // Unfortunately we rely on tab events in the renderer window process
+ // so use an IPC call here to notify that process of the new tab to track.
+ // TODO: move all events to browser process (this module) and do not handle all
+ // tab events inside the window.
+ if (shouldDebugTabEvents) {
+ console.log('notifyWindowWebContentsAdded: on tab creation in existing window', windowId)
+ }
+ notifyWindowWebContentsAdded(windowId, frameOpts, newTabValue.toJS())
}
})
@@ -509,7 +549,7 @@ const api = {
process.on('chrome-tabs-updated', (tabId, changeInfo) => {
if (shouldDebugTabEvents) {
- console.log(`tab [${tabId} via process] chrome-tabs-updated`)
+ console.log(`tab [${tabId} via process] chrome-tabs-updated`, changeInfo)
}
updateTab(tabId, changeInfo)
})
@@ -521,11 +561,15 @@ const api = {
})
app.on('web-contents-created', function (event, tab) {
- if (tab.isBackgroundPage() || !tab.isGuest()) {
+ if (!tab.isTab()) {
return
}
const tabId = tab.getId()
+ // This is the first and most consistent event for WebContents so cache the item in the Map.
+ // Not all contents will get the 'add-new-contents' event (e.g. replaced contents during tab discard).
+ webContentsCache.updateWebContents(tabId, tab, null)
+
// command-line flag --debug-tab-events
if (shouldDebugTabEvents) {
console.log(`Tab [${tabId}] created in window ${tab.tabValue().windowId}`)
@@ -586,15 +630,21 @@ const api = {
updateTab(tabId)
})
- tab.on('tab-moved', () => {
- appActions.tabMoved(tabId)
+ tab.on('tab-moved', (e, fromIndex, toIndex) => {
+ const tabValue = getTabValue(tabId)
+ appActions.tabMoved(tabId, fromIndex, toIndex, tabValue && tabValue.get('windowId'))
+ })
+
+ tab.on('pinned', (e, isPinned) => {
+ updateTab(tabId)
})
tab.on('will-attach', (e, windowWebContents) => {
- appActions.tabWillAttach(tab.getId())
+ // tab will attach to webview
})
tab.on('set-active', (sender, isActive) => {
+ updateTab(tab.getId(), { active: isActive })
if (isActive) {
const tabValue = getTabValue(tabId)
if (tabValue) {
@@ -609,31 +659,31 @@ const api = {
}
})
- tab.on('tab-strip-empty', () => {
- // It's only safe to close a window when the last web-contents tab has been
- // re-attached. A detach which already happens by this point is not enough.
- // Otherwise the closing window will destroy the tab web-contents and it'll
- // lead to a dead tab. The destroy will happen because the old main window
- // webcontents is still the embedder.
- const tabValue = getTabValue(tabId)
- const windowId = tabValue.get('windowId')
- tab.once('did-attach', () => {
- appActions.tabStripEmpty(windowId)
- })
- })
+ tab.on('tab-replaced-at', (e, windowId, tabIndex, newContents) => {
+ // if not a placeholder, new contents is permanent replacement, e.g. tab has been discarded
+ // if is a placeholder, new contents is temporary, and should not be used for tab ID
+ const isPlaceholder = newContents.isPlaceholder()
+ const newTabId = newContents.getId()
+ const tabValue = getTabValue(newTabId)
+ if (shouldDebugTabEvents) {
+ if (isPlaceholder) {
+ console.log(`Tab [${tabId}] got a new placeholder (${newTabId}), not updating state.`)
+ } else {
+ console.log(`Tab [${tabId}] permanently changed to tabId ${newTabId}. Updating state references...`)
+ }
+ }
- tab.on('did-detach', (e, oldTabId) => {
- // forget last active trail in window tab
- // is detaching from
- const oldTab = getTabValue(oldTabId)
- const detachedFromWindowId = oldTab.get('windowId')
- if (detachedFromWindowId != null) {
- activeTabHistory.clearTabFromWindow(detachedFromWindowId, oldTabId)
+ // update state
+ appActions.tabReplaced(tabId, tabValue, windowId, !isPlaceholder)
+ if (!isPlaceholder) {
+ // update in-memory caches
+ webContentsCache.tabIdChanged(tabId, newTabId)
+ activeTabHistory.tabIdChanged(tabId, newTabId)
}
})
tab.on('did-attach', (e, tabId) => {
- appActions.tabAttached(tab.getId())
+ // tab has been attached to a webview
})
tab.on('save-password', (e, username, origin) => {
@@ -644,10 +694,26 @@ const api = {
appActions.updatePassword(username, origin, tabId)
})
- tab.on('did-get-response-details', (evt, status, newURL, originalURL, httpResponseCode, requestMethod, referrer, headers, resourceType) => {
- if (resourceType === 'mainFrame') {
- windowActions.gotResponseDetails(tabId, {status, newURL, originalURL, httpResponseCode, requestMethod, referrer, resourceType})
+ tab.on('enter-html-full-screen', () => {
+ let tabValue = getTabValue(tabId)
+ if (!tabValue) {
+ return
+ }
+ const windowId = tabValue.get('windowId')
+ appActions.tabSetFullScreen(tabId, true, true, windowId)
+ // disable the fullscreen warning after 5 seconds
+ setTimeout(() => {
+ appActions.tabSetFullScreen(tabId, undefined, false, windowId)
+ }, 5000)
+ })
+
+ tab.on('leave-html-full-screen', () => {
+ let tabValue = getTabValue(tabId)
+ if (!tabValue) {
+ return
}
+ const windowId = tabValue.get('windowId')
+ appActions.tabSetFullScreen(tabId, false, false, windowId)
})
tab.on('media-started-playing', (e) => {
@@ -667,22 +733,10 @@ const api = {
})
tab.once('will-destroy', (e) => {
+ api.willBeRemovedFromWindow(tabId)
const tabValue = getTabValue(tabId)
if (tabValue) {
const windowId = tabValue.get('windowId')
- // forget about this tab in the history of active tabs
- activeTabHistory.clearTabFromWindow(windowId, tabId)
- // handle closed tab being the current active tab for window
- if (tabValue.get('active')) {
- // set the next active tab, if different from what muon will have set to
- // Muon sets it to the next index (immediately above or below)
- // But this app can be configured to select the parent tab,
- // or the last active tab
- let nextTabId = api.getNextActiveTabId(windowId, tabId)
- if (nextTabId != null) {
- api.setActive(nextTabId)
- }
- }
// let the state know
appActions.tabClosed(tabId, windowId)
}
@@ -745,6 +799,9 @@ const api = {
},
setActive: (tabId) => {
+ if (shouldDebugTabEvents) {
+ console.log(`tabs.setActive: ${tabId}`)
+ }
let tab = webContentsCache.getWebContents(tabId)
if (tab && !tab.isDestroyed()) {
tab.setActive(true)
@@ -760,14 +817,22 @@ const api = {
reload: (tabId, ignoreCache = false) => {
const tab = webContentsCache.getWebContents(tabId)
+ let isIntermediate = false
if (tab && !tab.isDestroyed()) {
// TODO(bridiver) - removeEntryAtIndex for intermediate about pages after loading
- if (isIntermediateAboutPage(getSourceAboutUrl(tab.getURL()))) {
+ isIntermediate = isIntermediateAboutPage(getSourceAboutUrl(tab.getURL()))
+ if (isIntermediate) {
tab.goToOffset(-1)
} else {
tab.reload(ignoreCache)
}
}
+
+ if (shouldDebugTabEvents) {
+ const isNull = !tab
+ const isDestroyed = tab && tab.isDestroyed()
+ console.log(`Tab [${tabId}] reload - ignoreCache=${ignoreCache}, tab null: ${isNull}, tab.isDestroyed: ${isDestroyed}, isIntermediateAboutPage: ${isIntermediate}`)
+ }
},
discard: (tabId) => {
@@ -782,16 +847,44 @@ const api = {
}
},
+ willBeRemovedFromWindow (tabId) {
+ const tabValue = getTabValue(tabId)
+ if (tabValue) {
+ const windowId = tabValue.get('windowId')
+ const wasActive = tabValue.get('active')
+ if (shouldDebugTabEvents) {
+ console.log(`tab ${tabId} will be removed from window ${windowId}, wasActive: ${wasActive}`)
+ }
+ // forget about this tab in the history of active tabs
+ activeTabHistory.clearTabFromWindow(windowId, tabId)
+ // handle closed tab being the current active tab for window
+ if (wasActive) {
+ // set the next active tab, if different from what muon will have set to
+ // Muon sets it to the next index (immediately above or below)
+ // But this app can be configured to select the parent tab,
+ // or the last active tab
+ let nextTabId = api.getNextActiveTabId(windowId, tabId)
+ if (nextTabId != null) {
+ if (shouldDebugTabEvents) {
+ console.log(`Got next active tab Id of ${nextTabId}`)
+ }
+ api.setActive(nextTabId)
+ }
+ }
+ }
+ },
+
loadURL: (action) => {
action = makeImmutable(action)
const tabId = action.get('tabId')
const tab = webContentsCache.getWebContents(tabId)
if (tab && !tab.isDestroyed()) {
- let url = normalizeUrl(action.get('url'))
+ const url = normalizeUrl(action.get('url'))
+ const currentUrl = tab.getURL()
// We only allow loading URLs explicitly when the origin is
// the same for pinned tabs. This is to help preserve a users
// pins.
- if (tab.pinned && getOrigin(tab.getURL()) !== getOrigin(url)) {
+ if (tab.pinned && getOrigin(currentUrl) !== getOrigin(url)) {
api.create({
url,
partition: tab.session.partition
@@ -799,7 +892,19 @@ const api = {
return
}
- tab.loadURL(url)
+ const parsed = muon.url.parse(url)
+ // Set reloadMatchingUrl to true for hash URLs as workaround for
+ // https://github.com/brave/browser-laptop/issues/14231. (muon emits
+ // security-style-changed to insecure when a hash URL is loaded using
+ // tab.loadURL in a tab with the same URL)
+ const reloadMatchingUrl = action.get('reloadMatchingUrl') ||
+ (parsed && parsed.hash) ||
+ false
+ if (reloadMatchingUrl && currentUrl === url) {
+ tab.reload(true)
+ } else {
+ tab.loadURL(url)
+ }
}
},
@@ -822,11 +927,17 @@ const api = {
setAudioMuted: (action) => {
action = makeImmutable(action)
const muted = action.get('muted')
+ // We're crossing into type-safe muon code so make sure args
+ // are of correct type
+ if (typeof muted !== 'boolean') {
+ return
+ }
const tabId = action.get('tabId')
const tab = webContentsCache.getWebContents(tabId)
- if (tab && !tab.isDestroyed()) {
- tab.setAudioMuted(muted)
+ if (!tab || tab.isDestroyed()) {
+ return
}
+ tab.setAudioMuted(muted)
},
clone: (action) => {
@@ -873,6 +984,9 @@ const api = {
},
closeTab: (tabId, forceClosePinned = false) => {
+ if (shouldDebugTabEvents) {
+ console.log(`[${tabId}] tabs.closeTab(forceClosePinned: ${forceClosePinned})`)
+ }
const tabValue = getTabValue(tabId)
if (!tabValue) {
return false
@@ -934,19 +1048,15 @@ const api = {
if (preventLazyLoad) {
createProperties.discarded = false
}
- // Similarly, autoDiscardable will happen for regular tabs (not about: tabs)
- const preventAutoDiscard = createProperties.pinned || !isRegularContent
- if (preventAutoDiscard) {
- createProperties.autoDiscardable = false
- } else {
- // (temporarily) forced autoDiscardable to ALWAYS false due to
- // inability to switch to auto-discarded tabs.
- // See https://github.com/brave/browser-laptop/issues/10673
- // remove this forced 'else' condition when #10673 is resolved
- createProperties.autoDiscardable = false
- }
+ // autoDiscardable can happen for all tabs
+ // TODO(petemill): if there are schemes / Urls that should not be autodiscarded
+ // then the flag should be exposed from muon and set on each URL change for a tab
+ createProperties.autoDiscardable = true
const doCreate = () => {
+ if (shouldDebugTabEvents) {
+ console.log('Creating tab with properties: ', createProperties)
+ }
extensions.createTab(createProperties, (tab) => {
cb && cb(tab)
})
@@ -969,94 +1079,81 @@ const api = {
})
},
- /**
- * Execute script in the background browser window
- * @param script{string} - script that we want to run
- * @param cb{function} - function that we want to call when script is done
- * @param debug{boolean} - would you like to keep browser window when script is done
- */
- executeScriptInBackground: (script, cb, debug = false) => {
- if (backgroundProcessTimer) {
- clearTimeout(backgroundProcessTimer)
- }
-
- if (backgroundProcess === null) {
- backgroundProcess = new BrowserWindow({
- show: debug,
- webPreferences: {
- partition: 'default'
- }
- })
-
- backgroundProcess.webContents.on('did-finish-load', () => {
- runScript(backgroundProcess, debug, script, cb)
- })
- backgroundProcess.loadURL('about:blank')
- } else {
- runScript(backgroundProcess, debug, script, cb)
- }
- },
-
moveTo: (state, tabId, frameOpts, browserOpts, toWindowId) => {
frameOpts = makeImmutable(frameOpts)
browserOpts = makeImmutable(browserOpts)
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] tabs.moveTo(window: ${toWindowId}, index: ${frameOpts.get('index')})`)
+ }
const tab = webContentsCache.getWebContents(tabId)
- if (tab && !tab.isDestroyed()) {
- const tabValue = getTabValue(tabId)
- const guestInstanceId = tabValue && tabValue.get('guestInstanceId')
- if (guestInstanceId != null) {
- frameOpts.set('guestInstanceId', guestInstanceId)
- }
-
- const currentWindowId = tabValue && tabValue.get('windowId')
- if (toWindowId != null && currentWindowId === toWindowId) {
+ if (!tab || tab.isDestroyed()) {
+ return
+ }
+ const tabValue = getTabValue(tabId)
+ // don't move it to the same window
+ const currentWindowId = tabValue && tabValue.get('windowId')
+ if (toWindowId != null && currentWindowId === toWindowId) {
+ return
+ }
+ // If there's only one tab and we're dragging outside the window, then disallow
+ // a new window to be created.
+ if (toWindowId == null || toWindowId === -1) {
+ const windowTabCount = tabState.getTabsByWindowId(state, currentWindowId).size
+ if (windowTabCount === 1) {
return
}
-
- if (toWindowId == null || toWindowId === -1) {
- // If there's only one tab and we're dragging outside the window, then disallow
- // a new window to be created.
- const windowTabCount = tabState.getTabsByWindowId(state, currentWindowId).size
- if (windowTabCount === 1) {
- return
- }
- }
-
- if (tabValue.get('pinned')) {
- // If the current tab is pinned, then don't allow to drag out
- return
+ }
+ // If the current tab is pinned, then don't allow to drag out
+ if (tabValue.get('pinned')) {
+ return
+ }
+ //
+ // perform the actual moving
+ //
+
+ // It's only safe to close a window when the last web-contents tab has been
+ // re-attached. A tab-removed-at or tab-strip-empty is not enough.
+ // Otherwise the closing window will destroy the tab web-contents by the time it gets to the new window.
+ // The destroy will happen because the old main window
+ // webcontents is still the embedder.
+ tab.once('did-attach', () => {
+ // let the window know the tab has moved to another window, so
+ // it is free to close
+ const win = getWindow(currentWindowId)
+ if (win && !win.isDestroyed()) {
+ win.webContents.emit('detached-tab-new-window')
}
-
- // detach from current window
- tab.detach(() => {
- // handle tab has detached from window
- // handle tab was the active tab of the window
- if (tabValue.get('active')) {
- // decide and set next-active-tab muon override
- const nextActiveTabIdForOldWindow = api.getNextActiveTabId(currentWindowId, tabId)
- if (nextActiveTabIdForOldWindow !== null) {
- api.setActive(nextActiveTabIdForOldWindow)
- }
- }
- if (toWindowId == null || toWindowId === -1) {
- // move tab to a new window
- frameOpts = frameOpts.set('index', 0)
- appActions.newWindow(frameOpts, browserOpts)
- } else {
- // ask for tab to be attached (via frame state and webview) to
- // specified window
- appActions.newWebContentsAdded(toWindowId, frameOpts, tabValue)
- }
- // handle tab has made it to the new window
- tab.once('did-attach', () => {
- // put the tab in the desired index position
- const index = frameOpts.get('index')
- if (index !== undefined) {
- api.setTabIndex(tabId, frameOpts.get('index'))
- }
- })
- })
+ })
+ // make sure frame has latest guestinstanceid
+ const guestInstanceId = tabValue && tabValue.get('guestInstanceId')
+ if (guestInstanceId != null) {
+ frameOpts.set('guestInstanceId', guestInstanceId)
+ }
+ // create a new window if required
+ if (toWindowId == null || toWindowId === -1) {
+ // this will eventually call tab.moveTo when the window is known
+ api.willBeRemovedFromWindow(tabId, currentWindowId)
+ appActions.newWindow(frameOpts, browserOpts)
+ return
+ }
+ // use existing window
+ let toIndex = frameOpts.get('index')
+ // invalid index? add to end of tab strip by specifying -1 index
+ if (toIndex == null || toIndex === -1) {
+ toIndex = -1
+ frameOpts = frameOpts.set('index', -1)
}
+ const win = getWindow(toWindowId)
+ if (!win || win.isDestroyed()) {
+ console.error('Error: invalid window to move tab to')
+ return
+ }
+ api.willBeRemovedFromWindow(tabId, currentWindowId)
+ if (shouldDebugTabEvents) {
+ console.log('notifyWindowWebContentsAdded: on tab move to existing window', toWindowId)
+ }
+ notifyWindowWebContentsAdded(toWindowId, frameOpts.toJS(), tabValue.toJS())
+ tab.moveTo(toIndex, toWindowId)
},
maybeCreateTab: (state, createProperties) => {
@@ -1082,6 +1179,47 @@ const api = {
}
},
+ setFullScreen (tabId, isFullScreen) {
+ const tab = webContentsCache.getWebContents(tabId)
+ if (!tab || tab.isDestroyed()) {
+ return
+ }
+ const script = isFullScreen
+ ? 'document.documentElement.webkitRequestFullScreen()'
+ : 'document.webkitExitFullscreen()'
+ tab.executeScriptInTab(config.braveExtensionId, script, {})
+ },
+
+ findInPage (tabId, searchString, caseSensitivity, forward, findNext) {
+ const tab = webContentsCache.getWebContents(tabId)
+ if (shouldDebugTabEvents) {
+ console.log(`tabs.findInPage: ${tabId}, ${searchString}, ${caseSensitivity}, ${forward}, ${findNext}`)
+ }
+ if (!tab || tab.isDestroyed()) {
+ return
+ }
+ if (searchString) {
+ tab.findInPage(searchString, {
+ matchCase: caseSensitivity,
+ forward,
+ findNext
+ })
+ } else {
+ tab.stopFindInPage('clearSelection')
+ }
+ },
+
+ stopFindInPage (tabId) {
+ const tab = webContentsCache.getWebContents(tabId)
+ if (shouldDebugTabEvents) {
+ console.log(`tabs.stopFindInPage: ${tabId}`)
+ }
+ if (!tab || tab.isDestroyed()) {
+ return
+ }
+ tab.stopFindInPage('keepSelection')
+ },
+
goBack: (tabId) => {
const tab = webContentsCache.getWebContents(tabId)
if (tab && !tab.isDestroyed()) {
@@ -1194,7 +1332,6 @@ const api = {
tab.forceClose()
}
})
- state = api.updateTabsStateForWindow(state, windowId)
return state
},
@@ -1216,7 +1353,6 @@ const api = {
tab.forceClose()
}
})
- state = api.updateTabsStateForWindow(state, windowId)
return state
},
@@ -1238,7 +1374,6 @@ const api = {
tab.forceClose()
}
})
- state = api.updateTabsStateForWindow(state, windowId)
return state
},
@@ -1255,7 +1390,6 @@ const api = {
tab.forceClose()
}
})
- state = api.updateTabsStateForWindow(state, windowId)
return state
},
@@ -1286,39 +1420,62 @@ const api = {
if (!tabValue) {
return state
}
- return api.updateTabsStateForWindow(state, tabValue.get('windowId'))
+ return api.updateTabIndexesForWindow(state, tabValue.get('windowId'))
},
- updateTabsStateForWindow: (state, windowId) => {
- tabState.getTabsByWindowId(state, windowId).forEach((tabValue) => {
- const tabId = tabValue.get('tabId')
- const oldTabValue = tabState.getByTabId(state, tabId)
+ updateTabIndexesForWindow: (state, windowId) => {
+ const t0 = shouldDebugTabEvents ? process.hrtime() : null
+ let changesMade = 0
+ // make sure all indexes are up to date
+ const stateTabs = tabState.getTabsByWindowId(state, windowId)
+ for (const stateTab of stateTabs.values()) {
+ const tabId = stateTab.get('tabId')
const newTabValue = getTabValue(tabId)
-
- // For now the renderer needs to know about index and pinned changes
- // communicate those out here.
- if (newTabValue && oldTabValue) {
- const changeInfo = {}
- const rendererAwareProps = ['index', 'pinned', 'url', 'active']
- rendererAwareProps.forEach((prop) => {
- const newPropVal = newTabValue.get(prop)
- if (oldTabValue.get(prop) !== newPropVal) {
- changeInfo[prop] = newPropVal
- }
- })
- if (Object.keys(changeInfo).length > 0) {
- updateTab(tabId, changeInfo)
- }
+ if (!newTabValue) {
+ // This is probably the deleted tab
+ continue
}
-
- if (newTabValue) {
- state = tabState.updateTabValue(state, newTabValue, false)
+ const oldIndex = stateTab.get('index')
+ const newIndex = newTabValue.get('index')
+ if (oldIndex !== newIndex) {
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId} Updating state index from ${oldIndex} to ${newIndex}`)
+ }
+ state = tabState.updateTabValue(state, Immutable.Map({ tabId, index: newIndex }))
+ changesMade++
}
- })
+ }
+ if (shouldDebugTabEvents) {
+ const t1 = process.hrtime(t0)
+ console.info(`updateTabIndexesForWindow took: %ds %dms with ${changesMade} changes`, t1[0], t1[1] / 1000000)
+ }
return state
},
+
forgetTab: (tabId) => {
- webContentsCache.cleanupWebContents(tabId)
+ const tab = webContentsCache.getWebContents(tabId)
+ if (!tab) {
+ // perhaps tab was set to be null, but other cache data still exists
+ webContentsCache.cleanupWebContents(tabId)
+ return
+ }
+ // Do not remove tab until it is destroyed, as we still need to refer to it,
+ // even though state has let us know it does not care about the tab anymore
+ // But, we do this here in case state still needs to refer to tab
+ // after it is destroyed, for a brief time.
+ if (tab.isDestroyed()) {
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] forgetTab: is already destroyed, cleaning up webContents from cache immediately`)
+ }
+ webContentsCache.cleanupWebContents(tabId)
+ } else {
+ tab.once('destroyed', function () {
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] forgetTab: 'destroyed' emitted, cleaning up webContents from cache`)
+ }
+ webContentsCache.cleanupWebContents(tabId)
+ })
+ }
}
}
diff --git a/app/browser/webContentsCache.js b/app/browser/webContentsCache.js
index e483ffb3bf6..7e27bd00952 100644
--- a/app/browser/webContentsCache.js
+++ b/app/browser/webContentsCache.js
@@ -31,11 +31,29 @@ const forgetOpenerForTabId = (tabId) => {
}
}
+const tabIdChanged = (oldTabId, newTabId) => {
+ // any tabs referencing the old contents Id as the opener,
+ // should now reference the new contents Id
+ for (const tabId in currentWebContents) {
+ const tabData = currentWebContents[tabId]
+ if (tabData && tabData.openerTabId != null && tabData.openerTabId === oldTabId) {
+ tabData.openerTabId = newTabId
+ }
+ }
+ // we should also give the replacement tab the opener for the old tab
+ const newTabData = currentWebContents[newTabId]
+ const oldTabData = currentWebContents[oldTabId]
+ if (newTabData && oldTabData && oldTabData.openerTabId != null) {
+ newTabData.openerTabId = oldTabData.openerTabId
+ }
+}
+
module.exports = {
cleanupWebContents,
getWebContents,
getOpenerTabId,
forgetOpenerForTabId,
updateWebContents,
+ tabIdChanged,
currentWebContents
}
diff --git a/app/browser/windows.js b/app/browser/windows.js
index 9fdb4636b59..6009dbd4604 100644
--- a/app/browser/windows.js
+++ b/app/browser/windows.js
@@ -25,8 +25,9 @@ const browserWindowUtil = require('../common/lib/browserWindowUtil')
const windowState = require('../common/state/windowState')
const pinnedSitesState = require('../common/state/pinnedSitesState')
const {zoomLevel} = require('../common/constants/toolbarUserInterfaceScale')
-const { shouldDebugWindowEvents } = require('../cmdLine')
+const { shouldDebugWindowEvents, shouldDebugTabEvents, shouldDebugStoreActions, disableBufferWindow, disableDeferredWindowLoad } = require('../cmdLine')
const activeTabHistory = require('./activeTabHistory')
+const webContentsCache = require('./webContentsCache')
const isDarwin = platformUtil.isDarwin()
const isWindows = platformUtil.isWindows()
@@ -125,7 +126,10 @@ const updatePinnedTabs = (win, appState) => {
// tabs are sites our window already has pinned
// for each site which should be pinned, find if it's already pinned
const statePinnedSitesOrdered = statePinnedSites.sort((a, b) => a.get('order') - b.get('order'))
+ // pinned sites should always be at the front of the window tab indexes, starting with 0
+ let pinnedSiteIndex = -1
for (const site of statePinnedSitesOrdered.values()) {
+ pinnedSiteIndex++
const existingPinnedTabIdx = pinnedWindowTabs.findIndex(tab => siteMatchesTab(site, tab))
if (existingPinnedTabIdx !== -1) {
// if it's already pinned we don't need to consider the tab in further searches
@@ -135,6 +139,7 @@ const updatePinnedTabs = (win, appState) => {
appActions.createTabRequested({
url: site.get('location'),
partitionNumber: site.get('partitionNumber'),
+ index: pinnedSiteIndex,
pinned: true,
active: false,
windowId
@@ -147,11 +152,39 @@ const updatePinnedTabs = (win, appState) => {
}
}
+function refocusFocusedWindow (win) {
+ if (win && !win.isDestroyed()) {
+ if (shouldDebugWindowEvents) {
+ console.log('focusing on window', win.id)
+ }
+ win.focus()
+ }
+}
+
function showDeferredShowWindow (win) {
- if (shouldDebugWindowEvents) {
- console.log(`Window [${win.id}] showDeferredShowWindow`)
+ // were we asked to make the window active / foreground?
+ // note: do not call win.showInactive if there is no other active window, otherwise this window will
+ // never get an entry in taskbar on Windows
+ const currentlyFocused = BrowserWindow.getFocusedWindow()
+ const shouldShowInactive = win.webContents.browserWindowOptions.inactive && currentlyFocused
+ if (shouldShowInactive) {
+ // we were asked NOT to show the window active.
+ // we should maintain focus on the window which already has it
+ if (shouldDebugWindowEvents) {
+ console.log('showing deferred window inactive', win.id)
+ }
+ win.show()
+ // Whilst the window will not have focus, it will potentially be
+ // on top of the window which already had focus,
+ // so re-focus the focused window.
+ setImmediate(refocusFocusedWindow.bind(null, currentlyFocused))
+ } else {
+ // we were asked to show the window active
+ if (shouldDebugWindowEvents) {
+ console.log('showing deferred window active', win.id)
+ }
+ win.show()
}
- win.show()
if (win.__shouldFullscreen) {
// this timeout helps with an issue that
// when a user is loading from state, and
@@ -160,6 +193,9 @@ function showDeferredShowWindow (win) {
// spaces because macOS has switched away from the desktop space
setTimeout(() => {
win.setFullScreen(true)
+ if (shouldShowInactive) {
+ setImmediate(refocusFocusedWindow.bind(null, currentlyFocused))
+ }
}, 100)
} else if (win.__shouldMaximize) {
win.maximize()
@@ -175,8 +211,15 @@ function openFramesInWindow (win, frames, activeFrameKey) {
let frameIndex = -1
for (const frame of frames) {
frameIndex++
- if (frame.guestInstanceId) {
- appActions.newWebContentsAdded(win.id, frame)
+ if (frame.tabId != null && frame.guestInstanceId != null) {
+ if (shouldDebugTabEvents) {
+ console.log('notifyWindowWebContentsAdded: on window create with existing tab', win.id)
+ }
+ api.notifyWindowWebContentsAdded(win.id, frame)
+ const tab = webContentsCache.getWebContents(frame.tabId)
+ if (tab && !tab.isDestroyed()) {
+ tab.moveTo(frameIndex, win.id)
+ }
} else {
appActions.createTabRequested({
windowId: win.id,
@@ -242,6 +285,30 @@ const api = {
win.once('close', () => {
LocalShortcuts.unregister(win)
})
+ win.webContents.on('tab-inserted-at', (e, contents, index, active) => {
+ const tabId = contents.getId()
+ appActions.tabInsertedToTabStrip(win.id, tabId, index)
+ if (shouldDebugWindowEvents) {
+ console.log(`window ${win.id} had ${!active ? 'in' : ''}active tab ${tabId} inserted at index ${index}`)
+ }
+ })
+ win.webContents.on('tab-detached-at', (e, index, windowId) => {
+ appActions.tabDetachedFromTabStrip(windowId, index)
+ if (shouldDebugWindowEvents) {
+ console.log(`window ${win.id} had tab at removed at index ${index}`)
+ }
+ })
+ win.webContents.on('tab-strip-empty', () => {
+ // must wait for pending tabs to be attached to new window before closing
+ // TODO(petemill): race condition if multiple different tabs are moved at the same time
+ // ...tab-strip-empty may fire before all of those tabs are inserted to new window
+ win.webContents.once('detached-tab-new-window', () => {
+ if (shouldDebugWindowEvents) {
+ console.log('departing tab made it to new window')
+ }
+ api.closeWindow(win.id)
+ })
+ })
win.on('scroll-touch-begin', function (e) {
win.webContents.send('scroll-touch-begin')
})
@@ -305,6 +372,19 @@ const api = {
win.once('closed', () => {
appActions.windowClosed(windowId)
cleanupWindow(windowId)
+ // if we have a bufferWindow, the 'window-all-closed'
+ // event will not fire once the last window is closed,
+ // so close the buffer window if this is the last closed window
+ // apart from the buffer window.
+ // This would mean that the last window to close is the buffer window, but
+ // that will not get saved to state as the last-closed window which should be restored
+ // since we won't save state if there are no frames.
+ if (!platformUtil.isDarwin() && api.getBufferWindow()) {
+ const remainingWindows = api.getAllRendererWindows()
+ if (!remainingWindows.length) {
+ api.closeBufferWindow()
+ }
+ }
})
win.on('blur', () => {
appActions.windowBlurred(windowId)
@@ -401,6 +481,18 @@ const api = {
})
},
+ focus: (windowId) => {
+ setImmediate(() => {
+ const win = currentWindows[windowId]
+ if (win && !win.isDestroyed()) {
+ if (win.isMinimized()) {
+ win.restore()
+ }
+ win.focus()
+ }
+ })
+ },
+
setFullScreen: (windowId, fullScreen) => {
setImmediate(() => {
const win = currentWindows[windowId]
@@ -444,6 +536,9 @@ const api = {
renderedWindows.add(win)
setImmediate(() => {
if (win && win.__showWhenRendered && !win.isDestroyed() && !win.isVisible()) {
+ if (shouldDebugWindowEvents) {
+ console.log('rendered window so showing window')
+ }
// window is hidden by default until we receive 'ready' message,
// so show it now
showDeferredShowWindow(win)
@@ -521,6 +616,12 @@ const api = {
},
getOrCreateBufferWindow: function (options = { }) {
+ if (disableBufferWindow) {
+ if (shouldDebugWindowEvents) {
+ console.log(`getOrCreateBufferWindow: buffer window disabled, not creating one.`)
+ }
+ return
+ }
// only if we don't have one already
let win = api.getBufferWindow()
if (!win) {
@@ -539,6 +640,9 @@ const api = {
},
createWindow: function (windowOptionsIn, parentWindow, maximized, frames, immutableState = Immutable.Map(), hideUntilRendered = true, cb = null) {
+ if (disableDeferredWindowLoad) {
+ hideUntilRendered = false
+ }
const defaultOptions = {
// hide the window until the window reports that it is rendered
show: true,
@@ -562,6 +666,16 @@ const api = {
defaultOptions,
windowOptionsIn
)
+ // validate activeFrameKey if provided
+ let activeFrameKey = immutableState.get('activeFrameKey')
+ if (frames && frames.length && activeFrameKey) {
+ const keyIsValid = frames.some(frame => frame.key === activeFrameKey)
+ if (!keyIsValid) {
+ // make first frame active if invalid key provided
+ activeFrameKey = frames[0].key
+ }
+ immutableState = immutableState.set('activeFrameKey', activeFrameKey)
+ }
// will only hide until rendered if the options specify to show window
// so that a caller can control showing the window themselves with the option { show: false }
const showWhenRendered = hideUntilRendered && windowOptions.show
@@ -650,6 +764,7 @@ const api = {
if (shouldDebugWindowEvents) {
markWindowCreationTime(win.id)
+ console.log(`createWindow: new BrowserWindow with ID ${win.id} created with options`, windowOptions)
}
// TODO: pass UUID
publicEvents.emit('new-window-state', win.id, immutableState)
@@ -665,6 +780,9 @@ const api = {
// in those cases, we want to still show it, so that the user can find the error message
setTimeout(() => {
if (win && !win.isDestroyed() && !win.isVisible()) {
+ if (shouldDebugWindowEvents) {
+ console.log('deferred-show window passed timeout, so showing deferred')
+ }
showDeferredShowWindow(win)
}
}, config.windows.timeoutToShowWindowMs)
@@ -689,7 +807,11 @@ const api = {
const position = win.getPosition()
const size = win.getSize()
- const windowState = (immutableState && immutableState.toJS()) || undefined
+
+ const windowState = (immutableState && immutableState.toJS()) || { }
+ windowState.debugTabEvents = shouldDebugTabEvents
+ windowState.debugStoreActions = shouldDebugStoreActions
+
const mem = muon.shared_memory.create({
windowValue: {
disposition: windowOptions.disposition,
@@ -701,13 +823,10 @@ const api = {
width: size[0]
},
appState: appStore.getLastEmittedState().toJS(),
- windowState,
- // TODO: dispatch frame create action on appStore, as this is what the window does anyway
- // ...and do it after the window has rendered
- frames
+ windowState
})
-
e.sender.sendShared(messages.INITIALIZE_WINDOW, mem)
+ openFramesInWindow(win, frames, windowState && windowState.activeFrameKey)
// TODO: remove callback, use store action, returning a new window UUID from this function
if (cb) {
cb()
@@ -720,21 +839,51 @@ const api = {
return currentWindows[windowId]
},
- getActiveWindowId: () => {
- if (BrowserWindow.getFocusedWindow()) {
- return BrowserWindow.getFocusedWindow().id
+ getActiveWindow: () => {
+ const focusedWindow = BrowserWindow.getFocusedWindow()
+ const allOpenWindows = api.getAllRendererWindows()
+ if (allOpenWindows.includes(focusedWindow)) {
+ return focusedWindow
+ }
+ // handle no active window, but do have open windows
+ if (allOpenWindows && allOpenWindows.length) {
+ // use first window
+ return allOpenWindows[0]
}
- return windowState.WINDOW_ID_NONE
+ // no open windows
+ return null
+ },
+
+ getActiveWindowId: () => {
+ const activeWindow = api.getActiveWindow()
+ return activeWindow ? activeWindow.id : windowState.WINDOW_ID_NONE
},
/**
* Provides an array of all Browser Windows which are actual
* main windows (not background workers), and are not destroyed
*/
- getAllRendererWindows: () => {
+ getAllRendererWindows: (includingBufferWindow = false) => {
return Object.keys(currentWindows)
.map(key => currentWindows[key])
- .filter(win => win && !win.isDestroyed())
+ .filter(win =>
+ win &&
+ !win.isDestroyed() &&
+ (includingBufferWindow || win !== api.getBufferWindow())
+ )
+ },
+
+ notifyWindowWebContentsAdded (windowId, frame, tabValue) {
+ const win = api.getWindow(windowId)
+ if (!win || win.isDestroyed()) {
+ console.error(`notifyWindowWebContentsAdded, no window for id ${windowId}`)
+ return
+ }
+ if (!win.webContents || win.webContents.isDestroyed()) {
+ console.error(`notifyWindowWebContentsAdded, no window webContents for id ${windowId}`)
+ return
+ }
+ win.webContents.send('new-web-contents-added', frame, tabValue)
},
on: (...args) => publicEvents.on(...args),
diff --git a/app/cmdLine.js b/app/cmdLine.js
index 3566a70b78c..cbd4dbf667a 100644
--- a/app/cmdLine.js
+++ b/app/cmdLine.js
@@ -4,11 +4,9 @@
'use strict'
-const Immutable = require('immutable')
const electron = require('electron')
const app = electron.app
const messages = require('../js/constants/messages')
-const BrowserWindow = electron.BrowserWindow
const appActions = require('../js/actions/appActions')
const urlParse = require('./common/urlParse')
const {fileUrl} = require('../js/lib/appUrlUtil')
@@ -17,41 +15,31 @@ const fs = require('fs')
const path = require('path')
const isDarwin = process.platform === 'darwin'
-const promoCodeFilenameRegex = /-([a-zA-Z\d]{3}\d{3})\s?(?:\(\d+\))?$/g
const debugTabEventsFlagName = '--debug-tab-events'
let appInitialized = false
let newWindowURL
const debugWindowEventsFlagName = '--debug-window-events'
+const disableBufferWindowFlagName = '--disable-buffer-window'
+const disableDeferredWindowLoadFlagName = '--show-windows-immediately'
+const debugStoreActionsFlagName = '--debug-store-actions'
const focusOrOpenWindow = function (url) {
// don't try to do anything if the app hasn't been initialized
if (!appInitialized) {
return false
}
-
- let win = BrowserWindow.getFocusedWindow()
- if (!win) {
- win = BrowserWindow.getActiveWindow() || BrowserWindow.getAllWindows()[0]
- if (win) {
- if (win.isMinimized()) {
- win.restore()
- }
- win.focus()
+ // create a tab and focus the tab's window
+ if (url) {
+ const tabCreateProperties = {
+ url
}
+ // request to create tab in a new or existing window, and focus the window
+ appActions.createTabRequested(tabCreateProperties, false, false, true)
+ return true
}
-
- if (!win) {
- appActions.newWindow(Immutable.fromJS({
- location: url
- }))
- } else if (url) {
- appActions.createTabRequested({
- url,
- windowId: win.id
- })
- }
-
+ // focus the active window, or create a new one with default tabs
+ appActions.focusOrCreateWindow()
return true
}
@@ -164,13 +152,17 @@ const api = module.exports = {
// parse promo code from installer path
// first, get filename
const fileName = path.win32.parse(installerPath).name
+ const promoCodeFilenameRegex = /-(([a-zA-Z\d]{3}\d{3})|([a-zA-Z]{1,}-[a-zA-Z]{1,}))\s?(?:\(\d+\))?$/g
const matches = promoCodeFilenameRegex.exec(fileName)
- if (matches && matches.length === 2) {
+ if (matches && matches.length > 1) {
return matches[1]
}
return null
},
shouldDebugTabEvents: process.argv.includes(debugTabEventsFlagName),
- shouldDebugWindowEvents: process.argv.includes(debugWindowEventsFlagName)
+ shouldDebugWindowEvents: process.argv.includes(debugWindowEventsFlagName),
+ disableBufferWindow: process.env.NODE_ENV === 'test' || process.argv.includes(disableBufferWindowFlagName),
+ disableDeferredWindowLoad: process.argv.includes(disableDeferredWindowLoadFlagName),
+ shouldDebugStoreActions: process.argv.includes(debugStoreActionsFlagName)
}
diff --git a/app/common/actions/tabActions.js b/app/common/actions/tabActions.js
index 8f336450cad..2bddff5098e 100644
--- a/app/common/actions/tabActions.js
+++ b/app/common/actions/tabActions.js
@@ -35,6 +35,36 @@ const tabActions = {
windowId
}
})
+ },
+
+ findInPageRequest (tabId, searchString, caseSensitivity, forward, findNext) {
+ dispatchAction(tabActionConstants.FIND_IN_PAGE_REQUEST, {
+ tabId,
+ searchString,
+ caseSensitivity,
+ forward,
+ findNext
+ })
+ },
+
+ stopFindInPageRequest (tabId) {
+ dispatchAction(tabActionConstants.STOP_FIND_IN_PAGE_REQUEST, {
+ tabId
+ })
+ },
+
+ zoomChanged (tabId, zoomPercent) {
+ dispatchAction(tabActionConstants.ZOOM_CHANGED, {
+ tabId,
+ zoomPercent
+ })
+ },
+
+ setContentsError (tabId, errorDetails) {
+ dispatchAction(tabActionConstants.SET_CONTENTS_ERROR, {
+ tabId,
+ errorDetails
+ })
}
}
diff --git a/app/common/cache/ledgerVideoCache.js b/app/common/cache/ledgerVideoCache.js
index c7f0ae3fcb1..adab8a5f561 100644
--- a/app/common/cache/ledgerVideoCache.js
+++ b/app/common/cache/ledgerVideoCache.js
@@ -33,7 +33,24 @@ const setCacheByVideoId = (state, key, data) => {
return state.setIn(['cache', 'ledgerVideos', key], data)
}
+const mergeCacheByVideoId = (state, key, data) => {
+ state = validateState(state)
+
+ if (key == null || data == null) {
+ return state
+ }
+
+ data = makeImmutable(data)
+
+ if (data.isEmpty()) {
+ return state
+ }
+
+ return state.mergeIn(['cache', 'ledgerVideos', key], data)
+}
+
module.exports = {
getDataByVideoId,
- setCacheByVideoId
+ setCacheByVideoId,
+ mergeCacheByVideoId
}
diff --git a/app/common/commonMenu.js b/app/common/commonMenu.js
index bf28b204621..ede60939542 100644
--- a/app/common/commonMenu.js
+++ b/app/common/commonMenu.js
@@ -13,27 +13,22 @@ const getSetting = require('../../js/settings').getSetting
const communityURL = 'https://community.brave.com/'
const isDarwin = process.platform === 'darwin'
const electron = require('electron')
-
-let BrowserWindow
-if (process.type === 'browser') {
- BrowserWindow = electron.BrowserWindow
-} else {
- BrowserWindow = electron.remote.BrowserWindow
-}
+const menuUtil = require('./lib/menuUtil')
const ensureAtLeastOneWindow = (frameOpts) => {
- if (process.type === 'browser') {
- if (BrowserWindow.getAllWindows().length === 0) {
- appActions.newWindow(frameOpts || {})
- return
- }
- }
-
- if (!frameOpts) {
+ // Handle no new tab requested, but need a window
+ // and possibly there is no window.
+ if (!frameOpts && process.type === 'browser') {
+ // focus active window, or create a new one if there are none
+ appActions.focusOrCreateWindow()
return
}
-
- appActions.createTabRequested(frameOpts)
+ // If this action is dispatched from a renderer window (Windows OS),
+ // it will create the tab in the current window since the action originates from it.
+ // If it was dispatched by the browser (macOS / Linux),
+ // then it will create the tab in the active window
+ // or a new window if there is no active window.
+ appActions.createTabRequested(frameOpts, false, false, true)
}
/**
@@ -142,7 +137,7 @@ module.exports.printMenuItem = () => {
}
module.exports.simpleShareActiveTabMenuItem = (l10nId, type, accelerator) => {
- const siteName = type.charAt(0).toUpperCase() + type.slice(1)
+ const siteName = menuUtil.extractSiteName(type)
return {
label: locale.translation(l10nId, {siteName: siteName}),
diff --git a/app/common/constants/ledgerMediaProviders.js b/app/common/constants/ledgerMediaProviders.js
index 84ef2d1af80..b8d241eb3d2 100644
--- a/app/common/constants/ledgerMediaProviders.js
+++ b/app/common/constants/ledgerMediaProviders.js
@@ -3,7 +3,8 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const providers = {
- YOUTUBE: 'youtube'
+ YOUTUBE: 'youtube',
+ TWITCH: 'twitch'
}
module.exports = providers
diff --git a/app/common/constants/ledgerStatuses.js b/app/common/constants/ledgerStatuses.js
new file mode 100644
index 00000000000..216ca1f966d
--- /dev/null
+++ b/app/common/constants/ledgerStatuses.js
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const statuses = {
+ CORRUPTED_SEED: 'corruptedSeed',
+ IN_PROGRESS: 'contributionInProgress',
+ SERVER_PROBLEM: 'serverProblem',
+ FUZZING: 'fuzzing'
+}
+
+module.exports = statuses
diff --git a/app/common/constants/promotionStatuses.js b/app/common/constants/promotionStatuses.js
new file mode 100644
index 00000000000..767f42e4834
--- /dev/null
+++ b/app/common/constants/promotionStatuses.js
@@ -0,0 +1,12 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const statuses = {
+ GENERAL_ERROR: 'generalError',
+ PROMO_EXPIRED: 'expiredError',
+ CAPTCHA_CHECK: 'captchaCheck',
+ CAPTCHA_ERROR: 'captchaError'
+}
+
+module.exports = statuses
diff --git a/app/common/constants/tabAction.js b/app/common/constants/tabAction.js
index 739bb1680e2..23898d601eb 100644
--- a/app/common/constants/tabAction.js
+++ b/app/common/constants/tabAction.js
@@ -5,5 +5,9 @@
module.exports = {
RELOAD: 'tabActionsReload',
FINISH_NAVIGATION: 'tabActionsDidFinishNavigation',
- START_NAVIGATION: 'tabActionsDidStartNavigation'
+ START_NAVIGATION: 'tabActionsDidStartNavigation',
+ FIND_IN_PAGE_REQUEST: 'tabActionsFindInPageRequest',
+ STOP_FIND_IN_PAGE_REQUEST: 'tabActionsStopFindInPageRequest',
+ ZOOM_CHANGED: 'tabActionsZoomChanged',
+ SET_CONTENTS_ERROR: 'tabActionsSetContentsError'
}
diff --git a/app/common/constants/twitchEvents.js b/app/common/constants/twitchEvents.js
new file mode 100644
index 00000000000..cb069eef190
--- /dev/null
+++ b/app/common/constants/twitchEvents.js
@@ -0,0 +1,16 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const events = {
+ BUFFER_EMPTY: 'buffer-empty',
+ BUFFER_REFILL: 'buffer-refill',
+ MINUTE_WATCHED: 'minute-watched',
+ PLAY_PAUSE: 'video_pause',
+ SEEK: 'player_click_vod_seek',
+ START: 'video-play',
+ END: 'video_end',
+ VIDEO_ERROR: 'video_error'
+}
+
+module.exports = events
diff --git a/app/common/lib/bookmarkToolbarUtil.js b/app/common/lib/bookmarkToolbarUtil.js
deleted file mode 100644
index 872338cd6e2..00000000000
--- a/app/common/lib/bookmarkToolbarUtil.js
+++ /dev/null
@@ -1,93 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const Immutable = require('immutable')
-
-// Utils
-const bookmarkUtil = require('../lib/bookmarkUtil')
-const bookmarkFoldersUtil = require('../lib/bookmarkFoldersUtil')
-
-// Styles
-const globalStyles = require('../../renderer/components/styles/global')
-const {iconSize} = require('../../../js/constants/config')
-const maxWidth = parseInt(globalStyles.spacing.bookmarksItemMaxWidth, 10)
-const padding = parseInt(globalStyles.spacing.bookmarksItemPadding, 10) * 2
-const itemMargin = parseInt(globalStyles.spacing.bookmarksItemMargin, 10)
-const toolbarPadding = parseInt(globalStyles.spacing.bookmarksToolbarPadding)
-const overflowButtonWidth = parseInt(globalStyles.spacing.bookmarksToolbarOverflowButtonWidth, 10)
-const chevronMargin = parseInt(globalStyles.spacing.bookmarksItemChevronMargin)
-const chevronFontSize = parseInt(globalStyles.spacing.bookmarksItemChevronFontSize)
-const chevronWidth = chevronMargin + chevronFontSize
-
-const getBookmarkKeys = (width, bookmarks) => {
- if (bookmarks == null) {
- return {
- toolbar: Immutable.List(),
- other: Immutable.List()
- }
- }
-
- let widthAccountedFor = 0
-
- const onlyText = bookmarkUtil.showOnlyText()
- const textAndFavicon = bookmarkUtil.showTextAndFavicon()
- const onlyFavicon = bookmarkUtil.showOnlyFavicon()
-
- // No margin for show only fav icons
- const margin = onlyFavicon ? 0 : (itemMargin * 2)
- const maximumBookmarksToolbarWidth = width - overflowButtonWidth
-
- widthAccountedFor += toolbarPadding
-
- // Loop through until we fill up the entire bookmark toolbar width
- let i = 0
- for (let item of bookmarks) {
- let iconWidth
- const isFolder = bookmarkFoldersUtil.isFolder(item)
-
- if (onlyText) {
- iconWidth = 0
- } else if (textAndFavicon || isFolder) {
- iconWidth = iconSize + itemMargin
- } else if (onlyFavicon) {
- iconWidth = iconSize
- }
-
- let extraWidth = 0
-
- if (onlyText) {
- extraWidth = padding + item.get('width')
- } else if (textAndFavicon) {
- extraWidth = padding + iconWidth + item.get('width')
- } else if (onlyFavicon) {
- extraWidth = padding + iconWidth
-
- if (isFolder) {
- extraWidth += item.get('width')
- }
- }
-
- if (isFolder) {
- extraWidth += chevronWidth
- }
-
- extraWidth = Math.min(extraWidth, maxWidth)
- widthAccountedFor += extraWidth + margin
-
- if (widthAccountedFor >= maximumBookmarksToolbarWidth) {
- break
- }
-
- i++
- }
-
- return {
- toolbar: bookmarks.take(i).map((item) => item.get('key')).toList(),
- other: bookmarks.skip(i).take(100).map((item) => item.get('key')).toList()
- }
-}
-
-module.exports = {
- getBookmarkKeys
-}
diff --git a/app/common/lib/bookmarkUtil.js b/app/common/lib/bookmarkUtil.js
index afd20aa9f1d..3bec9133119 100644
--- a/app/common/lib/bookmarkUtil.js
+++ b/app/common/lib/bookmarkUtil.js
@@ -22,6 +22,9 @@ const {getSetting} = require('../../../js/settings')
const UrlUtil = require('../../../js/lib/urlutil')
const {makeImmutable} = require('../state/immutableUtil')
+// Actions
+const appActions = require('../../../js/actions/appActions')
+
const bookmarkHangerHeading = (editMode, isAdded) => {
if (isAdded) {
return 'bookmarkAdded'
@@ -36,23 +39,10 @@ const isBookmarkNameValid = (location) => {
return location != null && location.trim().length > 0
}
-const showOnlyText = () => {
- const btbMode = getSetting(settings.BOOKMARKS_TOOLBAR_MODE)
- return btbMode === bookmarksToolbarMode.TEXT_ONLY
-}
+const getBookmarksToolbarMode = (appState) =>
+ getSetting(settings.BOOKMARKS_TOOLBAR_MODE, appState && appState.get('settings'))
-const showTextAndFavicon = () => {
- const btbMode = getSetting(settings.BOOKMARKS_TOOLBAR_MODE)
- return btbMode === bookmarksToolbarMode.TEXT_AND_FAVICONS
-}
-
-const showOnlyFavicon = () => {
- const btbMode = getSetting(settings.BOOKMARKS_TOOLBAR_MODE)
- return btbMode === bookmarksToolbarMode.FAVICONS_ONLY
-}
-
-const showFavicon = () => {
- const btbMode = getSetting(settings.BOOKMARKS_TOOLBAR_MODE)
+const showFavicon = (appState, btbMode = getBookmarksToolbarMode(appState)) => {
return btbMode === bookmarksToolbarMode.TEXT_AND_FAVICONS ||
btbMode === bookmarksToolbarMode.FAVICONS_ONLY
}
@@ -198,8 +188,7 @@ const buildBookmark = (state, bookmarkDetail) => {
themeColor: dataItem.get('themeColor'),
type: siteTags.BOOKMARK,
key: key,
- skipSync: bookmarkDetail.get('skipSync', null),
- width: 0
+ skipSync: bookmarkDetail.get('skipSync', null)
})
}
@@ -220,10 +209,16 @@ const buildEditBookmark = (oldBookmark, bookmarkDetail) => {
return newBookmark.set('key', newKey)
}
+const closeToolbarIfEmpty = (state) => {
+ const bookmarkBarItemCount = bookmarksState.getBookmarksWithFolders(state, 0).size
+ if (bookmarkBarItemCount === 0 && getSetting(settings.SHOW_BOOKMARKS_TOOLBAR, state.get('settings'))) {
+ appActions.changeSetting(settings.SHOW_BOOKMARKS_TOOLBAR, false)
+ }
+}
+
module.exports = {
bookmarkHangerHeading,
isBookmarkNameValid,
- showOnlyFavicon,
showFavicon,
getDNDBookmarkData,
getDetailFromFrame,
@@ -233,8 +228,8 @@ module.exports = {
updateTabBookmarked,
updateActiveTabBookmarked,
getKey,
- showOnlyText,
- showTextAndFavicon,
+ getBookmarksToolbarMode,
buildBookmark,
- buildEditBookmark
+ buildEditBookmark,
+ closeToolbarIfEmpty
}
diff --git a/app/common/lib/historyUtil.js b/app/common/lib/historyUtil.js
index 995cf35250d..dfcf5597a7b 100644
--- a/app/common/lib/historyUtil.js
+++ b/app/common/lib/historyUtil.js
@@ -160,8 +160,8 @@ const mergeSiteDetails = (oldDetail, newDetail) => {
}
const getDetailFromFrame = (frame) => {
- if (frame == null) {
- return Immutable.Map()
+ if (frame == null || !frame.has('location')) {
+ return null
}
return makeImmutable({
diff --git a/app/common/lib/ledgerUtil.js b/app/common/lib/ledgerUtil.js
index 6b02863b09a..34cf47782e0 100644
--- a/app/common/lib/ledgerUtil.js
+++ b/app/common/lib/ledgerUtil.js
@@ -9,20 +9,26 @@ const format = require('date-fns/format')
const distanceInWordsToNow = require('date-fns/distance_in_words_to_now')
const BigNumber = require('bignumber.js')
const queryString = require('querystring')
+const tldjs = require('tldjs')
// State
const siteSettingsState = require('../state/siteSettingsState')
const ledgerState = require('../state/ledgerState')
+const ledgerVideoCache = require('../cache/ledgerVideoCache')
// Constants
const settings = require('../../../js/constants/settings')
const ledgerMediaProviders = require('../constants/ledgerMediaProviders')
+const twitchEvents = require('../constants/twitchEvents')
+const ledgerStatuses = require('../constants/ledgerStatuses')
// Utils
const {responseHasContent} = require('./httpUtil')
const urlUtil = require('../../../js/lib/urlutil')
const getSetting = require('../../../js/settings').getSetting
const urlParse = require('../urlParse')
+const {makeImmutable} = require('../state/immutableUtil')
+
/**
* Is page an actual page being viewed by the user? (not an error page, etc)
* If the page is invalid, we don't want to collect usage info.
@@ -59,22 +65,22 @@ const batToCurrencyString = (bat, ledgerData) => {
return `${converted} ${currency}`
}
-const formatCurrentBalance = (ledgerData) => {
+const formatCurrentBalance = (ledgerData, amount, showAlt = true) => {
let currency = 'USD'
let balance = 0
let converted = 0
let hasRate = false
if (ledgerData != null) {
- balance = Number(ledgerData.get('balance') || 0)
+ balance = Number(amount || 0)
converted = Number.parseFloat(ledgerData.get('converted')) || 0
- hasRate = ledgerData.has('currentRate') && ledgerData.hasIn(['rates', 'BTC'])
+ hasRate = showAlt ? ledgerData.has('currentRate') && ledgerData.hasIn(['rates', 'BTC']) : false
}
balance = balance.toFixed(2)
if (converted > 0 && converted < 0.01) {
- converted = '<.01'
+ converted = '< 0.01'
} else {
converted = converted.toFixed(2)
}
@@ -90,9 +96,18 @@ const formattedDateFromTimestamp = (timestamp, dateFormat) => {
return format(new Date(timestamp), dateFormat, {locale: navigator.language})
}
-const walletStatus = (ledgerData) => {
+const walletStatus = (ledgerData, settings) => {
let status = {}
+ switch (ledgerData.get('status')) {
+ case ledgerStatuses.FUZZING:
+ {
+ return {
+ id: 'ledgerFuzzed'
+ }
+ }
+ }
+
if (ledgerData == null) {
return {
id: 'createWalletStatus'
@@ -105,7 +120,7 @@ const walletStatus = (ledgerData) => {
const transactions = ledgerData.get('transactions')
const pendingFunds = Number(ledgerData.get('unconfirmed') || 0)
const balance = Number(ledgerData.get('balance') || 0)
- const minBalance = ledgerState.getContributionAmount(null, ledgerData.get('contributionAmount'))
+ const minBalance = ledgerState.getContributionAmount(null, ledgerData.get('contributionAmount'), settings)
if (pendingFunds + balance < minBalance) {
status.id = 'insufficientFundsStatus'
@@ -129,6 +144,24 @@ const walletStatus = (ledgerData) => {
return status
}
+const shouldShowMenuOption = (state, location) => {
+ if (location == null) {
+ return false
+ }
+
+ const publisherKey = tldjs.tldExists(location) && tldjs.getDomain(location)
+ const validUrl = urlUtil.isURL(location) && urlParse(location).protocol !== undefined
+
+ if (!publisherKey || !validUrl) {
+ return false
+ }
+
+ const isVisible = visibleP(state, publisherKey)
+ const isBlocked = blockedP(state, publisherKey)
+
+ return (!isVisible && !isBlocked)
+}
+
// TODO rename function
const blockedP = (state, publisherKey) => {
const pattern = urlUtil.getHostPattern(publisherKey)
@@ -221,6 +254,21 @@ const getMediaId = (data, type) => {
id = data.docid
break
}
+ case ledgerMediaProviders.TWITCH:
+ {
+ if (
+ Object.values(twitchEvents).includes(data.event) &&
+ data.properties
+ ) {
+ id = data.properties.channel
+ let vod = data.properties.vod
+
+ if (vod) {
+ vod = vod.replace('v', '')
+ id += `_vod_${vod}`
+ }
+ }
+ }
}
return id
@@ -234,23 +282,76 @@ const getMediaKey = (id, type) => {
return `${type.toLowerCase()}_${id}`
}
-const getMediaData = (xhr, type) => {
+const getMediaData = (xhr, type, details) => {
let result = null
if (xhr == null || type == null) {
return result
}
+ const parsedUrl = urlParse(xhr)
+ const query = parsedUrl && parsedUrl.query
+
+ if (!parsedUrl) {
+ return null
+ }
+
switch (type) {
case ledgerMediaProviders.YOUTUBE:
{
- const parsedUrl = urlParse(xhr)
- let query = null
+ if (!query) {
+ return null
+ }
+
+ result = queryString.parse(query)
+ break
+ }
+ case ledgerMediaProviders.TWITCH:
+ {
+ const uploadData = details.get('uploadData') || Immutable.List()
+
+ if (uploadData.size === 0) {
+ result = null
+ break
+ }
+
+ let params = uploadData.reduce((old, item) => {
+ const bytes = item.get('bytes')
+ let data = ''
+ if (bytes) {
+ data = Buffer.from(bytes).toString('utf8') || ''
+ }
+ return old + data
+ }, '')
+
+ if (!params || params.length === 0) {
+ result = null
+ break
+ }
+
+ const paramQuery = queryString.parse(params)
+
+ if (!paramQuery || !paramQuery.data) {
+ result = null
+ break
+ }
- if (parsedUrl && parsedUrl.query) {
- query = queryString.parse(parsedUrl.query)
+ let obj = Buffer.from(paramQuery.data, 'base64').toString('utf8')
+ if (obj == null) {
+ result = null
+ break
}
- result = query
+
+ let parsed
+ try {
+ parsed = JSON.parse(obj)
+ } catch (error) {
+ result = null
+ console.error(error.toString(), obj)
+ break
+ }
+
+ result = parsed
break
}
}
@@ -258,18 +359,198 @@ const getMediaData = (xhr, type) => {
return result
}
-const getMediaDuration = (data, type) => {
+const getMediaDuration = (state, data, mediaKey, type) => {
let duration = 0
+
+ if (data == null) {
+ return duration
+ }
+
switch (type) {
- case ledgerMediaProviders.YOUTUBE: {
- duration = getYouTubeDuration(data)
- break
- }
+ case ledgerMediaProviders.YOUTUBE:
+ {
+ duration = getYouTubeDuration(data)
+ break
+ }
+ case ledgerMediaProviders.TWITCH:
+ {
+ duration = getTwitchDuration(state, data, mediaKey)
+ break
+ }
}
return duration
}
+const generateMediaCacheData = (state, parsed, type, mediaKey) => {
+ let data = Immutable.Map()
+
+ if (parsed == null) {
+ return data
+ }
+
+ switch (type) {
+ case ledgerMediaProviders.TWITCH:
+ {
+ data = generateTwitchCacheData(state, parsed, mediaKey)
+ break
+ }
+ }
+
+ return data
+}
+
+const generateTwitchCacheData = (state, parsed, mediaKey) => {
+ if (parsed == null) {
+ return Immutable.Map()
+ }
+
+ const statusConst = {
+ playing: 'playing',
+ paused: 'paused'
+ }
+
+ const previousData = ledgerVideoCache.getDataByVideoId(state, mediaKey)
+ let status = statusConst.playing
+
+ if (
+ (
+ parsed.event === twitchEvents.PLAY_PAUSE &&
+ previousData.get('event') !== twitchEvents.PLAY_PAUSE
+ ) || // user clicked pause (we need to exclude seeking while paused)
+ (
+ parsed.event === twitchEvents.PLAY_PAUSE &&
+ previousData.get('event') === twitchEvents.PLAY_PAUSE &&
+ previousData.get('status') === statusConst.playing
+ ) || // user clicked pause as soon as he clicked played
+ (
+ parsed.event === twitchEvents.SEEK &&
+ previousData.get('status') === statusConst.paused
+ ) // seeking video while it is paused
+ ) {
+ status = statusConst.paused
+ }
+
+ // User pauses a video, then seek it and play it again
+ if (
+ parsed.event === twitchEvents.PLAY_PAUSE &&
+ previousData.get('event') === twitchEvents.SEEK &&
+ previousData.get('status') === statusConst.paused
+ ) {
+ status = statusConst.playing
+ }
+
+ if (parsed.properties) {
+ return Immutable.fromJS({
+ event: parsed.event,
+ time: parsed.properties.time,
+ status
+ })
+ }
+
+ return Immutable.fromJS({
+ event: parsed.event,
+ status
+ })
+}
+
+const getDefaultMediaFavicon = (providerName) => {
+ let image = null
+
+ if (!providerName) {
+ return image
+ }
+
+ providerName = providerName.toLowerCase()
+
+ switch (providerName) {
+ case ledgerMediaProviders.YOUTUBE:
+ {
+ image = require('../../../img/mediaProviders/youtube.png')
+ break
+ }
+ case ledgerMediaProviders.TWITCH:
+ {
+ image = require('../../../img/mediaProviders/twitch.svg')
+ break
+ }
+ }
+
+ return image
+}
+
+const getTwitchDuration = (state, data, mediaKey) => {
+ if (data == null || mediaKey == null || !data.properties) {
+ return 0
+ }
+
+ const previousData = ledgerVideoCache.getDataByVideoId(state, mediaKey)
+
+ // remove duplicate events
+ if (
+ previousData.get('event') === data.event &&
+ previousData.get('time') === data.properties.time
+ ) {
+ return null
+ }
+
+ const oldEvent = previousData.get('event')
+ const twitchMinimumSeconds = 10
+
+ if (data.event === twitchEvents.START && oldEvent === twitchEvents.START) {
+ return 0
+ }
+
+ if (data.event === twitchEvents.START) {
+ return twitchMinimumSeconds * milliseconds.second
+ }
+
+ let time = 0
+ const currentTime = parseFloat(data.properties.time)
+ const oldTime = parseFloat(previousData.get('time'))
+ const currentEvent = data.event
+
+ if (oldEvent === twitchEvents.START) {
+ // From video play event to x event
+ time = currentTime - oldTime - twitchMinimumSeconds
+ } else if (
+ currentEvent === twitchEvents.MINUTE_WATCHED || // Minute watched
+ currentEvent === twitchEvents.BUFFER_EMPTY || // Run out of buffer
+ currentEvent === twitchEvents.VIDEO_ERROR || // Video has some problems
+ currentEvent === twitchEvents.END || // Video ended
+ (currentEvent === twitchEvents.SEEK && previousData.get('status') !== 'paused') || // Vod seek
+ (
+ currentEvent === twitchEvents.PLAY_PAUSE &&
+ (
+ (
+ oldEvent !== twitchEvents.PLAY_PAUSE &&
+ oldEvent !== twitchEvents.SEEK
+ ) ||
+ previousData.get('status') === 'playing'
+ )
+ ) // User paused a video
+ ) {
+ time = currentTime - oldTime
+ }
+
+ if (isNaN(time)) {
+ return 0
+ }
+
+ if (time < 0) {
+ return 0
+ }
+
+ if (time > 120) {
+ time = 120 // 2 minutes
+ }
+
+ // we get seconds back, so we need to convert it into ms
+ time = time * milliseconds.second
+
+ return time
+}
+
const getYouTubeDuration = (data) => {
let time = 0
@@ -294,7 +575,7 @@ const getYouTubeDuration = (data) => {
return parseInt(time)
}
-const getMediaProvider = (url) => {
+const getMediaProvider = (url, firstPartyUrl, referrer) => {
let provider = null
if (url == null) {
@@ -303,16 +584,77 @@ const getMediaProvider = (url) => {
// Youtube
if (url.startsWith('https://www.youtube.com/api/stats/watchtime?')) {
- provider = ledgerMediaProviders.YOUTUBE
+ return ledgerMediaProviders.YOUTUBE
+ }
+
+ // Twitch
+ if (
+ (
+ (firstPartyUrl && firstPartyUrl.startsWith('https://www.twitch.tv/')) ||
+ (referrer && referrer.startsWith('https://player.twitch.tv/'))
+ ) &&
+ (
+ url.includes('.ttvnw.net/v1/segment/') ||
+ url.includes('https://ttvnw.net/v1/segment/')
+ )
+ ) {
+ return ledgerMediaProviders.TWITCH
}
return provider
}
+const hasRequiredVisits = (state, publisherKey) => {
+ if (!publisherKey) {
+ return false
+ }
+
+ state = makeImmutable(state) || Immutable.Map()
+
+ const minimumVisits = parseInt(getSetting(settings.PAYMENTS_MINIMUM_VISITS))
+
+ if (minimumVisits === 1) {
+ return true
+ }
+
+ const publisher = ledgerState.getPublisher(state, publisherKey)
+ const publisherVisits = publisher.get('visits')
+
+ if (typeof publisherVisits !== 'number') {
+ return minimumVisits === 1
+ }
+
+ const visitDifference = minimumVisits - publisherVisits
+
+ return (visitDifference === 1)
+}
+
+const getRemainingRequiredTime = (state, publisherKey) => {
+ state = makeImmutable(state) || Immutable.Map()
+ const minimumVisitTime = parseInt(getSetting(settings.PAYMENTS_MINIMUM_VISIT_TIME))
+
+ if (!publisherKey) {
+ return minimumVisitTime
+ }
+
+ const publisher = ledgerState.getPublisher(state, publisherKey)
+ const publisherDuration = publisher.get('duration')
+
+ if (
+ typeof publisherDuration !== 'number' ||
+ publisherDuration >= minimumVisitTime
+ ) {
+ return minimumVisitTime
+ }
+
+ return (minimumVisitTime - publisherDuration)
+}
+
const defaultMonthlyAmounts = Immutable.List([5.0, 7.5, 10.0, 17.5, 25.0, 50.0, 75.0, 100.0])
const milliseconds = {
year: 365 * 24 * 60 * 60 * 1000,
+ month: (365 * 24 * 60 * 60 * 1000) / 12,
week: 7 * 24 * 60 * 60 * 1000,
day: 24 * 60 * 60 * 1000,
hour: 60 * 60 * 1000,
@@ -339,14 +681,21 @@ const getMethods = () => {
getMediaData,
getMediaKey,
milliseconds,
- defaultMonthlyAmounts
+ defaultMonthlyAmounts,
+ getDefaultMediaFavicon,
+ generateMediaCacheData,
+ shouldShowMenuOption,
+ hasRequiredVisits,
+ getRemainingRequiredTime
}
let privateMethods = {}
if (process.env.NODE_ENV === 'test') {
privateMethods = {
- getYouTubeDuration
+ getYouTubeDuration,
+ getTwitchDuration,
+ generateTwitchCacheData
}
}
diff --git a/app/common/lib/menuUtil.js b/app/common/lib/menuUtil.js
index 508b28256e0..894fd460bae 100644
--- a/app/common/lib/menuUtil.js
+++ b/app/common/lib/menuUtil.js
@@ -67,16 +67,20 @@ const getTemplateItem = (template, label) => {
return null
}
+module.exports.extractSiteName = (type) => {
+ return type.charAt(0).toUpperCase() + type.slice(1)
+}
+
/**
- * Search a menu template and update the checked status
+ * Searches a menu template and updates a passed item key
*
* @return the new template OR null if no change was made (no update needed)
*/
-module.exports.setTemplateItemChecked = (template, label, checked) => {
+module.exports.setTemplateItemAttribute = (template, label, key, value) => {
const menu = template.toJS()
const menuItem = getTemplateItem(menu, label)
- if (menuItem.checked !== checked) {
- menuItem.checked = checked
+ if (menuItem[key] !== value) {
+ menuItem[key] = value
return makeImmutable(menu)
}
return null
@@ -129,6 +133,15 @@ module.exports.createBookmarkTemplateItems = (state) => {
return createBookmarkTemplateItems(state)
}
+/**
+ * Used to create bookmarks and bookmark folder entries for "Other Bookamrks" in the "Bookmarks" menu
+ *
+ * @param state The application state
+ */
+module.exports.createOtherBookmarkTemplateItems = (state) => {
+ return createBookmarkTemplateItems(state, -1)
+}
+
/**
* @param {string} key within closedFrames, i.e. a URL
* @return {string}
diff --git a/app/common/lib/publisherUtil.js b/app/common/lib/publisherUtil.js
index 89d1c503175..45b5a70c171 100644
--- a/app/common/lib/publisherUtil.js
+++ b/app/common/lib/publisherUtil.js
@@ -8,17 +8,17 @@ const settings = require('../../../js/constants/settings')
// Utils
const ledgerUtil = require('./ledgerUtil')
const {getSetting} = require('../../../js/settings')
-const {isHttpOrHttps} = require('../../../js/lib/urlutil')
+const {isHttpOrHttps, getUrlFromPDFUrl} = require('../../../js/lib/urlutil')
const {isSourceAboutUrl} = require('../../../js/lib/appUrlUtil')
-const publisherState = {
+const publisherUtil = {
shouldShowAddPublisherButton: (state, location, publisherKey) => {
return location &&
!isSourceAboutUrl(location) &&
getSetting(settings.PAYMENTS_ENABLED) &&
- isHttpOrHttps(location) &&
+ isHttpOrHttps(getUrlFromPDFUrl(location)) &&
!ledgerUtil.blockedP(state, publisherKey)
}
}
-module.exports = publisherState
+module.exports = publisherUtil
diff --git a/app/common/lib/siteSuggestions.js b/app/common/lib/siteSuggestions.js
index 9cfc0def82c..567ce4a70c0 100644
--- a/app/common/lib/siteSuggestions.js
+++ b/app/common/lib/siteSuggestions.js
@@ -102,8 +102,9 @@ const tokenizeInput = (data) => {
}
}
- if (url && isUrl(url)) {
- const parsedUrl = urlParse(url.toLowerCase())
+ const parsedUrl = typeof url === 'string' && isUrl(url) && urlParse(url.toLowerCase())
+
+ if (parsedUrl && (parsedUrl.hash || parsedUrl.host || parsedUrl.pathname || parsedUrl.query || parsedUrl.protocol)) {
if (parsedUrl.hash) {
parts.push(parsedUrl.hash.slice(1))
}
diff --git a/app/common/lib/suggestion.js b/app/common/lib/suggestion.js
index e89a0e6cc9c..cd4c616e93b 100644
--- a/app/common/lib/suggestion.js
+++ b/app/common/lib/suggestion.js
@@ -124,9 +124,8 @@ const isParsedUrlSimpleDomainNameValue = (parsed) => {
*/
const normalizeLocation = (location) => {
if (typeof location === 'string') {
- location = location.replace(/www\./, '')
- location = location.replace(/^http:\/\//, '')
- location = location.replace(/^https:\/\//, '')
+ // remove http://, https:// and www. from beginning of location string
+ location = location.replace(/^(https?:\/\/)?(www\.)?/, '')
}
return location
}
@@ -250,8 +249,8 @@ const getSortByDomainForSites = (userInputLower, userInputHost) => {
// what the user is entering as the host and the host is null.
let host1 = s1.get('parsedUrl').host || s1.get('parsedUrl').pathname || s1.get('location') || ''
let host2 = s2.get('parsedUrl').host || s2.get('parsedUrl').pathname || s2.get('location') || ''
- host1 = host1.replace('www.', '')
- host2 = host2.replace('www.', '')
+ host1 = normalizeLocation(host1)
+ host2 = normalizeLocation(host2)
let pos1 = host1.indexOf(userInputHost)
let pos2 = host2.indexOf(userInputHost)
@@ -287,8 +286,8 @@ const getSortByDomainForSites = (userInputLower, userInputHost) => {
*/
const getSortByDomainForHosts = (userInputHost) => {
return (host1, host2) => {
- host1 = host1.replace('www.', '')
- host2 = host2.replace('www.', '')
+ host1 = normalizeLocation(host1)
+ host2 = normalizeLocation(host2)
let pos1 = host1.indexOf(userInputHost)
let pos2 = host2.indexOf(userInputHost)
if (pos1 !== -1 && pos2 === -1) {
diff --git a/app/common/state/aboutPreferencesState.js b/app/common/state/aboutPreferencesState.js
new file mode 100644
index 00000000000..c23231b3fe2
--- /dev/null
+++ b/app/common/state/aboutPreferencesState.js
@@ -0,0 +1,71 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this file,
+* You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const assert = require('assert')
+
+// utils
+const {makeImmutable, isMap} = require('../../common/state/immutableUtil')
+
+const validateState = (state) => {
+ state = makeImmutable(state)
+ assert.ok(isMap(state), 'state must be an Immutable.Map')
+ assert.ok(isMap(state.getIn(['about', 'preferences'])), 'state must contain an Immutable.Map of \'about\' \'preferences\'')
+ return state
+}
+const aboutPreferencesState = {
+ setBackupStatus: (state, status) => {
+ state = validateState(state)
+ if (status == null) {
+ return state
+ }
+ const date = new Date().getTime()
+ state = aboutPreferencesState.setPreferencesProp(state, 'backupSucceeded', status)
+ return aboutPreferencesState.setPreferencesProp(state, 'updatedStamp', date)
+ },
+
+ hasBeenBackedUp: (state) => {
+ state = validateState(state)
+ return (aboutPreferencesState.getPreferencesProp(state, 'backupSucceeded') || aboutPreferencesState.getPreferencesProp(state, 'updatedStamp') != null) || false
+ },
+
+ getPreferencesProp: (state, key) => {
+ state = validateState(state)
+ if (key == null) {
+ return null
+ }
+ return state.getIn(['about', 'preferences', key])
+ },
+
+ setPreferencesProp: (state, key, value) => {
+ state = validateState(state)
+ if (key == null) {
+ return state
+ }
+ return state.setIn(['about', 'preferences', key], value)
+ },
+
+ setRecoveryInProgress: (state, inProgress) => {
+ state = validateState(state)
+ return aboutPreferencesState.setPreferencesProp(state, 'recoveryInProgress', inProgress)
+ },
+
+ setRecoveryBalanceRecalculated: (state, hasRecalculated) => {
+ state = validateState(state)
+ return aboutPreferencesState.setPreferencesProp(state, 'recoveryBalanceRecalculated', hasRecalculated)
+ },
+
+ getRecoveryBalanceRecalulated: (state) => {
+ state = validateState(state)
+ return aboutPreferencesState.getPreferencesProp(state, 'recoveryBalanceRecalculated') || false
+ },
+
+ setRecoveryStatus: (state, status) => {
+ state = validateState(state)
+ const date = new Date().getTime()
+ state = aboutPreferencesState.setRecoveryInProgress(state, false)
+ state = aboutPreferencesState.setPreferencesProp(state, 'recoverySucceeded', status)
+ return aboutPreferencesState.setPreferencesProp(state, 'updatedStamp', date)
+ }
+}
+module.exports = aboutPreferencesState
diff --git a/app/common/state/bookmarkFoldersState.js b/app/common/state/bookmarkFoldersState.js
index 4db477cacd4..7cbfb29ccc6 100644
--- a/app/common/state/bookmarkFoldersState.js
+++ b/app/common/state/bookmarkFoldersState.js
@@ -198,17 +198,6 @@ const bookmarkFoldersState = {
append
)
return state
- },
-
- setWidth: (state, key, width) => {
- state = validateState(state)
- width = parseFloat(width)
-
- if (key == null || isNaN(width)) {
- return state
- }
-
- return state.setIn([STATE_SITES.BOOKMARK_FOLDERS, key, 'width'], width)
}
}
diff --git a/app/common/state/bookmarkToolbarState.js b/app/common/state/bookmarkToolbarState.js
deleted file mode 100644
index 9b10bcc577e..00000000000
--- a/app/common/state/bookmarkToolbarState.js
+++ /dev/null
@@ -1,72 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const assert = require('assert')
-const Immutable = require('immutable')
-
-// State
-const bookmarksState = require('./bookmarksState')
-const windowState = require('./windowState')
-
-// Utils
-const {makeImmutable, isList, isMap} = require('./immutableUtil')
-const bookmarkToolbarUtil = require('../lib/bookmarkToolbarUtil')
-
-const validateState = function (state) {
- state = makeImmutable(state)
- assert.ok(isMap(state), 'state must be an Immutable.Map')
- assert.ok(isList(state.get('windows'), 'state must contain an Immutable.List of windows'))
- return state
-}
-
-const bookmarkToolbarState = {
- setToolbars: (state) => {
- validateState(state)
- const bookmarks = bookmarksState.getBookmarksWithFolders(state, 0)
-
- state.get('windows').forEach((item, index) => {
- const width = state.getIn(['windows', index, 'width'])
- const data = bookmarkToolbarUtil.getBookmarkKeys(width, bookmarks)
-
- if (!state.hasIn(['windows', index])) {
- return state
- }
-
- state = state
- .setIn(['windows', index, 'bookmarksToolbar', 'toolbar'], data.toolbar)
- .setIn(['windows', index, 'bookmarksToolbar', 'other'], data.other)
- })
-
- return state
- },
-
- setToolbar: (state, windowId) => {
- validateState(state)
- const bookmarks = bookmarksState.getBookmarksWithFolders(state, 0)
- const windowIndex = windowState.getWindowIndexByWindowId(state, windowId)
-
- if (!state.hasIn(['windows', windowIndex])) {
- return state
- }
-
- const width = state.getIn(['windows', windowIndex, 'width'])
- const data = bookmarkToolbarUtil.getBookmarkKeys(width, bookmarks)
-
- return state
- .setIn(['windows', windowIndex, 'bookmarksToolbar', 'toolbar'], data.toolbar)
- .setIn(['windows', windowIndex, 'bookmarksToolbar', 'other'], data.other)
- },
-
- getToolbar: (state, windowId) => {
- const index = windowState.getWindowIndexByWindowId(state, windowId)
- return state.getIn(['windows', index, 'bookmarksToolbar', 'toolbar'], Immutable.List())
- },
-
- getOther: (state, windowId) => {
- const index = windowState.getWindowIndexByWindowId(state, windowId)
- return state.getIn(['windows', index, 'bookmarksToolbar', 'other'], Immutable.List())
- }
-}
-
-module.exports = bookmarkToolbarState
diff --git a/app/common/state/bookmarksState.js b/app/common/state/bookmarksState.js
index 1053e7a0378..320c71fef9f 100644
--- a/app/common/state/bookmarksState.js
+++ b/app/common/state/bookmarksState.js
@@ -290,16 +290,6 @@ const bookmarksState = {
const cache = bookmarkOrderCache.getBookmarksByParentId(state, folderKey)
return cache.map((item) => bookmarksState.getBookmark(state, item.get('key')))
- },
-
- setWidth: (state, key, width) => {
- width = parseFloat(width)
-
- if (key == null || isNaN(width)) {
- return state
- }
-
- return state.setIn([STATE_SITES.BOOKMARKS, key, 'width'], width)
}
}
diff --git a/app/common/state/contextMenuState.js b/app/common/state/contextMenuState.js
index 31840aa9830..aa4b5cf356e 100644
--- a/app/common/state/contextMenuState.js
+++ b/app/common/state/contextMenuState.js
@@ -5,6 +5,7 @@
const Immutable = require('immutable')
const assert = require('assert')
const { makeImmutable, isMap } = require('./immutableUtil')
+const uuid = require('uuid')
const validateState = function (state) {
state = makeImmutable(state)
@@ -12,31 +13,34 @@ const validateState = function (state) {
return state
}
+let contextMenuDetail = Immutable.Map()
+
const api = {
setContextMenu: (windowState, detail) => {
detail = makeImmutable(detail)
windowState = validateState(windowState)
if (!detail) {
- if (windowState.getIn(['contextMenuDetail', 'type']) === 'hamburgerMenu') {
+ if (contextMenuDetail.get('type') === 'hamburgerMenu') {
windowState = windowState.set('hamburgerMenuWasOpen', true)
} else {
windowState = windowState.set('hamburgerMenuWasOpen', false)
}
+ contextMenuDetail = Immutable.Map()
windowState = windowState.delete('contextMenuDetail')
} else {
if (!(detail.get('type') === 'hamburgerMenu' && windowState.get('hamburgerMenuWasOpen'))) {
- windowState = windowState.set('contextMenuDetail', detail)
+ contextMenuDetail = detail
+ windowState = windowState.set('contextMenuDetail', uuid())
}
windowState = windowState.set('hamburgerMenuWasOpen', false)
}
-
return windowState
},
getContextMenu: (windowState) => {
windowState = validateState(windowState)
- return windowState.get('contextMenuDetail', Immutable.Map())
+ return contextMenuDetail
},
selectedIndex: (windowState) => {
diff --git a/app/common/state/extensionState.js b/app/common/state/extensionState.js
index 68cfa50022b..84d22cd21ba 100644
--- a/app/common/state/extensionState.js
+++ b/app/common/state/extensionState.js
@@ -2,9 +2,15 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
-const { makeImmutable } = require('./immutableUtil')
const Immutable = require('immutable')
+
+// Constants
+const settings = require('../../../js/constants/settings')
+
+// Utils
+const { makeImmutable } = require('./immutableUtil')
const platformUtil = require('../lib/platformUtil')
+const getSetting = require('../../../js/settings').getSetting
const {chromeUrl} = require('../../../js/lib/appUrlUtil')
const browserActionDefaults = Immutable.fromJS({
@@ -205,6 +211,15 @@ const extensionState = {
})
})
return allProperties
+ },
+
+ isWebTorrentEnabled: (state) => {
+ if (state == null) {
+ return false
+ }
+
+ const settingsState = state.get('settings')
+ return getSetting(settings.TORRENT_VIEWER_ENABLED, settingsState)
}
}
diff --git a/app/common/state/frameState.js b/app/common/state/frameState.js
index dbbe8b3275e..befb3f8ed50 100644
--- a/app/common/state/frameState.js
+++ b/app/common/state/frameState.js
@@ -37,7 +37,7 @@ const api = {
return null
}
return path.concat(['frames', index])
- } else {
+ } else if (state.get('tabs')) {
// in AppState
const index = state.get('tabs').findIndex((tab) => tab.getIn(['frame', 'key']) === frameKey)
if (index === -1) {
diff --git a/app/common/state/historyState.js b/app/common/state/historyState.js
index 4dd8cf41401..130d378f3fc 100644
--- a/app/common/state/historyState.js
+++ b/app/common/state/historyState.js
@@ -8,6 +8,7 @@ const {STATE_SITES} = require('../../../js/constants/stateConstants')
const historyUtil = require('../lib/historyUtil')
const urlUtil = require('../../../js/lib/urlutil')
const {makeImmutable, isMap} = require('./immutableUtil')
+const shouldLogWarnings = process.env.NODE_ENV !== 'production'
const validateState = function (state) {
state = makeImmutable(state)
@@ -33,8 +34,20 @@ const historyState = {
},
addSite: (state, siteDetail) => {
+ if (!siteDetail) {
+ if (shouldLogWarnings) {
+ console.error('historyState:addSite siteDetail was null')
+ }
+ return state
+ }
let sites = historyState.getSites(state)
let siteKey = historyUtil.getKey(siteDetail)
+ if (!siteKey) {
+ if (shouldLogWarnings) {
+ console.log('historyState:addSite siteKey was null for siteDetail:', (siteDetail && siteDetail.toJS) ? siteDetail.toJS() : siteDetail)
+ }
+ return state
+ }
siteDetail = makeImmutable(siteDetail)
const oldSite = sites.get(siteKey)
diff --git a/app/common/state/immutableUtil.js b/app/common/state/immutableUtil.js
index 2d758d1225b..920d92eb28b 100644
--- a/app/common/state/immutableUtil.js
+++ b/app/common/state/immutableUtil.js
@@ -45,6 +45,22 @@ const api = {
return defaultValue
}
return api.isImmutable(obj) ? obj.toJS() : obj
+ },
+
+ findNullKeyPaths (state, pathToState = []) {
+ let nullKeys = [ ]
+ if (!Immutable.Map.isMap(state) && !Immutable.List.isList(state)) {
+ return nullKeys
+ }
+ for (const key of state.keySeq()) {
+ const keyPath = [...pathToState, key]
+ if (key === null) {
+ nullKeys.push(keyPath)
+ }
+ // recursive, to find deep keys
+ nullKeys.push(...api.findNullKeyPaths(state.get(key), keyPath))
+ }
+ return nullKeys
}
}
diff --git a/app/common/state/ledgerState.js b/app/common/state/ledgerState.js
index 2392ff24b37..1bc60144060 100644
--- a/app/common/state/ledgerState.js
+++ b/app/common/state/ledgerState.js
@@ -16,9 +16,9 @@ const settings = require('../../../js/constants/settings')
// Utils
const getSetting = require('../../../js/settings').getSetting
-const siteSettings = require('../../../js/state/siteSettings')
-const urlUtil = require('../../../js/lib/urlutil')
const {makeImmutable, isMap} = require('../../common/state/immutableUtil')
+const urlParse = require('../../common/urlParse')
+const getBaseDomain = require('../../../js/lib/baseDomain').getBaseDomain
const validateState = function (state) {
state = makeImmutable(state)
@@ -67,12 +67,28 @@ const ledgerState = {
return state.setIn(['ledger', 'locations', url, prop], value)
},
+ getVerifiedPublisherLocation: (state, url) => {
+ state = validateState(state)
+ if (url == null) {
+ return null
+ }
+
+ let publisherKey = state.getIn(['ledger', 'locations', url, 'publisher'])
+
+ if (!publisherKey) {
+ const parsedUrl = urlParse(url) || {}
+ if (parsedUrl.hostname != null) {
+ publisherKey = getBaseDomain(parsedUrl.hostname)
+ }
+ }
+ return publisherKey
+ },
+
getLocationProp: (state, url, prop) => {
state = validateState(state)
if (url == null || prop == null) {
return null
}
-
return state.getIn(['ledger', 'locations', url, prop])
},
@@ -106,21 +122,25 @@ const ledgerState = {
return state
},
- resetSynopsis: (state, options = false) => {
+ deleteSynopsis: (state) => {
state = validateState(state)
-
- if (options) {
- state = state
- .setIn(['ledger', 'synopsis', 'options'], Immutable.Map())
- .setIn(['ledger', 'about', 'synopsisOptions'], Immutable.Map())
- }
-
state = pageDataState.resetPageData(state)
return state
- .setIn(['ledger', 'synopsis', 'publishers'], Immutable.Map())
- .setIn(['ledger', 'locations'], Immutable.Map())
- .setIn(['ledger', 'about', 'synopsis'], Immutable.List())
+ .setIn(['cache', 'ledgerVideos'], Immutable.Map())
+ .set('ledger', Immutable.fromJS({
+ about: {
+ synopsis: [],
+ synopsisOptions: {}
+ },
+ info: {},
+ locations: {},
+ synopsis: {
+ options: {},
+ publishers: {}
+ },
+ promotion: {}
+ }))
},
/**
@@ -179,6 +199,18 @@ const ledgerState = {
return state.setIn(['ledger', 'synopsis', 'publishers', key, prop], value)
},
+ resetPublishers: (state) => {
+ state = validateState(state)
+ state = pageDataState.resetPageData(state)
+
+ return state
+ .setIn(['ledger', 'synopsis', 'publishers'], Immutable.Map())
+ .setIn(['ledger', 'locations'], Immutable.Map())
+ .setIn(['ledger', 'about', 'synopsis'], Immutable.List())
+ .setIn(['ledger', 'publisherTimestamp'], 0)
+ .setIn(['cache', 'ledgerVideos'], Immutable.Map())
+ },
+
/**
* SYNOPSIS / PUBLISHER / OPTIONS
*/
@@ -288,6 +320,11 @@ const ledgerState = {
if (paymentId) {
newData = newData.set('paymentId', paymentId)
}
+
+ const transactions = ledgerState.getInfoProp(state, 'transactions')
+ if (transactions) {
+ newData = newData.set('transactions', transactions)
+ }
}
return state.setIn(['ledger', 'info'], newData)
@@ -332,13 +369,6 @@ const ledgerState = {
/**
* OTHERS
*/
- setRecoveryStatus: (state, status) => {
- state = validateState(state)
- const date = new Date().getTime()
- state = state.setIn(['about', 'preferences', 'recoverySucceeded'], status)
- return state.setIn(['about', 'preferences', 'updatedStamp'], date)
- },
-
setLedgerError: (state, error, caller) => {
state = validateState(state)
if (error == null && caller == null) {
@@ -351,24 +381,6 @@ const ledgerState = {
}))
},
- changePinnedValues: (state, publishers) => {
- state = validateState(state)
- if (publishers == null) {
- return state
- }
-
- publishers = makeImmutable(publishers)
- publishers.forEach((item) => {
- const publisherKey = item.get('publisherKey')
- const pattern = urlUtil.getHostPattern(publisherKey)
- const percentage = item.get('pinPercentage')
- let newSiteSettings = siteSettings.mergeSiteSetting(state.get('siteSettings'), pattern, 'ledgerPinPercentage', percentage)
- state = state.set('siteSettings', newSiteSettings)
- })
-
- return state
- },
-
/**
* PROMOTIONS
*/
@@ -513,15 +525,15 @@ const ledgerState = {
// TODO (optimization) don't have two almost identical object in state (synopsi->publishers and about->synopsis)
saveAboutSynopsis: (state, publishers) => {
state = validateState(state)
+ state = ledgerState.setAboutProp(state, 'synopsis', publishers)
+ state = ledgerState.setAboutProp(state, 'synopsisOptions', ledgerState.getSynopsisOptions(state))
+
return state
- .setIn(['ledger', 'about', 'synopsis'], publishers)
- .setIn(['ledger', 'about', 'synopsisOptions'], ledgerState.getSynopsisOptions(state))
},
setAboutSynopsisOptions: (state) => {
state = validateState(state)
- return state
- .setIn(['ledger', 'about', 'synopsisOptions'], ledgerState.getSynopsisOptions(state))
+ return ledgerState.setAboutProp(state, 'synopsisOptions', ledgerState.getSynopsisOptions(state))
},
getAboutData: (state) => {
@@ -545,6 +557,7 @@ const ledgerState = {
let promotion = ledgerState.getActivePromotion(state)
const claim = state.getIn(['ledger', 'promotion', 'claimedTimestamp']) || null
const status = state.getIn(['ledger', 'promotion', 'promotionStatus']) || null
+ const captcha = state.getIn(['ledger', 'promotion', 'captcha']) || null
if (claim) {
promotion = promotion.set('claimedTimestamp', claim)
@@ -554,7 +567,31 @@ const ledgerState = {
promotion = promotion.set('promotionStatus', status)
}
+ if (captcha) {
+ promotion = promotion.set('captcha', captcha)
+ }
+
return promotion
+ },
+
+ setAboutProp: (state, prop, value) => {
+ state = validateState(state)
+
+ if (prop == null) {
+ return state
+ }
+
+ return state.setIn(['ledger', 'about', prop], value)
+ },
+
+ getAboutProp: (state, prop) => {
+ state = validateState(state)
+
+ if (prop == null) {
+ return null
+ }
+
+ return state.getIn(['ledger', 'about', prop])
}
}
diff --git a/app/common/state/migrationState.js b/app/common/state/migrationState.js
deleted file mode 100644
index 06f8985527d..00000000000
--- a/app/common/state/migrationState.js
+++ /dev/null
@@ -1,69 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const assert = require('assert')
-
-const {makeImmutable, isMap} = require('../../common/state/immutableUtil')
-
-const validateState = function (state) {
- state = makeImmutable(state)
- assert.ok(isMap(state), 'state must be an Immutable.Map')
- assert.ok(isMap(state.get('migrations')), 'state must contain an Immutable.Map of migrations')
- return state
-}
-
-const migrationState = {
- setTransitionStatus: (state, value) => {
- state = validateState(state)
- if (value == null) {
- return state
- }
-
- return state.setIn(['migrations', 'btc2BatTransitionPending'], value)
- },
-
- inTransition: (state) => {
- state = validateState(state)
- return state.getIn(['migrations', 'btc2BatTransitionPending']) === true
- },
-
- setConversionTimestamp: (state, value) => {
- state = validateState(state)
- if (value == null) {
- return state
- }
-
- return state.setIn(['migrations', 'btc2BatTimestamp'], value)
- },
-
- setNotifiedTimestamp: (state, value) => {
- state = validateState(state)
- if (value == null) {
- return state
- }
-
- return state.setIn(['migrations', 'btc2BatNotifiedTimestamp'], value)
- },
-
- isNewInstall: (state) => {
- state = validateState(state)
- return state.get('firstRunTimestamp') === state.getIn(['migrations', 'batMercuryTimestamp'])
- },
-
- // we set this values when we initialize 0.19 state and this will be only true when transition is done
- // or when you create wallet on 0.19+ version
- hasUpgradedWallet: (state) => {
- state = validateState(state)
- return state.getIn(['migrations', 'batMercuryTimestamp']) !== state.getIn(['migrations', 'btc2BatTimestamp'])
- },
-
- // we set this values when we initialize 0.19 state and this will be only true when transition is done
- // or when you create wallet on 0.19+ version
- hasBeenNotified: (state) => {
- state = validateState(state)
- return state.getIn(['migrations', 'batMercuryTimestamp']) !== state.getIn(['migrations', 'btc2BatNotifiedTimestamp'])
- }
-}
-
-module.exports = migrationState
diff --git a/app/common/state/pageDataState.js b/app/common/state/pageDataState.js
index da6cc816489..47e9fd923e4 100644
--- a/app/common/state/pageDataState.js
+++ b/app/common/state/pageDataState.js
@@ -83,6 +83,7 @@ const pageDataState = {
.setIn(['pageData', 'info'], Immutable.Map())
.setIn(['pageData', 'last', 'info'], null)
.setIn(['pageData', 'last', 'tabId'], null)
+ .setIn(['pageData', 'last', 'closedTabValue'], null)
}
}
diff --git a/app/common/state/pinnedSitesState.js b/app/common/state/pinnedSitesState.js
index 59fd051a50a..ad4a5ddf186 100644
--- a/app/common/state/pinnedSitesState.js
+++ b/app/common/state/pinnedSitesState.js
@@ -98,48 +98,42 @@ const pinnedSiteState = {
},
/**
- * Moves the specified pinned site from one location to another
+ * Moves the specified pinned site from one position to another
*
- * @param state The application state Immutable map
+ * @param state The application state Immutable map
* @param sourceKey The site key to move
- * @param destinationKey The site key to move to
- * @param prepend Whether the destination detail should be prepended or not
+ * @param newOrder The new position to move to
* @return The new state Immutable object
*/
- reOrderSite: (state, sourceKey, destinationKey, prepend) => {
- state = validateState(state)
- let sites = state.get(STATE_SITES.PINNED_SITES)
+ moveSiteToNewOrder: (state, sourceKey, newOrder, shouldDebug = false) => {
+ const sites = state.get(STATE_SITES.PINNED_SITES)
+ if (shouldDebug) {
+ console.log('moveSiteToNewOrder pinnedSites before', sites.toJS())
+ }
let sourceSite = sites.get(sourceKey, Immutable.Map())
- const destinationSite = sites.get(destinationKey, Immutable.Map())
-
- if (sourceSite.isEmpty()) {
+ if (sourceSite.isEmpty() || sourceSite.get('order') === newOrder) {
+ if (shouldDebug) {
+ console.log('NO CHANGE')
+ }
return state
}
-
- const sourceSiteIndex = sourceSite.get('order')
- const destinationSiteIndex = destinationSite.get('order')
- let newIndex = destinationSiteIndex + (prepend ? 0 : 1)
- if (destinationSiteIndex > sourceSiteIndex) {
- --newIndex
- }
-
- state = state.set(STATE_SITES.PINNED_SITES, state.get(STATE_SITES.PINNED_SITES).map((site, index) => {
+ const sourceSiteOrder = sourceSite.get('order')
+ state = state.set(STATE_SITES.PINNED_SITES, sites.map((site, index) => {
const siteOrder = site.get('order')
- if (index === sourceKey) {
- return site
+ if (index === sourceKey && siteOrder !== newOrder) {
+ return site.set('order', newOrder)
}
-
- if (siteOrder >= newIndex && siteOrder < sourceSiteIndex) {
+ if (siteOrder >= newOrder && siteOrder < sourceSiteOrder) {
return site.set('order', siteOrder + 1)
- } else if (siteOrder <= newIndex && siteOrder > sourceSiteIndex) {
+ } else if (siteOrder <= newOrder && siteOrder > sourceSiteOrder) {
return site.set('order', siteOrder - 1)
}
-
return site
}))
-
- sourceSite = sourceSite.set('order', newIndex)
- return state.setIn([STATE_SITES.PINNED_SITES, sourceKey], sourceSite)
+ if (shouldDebug) {
+ console.log('moveSiteToNewOrder pinnedSites after', state.get(STATE_SITES.PINNED_SITES).toJS())
+ }
+ return state
}
}
diff --git a/app/common/state/tabContentState/audioState.js b/app/common/state/tabContentState/audioState.js
index 49b8b5835d8..4f88eb9089d 100644
--- a/app/common/state/tabContentState/audioState.js
+++ b/app/common/state/tabContentState/audioState.js
@@ -49,6 +49,10 @@ module.exports.showAudioTopBorder = (state, frameKey, isPinned) => {
return false
}
+ if (module.exports.isAudioMuted(state, frameKey)) {
+ return false
+ }
+
return (
module.exports.canPlayAudio(state, frameKey) &&
(isEntryIntersected(state, 'tabs') || isPinned)
diff --git a/app/common/state/tabContentState/titleState.js b/app/common/state/tabContentState/titleState.js
index 6bdc5b75f47..1c21e294c35 100644
--- a/app/common/state/tabContentState/titleState.js
+++ b/app/common/state/tabContentState/titleState.js
@@ -8,6 +8,7 @@
const partitionState = require('../tabContentState/partitionState')
const privateState = require('../tabContentState/privateState')
const frameStateUtil = require('../../../../js/state/frameStateUtil')
+ const tabUIState = require('../tabUIState')
// Utils
const {isEntryIntersected} = require('../../../../app/renderer/lib/observerUtil')
@@ -26,11 +27,13 @@
const isActive = frameStateUtil.isFrameKeyActive(state, frameKey)
const isPartition = partitionState.isPartitionTab(state, frameKey)
const isPrivate = privateState.isPrivateTab(state, frameKey)
- const secondaryIconVisible = !isNewTabPage && (isPartition || isPrivate || isActive)
+ const secondaryIconVisible = !isNewTabPage &&
+ (isPartition || isPrivate || isActive) &&
+ tabUIState.showTabEndIcon(state, frameKey)
// If title is being intersected by ~half with other icons visible
// such as closeTab (activeTab) or session icons, do not show it
- if (isEntryIntersected(state, 'tabs', intersection.at45) && secondaryIconVisible) {
+ if (isEntryIntersected(state, 'tabs', intersection.at46) && secondaryIconVisible) {
return false
}
diff --git a/app/common/state/tabState.js b/app/common/state/tabState.js
index 74cb2cf1222..346d2a53514 100644
--- a/app/common/state/tabState.js
+++ b/app/common/state/tabState.js
@@ -61,6 +61,10 @@ const validateAction = function (action) {
return action
}
+const selectTabs = function (state) {
+ return state.get('tabs', Immutable.List()).filter(tab => !tab.isEmpty())
+}
+
const matchTab = function (queryInfo, tab) {
queryInfo = queryInfo.toJS ? queryInfo.toJS() : queryInfo
return !Object.keys(queryInfo).map((queryKey) => (tab.get(queryKey) === queryInfo[queryKey])).includes(false)
@@ -130,6 +134,9 @@ const updateTabsInternalIndex = (state, fromIndex) => {
fromIndex = validateIndex(fromIndex)
let tabsInternal = state.get('tabsInternal') || Immutable.Map()
state.get('tabs').slice(fromIndex).forEach((tab, idx) => {
+ if (tab.isEmpty()) {
+ return
+ }
const tabId = validateId('tabId', tab.get('tabId')).toString()
if (tabId !== tabState.TAB_ID_NONE) {
tabsInternal = tabsInternal.setIn(['index', tabId], (idx + fromIndex).toString())
@@ -171,7 +178,7 @@ const tabState = {
return state
}
state = deleteTabsInternalIndex(state, tabValue)
- state = state.set('tabs', state.get('tabs').delete(index))
+ state = state.setIn(['tabs', index], Immutable.Map())
return updateTabsInternalIndex(state, index)
},
@@ -208,12 +215,12 @@ const tabState = {
getTabsByWindowId: (state, windowId) => {
state = validateState(state)
windowId = validateId('windowId', windowId)
- return state.get('tabs').filter((tab) => tab.get('windowId') === windowId)
+ return selectTabs(state).filter((tab) => tab.get('windowId') === windowId)
},
getPinnedTabs: (state) => {
state = validateState(state)
- return state.get('tabs').filter((tab) => !!tab.get('pinned'))
+ return selectTabs(state).filter((tab) => !!tab.get('pinned'))
},
isTabPinned: (state, tabId) => {
@@ -225,7 +232,7 @@ const tabState = {
getNonPinnedTabs: (state) => {
state = validateState(state)
- return state.get('tabs').filter((tab) => !tab.get('pinned'))
+ return selectTabs(state).filter((tab) => !tab.get('pinned'))
},
getPinnedTabsByWindowId: (state, windowId) => {
@@ -404,6 +411,31 @@ const tabState = {
return state.set('tabs', tabs.delete(index).insert(index, tabValue))
},
+ replaceTabValue: (state, tabId, newTabValue) => {
+ state = validateState(state)
+ newTabValue = makeImmutable(newTabValue)
+ // update tab
+ const index = getTabInternalIndexByTabId(state, tabId)
+ const oldTabValue = state.getIn(['tabs', index])
+ if (index == null || index === -1) {
+ console.error(`tabState: cannot replace tab ${tabId} as tab's index did not exist in state`, { index })
+ return state
+ }
+ let mergedTabValue = oldTabValue.mergeDeep(newTabValue)
+ if (mergedTabValue.has('frame')) {
+ mergedTabValue = mergedTabValue.mergeIn(['frame'], {
+ tabId: newTabValue.get('tabId'),
+ guestInstanceId: newTabValue.get('guestInstanceId')
+ })
+ }
+ mergedTabValue = mergedTabValue.set('windowId', oldTabValue.get('windowId'))
+ state = state.set('tabs', state.get('tabs').delete(index).insert(index, mergedTabValue))
+ // update tabId at tabsInternal index
+ state = deleteTabsInternalIndex(state, oldTabValue)
+ state = updateTabsInternalIndex(state, 0)
+ return state
+ },
+
removeTabField: (state, field) => {
state = makeImmutable(state)
@@ -417,23 +449,30 @@ const tabState = {
return state.set('tabs', tabs)
},
- updateFrame: (state, action) => {
+ updateFrame: (state, action, shouldDebugTabEvents = false) => {
state = validateState(state)
action = validateAction(action)
const tabId = action.getIn(['frame', 'tabId'])
+
if (!tabId) {
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] frame changed for tab - no tabId provided!`)
+ }
return state
}
let tabValue = tabState.getByTabId(state, tabId)
if (!tabValue) {
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] frame changed for tab - tab not found in state, probably a temporary frame`)
+ }
return state
}
- const bookmarkUtil = require('../lib/bookmarkUtil')
- const frameLocation = action.getIn(['frame', 'location'])
- const frameBookmarked = bookmarkUtil.isLocationBookmarked(state, frameLocation)
- const frameValue = action.get('frame').set('bookmarked', frameBookmarked)
+ if (shouldDebugTabEvents) {
+ console.log(`Tab [${tabId}] frame changed for tab`)
+ }
+ const frameValue = action.get('frame')
tabValue = tabValue.set('frame', makeImmutable(frameValue))
return tabState.updateTabValue(state, tabValue)
},
@@ -620,7 +659,8 @@ const tabState = {
getVisibleOrigin: (state, tabId) => {
const entry = tabState.getVisibleEntry(state, tabId)
- const origin = entry ? entry.get('origin') : ''
+ // plain js in browser, immutable in renderer
+ const origin = entry ? entry.get ? entry.get('origin') : entry.origin : ''
// TODO(bridiver) - all origins in browser-laptop should be changed to have a trailing slash to match chromium
return (origin || '').replace(/\/$/, '')
},
@@ -628,6 +668,35 @@ const tabState = {
getVisibleVirtualURL: (state, tabId) => {
const entry = tabState.getVisibleEntry(state, tabId)
return entry ? entry.get('virtualURL') : ''
+ },
+
+ setTabStripWindowId: (state, tabId, windowId) => {
+ let path = tabState.getPathByTabId(state, tabId)
+ if (!path) {
+ console.error(`setTabStripWindowId: tab with ID ${tabId} not found!`)
+ return state
+ }
+ path = [...path, 'tabStripWindowId']
+ // handle clear window
+ if (windowId == null || windowId === -1) {
+ return state.deleteIn(path)
+ }
+ // handle set window
+ return state.setIn(path, windowId)
+ },
+
+ setZoomPercent: (state, tabId, zoomPercent) => {
+ let path = tabState.getPathByTabId(state, tabId)
+ if (!path) {
+ console.error(`setZoomPercent: tab with ID ${tabId} not found!`)
+ return state
+ }
+ if (typeof zoomPercent !== 'number') {
+ console.error(`setZoomPercent: bad value for zoomPercent: ${zoomPercent}`)
+ return state
+ }
+ path = [...path, 'zoomPercent']
+ return state.setIn(path, zoomPercent)
}
}
diff --git a/app/common/state/tabUIState.js b/app/common/state/tabUIState.js
index 072ff4f0d04..55159538bc9 100644
--- a/app/common/state/tabUIState.js
+++ b/app/common/state/tabUIState.js
@@ -6,8 +6,6 @@
const settings = require('../../../js/constants/settings')
// State helpers
-const partitionState = require('../../common/state/tabContentState/partitionState')
-const privateState = require('../../common/state/tabContentState/privateState')
const closeState = require('../../common/state/tabContentState/closeState')
const frameStateUtil = require('../../../js/state/frameStateUtil')
@@ -20,7 +18,6 @@ const {getSetting} = require('../../../js/settings')
// Styles
const {intersection} = require('../../renderer/components/styles/global')
-const {theme} = require('../../renderer/components/styles/theme')
module.exports.getThemeColor = (state, frameKey) => {
const frame = frameStateUtil.getFrameByKey(state, frameKey)
@@ -76,7 +73,7 @@ module.exports.showTabEndIcon = (state, frameKey) => {
return (
!closeState.hasFixedCloseIcon(state, frameKey) &&
!closeState.hasRelativeCloseIcon(state, frameKey) &&
- !isEntryIntersected(state, 'tabs', intersection.at40)
+ !isEntryIntersected(state, 'tabs', intersection.at46)
)
}
@@ -99,41 +96,3 @@ module.exports.centralizeTabIcons = (state, frameKey, isPinned) => {
return isPinned || isEntryIntersected(state, 'tabs', intersection.at40)
}
-
-module.exports.getTabEndIconBackgroundColor = (state, frameKey) => {
- const frame = frameStateUtil.getFrameByKey(state, frameKey)
-
- if (frame == null) {
- return false
- }
-
- const themeColor = module.exports.getThemeColor(state, frameKey)
- const isPrivate = privateState.isPrivateTab(state, frameKey)
- const isPartition = partitionState.isPartitionTab(state, frameKey)
- const isHover = frameStateUtil.getTabHoverState(state, frameKey)
- const isActive = frameStateUtil.isFrameKeyActive(state, frameKey)
- const hasCloseIcon = closeState.showCloseTabIcon(state, frameKey)
- const isIntersecting = isEntryIntersected(state, 'tabs', intersection.at40)
-
- let backgroundColor = theme.tab.background
-
- if (isActive && themeColor) {
- backgroundColor = themeColor
- }
- if (isActive && !themeColor) {
- backgroundColor = theme.tab.active.background
- }
- if (isIntersecting) {
- backgroundColor = 'transparent'
- }
- if (!isActive && isPrivate) {
- backgroundColor = theme.tab.private.background
- }
- if ((isActive || isHover) && isPrivate) {
- backgroundColor = theme.tab.active.private.background
- }
-
- return isPartition || isPrivate || hasCloseIcon
- ? `linear-gradient(to left, ${backgroundColor} 10px, transparent 40px)`
- : `linear-gradient(to left, ${backgroundColor} 0, transparent 12px)`
-}
diff --git a/app/common/state/urlBarState.js b/app/common/state/urlBarState.js
index b07420d75bc..e45e37d753d 100644
--- a/app/common/state/urlBarState.js
+++ b/app/common/state/urlBarState.js
@@ -19,27 +19,33 @@ const api = {
*/
getSearchData: function (state, activeFrame) {
// TODO: don't have activeFrame param when reselect is used for state retrieval memoization
- const urlbar = api.getActiveFrameUrlBarState(activeFrame)
- const activeFrameIsPrivate = activeFrame.get('isPrivate')
- const urlbarSearchDetail = urlbar.get('searchDetail')
- const appSearchDetail = state.get('searchDetail')
- const activateSearchEngine = urlbarSearchDetail && urlbarSearchDetail.get('activateSearchEngine')
+ let searchURL
+ let searchShortcut
// get default search provider from app state
- let searchURL =
+ const appSearchDetail = state.get('searchDetail')
+ const activeFrameIsPrivate = activeFrame.get('isPrivate')
+ if (appSearchDetail) {
+ searchURL =
(activeFrameIsPrivate && appSearchDetail.has('privateSearchURL'))
? appSearchDetail.get('privateSearchURL')
: appSearchDetail.get('searchURL')
- let searchShortcut = ''
+ searchShortcut = ''
+ }
+
// change search url if overrided by active frame state or shortcut
+ const urlbar = api.getActiveFrameUrlBarState(activeFrame)
+ const urlbarSearchDetail = urlbar && urlbar.get('searchDetail')
+ const activateSearchEngine = urlbarSearchDetail && urlbarSearchDetail.get('activateSearchEngine')
if (activateSearchEngine) {
const provider = urlbarSearchDetail
searchShortcut = new RegExp('^' + provider.get('shortcut') + ' ', 'g')
searchURL =
- (activeFrame.get('isPrivate') && provider.has('privateSearch'))
+ (activeFrameIsPrivate && provider.has('privateSearch'))
? provider.get('privateSearch')
: provider.get('search')
}
+
return {
searchURL,
searchShortcut
diff --git a/app/common/tracing.js b/app/common/tracing.js
index 747a1ac3d11..7a07012ddf7 100644
--- a/app/common/tracing.js
+++ b/app/common/tracing.js
@@ -52,7 +52,7 @@ exports.trace = (obj, ...args) => {
}
return function (...fnArgs) {
metadata.name = propKey
- muon.crashReporter.setCrashKeyValue('javascript-info', JSON.stringify(metadata))
+ muon.crashReporter.setJavascriptInfoCrashValue(JSON.stringify(metadata))
let result, end, exception
const start = timer.now()
try {
@@ -64,7 +64,7 @@ exports.trace = (obj, ...args) => {
metadata.stack = e.stack != null ? e.stack : e.name + ': ' + e.message
exception = e
}
- muon.crashReporter.setCrashKeyValue('javascript-info', JSON.stringify(metadata))
+ muon.crashReporter.setJavascriptInfoCrashValue(JSON.stringify(metadata))
if (exception) {
muon.crashReporter.dumpWithoutCrashing()
throw exception
diff --git a/app/crash-herald.js b/app/crash-herald.js
index 682bc53b14b..de23e0e6458 100644
--- a/app/crash-herald.js
+++ b/app/crash-herald.js
@@ -8,19 +8,13 @@ const {app} = require('electron')
const version = app.getVersion()
const channel = Channel.channel()
-const crashKeys = {
- '_version': version,
- 'channel': channel
-}
-
const initCrashKeys = () => {
// set muon-app-version switch to pass version to renderer processes
app.commandLine.appendSwitch('muon-app-version', version)
app.commandLine.appendSwitch('muon-app-channel', channel)
- for (let key in crashKeys) {
- muon.crashReporter.setCrashKeyValue(key, crashKeys[key])
- }
+ muon.crashReporter.setVersionCrashValue(version)
+ muon.crashReporter.setChannelCrashValue(channel)
}
exports.init = (enabled) => {
diff --git a/app/dataFile.js b/app/dataFile.js
index 6abe76f8c9f..8f02c0438dc 100644
--- a/app/dataFile.js
+++ b/app/dataFile.js
@@ -87,7 +87,7 @@ module.exports.init = (resourceName, version, startExtension, onInitDone, forceD
let versionFolder = version
const hasStagedDatFile = [appConfig.resourceNames.ADBLOCK, appConfig.resourceNames.SAFE_BROWSING].includes(resourceName)
- if (process.env.NODE_ENV === 'development' && hasStagedDatFile) {
+ if (hasStagedDatFile && (process.env.NODE_ENV === 'development' || process.env.BRAVE_USE_STAGING_DATA_FILES !== undefined)) {
versionFolder = `test/${versionFolder}`
}
const url = appConfig[resourceName].url.replace('{version}', versionFolder)
diff --git a/app/extensions.js b/app/extensions.js
index 9cae84b5d07..82ca7772b47 100644
--- a/app/extensions.js
+++ b/app/extensions.js
@@ -4,7 +4,7 @@ const extensionActions = require('./common/actions/extensionActions')
const config = require('../js/constants/config')
const appConfig = require('../js/constants/appConfig')
const {fileUrl} = require('../js/lib/appUrlUtil')
-const {getExtensionsPath, getBraveExtUrl, getBraveExtIndexHTML} = require('../js/lib/appUrlUtil')
+const {getComponentExtensionsPath, getExtensionsPath, getBraveExtUrl, getBraveExtIndexHTML} = require('../js/lib/appUrlUtil')
const {getSetting} = require('../js/settings')
const settings = require('../js/constants/settings')
const extensionStates = require('../js/constants/extensionStates')
@@ -38,10 +38,18 @@ let generateBraveManifest = () => {
manifest_version: 2,
version: '1.0',
background: {
- scripts: [ 'content/scripts/idleHandler.js' ],
+ scripts: [ 'content/scripts/metaScraper.js', 'content/scripts/requestHandler.js', 'content/scripts/idleHandler.js' ],
persistent: true
},
content_scripts: [
+ {
+ run_at: 'document_start',
+ all_frames: true,
+ matches: ['https://www.marketwatch.com/*'],
+ css: [
+ 'content/styles/siteHack-marketwatch.com.css'
+ ]
+ },
{
run_at: 'document_start',
all_frames: true,
@@ -175,7 +183,7 @@ let generateBraveManifest = () => {
'img/favicon.ico',
'img/newtab/defaultTopSitesIcon/appstore.png',
'img/newtab/defaultTopSitesIcon/brave.ico',
- 'img/newtab/defaultTopSitesIcon/facebook.png',
+ 'img/newtab/defaultTopSitesIcon/github.png',
'img/newtab/defaultTopSitesIcon/playstore.png',
'img/newtab/defaultTopSitesIcon/twitter.png',
'img/newtab/defaultTopSitesIcon/youtube.png'
@@ -198,6 +206,7 @@ let generateBraveManifest = () => {
'style-src': '\'self\' \'unsafe-inline\'',
'font-src': '\'self\' data:',
'img-src': '* data: file://*',
+ 'connect-src': '\'self\' https://www.youtube.com',
'frame-src': '\'self\' https://brave.com'
}
@@ -205,9 +214,11 @@ let generateBraveManifest = () => {
// allow access to webpack dev server resources
let devServer = 'localhost:' + process.env.npm_package_config_port
cspDirectives['default-src'] = '\'self\' http://' + devServer
- cspDirectives['connect-src'] = ['\'self\'',
+ cspDirectives['connect-src'] = [
+ cspDirectives['connect-src'],
'http://' + devServer,
- 'ws://' + devServer].join(' ')
+ 'ws://' + devServer
+ ].join(' ')
cspDirectives['style-src'] = '\'self\' \'unsafe-inline\' http://' + devServer
cspDirectives['font-src'] += ` http://${devServer}`
}
@@ -465,7 +476,7 @@ module.exports.init = () => {
manifest = {
name: 'PDF Viewer',
manifest_version: 2,
- version: '1.9.457',
+ version: '1.9.459',
description: 'Uses HTML5 to display PDF files directly in the browser.',
icons: {
'128': 'icon128.png',
@@ -524,7 +535,7 @@ module.exports.init = () => {
loadExtension(config.braveExtensionId, getExtensionsPath('brave'), generateBraveManifest(), 'component')
// Cryptotoken extension is loaded from electron_resources.pak
extensionInfo.setState(config.cryptoTokenExtensionId, extensionStates.REGISTERED)
- loadExtension(config.cryptoTokenExtensionId, path.join(process.resourcesPath, 'cryptotoken'), {}, 'component')
+ loadExtension(config.cryptoTokenExtensionId, getComponentExtensionsPath('cryptotoken'), {}, 'component')
extensionInfo.setState(config.syncExtensionId, extensionStates.REGISTERED)
loadExtension(config.syncExtensionId, getExtensionsPath('brave'), generateSyncManifest(), 'unpacked')
diff --git a/app/extensions/brave/about-printkeys.html b/app/extensions/brave/about-printkeys.html
new file mode 100644
index 00000000000..33a14a1c879
--- /dev/null
+++ b/app/extensions/brave/about-printkeys.html
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/extensions/brave/content/scripts/adInsertion.js b/app/extensions/brave/content/scripts/adInsertion.js
index 5430444eed8..0fc314f2eea 100644
--- a/app/extensions/brave/content/scripts/adInsertion.js
+++ b/app/extensions/brave/content/scripts/adInsertion.js
@@ -157,7 +157,7 @@ if (chrome.contentSettings.adInsertion == 'allow') {
var host = document.location.hostname
if (host) {
- host = host.replace('www.', '')
+ host = host.replace(/^www\./, '')
chrome.ipcRenderer.on('set-ad-div-candidates', (e, divHost, adDivCandidates, placeholderUrl) => {
// don't accidentally intercept messages not intended for this host
if (host === divHost) {
diff --git a/app/extensions/brave/content/scripts/blockCanvasFingerprinting.js b/app/extensions/brave/content/scripts/blockCanvasFingerprinting.js
index 06dafc3f721..d58606b5cc6 100644
--- a/app/extensions/brave/content/scripts/blockCanvasFingerprinting.js
+++ b/app/extensions/brave/content/scripts/blockCanvasFingerprinting.js
@@ -144,7 +144,7 @@ if (chrome.contentSettings.canvasFingerprinting == 'block') {
})
function reportBlock (type) {
- var script_url = getOriginatingScriptUrl()
+ var script_url = getOriginatingScriptUrl() || window.location.href
var msg = {
type,
scriptUrl: stripLineAndColumnNumbers(script_url)
diff --git a/app/extensions/brave/content/scripts/metaScraper.js b/app/extensions/brave/content/scripts/metaScraper.js
new file mode 100644
index 00000000000..e8855b2ff04
--- /dev/null
+++ b/app/extensions/brave/content/scripts/metaScraper.js
@@ -0,0 +1,102 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ // Main repository
+ // Version 3.9.2
+// https://github.com/microlinkhq/metascraper
+
+// Image
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-image
+
+// Author
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-author
+
+// Title
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-title
+
+// YouTube
+// https://github.com/microlinkhq/metascraper/tree/master/packages/metascraper-youtube
+
+const metaScraperRules = {
+ // Rules
+ getImageRules: () => {
+ const wrap = rule => ({htmlDom,url}) => {
+ const value = rule(htmlDom)
+ return requestHandlerApi.isUrl(value) && requestHandlerApi.getUrl(url, value)
+ }
+
+ return [
+ // Youtube
+ ({htmlDom,url}) => {
+ const {id,service} = requestHandlerApi.getVideoId(url)
+ return service === 'youtube' && id && requestHandlerApi.getThumbnailUrl(id)
+ },
+ // Regular
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:image:secure_url"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:image:url"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:image"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="twitter:image:src"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="twitter:image"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.image.thumb"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.image.full"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.image"]'))),
+ wrap(html => requestHandlerApi.getValue(html.querySelectorAll('article img[src]'), requestHandlerApi.getSrc)),
+ wrap(html => requestHandlerApi.getValue(html.querySelectorAll('#content img[src]'), requestHandlerApi.getSrc)),
+ wrap(html => requestHandlerApi.getSrc(html.querySelector('img[alt*="author"]'))),
+ wrap(html => requestHandlerApi.getSrc(html.querySelector('img[src]')))
+ ]
+ },
+
+ getTitleRules: () => {
+ const wrap = rule => ({htmlDom}) => {
+ const value = rule(htmlDom)
+ return requestHandlerApi.isString(value) && requestHandlerApi.titleize(value)
+ }
+
+ return [
+ // Regular
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="og:title"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="twitter:title"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.title"]'))),
+ wrap(html => requestHandlerApi.getText(html.querySelector('.post-title'))),
+ wrap(html => requestHandlerApi.getText(html.querySelector('.entry-title'))),
+ wrap(html => requestHandlerApi.getText(html.querySelector('[itemtype="http://schema.org/BlogPosting"] [itemprop="name"]'))),
+ wrap(html => requestHandlerApi.getText(html.querySelector('h1[class*="title"] a'))),
+ wrap(html => requestHandlerApi.getText(html.querySelector('h1[class*="title"]'))),
+ wrap(html => requestHandlerApi.getText(html.querySelector('title')))
+ ]
+ },
+
+ getAuthorRules: () => {
+ const wrap = rule => ({htmlDom}) => {
+ const value = rule(htmlDom)
+
+ return requestHandlerApi.isString(value) &&
+ !requestHandlerApi.isUrl(value, {relative: false}) &&
+ requestHandlerApi.titleize(value, {removeBy: true})
+ }
+
+ return [
+ // Youtube
+ wrap(html => requestHandlerApi.getText(html.querySelector('#owner-name'))),
+ wrap(html => requestHandlerApi.getText(html.querySelector('#channel-title'))),
+ wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="user-info"]'))),
+ // Regular
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="author"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="article:author"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="author"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[name="sailthru.author"]'))),
+ wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[rel="author"]'))),
+ wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[itemprop*="author"] [itemprop="name"]'))),
+ wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[itemprop*="author"]'))),
+ wrap(html => requestHandlerApi.getContent(html.querySelector('meta[property="book:author"]'))),
+ requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('a[class*="author"]')))),
+ requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="author"] a')))),
+ requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('a[href*="/author/"]')))),
+ wrap(html => requestHandlerApi.getValue(html.querySelectorAll('a[class*="screenname"]'))),
+ requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="author"]')))),
+ requestHandlerApi.strict(wrap(html => requestHandlerApi.getValue(html.querySelectorAll('[class*="byline"]'))))
+ ]
+ }
+}
diff --git a/app/extensions/brave/content/scripts/navigator.js b/app/extensions/brave/content/scripts/navigator.js
index 261485ca4a2..02bf81fe8af 100644
--- a/app/extensions/brave/content/scripts/navigator.js
+++ b/app/extensions/brave/content/scripts/navigator.js
@@ -12,6 +12,11 @@ chrome.webFrame.setGlobal("navigator.getBattery", function () {
return new Promise((resolve, reject) => { reject(new Error('navigator.getBattery not supported.')) })
})
+// bluetooth is not currently supported
+executeScript("window.Navigator.prototype.__defineGetter__('bluetooth', () => { return undefined })")
+// webusb also not supported yet
+executeScript("window.Navigator.prototype.__defineGetter__('usb', () => { return undefined })")
+
if (chrome.contentSettings.doNotTrack == 'allow') {
executeScript("window.Navigator.prototype.__defineGetter__('doNotTrack', () => { return 1 })")
}
diff --git a/app/extensions/brave/content/scripts/requestHandler.js b/app/extensions/brave/content/scripts/requestHandler.js
new file mode 100644
index 00000000000..7cf87589305
--- /dev/null
+++ b/app/extensions/brave/content/scripts/requestHandler.js
@@ -0,0 +1,389 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const ipc = chrome.ipcRenderer
+
+ipc.send('got-background-page-webcontents')
+const domParser = new DOMParser()
+
+/**
+ * Takes a string and sanitizes it for HTML.
+ * This doesn't defend against other forms of code injection (for instance
+ * interpreting the input as js), so the input should still be considered
+ * untrusted.
+ * @param {string} input
+ * @returns {string}
+ */
+const sanitizeHtml = (input) => {
+ if (typeof input !== 'string') {
+ return ''
+ }
+ return input.replace(/([\s\n]*<[^>]*>[\s\n]*)+/g, ' ')
+}
+
+ipc.on('fetch-publisher-info', (e, url, options) => {
+ let finalUrl = url
+ window.fetch(url, options).then((response) => {
+ finalUrl = response.url
+ return response.text()
+ }).then((text) => {
+ const html = domParser.parseFromString(text, 'text/html')
+ requestHandlerApi.getMetaData(html, url, finalUrl)
+ }).catch((err) => {
+ requestHandlerApi.onError(err, url, finalUrl)
+ })
+})
+
+const requestHandlerApi = {
+ onError: (err, url, finalUrl) => {
+ console.error('fetch error', err)
+ ipc.send(`got-publisher-info-${url}`, {
+ error: err.message,
+ body: {
+ url: finalUrl
+ }
+ })
+ },
+
+ getMetaData: async (htmlDom, url, finalUrl) => {
+ try {
+ const result = {
+ image: await requestHandlerApi.getData({ htmlDom, finalUrl, conditions: metaScraperRules.getImageRules() }),
+ title: await requestHandlerApi.getData({ htmlDom, finalUrl, conditions: metaScraperRules.getTitleRules() }),
+ author: await requestHandlerApi.getData({ htmlDom, finalUrl, conditions: metaScraperRules.getAuthorRules() })
+ }
+
+ ipc.send(`got-publisher-info-${url}`, {
+ error: null,
+ body: {
+ url: finalUrl,
+ title: sanitizeHtml(result.title) || '',
+ image: sanitizeHtml(result.image) || '',
+ author: sanitizeHtml(result.author) || ''
+ }
+ })
+ } catch (err) {
+ requestHandlerApi.onError(err, url, finalUrl)
+ }
+ },
+
+ // Basic logic
+ getData: async ({htmlDom,url,conditions}) => {
+ const size = conditions.length
+ let index = -1
+ let value
+
+ while (!value && index++ < size - 1) {
+ value = await conditions[index]({htmlDom,url})
+ }
+
+ return value
+ },
+
+ // Helpers
+ getText: (node) => {
+ if (!node) {
+ return ''
+ }
+
+ const html = (node.outerHTML || new XMLSerializer().serializeToString(node)) || ''
+ return sanitizeHtml(html)
+ },
+
+ urlCheck: (url) => {
+ try {
+ new URL(url)
+ return true
+ } catch (e) {
+ return false
+ }
+ },
+
+ getContent: (selector) => {
+ if (!selector) {
+ return null
+ }
+
+ return selector.content
+ },
+
+ getSrc: (selector) => {
+ if (!selector) {
+ return null
+ }
+
+ return selector.src
+ },
+
+ urlTest: (url, opts) => {
+ let relative
+ if (opts == null) {
+ relative = true
+ } else {
+ relative = opts.relative == null ? true : opts.relative
+ }
+
+ return relative
+ ? requestHandlerApi.isAbsoluteUrl(url) === false || requestHandlerApi.urlCheck(url)
+ : requestHandlerApi.urlCheck(url)
+ },
+
+ isEmpty: (value) => {
+ return value == null || value.length === 0
+ },
+
+ isUrl: (url, opts = {}) => {
+ return !requestHandlerApi.isEmpty(url) && requestHandlerApi.urlTest(url, opts)
+ },
+
+ getUrl: (baseUrl, relativePath = '') => {
+ return requestHandlerApi.isAbsoluteUrl(relativePath) === false
+ ? requestHandlerApi.resolveUrl(baseUrl, relativePath)
+ : relativePath
+ },
+
+ strict: rule => htmlDom => {
+ const value = rule(htmlDom)
+ return requestHandlerApi.isStrictString(value)
+ },
+
+ isStrictString: value => {
+ return /^\S+\s+\S+/.test(value) && value
+ },
+
+ titleize: (src, {removeBy = false} = {}) => {
+ if (!src) {
+ return ''
+ }
+
+ let title = requestHandlerApi.createTitle(src)
+ if (removeBy) title = requestHandlerApi.removeByPrefix(title).trim()
+ return title
+ },
+
+ defaultFn: (el) => {
+ if (!el) {
+ return ''
+ }
+
+ const text = requestHandlerApi.getText(el) || ''
+ return text.trim()
+ },
+
+ getValue: (collection, fn = requestHandlerApi.defaultFn) => {
+ if (!collection || !fn) {
+ return null
+ }
+
+ if (!NodeList.prototype.isPrototypeOf(collection)) {
+ return fn(collection)
+ }
+
+ for (const ele of collection) {
+ const value = fn(ele)
+ if (value) {
+ return value
+ }
+ }
+
+ return null
+ },
+
+ getThumbnailUrl: (id) => {
+ if (id == null) {
+ return null
+ }
+
+ return `https://img.youtube.com/vi/${id}/sddefault.jpg`
+ },
+
+ getVideoId: (str) => {
+ let metadata = {}
+
+ if (typeof str !== 'string') {
+ return metadata
+ }
+
+ // remove surrounding white spaces or line feeds
+ str = str.trim()
+
+ // remove the '-nocookie' flag from youtube urls
+ str = str.replace('-nocookie', '')
+
+ // remove any leading `www.`
+ str = str.replace('/www.', '/')
+
+ if (/youtube|youtu\.be|i.ytimg\./.test(str)) {
+ metadata = {
+ id: requestHandlerApi.getYouTubeId(str),
+ service: 'youtube'
+ }
+ }
+
+ return metadata
+ },
+
+ // https://github.com/radiovisual/get-video-id
+ getYouTubeId: (str) => {
+ if (str == null) {
+ return ''
+ }
+
+ // short code
+ const shortCode = /youtube:\/\/|https?:\/\/youtu\.be\//g
+ if (shortCode.test(str)) {
+ const shortCodeId = str.split(shortCode)[1]
+ return requestHandlerApi.stripParameters(shortCodeId)
+ }
+
+ // /v/ or /vi/
+ const inlineV = /\/v\/|\/vi\//g
+ if (inlineV.test(str)) {
+ const inlineId = str.split(inlineV)[1]
+ return requestHandlerApi.stripParameters(inlineId)
+ }
+
+ // v= or vi=
+ const parameterV = /v=|vi=/g
+ if (parameterV.test(str)) {
+ const arr = str.split(parameterV)
+ return arr[1].split('&')[0]
+ }
+
+ // v= or vi=
+ const parameterWebP = /\/an_webp\//g
+ if (parameterWebP.test(str)) {
+ const webP = str.split(parameterWebP)[1]
+ return requestHandlerApi.stripParameters(webP)
+ }
+
+ // embed
+ const embedReg = /\/embed\//g
+ if (embedReg.test(str)) {
+ const embedId = str.split(embedReg)[1]
+ return requestHandlerApi.stripParameters(embedId)
+ }
+
+ // user
+ const userReg = /\/user\//g
+ if (userReg.test(str)) {
+ const elements = str.split('/')
+ return requestHandlerApi.stripParameters(elements.pop())
+ }
+
+ // attribution_link
+ const attrReg = /\/attribution_link\?.*v%3D([^%&]*)(%26|&|$)/
+ if (attrReg.test(str)) {
+ return str.match(attrReg)[1]
+ }
+ },
+
+ stripParameters: (str) => {
+ if (str == null) {
+ return ''
+ }
+
+ // Split parameters
+ if (str.includes('?')) {
+ return str.split('?')[0]
+ }
+
+ // Split folder separator
+ if (str.includes('/')) {
+ return str.split('/')[0]
+ }
+
+ return str
+ },
+
+ // https://github.com/kellym/smartquotesjs
+ getReplacements: () => {
+ return [
+ // triple prime
+ [/'''/g, retainLength => '\u2034' + (retainLength ? '\u2063\u2063' : '')],
+ // beginning "
+ [/(\W|^)"(\w)/g, '$1\u201c$2'],
+ // ending "
+ [/(\u201c[^"]*)"([^"]*$|[^\u201c"]*\u201c)/g, '$1\u201d$2'],
+ // remaining " at end of word
+ [/([^0-9])"/g, '$1\u201d'],
+ // double prime as two single quotes
+ [/''/g, retainLength => '\u2033' + (retainLength ? '\u2063' : '')],
+ // beginning '
+ [/(\W|^)'(\S)/g, '$1\u2018$2'],
+ // conjunction's possession
+ [/([a-z])'([a-z])/ig, '$1\u2019$2'],
+ // abbrev. years like '93
+ [/(\u2018)([0-9]{2}[^\u2019]*)(\u2018([^0-9]|$)|$|\u2019[a-z])/ig, '\u2019$2$3'],
+ // ending '
+ [/((\u2018[^']*)|[a-z])'([^0-9]|$)/ig, '$1\u2019$3'],
+ // backwards apostrophe
+ [/(\B|^)\u2018(?=([^\u2018\u2019]*\u2019\b)*([^\u2018\u2019]*\B\W[\u2018\u2019]\b|[^\u2018\u2019]*$))/ig, '$1\u2019'],
+ // double prime
+ [/"/g, '\u2033'],
+ // prime
+ [/'/g, '\u2032']
+ ]
+ },
+
+ smartQuotes: (str) => {
+ const replacements = requestHandlerApi.getReplacements()
+ if (!replacements || !str) {
+ return ''
+ }
+
+ replacements.forEach(replace => {
+ const replacement = typeof replace[1] === 'function' ? replace[1]({}) : replace[1]
+ str = str.replace(replace[0], replacement)
+ })
+
+ return str
+ },
+
+ removeByPrefix: (str = '') => {
+ if (str == null) {
+ return ''
+ }
+
+ return str.replace(/^[\s\n]*by|@[\s\n]*/i, '').trim()
+ },
+
+ createTitle: (str = '') => {
+ if (str == null) {
+ return ''
+ }
+
+ str = str.trim().replace(/\s{2,}/g, ' ')
+ return requestHandlerApi.smartQuotes(str)
+ },
+
+ // https://github.com/sindresorhus/is-absolute-url
+ isAbsoluteUrl: (url) => {
+ if (!requestHandlerApi.isString(url)) {
+ return
+ }
+
+ return /^[a-z][a-z0-9+.-]*:/.test(url)
+ },
+
+ resolveUrl: (baseUrl, relativePath) => {
+ let url = baseUrl
+
+ if (!relativePath) {
+ return url
+ }
+
+ try {
+ url = new URL(relativePath, [baseUrl])
+ } catch (e) {}
+
+ return url
+ },
+
+ isString: (str) => {
+ return typeof str === 'string'
+ }
+}
+
+if (module) module.exports = requestHandlerApi
diff --git a/app/extensions/brave/content/scripts/themeColor.js b/app/extensions/brave/content/scripts/themeColor.js
index 345b77b1bbe..71c5d034976 100644
--- a/app/extensions/brave/content/scripts/themeColor.js
+++ b/app/extensions/brave/content/scripts/themeColor.js
@@ -57,6 +57,16 @@
}
if(window.top == window.self) {
- chrome.ipcRenderer.sendToHost('theme-color-computed', computeThemeColor())
+ if (document.visibilityState !== 'visible' && window.innerWidth === 0 && window.innerHeight === 0) {
+ const handleVisibilityChange = function() {
+ if (window.innerWidth !== 0 && window.innerHeight !== 0) {
+ window.removeEventListener('resize', handleVisibilityChange)
+ chrome.ipcRenderer.sendToHost('theme-color-computed', computeThemeColor())
+ }
+ }
+ window.addEventListener('resize', handleVisibilityChange)
+ } else {
+ chrome.ipcRenderer.sendToHost('theme-color-computed', computeThemeColor())
+ }
}
})()
diff --git a/app/extensions/brave/content/styles/siteHack-marketwatch.com.css b/app/extensions/brave/content/styles/siteHack-marketwatch.com.css
new file mode 100644
index 00000000000..03de69bfbe0
--- /dev/null
+++ b/app/extensions/brave/content/styles/siteHack-marketwatch.com.css
@@ -0,0 +1,7 @@
+.element--ad,
+.container--bannerAd,
+#brass-rail,
+.ad.module,
+iframe[src*="smartads.epl"] {
+ display: none !important;
+}
\ No newline at end of file
diff --git a/app/extensions/brave/img/favicons/fireball.ico b/app/extensions/brave/img/favicons/fireball.ico
new file mode 100644
index 00000000000..08cbac9b16b
Binary files /dev/null and b/app/extensions/brave/img/favicons/fireball.ico differ
diff --git a/app/extensions/brave/img/ledger/BAT_captcha_BG_arrow.png b/app/extensions/brave/img/ledger/BAT_captcha_BG_arrow.png
new file mode 100644
index 00000000000..9f7eafd5d8f
Binary files /dev/null and b/app/extensions/brave/img/ledger/BAT_captcha_BG_arrow.png differ
diff --git a/app/extensions/brave/img/ledger/BAT_captcha_dragicon.png b/app/extensions/brave/img/ledger/BAT_captcha_dragicon.png
new file mode 100644
index 00000000000..fc8c7199eb2
Binary files /dev/null and b/app/extensions/brave/img/ledger/BAT_captcha_dragicon.png differ
diff --git a/app/extensions/brave/img/newtab/defaultTopSitesIcon/brave.ico b/app/extensions/brave/img/newtab/defaultTopSitesIcon/brave.ico
index 374fb80899c..389d8d8f6f8 100644
Binary files a/app/extensions/brave/img/newtab/defaultTopSitesIcon/brave.ico and b/app/extensions/brave/img/newtab/defaultTopSitesIcon/brave.ico differ
diff --git a/app/extensions/brave/img/newtab/defaultTopSitesIcon/facebook.png b/app/extensions/brave/img/newtab/defaultTopSitesIcon/facebook.png
deleted file mode 100644
index 231076c247e..00000000000
Binary files a/app/extensions/brave/img/newtab/defaultTopSitesIcon/facebook.png and /dev/null differ
diff --git a/app/extensions/brave/img/newtab/defaultTopSitesIcon/github.png b/app/extensions/brave/img/newtab/defaultTopSitesIcon/github.png
new file mode 100644
index 00000000000..ea6ff545a24
Binary files /dev/null and b/app/extensions/brave/img/newtab/defaultTopSitesIcon/github.png differ
diff --git a/app/extensions/brave/img/newtab/defaultTopSitesIcon/playstore.png b/app/extensions/brave/img/newtab/defaultTopSitesIcon/playstore.png
index 5d6419829d0..29780b1ad07 100644
Binary files a/app/extensions/brave/img/newtab/defaultTopSitesIcon/playstore.png and b/app/extensions/brave/img/newtab/defaultTopSitesIcon/playstore.png differ
diff --git a/app/extensions/brave/img/tabs/close_btn.svg b/app/extensions/brave/img/tabs/close_btn.svg
deleted file mode 100644
index 926636ea455..00000000000
--- a/app/extensions/brave/img/tabs/close_btn.svg
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/app/extensions/brave/locales/bn-BD/app.properties b/app/extensions/brave/locales/bn-BD/app.properties
index ad64e12593c..85731c4ff9e 100644
--- a/app/extensions/brave/locales/bn-BD/app.properties
+++ b/app/extensions/brave/locales/bn-BD/app.properties
@@ -132,8 +132,7 @@ issuedBy=প্রদান করেছেন
issuedTo=যার জন্য জারি করা হয়েছে
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=ঠিক আছে
listOfAboutPages=About পাতা সমূহের তালিকা
diff --git a/app/extensions/brave/locales/bn-IN/app.properties b/app/extensions/brave/locales/bn-IN/app.properties
index f7847d4d1c5..23ab74db212 100644
--- a/app/extensions/brave/locales/bn-IN/app.properties
+++ b/app/extensions/brave/locales/bn-IN/app.properties
@@ -132,8 +132,7 @@ issuedBy=Issued By
issuedTo=Issued To
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=Ok
listOfAboutPages=পৃষ্ঠাগুলি সম্পর্কে এর তালিকা
diff --git a/app/extensions/brave/locales/cs/app.properties b/app/extensions/brave/locales/cs/app.properties
index e29a99cce48..4e9ab9d4be1 100644
--- a/app/extensions/brave/locales/cs/app.properties
+++ b/app/extensions/brave/locales/cs/app.properties
@@ -132,8 +132,7 @@ issuedBy=Vystaveno
issuedTo=Vystaveno pro
ledgerBackupText1=Klíče pro obnovení peněženky Brave
ledgerBackupText2=Datum vytvoření:
-ledgerBackupText3=Klíč pro obnovení 1:
-ledgerBackupText4=Klíč pro obnovení 2:
+ledgerBackupText4=Klíč pro obnovení:
ledgerBackupText5=Poznámka: Tyto klíče nejsou uloženy na serverech Brave. Tyto klíče jsou vaším jediným způsobem, kterým můžete obnovit svoji peněženku Brave. Tyto klíče uložte na bezpečném místě, odděleně od prohlížeče Brave.
licenseTextOk=OK
listOfAboutPages=Seznam stránek s informacemi
diff --git a/app/extensions/brave/locales/de-DE/app.properties b/app/extensions/brave/locales/de-DE/app.properties
index 7f9f7599791..89bb0924db2 100644
--- a/app/extensions/brave/locales/de-DE/app.properties
+++ b/app/extensions/brave/locales/de-DE/app.properties
@@ -132,8 +132,7 @@ issuedBy=Ausgestellt von
issuedTo=Ausgestellt an
ledgerBackupText1=Brave Konto Wiederherstellungs-Schlüssel
ledgerBackupText2=Erstellt am:
-ledgerBackupText3=Wiederherstellungs-Schlüssel 1:
-ledgerBackupText4=Wiederherstellungs-Schlüssel 2:
+ledgerBackupText4=Wiederherstellungs-Schlüssel:
ledgerBackupText5=Hinweis: Diese Schlüssel werden nicht auf den Servern von Brave gespeichert, sie dienen allein der Wiederherstellung Ihres Brave Kontos. Bewahren Sie die Schlüssel an einem Sicheren Ort, getrennt vom Brave Browser.
licenseTextOk=Ok
listOfAboutPages=Übersicht der 'about' Seiten
diff --git a/app/extensions/brave/locales/en-GB/app.properties b/app/extensions/brave/locales/en-GB/app.properties
index c55cb6537d7..15f5d2cb1b9 100644
--- a/app/extensions/brave/locales/en-GB/app.properties
+++ b/app/extensions/brave/locales/en-GB/app.properties
@@ -145,8 +145,7 @@ goToAdobe=Reinstall Flash
allowFlashPlayer=Allow {{origin}} to run Flash Player?
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
allowWidevine=Allow {{origin}} to run Google Widevine?
diff --git a/app/extensions/brave/locales/en-US/app.properties b/app/extensions/brave/locales/en-US/app.properties
index 283a1de9e02..ef89a4df0b6 100644
--- a/app/extensions/brave/locales/en-US/app.properties
+++ b/app/extensions/brave/locales/en-US/app.properties
@@ -26,6 +26,8 @@ autocompleteData=Autocomplete data
autofillData=Autofill data
back=Back
backButton.title=Go back
+backupKeys=Let's backup your Brave wallet. It only takes a second...
+backupKeysNow=Backup Now
basicAuthMessage={{host}} requires a username and password.
basicAuthPasswordLabel=Password
basicAuthRequired=Authentication Required
@@ -160,7 +162,7 @@ notificationTryPaymentsYes=Sure, I'll try
notificationUpdatePassword=Would you like Brave to update your password on {{origin}}?
notificationUpdatePasswordWithUserName=Would you like Brave to update the password for {{username}} on {{origin}}?
notNow=Not Now
-notVisiblePublisher.title=Publisher is not yet added to the ledger, because it doesn't meet criteria yet.
+notVisiblePublisher.title=Publisher is not yet added to the ledger, click to include in Brave Payments.
ok=OK
openTypeInNewPrivateTab=Open {{type}} in a new private tab
openTypeInNewTab=Open {{type}} in a new tab
@@ -186,6 +188,7 @@ phone=Phone
postalCode=Postal Code
prefsRestart=Do you want to restart now?
preventMoreAlerts=Prevent this page from creating additional dialogs
+printKeysTitle=Backup keys
reconciliationNotification=Good news! Brave will pay your favorite publisher sites in less than 24 hours.
redirectedResources={{redirectedResourcesSize}} Resources upgraded to HTTPS
releaseNotes=Release Notes
@@ -260,10 +263,6 @@ versionInformation=Version Information
videoCapturePermission=Video Capture
viewCertificate=View Certificate
viewPageSource=View Page Source
-walletConvertedBackup=Back up your new wallet
-walletConvertedDismiss=Later
-walletConvertedLearnMore=Learn More
-walletConvertedToBat=Your BTC will be converted to BAT and will appear in your Brave wallet within approximately 30 minutes.
widevinePanelTitle=Brave needs to install Google Widevine to proceed
windowCaptionButtonClose=Close
windowCaptionButtonMaximize=Maximize
diff --git a/app/extensions/brave/locales/en-US/menu.properties b/app/extensions/brave/locales/en-US/menu.properties
index cdd0084f64b..dac4977850c 100644
--- a/app/extensions/brave/locales/en-US/menu.properties
+++ b/app/extensions/brave/locales/en-US/menu.properties
@@ -4,6 +4,7 @@ actualSize=Actual Size
addBookmark=Add Bookmark…
addFolder=Add Folder…
addToFavoritesBar=Add to Favorites Bar
+addToPublisherList=Include site in Brave Payments
addToReadingList=Add to reading list
allowFlashAlways=Allow for 1 week
allowFlashOnce=Allow once
@@ -45,6 +46,7 @@ cut=Cut
delete=Delete
deleteBookmark=Delete Bookmark
deleteBookmarks=Delete Selected Bookmarks
+deleteDomainFromHistory=Delete Domain from History
deleteFolder=Delete Folder
deleteHistoryEntries=Delete Selected History Entries
deleteHistoryEntry=Delete History Entry
@@ -91,6 +93,8 @@ learnSpelling=Learn Spelling
licenseText=This software uses libraries from the FFmpeg project under the LGPLv2.1
lookupSelection=Look Up “{{selectedVariable}}”
mergeAllWindows=Merge All Windows
+messageBoxOk=ok
+messageBoxCancel=cancel
minimize=Minimize
moveTabToNewWindow=Move to New Window
muteOtherTabs=Mute other Tabs
@@ -114,6 +118,7 @@ openInNewTabs=Open Links in New Tabs
openInNewWindow=Open Link in New Window
openLocation=Open Location…
openSearch=Search for "{{selectedVariable}}"
+otherBookmarks=Other Bookmarks
passwordsManager=Passwords…
paste=Paste
pasteAndGo=Paste and Go
diff --git a/app/extensions/brave/locales/en-US/passwords.properties b/app/extensions/brave/locales/en-US/passwords.properties
index 4636ff8e3dc..81aa68660d3 100644
--- a/app/extensions/brave/locales/en-US/passwords.properties
+++ b/app/extensions/brave/locales/en-US/passwords.properties
@@ -1,5 +1,5 @@
clearPasswords=Delete all saved passwords
-confirmClearPasswords=Are you sure you want to delete all passwords? This cannot be undone.
+confirmClearPasswords=Are you sure you want to delete all saved passwords? This cannot be undone.
deletePassword=Delete
hidePassword=Hide
noPasswordsSaved=No passwords have been saved.
diff --git a/app/extensions/brave/locales/en-US/preferences.properties b/app/extensions/brave/locales/en-US/preferences.properties
index 02b6dd5c8bc..a77a6f451ef 100644
--- a/app/extensions/brave/locales/en-US/preferences.properties
+++ b/app/extensions/brave/locales/en-US/preferences.properties
@@ -49,6 +49,7 @@ autoplay=Autoplay Media
autoSuggestSites=auto-include
backupLedger=Backup your wallet
balanceRecovered={{balance}} was recovered and transferred to your Brave wallet.
+banSiteConfirmation=Are you sure you want to delete this site?
beta=beta
bitcoin=Bitcoin
bitcoinBalance=Please transfer:
@@ -75,6 +76,7 @@ clearAll=Clear all
clearBrowsingDataNow=Clear Browsing Data Now…
comingSoon=Coming soon!
compactBraveryPanel=Use compact panel
+confirmPaymentsClear=A Brave Payment contribution is in progress. Brave Payment data cannot be cleared during this time.
contentSettings=Content Settings
contributionAmount=Contribution Amount
contributionDate=Contribution Date
@@ -89,6 +91,11 @@ contributionTime=Contribution Time
copied=Copied!
copy=Copy
copyToClipboard.title=Copy to clipboard
+corruptedOverlayTitle=Hello!
+corruptedOverlayMessage=Unfortunately your active wallet has been corrupted.
+corruptedOverlayText=You must recover your backup wallet with your recovery keys before any transactions can be processed. We apologize for the inconvenience.
+corruptedOverlayFAQ=View the Brave Payments FAQ…
+corruptedOverlayButton=Recover your Brave Wallet
createdWalletStatus=Your wallet is ready!
createWallet=create wallet
createWalletStatus=Click the Create Wallet button to get started.
@@ -100,10 +107,11 @@ dashboardShowImages=Show images
dashlane=Dashlane® (requires application)
date=Date
default=Default
-default=Default
defaultBrowser=Brave is your default browser.
defaultWalletStatus=Thanks for helping support your favorite websites!
defaultZoomLevel=Default zoom level
+deletedSitesHeader=Deleted Sites
+disableNonProxiedUdp=Disable non-proxied UDP
disableTitleMode=Always show the URL bar
disconnect=Disconnect
dollarsPaid=Amount
@@ -132,8 +140,7 @@ engineGoKey=Engine Go Key (Type First)
engineGoKey=Engine Go Key (type first)
enpass=Enpass® (requires application)
extensions=Extensions
-firstKey=Key 1
-firstRecoveryKey=Recovery Key 1
+expires=expires
flash=Run Adobe Flash Player
flashAllowAlways=Allow until {{time}}
flashTroubleshooting=Flash not working? Try the troubleshooting tips on our
@@ -158,17 +165,21 @@ lastPass=LastPass®
ledgerBackupText1=Below, you will find the anonymized recovery key that is required if you ever lose access to this computer.
ledgerBackupText2=Make sure you keep this key private, or else your wallet will be compromised.
ledgerBackupTitle=Backup your Brave wallet
-leaderLoaderText1=Please wait while we convert your Bitcoin to BAT.
-leaderLoaderText2=This can take anywhere from a few minutes to several hours, due to the Bitcoin transaction confirmation process, and will continue normally even if you quit Brave.
+ledgerFuzzed=You haven't accrued 30 minutes of browser activity yet so we pushed back the settlement date to give you more time.
+ledgerNetworkErrorMessage=The Brave Payments server is not responding. We will fix this as soon as possible.
+ledgerNetworkErrorTitle=Uh oh.
+ledgerNetworkErrorText=Note: This error could also be caused by a network connection problem.
ledgerPaymentsShown=Brave Payments
-ledgerRecoveryContent=Your previous wallet will now be used. Your new wallet will be discarded.
+ledgerRecoveryContent=Note: The recovered BAT wallet will replace the current BAT wallet, which will be discarded.
ledgerRecoveryFailedMessage=Please re-enter keys or try different keys.
ledgerRecoveryFailedTitle=Recovery Failed
+ledgerRecoveryInProgress=Recovery in progress...
+ledgerRecoveryInProgressTitle=Recovering
ledgerRecoveryNetworkFailedMessage=Please check your internet connection and try again.
ledgerRecoveryNetworkFailedTitle=Network Error
-ledgerRecoverySubtitle=Enter your recovery key below
+ledgerRecoverySubtitle=Enter your BAT wallet recovery key below:
ledgerRecoverySucceeded=Success!
-ledgerRecoveryTitle=Recover your Brave wallet
+ledgerRecoveryTitle=Recover your Brave BAT wallet
listOfContributionStatements=List of contribution statements
locationBarSettings=Search Bar Options
long=Long
@@ -217,6 +228,9 @@ paintTabs=Show tabs in page theme color
passwordManager=Password Manager
passwordsAndForms=Passwords and Forms
paymentsAllowPromotions=Notify me about token promotions
+paymentsDeleteWallet=Delete wallet
+paymentsDeleteWalletConfirmation=Are you sure that you want to delete your wallet? If you don't have your backup keys, your wallet will be lost forever.
+paymentHistory=Brave Payments statements
paymentHistoryDueFooterText=Your next contribution is due.
paymentHistoryFooterText=Your next contribution is {{reconcileDate}}.
paymentHistoryIcon.title=Your Payment History
@@ -224,6 +238,7 @@ paymentHistoryOKText=OK
paymentHistoryOverdueFooterText=Your contribution is overdue.
paymentHistoryTitle=Your Payment History
paymentHistoryTitle=Your Payment History
+paymentInProgress=Currently processing
payments=Payments
paymentsFAQLink.title=View the FAQ
paymentsSidebarText1=Our Partners
@@ -249,6 +264,11 @@ printKeys=Print key
privacy=Privacy
privateData=Private Data
privateDataMessage=Clear the following data types when I close Brave
+promotionCaptchaTitle=Almost there!
+promotionCaptchaErrorTitle=Hmmm…not quite.
+promotionCaptchaErrorText=Please try again.
+promotionCaptchaText=First, prove you are human:
+promotionCaptchaMessage=Drag and drop the BAT logo onto the target
promotionGeneralErrorMessage=The Brave Payments server is not responding. Please try again later to claim your token grant.
promotionGeneralErrorText=Note: This error could also be caused by a network connection problem.
promotionGeneralErrorTitle=Uh oh.
@@ -256,10 +276,14 @@ promotionClaimedErrorMessage=The promotion has ended.
promotionClaimedErrorText=There may be additional Basic Attention Token promotions in the future so stay tuned
promotionClaimedErrorTitle=Sorry!
protocolRegistrationPermission=Protocol registration
+publicOnly=Default public interface only
+publicPrivate=Default public and private interfaces
publisher=Site
+publishersClear=Brave Payments attention data
publisherMediaName={{publisherName}} on {{provider}}
publishers=Publishers
rank=Rank
+recalculatingBalance=Calculating balance...
receiptLink=Receipt Link
recover=Recover
recoverFromFile=Import recovery key
@@ -292,6 +316,7 @@ shieldsUp=All Brave Shields
short=Short
short=Short
showAll=Show All
+showDeletedSitesDialog=Show Deleted Sites
showBookmarkMatches=Show bookmark matches
showHistoryMatches=Show history matches
showHomeButton=Show home button on URL bar
@@ -337,7 +362,7 @@ syncHideQR=Hide QR code
syncHistory=Browsing history
syncNewDevice1=Open Brave on your new device and go to Preferences > Sync > 'I have an existing synced device'.
syncNewDevice2=If it asks you to scan a QR code, click the button below and point your camera at the QR code.
-syncNewDevice3=If asks you to enter code words, type in the words below.
+syncNewDevice3=If it asks you to enter code words, type in the words below.
syncNewDevice=Sync a new device…
syncQRImg.title=Brave sync QR code
syncReset=Reset Sync
@@ -366,6 +391,7 @@ tabsSettings=Tabs Settings
termsOfService=Terms of Service
timeSpent=Time Spent
toolbarUserInterfaceScale=Toolbar and UI elements scale
+total=total
totalAmount=Total Amount
update=Update
updateToPreviewReleases=Update to preview releases *
@@ -375,12 +401,17 @@ useHardwareAcceleration=Use hardware acceleration when available *
useSmoothScroll=Enable smooth scrolling *
siteIsolation=Strict Site Isolation
useSiteIsolation=Enhance security by loading each site in its own process (experimental) *
+firewall=Application Firewall
+useFirewall=Block external sites from connecting to private IP addresses, and only allow connections to private IP addresses with whitelisted hostnames (localhost, *.local, *.localhost).
verifiedExplainerText= = publisher has verified their wallet
viewLog=View Log
viewPaymentHistory= {{date}}
views=Views
visit=visit
visits=Visits
+webrtcPolicy=WebRTC IP Handling Policy
+webrtcPolicyExplanation=What do these policies mean?
wideURLbar=Use wide URL bar
widevine=Run Google Widevine
widevineSection=Google Widevine Support
+wordCount=Word Count:
diff --git a/app/extensions/brave/locales/en-US/styles.properties b/app/extensions/brave/locales/en-US/styles.properties
index b1ef50bb59f..d55675ca4ca 100644
--- a/app/extensions/brave/locales/en-US/styles.properties
+++ b/app/extensions/brave/locales/en-US/styles.properties
@@ -27,3 +27,5 @@ titles=Titles
typography=Typography
InfoBrowserButtonGrouped=To cancel the margin-left of the grouped buttons, they have to have a parent. Beginning with Selectors Level 4, it is no longer required.
InfoCommonFormCustom=It is possible to customize the style of the components with this.props.custom
. However, please consider to create a new component or enhance the existing one with props
to maintain style consistency.
+wordCount=Word Count:
+copyToClipboard.title=Copy to clipboard
diff --git a/app/extensions/brave/locales/es/app.properties b/app/extensions/brave/locales/es/app.properties
index c876abca893..b76096f98ea 100644
--- a/app/extensions/brave/locales/es/app.properties
+++ b/app/extensions/brave/locales/es/app.properties
@@ -132,8 +132,7 @@ issuedBy=Emitido por
issuedTo=Emitido para
ledgerBackupText1=Claves de recuperación de cartera Brave
ledgerBackupText2=Fecha de creación:
-ledgerBackupText3=Clave de recuperación 1:
-ledgerBackupText4=Clave de recuperación 2:
+ledgerBackupText4=Clave de recuperación:
ledgerBackupText5=Nota: Estas claves no están almacenadas en los servidores de Brave. Estas claves son la única manera de recuperar tu cartera Brave. Guarda estas claves en un lugar seguro, separado de tu navegador Brave.
licenseTextOk=Ok
listOfAboutPages=Lista de páginas de información
diff --git a/app/extensions/brave/locales/eu/app.properties b/app/extensions/brave/locales/eu/app.properties
index dae52961511..8a948239fd4 100644
--- a/app/extensions/brave/locales/eu/app.properties
+++ b/app/extensions/brave/locales/eu/app.properties
@@ -132,8 +132,7 @@ issuedBy=Honengatik bidalita
issuedTo=Bidali hona
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Sortutako data:
-ledgerBackupText3=Berreskuratzeko pasahitza 1:
-ledgerBackupText4=Berreskuratzeko pasahitza 2:
+ledgerBackupText4=Berreskuratzeko pasahitza:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=Ados
listOfAboutPages=Orrialdei buruzko zerrenda
diff --git a/app/extensions/brave/locales/fr-FR/app.properties b/app/extensions/brave/locales/fr-FR/app.properties
index 0badfd58965..76519eda91a 100644
--- a/app/extensions/brave/locales/fr-FR/app.properties
+++ b/app/extensions/brave/locales/fr-FR/app.properties
@@ -132,8 +132,7 @@ issuedBy=Émis par
issuedTo=Émis à
ledgerBackupText1=Clés de récupération du porte-monnaie Brave
ledgerBackupText2=Date de création :
-ledgerBackupText3=Clé de récupération N°1 :
-ledgerBackupText4=Clé de récupération N°2 :
+ledgerBackupText4=Clé de récupération:
ledgerBackupText5=Note : Ces clés ne sont pas stockées sur les serveurs Brave. Ces clés constituent pour vous la seule méthode pour récupérer votre porte-monnaie Brave. Conservez ces clés dans un endroit sûr, en dehors de votre navigateur Brave.
licenseTextOk=Ok
listOfAboutPages=Liste des pages « À propos »
diff --git a/app/extensions/brave/locales/hi-IN/app.properties b/app/extensions/brave/locales/hi-IN/app.properties
index 949121c7c2b..1167dc1eb53 100644
--- a/app/extensions/brave/locales/hi-IN/app.properties
+++ b/app/extensions/brave/locales/hi-IN/app.properties
@@ -132,8 +132,7 @@ issuedBy=Issued By
issuedTo=के लिए जारी किए
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=ठीक है
listOfAboutPages=पृष्ठों के बारे में सूची
diff --git a/app/extensions/brave/locales/id-ID/app.properties b/app/extensions/brave/locales/id-ID/app.properties
index 130b080ef65..13fbffba53a 100644
--- a/app/extensions/brave/locales/id-ID/app.properties
+++ b/app/extensions/brave/locales/id-ID/app.properties
@@ -132,8 +132,7 @@ issuedBy=Diterbitkan oleh
issuedTo=Diterbitkan untuk
ledgerBackupText1=Kunci Pemulihan Dompet Brave
ledgerBackupText2=Tanggal dibuat:
-ledgerBackupText3=Kunci Pemulihan 1:
-ledgerBackupText4=Kunci Pemulihan 2:
+ledgerBackupText4=Kunci Pemulihan:
ledgerBackupText5=Catatan: Kunci ini tidak disimpan di server Brave. Kunci ini adalah satu-satunya metode untuk memulihkan dompet Brave Anda. Simpan kunci tersebut di tempat yang aman, terpisah dari peramban Brave Anda.
licenseTextOk=Oke
listOfAboutPages=Daftar laman tentang
diff --git a/app/extensions/brave/locales/it-IT/app.properties b/app/extensions/brave/locales/it-IT/app.properties
index e29ffd4a06e..d5f586bff53 100644
--- a/app/extensions/brave/locales/it-IT/app.properties
+++ b/app/extensions/brave/locales/it-IT/app.properties
@@ -132,8 +132,7 @@ issuedBy=Rilasciato da
issuedTo=Rilasciato a
ledgerBackupText1=Chiavi di ripristino Brave Wallet
ledgerBackupText2=Data di creazione:
-ledgerBackupText3=Chiave di ripristino 1:
-ledgerBackupText4=Chiave di ripristino 2:
+ledgerBackupText4=Chiave di ripristino:
ledgerBackupText5=Nota: queste chiavi non sono memorizzate sui server Brave. Queste chiavi sono il tuo unico modo per ripristinare il tuo Brave Wallet. Salva queste chiavi in un luogo sicuro e diverso dal tuo browser Brave.
licenseTextOk=Ok
listOfAboutPages=Lista delle pagine di informazioni
diff --git a/app/extensions/brave/locales/ja-JP/app.properties b/app/extensions/brave/locales/ja-JP/app.properties
index a4f0ba962ee..94779d4b1be 100644
--- a/app/extensions/brave/locales/ja-JP/app.properties
+++ b/app/extensions/brave/locales/ja-JP/app.properties
@@ -132,8 +132,7 @@ issuedBy=発行元
issuedTo=発行先
ledgerBackupText1=Braveウォレットのリカバリーキー
ledgerBackupText2=作成日
-ledgerBackupText3=リカバリーキー 1
-ledgerBackupText4=リカバリーキー 2
+ledgerBackupText4=リカバリーキー
ledgerBackupText5=これらのキーはBraveのサーバーには保存されていません。これらのキーがBraveウォレットを回復する唯一の方法なので、ブラウザとは別に、安全な場所に保存してください。
licenseTextOk=了解
listOfAboutPages=List of about pages
diff --git a/app/extensions/brave/locales/ko-KR/app.properties b/app/extensions/brave/locales/ko-KR/app.properties
index fec92b657b4..4f8063cb722 100644
--- a/app/extensions/brave/locales/ko-KR/app.properties
+++ b/app/extensions/brave/locales/ko-KR/app.properties
@@ -132,8 +132,7 @@ issuedBy=발급한 곳
issuedTo=발급받은 대상
ledgerBackupText1=Brave 지갑 복구 키
ledgerBackupText2=만든 날짜:
-ledgerBackupText3=복구 키 1:
-ledgerBackupText4=복구 키 2:
+ledgerBackupText4=복구 키:
ledgerBackupText5=참고: 이 키는 Brave 서버에 저장되지 않습니다. 이 키는 Brave 지갑을 복구하는 유일한 방법입니다. 안전한 곳에 이 키를 저장하고, Brave 브라우저와 분리하세요.
licenseTextOk=확인
listOfAboutPages=페이지에 대한 목록
diff --git a/app/extensions/brave/locales/ms-MY/app.properties b/app/extensions/brave/locales/ms-MY/app.properties
index 15f9dc3308c..075212b0802 100644
--- a/app/extensions/brave/locales/ms-MY/app.properties
+++ b/app/extensions/brave/locales/ms-MY/app.properties
@@ -132,8 +132,7 @@ issuedBy=Dikeluarkan Oleh
issuedTo=Dikeluarkan Kepada
ledgerBackupText1=Kunci Pengembalian Semula Dompet Brave
ledgerBackupText2=Tarikh dicipta:
-ledgerBackupText3=Kunci Pengembalian Semula 1
-ledgerBackupText4=Kunci Pengembalian Semula 2
+ledgerBackupText4=Kunci Pengembalian Semula
ledgerBackupText5=Nota: Kunci ini tidak disimpan dalam pelayan Brave. Kunci ini adalah satu-satunya kaedah untuk anda mengembalikan semula dompet Brave anda. Simpan kunci ini di tempat yang selamat, selain daripada pelayar Brave anda.
licenseTextOk=Ok
listOfAboutPages=Senarai perihal halaman
diff --git a/app/extensions/brave/locales/nl-NL/app.properties b/app/extensions/brave/locales/nl-NL/app.properties
index da25164fe8a..832fc07ba4c 100644
--- a/app/extensions/brave/locales/nl-NL/app.properties
+++ b/app/extensions/brave/locales/nl-NL/app.properties
@@ -132,8 +132,7 @@ issuedBy=Uitgegeven Door
issuedTo=Uitgegeven Aan
ledgerBackupText1=Brave Wallet Herstelsleutels
ledgerBackupText2=Datum aangemaakt:
-ledgerBackupText3=Herstelsleutel 1:
-ledgerBackupText4=Herstelsleutel 2:
+ledgerBackupText4=Herstelsleutel:
ledgerBackupText5=Let op: Deze sleutels worden niet bewaard op de Brave servers. Deze sleutels zijn de enige manier waarmee u uw Brave wallet kunt herstellen. Bewaar deze sleutels op een veilige plek, afzonderlijk van uw Brave browser.
licenseTextOk=Ok
listOfAboutPages=Lijst van over pagina's
diff --git a/app/extensions/brave/locales/pl-PL/app.properties b/app/extensions/brave/locales/pl-PL/app.properties
index f0bbbf380f4..d425998491a 100644
--- a/app/extensions/brave/locales/pl-PL/app.properties
+++ b/app/extensions/brave/locales/pl-PL/app.properties
@@ -132,8 +132,7 @@ issuedBy=Wydane przez
issuedTo=Wystawiony dla
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=Ok
listOfAboutPages=Lista stron informacyjnych
diff --git a/app/extensions/brave/locales/pt-BR/app.properties b/app/extensions/brave/locales/pt-BR/app.properties
index 0ebddb203ee..df850a22eb0 100644
--- a/app/extensions/brave/locales/pt-BR/app.properties
+++ b/app/extensions/brave/locales/pt-BR/app.properties
@@ -132,8 +132,7 @@ issuedBy=Emitido Por
issuedTo=Emitido Para
ledgerBackupText1=Chave de Recuperação da Carteira Brave
ledgerBackupText2=Data de criação:
-ledgerBackupText3=Chave de Recuperação 1
-ledgerBackupText4=Chave de Recuperação 2
+ledgerBackupText4=Chave de Recuperação
ledgerBackupText5=Observação: essas chaves não são armazenadas nos servidores do Brave. Elas são o seu único método de recuperar sua carteira Brave. Salve as chaves em um lugar seguro e separado do seu navegador Brave.
licenseTextOk=Ok
listOfAboutPages=Lista de páginas Sobre
diff --git a/app/extensions/brave/locales/ru/app.properties b/app/extensions/brave/locales/ru/app.properties
index 9dc25534c22..af42a62531d 100644
--- a/app/extensions/brave/locales/ru/app.properties
+++ b/app/extensions/brave/locales/ru/app.properties
@@ -132,8 +132,7 @@ issuedBy=Кем выдан
issuedTo=Кому выдан
ledgerBackupText1=Ключи восстановления Brave кошелька
ledgerBackupText2=Дата создания:
-ledgerBackupText3=Ключ восстановления 1:
-ledgerBackupText4=Ключ восстановления 2:
+ledgerBackupText4=Ключ восстановления:
ledgerBackupText5=Примечание: Эти ключи не хранятся на серверах Brave. Эти ключи являются единственным способом восстановления вашего Brave кошелька. Сохраните эти ключи в надежном месте отдельно от браузера Brave.
licenseTextOk=Ok
listOfAboutPages=Список информационных страниц
diff --git a/app/extensions/brave/locales/sl/app.properties b/app/extensions/brave/locales/sl/app.properties
index 1aba3f64275..65f7a4dab84 100644
--- a/app/extensions/brave/locales/sl/app.properties
+++ b/app/extensions/brave/locales/sl/app.properties
@@ -132,8 +132,7 @@ issuedBy=Izdajatelj
issuedTo=Izdano
ledgerBackupText1=Obnovitveni ključi denarnice Brave
ledgerBackupText2=Datum izdelave:
-ledgerBackupText3=Obnovitveni ključ 1:
-ledgerBackupText4=Obnovitveni ključ 2:
+ledgerBackupText4=Obnovitveni ključ:
ledgerBackupText5=Opomba: Ti ključi niso shranjeni na strežnikih Brave. Tovrstni ključi so edini način, da obnovite svojo denarnico Brave. Shranite jih na varno mesto, ločeno od svojega brskalnika Brave.
licenseTextOk=V redu
listOfAboutPages=Seznam strani o ...
diff --git a/app/extensions/brave/locales/sv-SE/app.properties b/app/extensions/brave/locales/sv-SE/app.properties
index b089003ec3c..525c8f791cb 100644
--- a/app/extensions/brave/locales/sv-SE/app.properties
+++ b/app/extensions/brave/locales/sv-SE/app.properties
@@ -132,8 +132,7 @@ issuedBy=Utfärdats Av
issuedTo=Utfärdats Till
ledgerBackupText1=Brave plånbokens återställningsnycklar
ledgerBackupText2=Datum skapat:
-ledgerBackupText3=Återställningsnyckel 1:
-ledgerBackupText4=Återställningsnyckel 2:
+ledgerBackupText4=Återställningsnyckel:
ledgerBackupText5=Obs: Dessa knappar lagras inte på Brave servrar. Dessa koder är ditt enda sätt att få tillbaka din Brave plånbok. Spara dessa nycklar på ett säkert ställe, inte tillsammans med Brave webbläsare.
licenseTextOk=Ok
listOfAboutPages=Lista över "about" sidor
diff --git a/app/extensions/brave/locales/ta/app.properties b/app/extensions/brave/locales/ta/app.properties
index 91f02bc7c01..1b776db4a41 100644
--- a/app/extensions/brave/locales/ta/app.properties
+++ b/app/extensions/brave/locales/ta/app.properties
@@ -132,8 +132,7 @@ issuedBy=ஆல் வழங்கப்பட்டது
issuedTo=வழங்கப்பட்டது
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=Ok
listOfAboutPages=பற்றிய பக்கங்கள் பட்டியல்
diff --git a/app/extensions/brave/locales/te/app.properties b/app/extensions/brave/locales/te/app.properties
index 2bf351d5162..ef4a546d79d 100644
--- a/app/extensions/brave/locales/te/app.properties
+++ b/app/extensions/brave/locales/te/app.properties
@@ -132,8 +132,7 @@ issuedBy=Issued By
issuedTo=Issued To
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=Ok
listOfAboutPages=పేజిల గురించి జాబితా
diff --git a/app/extensions/brave/locales/tr-TR/app.properties b/app/extensions/brave/locales/tr-TR/app.properties
index 2bb336fd336..72c41c58367 100644
--- a/app/extensions/brave/locales/tr-TR/app.properties
+++ b/app/extensions/brave/locales/tr-TR/app.properties
@@ -132,8 +132,7 @@ issuedBy=Issued By
issuedTo=Adına Yayınlanan
ledgerBackupText1=Brave Wallet Recovery Keys
ledgerBackupText2=Date created:
-ledgerBackupText3=Recovery Key 1:
-ledgerBackupText4=Recovery Key 2:
+ledgerBackupText4=Recovery Key:
ledgerBackupText5=Note: These keys are not stored on Brave servers. These keys are your only method of recovering your Brave wallet. Save these keys in a safe place, separate from your Brave browser.
licenseTextOk=Tamam
listOfAboutPages=Sayfalar Hakkında Listesi
diff --git a/app/extensions/brave/locales/uk/app.properties b/app/extensions/brave/locales/uk/app.properties
index 02005e24074..48de4505a90 100644
--- a/app/extensions/brave/locales/uk/app.properties
+++ b/app/extensions/brave/locales/uk/app.properties
@@ -132,8 +132,7 @@ issuedBy=Випущено
issuedTo=Випущено для
ledgerBackupText1=Ключі відновлення гаманця Brave
ledgerBackupText2=Дата створення:
-ledgerBackupText3=Ключ відновлення 1:
-ledgerBackupText4=Ключ відновлення 2:
+ledgerBackupText4=Ключ відновлення:
ledgerBackupText5=Примітка: Ці ключі не зберігаються на серверах Brave. Вони є лише вашим засобом відновлення гаманця Brave. Збережіть ці ключі в надійне місце, окремо від браузера Brave.
licenseTextOk=Ok
listOfAboutPages=Список інформаційних сторінок
diff --git a/app/extensions/brave/locales/zh-CN/app.properties b/app/extensions/brave/locales/zh-CN/app.properties
index 7d5eff50998..b70998c6182 100644
--- a/app/extensions/brave/locales/zh-CN/app.properties
+++ b/app/extensions/brave/locales/zh-CN/app.properties
@@ -132,8 +132,7 @@ issuedBy=由...发布
issuedTo=发布给
ledgerBackupText1=Brave 钱包恢复秘钥
ledgerBackupText2=创建日期:
-ledgerBackupText3=恢复秘钥 1:
-ledgerBackupText4=恢复秘钥 2:
+ledgerBackupText4=恢复秘钥 :
ledgerBackupText5=请注意:上述秘钥未储存于 Brave 服务器上。秘钥是您恢复 Brave 钱包的唯一方式。请将秘钥保存于安全位置,与 Brave 浏览器分离开。
licenseTextOk=确定
listOfAboutPages=关于页面列表
diff --git a/app/filtering.js b/app/filtering.js
index 5b99063a90f..9e873b2eb24 100644
--- a/app/filtering.js
+++ b/app/filtering.js
@@ -115,12 +115,21 @@ function registerForBeforeRequest (session, partition) {
}
const firstPartyUrl = module.exports.getMainFrameUrl(details)
+ const url = details.url
// this can happen if the tab is closed and the webContents is no longer available
if (!firstPartyUrl) {
muonCb({ cancel: true })
return
}
+ if (!isPrivate && module.exports.isResourceEnabled('ledger') && module.exports.isResourceEnabled('ledgerMedia')) {
+ // Ledger media
+ const provider = ledgerUtil.getMediaProvider(url, firstPartyUrl, details.referrer)
+ if (provider) {
+ appActions.onLedgerMediaData(url, provider, details)
+ }
+ }
+
for (let i = 0; i < beforeRequestFilteringFns.length; i++) {
let results = beforeRequestFilteringFns[i](details, isPrivate)
const isAdBlock = (results.resourceName === appConfig.resourceNames.ADBLOCK) ||
@@ -201,7 +210,6 @@ function registerForBeforeRequest (session, partition) {
}
}
// Redirect to non-script version of DDG when it's blocked
- const url = details.url
if (details.resourceType === 'mainFrame' &&
url.startsWith('https://duckduckgo.com/?q') &&
module.exports.isResourceEnabled('noScript', url, isPrivate)) {
@@ -209,14 +217,6 @@ function registerForBeforeRequest (session, partition) {
} else {
muonCb({})
}
-
- if (module.exports.isResourceEnabled('ledger') && module.exports.isResourceEnabled('ledgerMedia')) {
- // Ledger media
- const provider = ledgerUtil.getMediaProvider(url)
- if (provider) {
- appActions.onLedgerMediaData(url, provider, details.tabId)
- }
- }
})
}
@@ -245,12 +245,13 @@ function registerForBeforeRedirect (session, partition) {
module.exports.applyCookieSetting = (requestHeaders, url, firstPartyUrl, isPrivate) => {
const cookieSetting = module.exports.isResourceEnabled(appConfig.resourceNames.COOKIEBLOCK, firstPartyUrl, isPrivate)
if (cookieSetting) {
- const parsedTargetUrl = urlParse(url || '')
- const parsedFirstPartyUrl = urlParse(firstPartyUrl)
+ const targetHostname = urlParse(url || '').hostname
+ const firstPartyHostname = urlParse(firstPartyUrl).hostname
const targetOrigin = getOrigin(url)
+ const referer = requestHeaders['Referer']
if (cookieSetting === 'blockAllCookies' ||
- isThirdPartyHost(parsedFirstPartyUrl.hostname, parsedTargetUrl.hostname)) {
+ isThirdPartyHost(firstPartyHostname, targetHostname)) {
let hasCookieException = false
const firstPartyOrigin = getOrigin(firstPartyUrl)
if (cookieExceptions.hasOwnProperty(firstPartyOrigin)) {
@@ -268,20 +269,19 @@ module.exports.applyCookieSetting = (requestHeaders, url, firstPartyUrl, isPriva
}
}
}
- // Clear cookie and referer on third-party requests
+
+ // Clear cookie on third-party requests
if (requestHeaders['Cookie'] &&
firstPartyOrigin !== pdfjsOrigin && !hasCookieException) {
requestHeaders['Cookie'] = undefined
}
}
- const referer = requestHeaders['Referer']
if (referer &&
cookieSetting !== 'allowAllCookies' &&
- !refererExceptions.includes(parsedTargetUrl.hostname) &&
- targetOrigin !== getOrigin(referer)) {
- // Unless the setting is 'allow all cookies', spoof the referer if it
- // is a cross-origin referer
+ !refererExceptions.includes(targetHostname) &&
+ isThirdPartyHost(targetHostname, urlParse(referer).hostname)) {
+ // Spoof third party referer
requestHeaders['Referer'] = targetOrigin
}
}
@@ -364,6 +364,18 @@ function registerForHeadersReceived (session, partition) {
muonCb({ cancel: true })
return
}
+
+ let parsedTargetUrl = urlParse(details.url || '')
+ let parsedFirstPartyUrl = urlParse(firstPartyUrl)
+ const trackableSecurityHeaders = ['Strict-Transport-Security', 'Expect-CT',
+ 'Public-Key-Pins', 'Public-Key-Pins-Report-Only']
+ if (isThirdPartyHost(parsedFirstPartyUrl.hostname, parsedTargetUrl.hostname)) {
+ trackableSecurityHeaders.forEach(function (header) {
+ delete details.responseHeaders[header]
+ delete details.responseHeaders[header.toLowerCase()]
+ })
+ }
+
for (let i = 0; i < headersReceivedFilteringFns.length; i++) {
let results = headersReceivedFilteringFns[i](details, isPrivate)
if (!module.exports.isResourceEnabled(results.resourceName, firstPartyUrl, isPrivate)) {
@@ -381,7 +393,10 @@ function registerForHeadersReceived (session, partition) {
return
}
}
- muonCb({})
+ muonCb({
+ responseHeaders: details.responseHeaders,
+ statusLine: details.statusLine
+ })
})
}
@@ -394,7 +409,7 @@ function registerPermissionHandler (session, partition) {
const isPrivate = module.exports.isPrivate(partition)
// Keep track of per-site permissions granted for this session.
let permissions = null
- session.setPermissionRequestHandler((origin, mainFrameUrl, permissionTypes, muonCb) => {
+ session.setPermissionRequestHandler((mainFrameOrigin, requestingUrl, permissionTypes, muonCb) => {
if (!permissions) {
permissions = {
media: {
@@ -427,35 +442,11 @@ function registerPermissionHandler (session, partition) {
// TODO(bridiver) - the permission handling should be converted to an action because we should never call `appStore.getState()`
// Check whether there is a persistent site setting for this host
const appState = appStore.getState()
- const isBraveOrigin = origin.startsWith(`chrome-extension://${config.braveExtensionId}/`)
- const isPDFOrigin = origin.startsWith(`${pdfjsOrigin}/`)
- let settings
- let tempSettings
- if (mainFrameUrl === appUrlUtil.getBraveExtIndexHTML() || isPDFOrigin || isBraveOrigin) {
- // lookup, display and store site settings by the origin alias
- origin = isPDFOrigin ? 'PDF Viewer' : 'Brave Browser'
- // display on all tabs
- mainFrameUrl = null
- // Lookup by exact host pattern match since 'Brave Browser' is not
- // a parseable URL
- settings = siteSettings.getSiteSettingsForHostPattern(appState.get('siteSettings'), origin)
- tempSettings = siteSettings.getSiteSettingsForHostPattern(appState.get('temporarySiteSettings'), origin)
- } else if (mainFrameUrl.startsWith('magnet:')) {
- // Show "Allow magnet URL to open an external application?", instead of
- // "Allow null to open an external application?"
- // This covers an edge case where you open a magnet link tab, then disable Torrent Viewer
- // and restart Brave. I don't think it needs localization. See 'Brave Browser' above.
- origin = 'Magnet URL'
- } else {
- // Strip trailing slash
- origin = getOrigin(origin)
- settings = siteSettings.getSiteSettingsForURL(appState.get('siteSettings'), origin)
- tempSettings = siteSettings.getSiteSettingsForURL(appState.get('temporarySiteSettings'), origin)
- }
-
+ const isBraveOrigin = mainFrameOrigin.startsWith(`chrome-extension://${config.braveExtensionId}/`)
+ const isPDFOrigin = mainFrameOrigin.startsWith(`${pdfjsOrigin}/`)
let response = []
- if (origin == null) {
+ if (!requestingUrl) {
response = new Array(permissionTypes.length)
response.fill(false, 0, permissionTypes.length)
muonCb(response)
@@ -466,17 +457,42 @@ function registerPermissionHandler (session, partition) {
const responseSizeThisIteration = response.length
const permission = permissionTypes[i]
const alwaysAllowFullscreen = module.exports.alwaysAllowFullscreen() === fullscreenOption.ALWAYS_ALLOW
+ const isFullscreen = permission === 'fullscreen'
+ const isOpenExternal = permission === 'openExternal'
+
+ let requestingOrigin
+
+ if (requestingUrl === appUrlUtil.getBraveExtIndexHTML() || isPDFOrigin || isBraveOrigin) {
+ // lookup, display and store site settings by the origin alias
+ requestingOrigin = isPDFOrigin ? 'PDF Viewer' : 'Brave Browser'
+ // display on all tabs
+ mainFrameOrigin = null
+ } else if (isOpenExternal) {
+ // Open external is a special case since we want to apply the permission
+ // for the entire scheme to avoid cluttering the saved permissions. See
+ // https://github.com/brave/browser-laptop/issues/13642
+ const protocol = urlParse(requestingUrl).protocol
+ requestingOrigin = protocol ? `${protocol} URLs` : requestingUrl
+ } else {
+ requestingOrigin = getOrigin(requestingUrl) || requestingUrl
+ }
+
+ // Look up by host pattern since requestingOrigin is not necessarily
+ // a parseable URL
+ const settings = siteSettings.getSiteSettingsForHostPattern(appState.get('siteSettings'), requestingOrigin)
+ const tempSettings = siteSettings.getSiteSettingsForHostPattern(appState.get('temporarySiteSettings'), requestingOrigin)
+
if (!permissions[permission]) {
console.warn('WARNING: got unregistered permission request', permission)
response.push(false)
- } else if (permission === 'fullscreen' &&
+ } else if (isFullscreen && mainFrameOrigin &&
// The Torrent Viewer extension is always allowed to show fullscreen media
- origin.startsWith('chrome-extension://' + config.torrentExtensionId)) {
+ mainFrameOrigin.startsWith('chrome-extension://' + config.torrentExtensionId)) {
response.push(true)
- } else if (permission === 'fullscreen' && alwaysAllowFullscreen) {
+ } else if (isFullscreen && alwaysAllowFullscreen) {
// Always allow fullscreen if setting is ON
response.push(true)
- } else if (permission === 'openExternal' && (
+ } else if (isOpenExternal && (
// The Brave extension and PDFJS are always allowed to open files in an external app
isPDFOrigin || isBraveOrigin)) {
response.push(true)
@@ -495,9 +511,7 @@ function registerPermissionHandler (session, partition) {
}
}
- // Display 'Brave Browser' if the origin is null; ex: when a mailto: link
- // is opened in a new tab via right-click
- const message = locale.translation('permissionMessage').replace(/{{\s*host\s*}}/, origin || 'Brave Browser').replace(/{{\s*permission\s*}}/, permissions[permission].action)
+ const message = locale.translation('permissionMessage').replace(/{{\s*host\s*}}/, requestingOrigin).replace(/{{\s*permission\s*}}/, permissions[permission].action)
// If this is a duplicate, clear the previous callback and use the new one
if (permissionCallbacks[message]) {
@@ -511,9 +525,9 @@ function registerPermissionHandler (session, partition) {
{text: locale.translation('deny')},
{text: locale.translation('allow')}
],
- frameOrigin: getOrigin(mainFrameUrl),
+ frameOrigin: getOrigin(mainFrameOrigin),
options: {
- persist: !!origin,
+ persist: !!requestingOrigin,
index: i
},
message
@@ -530,7 +544,7 @@ function registerPermissionHandler (session, partition) {
response[index] = result
if (persist) {
// remember site setting for this host
- appActions.changeSiteSetting(origin, permission + 'Permission', result, isPrivate)
+ appActions.changeSiteSetting(requestingOrigin, permission + 'Permission', result, isPrivate)
}
if (response.length === permissionTypes.length) {
permissionCallbacks[message] = null
@@ -582,12 +596,6 @@ function registerForDownloadListener (session) {
const hostWebContents = webContents.hostWebContents || webContents
const win = BrowserWindow.fromWebContents(hostWebContents) || BrowserWindow.getFocusedWindow()
- // TODO(bridiver) - move this fix to muon
- const controller = webContents.controller()
- if (controller && controller.isValid() && controller.isInitialNavigation()) {
- webContents.forceClose()
- }
-
item.setPrompt(getSetting(settings.DOWNLOAD_ALWAYS_ASK) || false)
const downloadId = item.getGuid()
@@ -776,13 +784,9 @@ module.exports.isResourceEnabled = (resourceName, url, isPrivate) => {
if (resourceName === 'pdfjs') {
return getSetting(settings.PDFJS_ENABLED, settingsState)
}
- if (resourceName === 'webtorrent') {
- return getSetting(settings.TORRENT_VIEWER_ENABLED, settingsState)
- }
if (resourceName === 'webtorrent') {
- const extension = extensionState.getExtensionById(appState, config.torrentExtensionId)
- return extension !== undefined ? extension.get('enabled') : false
+ return extensionState.isWebTorrentEnabled(appState)
}
if (resourceName === 'ledger') {
@@ -793,6 +797,10 @@ module.exports.isResourceEnabled = (resourceName, url, isPrivate) => {
return getSetting(settings.PAYMENTS_ALLOW_MEDIA_PUBLISHERS, settingsState)
}
+ if (resourceName === 'firewall') {
+ return siteSettings.braveryDefaults(appState, appConfig).firewall
+ }
+
const braverySettings = getBraverySettingsForUrl(url, appState, isPrivate)
// If full shields are down never enable extra protection
@@ -845,6 +853,15 @@ module.exports.clearStorageData = () => {
}
}
+module.exports.clearHSTSData = () => {
+ for (let partition in registeredSessions) {
+ let ses = registeredSessions[partition]
+ setImmediate(() => {
+ ses.clearHSTSData.bind(ses)(() => {})
+ })
+ }
+}
+
/**
* Clears all session caches.
*/
diff --git a/app/firewall.js b/app/firewall.js
new file mode 100644
index 00000000000..07b22d7f1ae
--- /dev/null
+++ b/app/firewall.js
@@ -0,0 +1,32 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const ip = require('ip')
+const Filtering = require('./filtering')
+const {isInternalUrl} = require('../js/lib/urlutil')
+
+module.exports.resourceName = 'firewall'
+
+const onHeadersReceived = (details) => {
+ const result = { resourceName: module.exports.resourceName }
+ const mainFrameUrl = Filtering.getMainFrameUrl(details)
+ const isIPInternal = ip.isPrivate(details.ip)
+ const isUrlInternal = isInternalUrl(details.url)
+
+ if ((isIPInternal || isUrlInternal) && !isInternalUrl(mainFrameUrl)) {
+ // Block requests to local origins from non-local top-level origins
+ console.log('firewall blocked request from external IP to internal IP')
+ result.cancel = true
+ } else if (isIPInternal && !isUrlInternal) {
+ // Block requests to an external name that resolves to an internal address
+ console.log('firewall blocked request for internal IP with external hostname')
+ result.cancel = true
+ }
+
+ return result
+}
+
+module.exports.init = () => {
+ Filtering.registerHeadersReceivedFilteringCB(onHeadersReceived)
+}
diff --git a/app/index.js b/app/index.js
index 597f218585a..dbc444a1787 100644
--- a/app/index.js
+++ b/app/index.js
@@ -16,7 +16,7 @@ const telemetry = require('./telemetry')
telemetry.setCheckpoint('init')
const handleUncaughtError = (stack, message) => {
- muon.crashReporter.setCrashKeyValue('javascript-info', JSON.stringify({stack, message}))
+ muon.crashReporter.setJavascriptInfoCrashValue(JSON.stringify({stack, message}))
muon.crashReporter.dumpWithoutCrashing()
if (!ready) {
@@ -64,6 +64,7 @@ const updater = require('./updater')
const Importer = require('./importer')
const messages = require('../js/constants/messages')
const appActions = require('../js/actions/appActions')
+const tabActions = require('./common/actions/tabActions')
const SessionStore = require('./sessionStore')
const {startSessionSaveInterval} = require('./sessionStoreShutdown')
const appStore = require('../js/stores/appStore')
@@ -73,6 +74,7 @@ const TrackingProtection = require('./trackingProtection')
const AdBlock = require('./adBlock')
const AdInsertion = require('./browser/ads/adInsertion')
const HttpsEverywhere = require('./httpsEverywhere')
+const Firewall = require('./firewall')
const PDFJS = require('./pdfJS')
const SiteHacks = require('./siteHacks')
const CmdLine = require('./cmdLine')
@@ -141,15 +143,17 @@ const notifyCertError = (webContents, url, error, cert) => {
fingerprint: cert.fingerprint
}
- // Tell the page to show an unlocked icon. Note this is sent to the main
- // window webcontents, not the webview webcontents
- let sender = webContents.hostWebContents || webContents
- sender.send(messages.CERT_ERROR, {
+ // Load the certificate error page
+ // and provide details about the error,
+ // including enough data for in-page actions to force the
+ // insecure page to load or show the certificate.
+ tabActions.setContentsError(webContents.getId(), {
url,
error,
cert,
tabId: webContents.getId()
})
+ appActions.loadURLRequested(webContents.getId(), 'about:certerror')
}
app.on('ready', () => {
@@ -202,12 +206,14 @@ app.on('ready', () => {
AdBlock.init()
AdInsertion.init()
PDFJS.init()
+ Firewall.init()
if (!loadedPerWindowImmutableState || loadedPerWindowImmutableState.size === 0) {
if (!CmdLine.newWindowURL()) {
appActions.newWindow()
}
} else {
+ const lastIndex = loadedPerWindowImmutableState.size - 1
loadedPerWindowImmutableState
.sort((a, b) => {
let comparison = 0
@@ -222,8 +228,12 @@ app.on('ready', () => {
return comparison
})
- .forEach((wndState) => {
- appActions.newWindow(undefined, undefined, wndState)
+ .forEach((wndState, i) => {
+ const isLastWindow = i === lastIndex
+ if (CmdLine.shouldDebugWindowEvents && isLastWindow) {
+ console.log(`The restored window which should get focus has ${wndState.get('frames').size} frames`)
+ }
+ appActions.newWindow(undefined, isLastWindow ? undefined : { inactive: true }, wndState, true)
})
}
process.emit(messages.APP_INITIALIZED)
diff --git a/app/locale.js b/app/locale.js
index c5ef2a5b2c5..13c43012a6d 100644
--- a/app/locale.js
+++ b/app/locale.js
@@ -60,12 +60,15 @@ var rendererIdentifiers = function () {
'deleteBookmarks',
'deleteHistoryEntry',
'deleteHistoryEntries',
+ 'deleteDomainFromHistory',
'deleteLedgerEntry',
'ledgerBackupText1',
'ledgerBackupText2',
'ledgerBackupText3',
'ledgerBackupText4',
'ledgerBackupText5',
+ 'backupKeys',
+ 'backupKeysNow',
'editFolder',
'editBookmark',
'unmuteTabs',
@@ -133,6 +136,7 @@ var rendererIdentifiers = function () {
'recentlyClosed',
'recentlyVisited',
'bookmarks',
+ 'otherBookmarks',
'addToFavoritesBar',
'window',
'minimize',
@@ -177,6 +181,7 @@ var rendererIdentifiers = function () {
'forgetLearnedSpelling',
'lookupSelection',
'publisherMediaName',
+ 'addToPublisherList',
// Other identifiers
'aboutBlankTitle',
'urlCopied',
@@ -226,13 +231,13 @@ var rendererIdentifiers = function () {
'no',
'noThanks',
'neverForThisSite',
- 'walletConvertedBackup',
- 'walletConvertedDismiss',
- 'walletConvertedLearnMore',
- 'walletConvertedToBat',
'dappDetected',
'dappDismiss',
'dappEnableExtension',
+ 'banSiteConfirmation',
+ 'paymentsDeleteWalletConfirmation',
+ 'messageBoxOk',
+ 'messageBoxCancel',
// other
'passwordsManager',
'extensionsManager',
@@ -283,7 +288,13 @@ var rendererIdentifiers = function () {
'promotionGeneralErrorText',
'promotionClaimedErrorMessage',
'promotionClaimedErrorText',
- 'promotionClaimedErrorTitle'
+ 'promotionClaimedErrorTitle',
+ 'corruptedOverlayTitle',
+ 'corruptedOverlayMessage',
+ 'corruptedOverlayText',
+ 'ledgerNetworkErrorTitle',
+ 'ledgerNetworkErrorMessage',
+ 'ledgerNetworkErrorText'
].concat(countryCodes).concat(availableLanguages)
}
diff --git a/app/migrations/20180518_uphold.js b/app/migrations/20180518_uphold.js
new file mode 100644
index 00000000000..044caa2b8ad
--- /dev/null
+++ b/app/migrations/20180518_uphold.js
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const compareVersions = require('compare-versions')
+
+// per https://github.com/brave/browser-laptop/issues/14152
+// add fingerprint exception for existing users for uphold.com
+module.exports = (data) => {
+ // don't apply if:
+ // - user chooses to block all fingerprinting (global setting)
+ // - user is not upgrading from 0.22.714 or earlier
+ if ((data.fingerprintingProtectionAll && data.fingerprintingProtectionAll.enabled) ||
+ !data.lastAppVersion) {
+ return false
+ }
+
+ let migrationNeeded = false
+
+ try {
+ migrationNeeded = compareVersions(data.lastAppVersion, '0.22.714') !== 1
+ } catch (e) {}
+
+ if (migrationNeeded) {
+ const pattern = 'https?://uphold.com'
+ if (!data.siteSettings) {
+ data.siteSettings = {}
+ }
+ if (!data.siteSettings[pattern]) {
+ data.siteSettings[pattern] = {}
+ }
+ let targetSetting = data.siteSettings[pattern]
+ if (targetSetting.fingerprintingProtection == null) {
+ targetSetting.fingerprintingProtection = 'allowAllFingerprinting'
+ }
+ }
+
+ return migrationNeeded
+}
diff --git a/app/migrations/pre.js b/app/migrations/pre.js
new file mode 100644
index 00000000000..d9486a8148c
--- /dev/null
+++ b/app/migrations/pre.js
@@ -0,0 +1,14 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+module.exports = (data) => {
+ let migrations = [
+ require('./20180518_uphold')
+ // TODO: put additional migrations here
+ ]
+
+ migrations.forEach((migration) => {
+ migration(data)
+ })
+}
diff --git a/app/renderer/about/ledger/printKeys.js b/app/renderer/about/ledger/printKeys.js
new file mode 100644
index 00000000000..beea3c99291
--- /dev/null
+++ b/app/renderer/about/ledger/printKeys.js
@@ -0,0 +1,63 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const React = require('react')
+const format = require('date-fns/format')
+const {StyleSheet, css} = require('aphrodite/no-important')
+const ipc = window.chrome.ipcRenderer
+
+// Constants
+const messages = require('../../../../js/constants/messages')
+
+class PrintKeys extends React.Component {
+ constructor (props) {
+ super(props)
+ this.state = {
+ passphrase: ''
+ }
+
+ ipc.on(messages.PRINTKEYS_UPDATED, (e, detail) => {
+ if (detail) {
+ this.setState({
+ passphrase: detail && detail.passphrase
+ })
+ }
+ })
+ }
+
+ componentDidUpdate (prevProps, prevState) {
+ if (prevState.passphrase !== this.state.passphrase) {
+ setTimeout(() => {
+ window.print()
+ }, 500)
+ }
+ }
+
+ render () {
+ const date = format(new Date(), 'MM/DD/YYYY')
+
+ return
+
+
+ {date}
+
+
+
+ {this.state.passphrase}
+
+
+
+
+ }
+}
+
+const styles = StyleSheet.create({
+ content: {
+ fontWeight: '400',
+ color: '#3b3b3b',
+ fontSize: '16px'
+ }
+})
+
+module.exports =
diff --git a/app/renderer/components/autofill/autofillAddressPanel.js b/app/renderer/components/autofill/autofillAddressPanel.js
index 1e4d7422bd6..bac1b2c69fc 100644
--- a/app/renderer/components/autofill/autofillAddressPanel.js
+++ b/app/renderer/components/autofill/autofillAddressPanel.js
@@ -11,9 +11,11 @@ const ReduxComponent = require('../reduxComponent')
const Dialog = require('../common/dialog')
const Button = require('../common/button')
const {
- CommonForm,
+ CommonFormLarge,
CommonFormSection,
+ CommonFormTitle,
CommonFormDropdown,
+ CommonFormButtonWrapper,
commonFormStyles
} = require('../common/commonForm')
@@ -158,8 +160,8 @@ class AutofillAddressPanel extends React.Component {
render () {
return
-
-
+
+
@@ -271,7 +273,7 @@ class AutofillAddressPanel extends React.Component {
-
+
-
-
+
+
}
}
diff --git a/app/renderer/components/autofill/autofillCreditCardPanel.js b/app/renderer/components/autofill/autofillCreditCardPanel.js
index 390055ae68c..064ec72e443 100644
--- a/app/renderer/components/autofill/autofillCreditCardPanel.js
+++ b/app/renderer/components/autofill/autofillCreditCardPanel.js
@@ -13,8 +13,10 @@ const Button = require('../common/button')
const {
CommonForm,
CommonFormSection,
+ CommonFormTitle,
CommonFormDropdown,
CommonFormTextbox,
+ CommonFormButtonWrapper,
commonFormStyles
} = require('../common/commonForm')
@@ -126,9 +128,9 @@ class AutofillCreditCardPanel extends React.Component {
render () {
return
-
@@ -200,7 +202,7 @@ class AutofillCreditCardPanel extends React.Component {
-
+
-
+
}
}
+module.exports = ReduxComponent.connect(AutofillCreditCardPanel)
+
const styles = StyleSheet.create({
// Copied from textbox.js
input: {
@@ -235,5 +239,3 @@ const styles = StyleSheet.create({
marginLeft: `calc(${globalStyles.spacing.dialogInsideMargin} / 3)`
}
})
-
-module.exports = ReduxComponent.connect(AutofillCreditCardPanel)
diff --git a/app/renderer/components/bookmarks/addEditBookmarkFolder.js b/app/renderer/components/bookmarks/addEditBookmarkFolder.js
index 9eef561e312..2bed10a30f0 100644
--- a/app/renderer/components/bookmarks/addEditBookmarkFolder.js
+++ b/app/renderer/components/bookmarks/addEditBookmarkFolder.js
@@ -4,15 +4,13 @@
const React = require('react')
const Immutable = require('immutable')
+const {StyleSheet, css} = require('aphrodite/no-important')
// Components
const ReduxComponent = require('../reduxComponent')
const Dialog = require('../common/dialog')
const AddEditBookmarkFolderForm = require('./addEditBookmarkFolderForm')
-const {
- CommonFormHanger,
- CommonFormSection
-} = require('../common/commonForm')
+const {CommonFormBookmarkHanger} = require('../common/commonForm')
// State
const bookmarkFoldersState = require('../../../common/state/bookmarkFoldersState')
@@ -25,6 +23,9 @@ const windowActions = require('../../../../js/actions/windowActions')
const cx = require('../../../../js/lib/classSet')
const bookmarkFoldersUtil = require('../../../common/lib/bookmarkFoldersUtil')
+// Styles
+const globalStyles = require('../styles/global')
+
class AddEditBookmarkFolder extends React.Component {
constructor (props) {
super(props)
@@ -67,8 +68,11 @@ class AddEditBookmarkFolder extends React.Component {
return
-
-
+
+
-
+
}
}
+const styles = StyleSheet.create({
+ // Copied from commonForm.js
+ commonFormSection: {
+ // PR #7985
+ margin: `${globalStyles.spacing.dialogInsideMargin} 30px`
+ },
+ commonFormTitle: {
+ color: globalStyles.color.braveOrange,
+ fontSize: '1.2em'
+ }
+})
+
module.exports = ReduxComponent.connect(AddEditBookmarkFolder)
diff --git a/app/renderer/components/bookmarks/addEditBookmarkFolderForm.js b/app/renderer/components/bookmarks/addEditBookmarkFolderForm.js
index 7b1d55a8d50..ab500a44b35 100644
--- a/app/renderer/components/bookmarks/addEditBookmarkFolderForm.js
+++ b/app/renderer/components/bookmarks/addEditBookmarkFolderForm.js
@@ -11,6 +11,7 @@ const BrowserButton = require('../common/browserButton')
const {
CommonFormSection,
CommonFormDropdown,
+ CommonFormButtonWrapper,
commonFormStyles
} = require('../common/commonForm')
@@ -192,7 +193,7 @@ class AddEditBookmarkFolderForm extends React.Component {
-
+
{
this.props.editKey != null
?
-
+
}
}
diff --git a/app/renderer/components/bookmarks/addEditBookmarkForm.js b/app/renderer/components/bookmarks/addEditBookmarkForm.js
index ba4da7e1b97..c3115f2e6bb 100644
--- a/app/renderer/components/bookmarks/addEditBookmarkForm.js
+++ b/app/renderer/components/bookmarks/addEditBookmarkForm.js
@@ -12,6 +12,7 @@ const {
CommonFormSection,
CommonFormDropdown,
CommonFormTextbox,
+ CommonFormButtonWrapper,
commonFormStyles
} = require('../common/commonForm')
@@ -228,7 +229,7 @@ class AddEditBookmarkForm extends React.Component {
-
+
{
this.props.editKey != null
?
-
+
}
}
diff --git a/app/renderer/components/bookmarks/addEditBookmarkHanger.js b/app/renderer/components/bookmarks/addEditBookmarkHanger.js
index 6b89226bc76..3a225f88993 100644
--- a/app/renderer/components/bookmarks/addEditBookmarkHanger.js
+++ b/app/renderer/components/bookmarks/addEditBookmarkHanger.js
@@ -11,8 +11,8 @@ const ReduxComponent = require('../reduxComponent')
const Dialog = require('../common/dialog')
const AddEditBookmarkForm = require('./addEditBookmarkForm')
const {
- CommonFormHanger,
- CommonFormSection
+ CommonFormBookmarkHanger,
+ CommonFormBottomWrapper
} = require('../common/commonForm')
// States
@@ -108,8 +108,8 @@ class AddEditBookmarkHanger extends React.Component {
bookmarkDialog: this.props.isModal,
bookmarkHanger: !this.props.isModal,
[css(styles.bookmarkHanger)]: !this.props.isModal
- })} isClickDismiss>
-
+ })} onHide={this.onClose} isClickDismiss>
+
{
!this.props.isModal
?
: null
}
-
+
{
!this.props.isModal
- ?
+ ?
-
+
: null
}
-
+
}
}
const styles = StyleSheet.create({
+ // Copied from commonForm.js
+ commonFormSection: {
+ // PR #7985
+ margin: `${globalStyles.spacing.dialogInsideMargin} 30px`
+ },
+ commonFormTitle: {
+ color: globalStyles.color.braveOrange,
+ fontSize: '1.2em'
+ },
+
bookmarkHanger: {
// See: #9040
justifyContent: 'flex-start !important',
@@ -169,7 +182,7 @@ const styles = StyleSheet.create({
position: 'absolute',
width: 0,
height: 0,
- border: `8px solid ${globalStyles.color.commonFormBackgroundColor}`,
+ border: `8px solid ${globalStyles.color.modalVeryLightGray}`,
boxShadow: globalStyles.shadow.bookmarkHangerArrowUpShadow,
transformOrigin: '0 0',
transform: 'rotate(135deg)'
diff --git a/app/renderer/components/bookmarks/bookmarkToolbarButton.js b/app/renderer/components/bookmarks/bookmarkToolbarButton.js
index 950730bbbc3..9810feb4597 100644
--- a/app/renderer/components/bookmarks/bookmarkToolbarButton.js
+++ b/app/renderer/components/bookmarks/bookmarkToolbarButton.js
@@ -22,6 +22,7 @@ const bookmarksState = require('../../../common/state/bookmarksState')
const dragTypes = require('../../../../js/constants/dragTypes')
const {iconSize} = require('../../../../js/constants/config')
const siteTags = require('../../../../js/constants/siteTags')
+const {bookmarksToolbarMode} = require('../../../common/constants/settingsEnums')
// Utils
const {getCurrentWindowId} = require('../../currentWindow')
@@ -175,15 +176,17 @@ class BookmarkToolbarButton extends React.Component {
mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')
const activeFrame = frameStateUtil.getActiveFrame(currentWindow) || Immutable.Map()
+ const bookmarkDisplayMode = ownProps.bookmarkDisplayMode
const bookmarkKey = ownProps.bookmarkKey
let bookmark = bookmarksState.findBookmark(state, bookmarkKey)
const draggingOverData = bookmarkUtil.getDNDBookmarkData(state, bookmarkKey)
const props = {}
+
// used in renderer
- props.showFavicon = bookmarkUtil.showFavicon()
- props.showOnlyFavicon = bookmarkUtil.showOnlyFavicon()
+ props.showFavicon = bookmarkUtil.showFavicon(state, bookmarkDisplayMode)
+ props.showOnlyFavicon = (bookmarkDisplayMode === bookmarksToolbarMode.FAVICONS_ONLY)
props.favIcon = bookmark.get('favicon')
props.title = bookmark.get('title')
props.location = bookmark.get('location')
@@ -242,6 +245,7 @@ class BookmarkToolbarButton extends React.Component {
draggable
ref={(node) => { this.bookmarkNode = node }}
title={hoverTitle}
+ data-bookmark-key={this.props.bookmarkKey}
onClick={this.onClick}
onMouseOver={this.onMouseOver}
onDragStart={this.onDragStart}
@@ -312,21 +316,22 @@ module.exports = ReduxComponent.connect(BookmarkToolbarButton)
const styles = StyleSheet.create({
bookmarkToolbarButton: {
- display: 'flex',
- alignItems: 'center',
+ WebkitAppRegion: 'no-drag',
boxSizing: 'border-box',
borderRadius: '3px',
color: globalStyles.color.mediumGray,
cursor: 'default',
fontSize: globalStyles.spacing.bookmarksItemFontSize,
lineHeight: '1.3',
- margin: `auto ${globalStyles.spacing.bookmarksItemMargin}`,
+ // margin-bottom hides the second row of items on the bookmark bar
+ margin: `0 ${globalStyles.spacing.bookmarksItemMargin} 0 ${globalStyles.spacing.bookmarksItemMargin}`,
maxWidth: globalStyles.spacing.bookmarksItemMaxWidth,
padding: `2px ${globalStyles.spacing.bookmarksItemPadding}`,
textOverflow: 'ellipsis',
userSelect: 'none',
whiteSpace: 'nowrap',
- WebkitAppRegion: 'no-drag',
+ display: 'flex',
+ alignItems: 'center',
':hover': {
background: '#fff',
diff --git a/app/renderer/components/bookmarks/bookmarksToolbar.js b/app/renderer/components/bookmarks/bookmarksToolbar.js
index 1608a3e0187..1adcbf51bc5 100644
--- a/app/renderer/components/bookmarks/bookmarksToolbar.js
+++ b/app/renderer/components/bookmarks/bookmarksToolbar.js
@@ -9,8 +9,8 @@ const Immutable = require('immutable')
// Components
const ReduxComponent = require('../reduxComponent')
-const BrowserButton = require('../common/browserButton')
const BookmarkToolbarButton = require('./bookmarkToolbarButton')
+const BookmarksToolbarOverflowIcon = require('./bookmarksToolbarOverflowIcon')
// Actions
const appActions = require('../../../../js/actions/appActions')
@@ -18,11 +18,12 @@ const windowActions = require('../../../../js/actions/windowActions')
// State
const windowState = require('../../../common/state/windowState')
-const bookmarkToolbarState = require('../../../common/state/bookmarkToolbarState')
+const bookmarksState = require('../../../common/state/bookmarksState')
// Constants
const dragTypes = require('../../../../js/constants/dragTypes')
const siteTags = require('../../../../js/constants/siteTags')
+const {bookmarksToolbarMode} = require('../../../common/constants/settingsEnums')
// Utils
const {isFocused} = require('../../currentWindow')
@@ -30,14 +31,37 @@ const contextMenus = require('../../../../js/contextMenus')
const dnd = require('../../../../js/dnd')
const dndData = require('../../../../js/dndData')
const isWindows = require('../../../common/lib/platformUtil').isWindows()
-const frameStateUtil = require('../../../../js/state/frameStateUtil')
const bookmarkUtil = require('../../../common/lib/bookmarkUtil')
+const frameStateUtil = require('../../../../js/state/frameStateUtil')
const {elementHasDataset} = require('../../../../js/lib/eventUtil')
-const {getCurrentWindowId} = require('../../currentWindow')
// Styles
const globalStyles = require('../styles/global')
+function getHiddenKeys (elements, immutableAllKeys) {
+ if (!elements || !elements.length) {
+ return
+ }
+ let firstOtherKey
+ // check again which ones are missing as now the indicator is there, we may have additional
+ for (let i = 1; i < elements.length; i++) {
+ // skip first item (0)
+ const thisElement = elements[i]
+ if (thisElement.offsetTop > 10) {
+ // the [i]th item is the first that does not fit
+ firstOtherKey = thisElement.dataset.bookmarkKey
+ break
+ }
+ }
+ if (firstOtherKey) {
+ const firstOtherIndex = immutableAllKeys.indexOf(firstOtherKey)
+ if (firstOtherIndex !== -1) {
+ const hiddenKeys = immutableAllKeys.slice(firstOtherIndex)
+ return hiddenKeys
+ }
+ }
+}
+
class BookmarksToolbar extends React.Component {
constructor (props) {
super(props)
@@ -46,6 +70,7 @@ class BookmarksToolbar extends React.Component {
this.onDragOver = this.onDragOver.bind(this)
this.onContextMenu = this.onContextMenu.bind(this)
this.onMoreBookmarksMenu = this.onMoreBookmarksMenu.bind(this)
+ this.setBookmarksToolbarRef = this.setBookmarksToolbarRef.bind(this)
}
onDrop (e) {
@@ -155,7 +180,7 @@ class BookmarksToolbar extends React.Component {
onMoreBookmarksMenu (e) {
const rect = e.target.getBoundingClientRect()
- windowActions.onMoreBookmarksMenu(this.props.hiddenBookmarks, rect.bottom)
+ windowActions.onMoreBookmarksMenu(this.hiddenBookmarkKeys, rect.bottom)
}
onContextMenu (e) {
@@ -172,70 +197,167 @@ class BookmarksToolbar extends React.Component {
mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')
const activeFrame = frameStateUtil.getActiveFrame(currentWindow) || Immutable.Map()
- const currentWindowId = getCurrentWindowId()
+ const toolbarMode = bookmarkUtil.getBookmarksToolbarMode(state)
const props = {}
// used in renderer
- props.showOnlyFavicon = bookmarkUtil.showOnlyFavicon()
- props.showFavicon = bookmarkUtil.showFavicon()
props.shouldAllowWindowDrag = !isWindows && windowState.shouldAllowWindowDrag(state, currentWindow, activeFrame, isFocused(state))
- props.visibleBookmarks = bookmarkToolbarState.getToolbar(state, currentWindowId)
- props.hiddenBookmarks = bookmarkToolbarState.getOther(state, currentWindowId)
-
+ props.toolbarBookmarks = bookmarksState.getBookmarksWithFolders(state, 0).take(110).map(item => item.get('key'))
+ props.textOnly = (toolbarMode === bookmarksToolbarMode.TEXT_ONLY)
+ props.bookmarkDisplayMode = toolbarMode // also forces re-compute toolbar space after change mode
// used in other functions
- props.activeFrameKey = activeFrame.get('key')
props.title = activeFrame.get('title')
props.location = activeFrame.get('location')
return props
}
+ calculateNonFirstRowItems () {
+ if (!this.bookmarksToolbarRef) {
+ return
+ }
+ const bookmarkRefs = this.bookmarksToolbarRef.children
+ const classNameShowOverflow = css(styles.bookmarksToolbar_hasOverflow)
+ this.hiddenBookmarkKeys = null
+ this.hasHiddenKeys = false
+ // first check which items overflow with indicator visible
+ this.bookmarksToolbarRef.classList.add(classNameShowOverflow)
+ // and save which keys were hidden for the overflow menu to open
+ this.hiddenBookmarkKeys = getHiddenKeys(bookmarkRefs, this.props.toolbarBookmarks)
+ // we don't need indicator if there were no hidden items with / without it
+ this.bookmarksToolbarRef.classList.remove(classNameShowOverflow)
+ // if there were hidden items with the indicator
+ if (this.hiddenBookmarkKeys && this.hiddenBookmarkKeys.size) {
+ // check again to see if we really need the indicator
+ const hiddenKeysWithNoIndicator = getHiddenKeys(bookmarkRefs, this.props.toolbarBookmarks)
+ if (hiddenKeysWithNoIndicator && hiddenKeysWithNoIndicator.size) {
+ // add overflow indicator as needed
+ this.hasHiddenKeys = true
+ this.bookmarksToolbarRef.classList.add(classNameShowOverflow)
+ }
+ }
+ }
+
+ setBookmarksToolbarRef (ref) {
+ const oldRef = this.bookmarksToolbarRef
+ this.bookmarksToolbarRef = ref
+ // handle there was a previous element
+ if (oldRef) {
+ // do not monitor size change for old element
+ // but we can keep ResizeObserver around
+ // note: this shouldn't happen because we're always returning
+ // the same root element from this.render(), but it's best practice.
+ if (this.resizeObserver) {
+ this.resizeObserver.unobserve(oldRef)
+ }
+ }
+ // handle null element this time
+ if (!ref) {
+ return
+ }
+ // recalculate which items are not on a single line on resize
+ let debounceAnimationFrame
+ this.resizeObserver = this.resizeObserver || new window.ResizeObserver(() => {
+ // (only once before the next paint frame)
+ debounceAnimationFrame = debounceAnimationFrame || window.requestAnimationFrame(() => {
+ debounceAnimationFrame = null
+ this.calculateNonFirstRowItems()
+ })
+ })
+ // observe this ref
+ this.resizeObserver.observe(this.bookmarksToolbarRef)
+ }
+
+ componentDidUpdate (prevProps) {
+ // Only recalc which bookmark items are overflowed if the bookmarks changed
+ // or the display mode changed.
+ if (prevProps.bookmarkDisplayMode !== this.props.bookmarkDisplayMode || !prevProps.toolbarBookmarks.equals(this.props.toolbarBookmarks)) {
+ // No need to wait for the new DOM render result to paint
+ // before measuring since reading offsetTop of the elements
+ // will force layout to be computed.
+ this.calculateNonFirstRowItems()
+ }
+ }
+
render () {
this.bookmarkRefs = []
- return
{
- this.props.visibleBookmarks.map((bookmarkKey, i) =>
- this.bookmarkRefs.push(node)}
- key={`toolbar-button-${i}`}
- bookmarkKey={bookmarkKey}
- />)
+ this.props.toolbarBookmarks.map((bookmarkKey, i) =>
+ this.bookmarkRefs.push(node)}
+ key={`toolbar-button-${i}`}
+ bookmarkKey={bookmarkKey}
+ bookmarkDisplayMode={this.props.bookmarkDisplayMode}
+ />)
}
- {
- this.props.hiddenBookmarks.size !== 0
- ?
+
- : null
- }
+
}
}
const styles = StyleSheet.create({
bookmarksToolbar: {
+ '--bookmarks-toolbar-overflow-indicator-width': '0px',
+ '--bookmarks-toolbar-height': globalStyles.spacing.bookmarksToolbarHeight,
+ flex: 1,
boxSizing: 'border-box',
+ height: 'var(--bookmarks-toolbar-height)',
display: 'flex',
- flex: 1,
- alignItems: 'center', // to align bookmarksToolbar__overflowIndicator to the center
- padding: `0 ${globalStyles.spacing.bookmarksToolbarPadding}`,
- margin: `${globalStyles.spacing.navbarMenubarMargin} 0`
+ flexDirection: 'row',
+ flexWrap: 'wrap',
+ alignItems: 'center',
+ overflow: 'hidden',
+ // leave space on the right for the overflow button when appropriate
+ // aphrodite cannot have a calc in a shorthand padding declaration :-(
+ paddingRight: `calc(${globalStyles.spacing.bookmarksToolbarPadding} + var(--bookmarks-toolbar-overflow-indicator-width))`,
+ paddingTop: 0,
+ paddingBottom: 0,
+ paddingLeft: globalStyles.spacing.bookmarksToolbarPadding,
+ margin: `${globalStyles.spacing.navbarMenubarMargin} 0`,
+ position: 'relative'
+ },
+
+ bookmarksToolbar_textOnly: {
+ '--bookmarks-toolbar-height': globalStyles.spacing.bookmarksToolbarTextOnlyHeight
+ },
+
+ bookmarksToolbar_hasOverflow: {
+ '--bookmarks-toolbar-overflow-indicator-visibility': 'visible',
+ '--bookmarks-toolbar-overflow-indicator-width': `${globalStyles.spacing.bookmarksToolbarOverflowButtonWidth} !important`
},
bookmarksToolbar_allowDragging: {
@@ -246,12 +368,30 @@ const styles = StyleSheet.create({
WebkitAppRegion: 'no-drag'
},
- bookmarksToolbar_showOnlyFavicon: {
- padding: `0 0 0 ${globalStyles.spacing.bookmarksToolbarPadding}`
+ bookmarksToolbar__overflowIndicator: {
+ WebkitAppRegion: 'no-drag',
+ position: 'absolute',
+ top: 0,
+ right: 0,
+ height: 'var(--bookmarks-toolbar-height)',
+ margin: `0 calc(${globalStyles.spacing.bookmarksToolbarPadding} + 5px) 0 auto`,
+ visibility: 'var(--bookmarks-toolbar-overflow-indicator-visibility, hidden)',
+ border: 'none',
+ background: 'transparent',
+ padding: 0,
+ width: 'auto',
+ outline: 'none',
+ display: 'flex',
+ alignItems: 'center',
+ color: globalStyles.button.color,
+ ':hover': {
+ color: globalStyles.button.default.hoverColor
+ }
},
- bookmarksToolbar__overflowIndicator: {
- margin: '0 5px 0 auto'
+ bookmarksToolbar__overflowIndicator__icon: {
+ width: globalStyles.spacing.bookmarksToolbarOverflowButtonWidth,
+ height: 'auto'
}
})
diff --git a/app/renderer/components/bookmarks/bookmarksToolbarOverflowIcon.js b/app/renderer/components/bookmarks/bookmarksToolbarOverflowIcon.js
new file mode 100644
index 00000000000..80b295b4fe1
--- /dev/null
+++ b/app/renderer/components/bookmarks/bookmarksToolbarOverflowIcon.js
@@ -0,0 +1,7 @@
+module.exports = function BookmarksToolbarOverflowIcon ({ className }) {
+ return (
+
+
+
+ )
+}
diff --git a/app/renderer/components/common/browserButton.js b/app/renderer/components/common/browserButton.js
index 739911fc1c8..5fb0a987ce8 100644
--- a/app/renderer/components/common/browserButton.js
+++ b/app/renderer/components/common/browserButton.js
@@ -13,6 +13,7 @@ class BrowserButton extends ImmutableComponent {
styles.browserButton,
this.props.primaryColor && [styles.browserButton_default, styles.browserButton_primaryColor],
this.props.secondaryColor && [styles.browserButton_default, styles.browserButton_secondaryColor],
+ this.props.alertColor && [styles.browserButton_default, styles.browserButton_alertColor],
this.props.subtleItem && [styles.browserButton_default, styles.browserButton_subtleItem],
// actionItem is just subtleItem with a blue background
this.props.actionItem &&
@@ -61,7 +62,6 @@ class BrowserButton extends ImmutableComponent {
return
+ }
+}
+
+class CommonFormSmall extends ImmutableComponent {
+ render () {
+ return
+ }
+}
+
+class CommonFormMedium extends ImmutableComponent {
+ render () {
+ return
+ }
+}
+
+class CommonFormLarge extends ImmutableComponent {
+ render () {
+ return
- {this.props.children}
-
+ styles.commonFormLarge
+ )} {...this.props} />
}
}
-class CommonFormHanger extends ImmutableComponent {
+class CommonFormBookmarkHanger extends ImmutableComponent {
render () {
- return
- {this.props.children}
-
+ return
}
}
@@ -55,41 +75,62 @@ class CommonFormTextbox extends ImmutableComponent {
}
}
+class CommonFormClickable extends ImmutableComponent {
+ render () {
+ return
+ }
+}
+
class CommonFormSection extends ImmutableComponent {
+ render () {
+ return
+ }
+}
+
+class CommonFormTitle extends ImmutableComponent {
render () {
return
- {this.props.children}
-
+ styles.commonFormSection,
+ styles.commonFormTitle
+ )} {...this.props} />
}
}
-class CommonFormClickable extends ImmutableComponent {
+class CommonFormSubSection extends ImmutableComponent {
render () {
return
- {this.props.children}
-
+ styles.commonFormSection,
+ styles.commonFormSubSection
+ )} {...this.props} />
+ }
+}
+
+class CommonFormButtonWrapper extends ImmutableComponent {
+ render () {
+ return
+ }
+}
+
+class CommonFormBottomWrapper extends ImmutableComponent {
+ render () {
+ return
}
}
const styles = StyleSheet.create({
+ flexJustifyEnd: {
+ display: 'flex',
+ justifyContent: 'flex-end'
+ },
+
commonForm: {
- background: globalStyles.color.commonFormBackgroundColor,
+ background: globalStyles.color.modalVeryLightGray,
color: globalStyles.color.commonTextColor,
padding: 0,
top: '40px',
@@ -98,10 +139,8 @@ const styles = StyleSheet.create({
maxWidth: globalStyles.spacing.dialogWidth,
minWidth: '310px',
height: 'auto',
- userSelect: 'none',
-
- // #8634: commonStyles.flyoutDialog,
- maxHeight: '100vh'
+ maxHeight: '100vh', // #8634: commonStyles.flyoutDialog,
+ userSelect: 'none'
// Need a general solution
// See: #7930
@@ -109,62 +148,53 @@ const styles = StyleSheet.create({
// maxHeight: '100%'
},
- commonForm_small: {
+ commonFormSmall: {
maxWidth: globalStyles.spacing.dialogSmallWidth
},
- commonForm_medium: {
+ commonFormMedium: {
maxWidth: globalStyles.spacing.dialogMediumWidth
},
- commonForm_large: {
+ commonFormLarge: {
maxWidth: globalStyles.spacing.dialogLargeWidth
},
- commonForm_hanger: {
+ commonFormBookmarkHanger: {
+ maxWidth: globalStyles.spacing.bookmarkHangerMaxWidth,
+ height: 'initial', // #8634
+
// Cancel the inherited value from .navbarMenubarFlexContainer, which is 'nowrap'.
- whiteSpace: 'normal',
+ whiteSpace: 'normal'
+ },
- // #8634
- height: 'initial'
+ commonFormClickable: {
+ color: '#5b5b5b',
+
+ ':hover': {
+ color: '#000'
+ }
},
- commonForm_hanger_bookmark: {
- maxWidth: globalStyles.spacing.bookmarkHangerMaxWidth
+ commonFormTitle: {
+ color: globalStyles.color.braveOrange,
+ fontSize: '1.2em'
},
- commonForm__section: {
+ commonFormSection: {
// PR #7985
margin: `${globalStyles.spacing.dialogInsideMargin} 30px`
},
- commonForm__section_sub: {
+ commonFormSubSection: {
margin: `0 0 ${globalStyles.spacing.dialogInsideMargin} ${globalStyles.spacing.dialogInsideMargin}`
},
- commonForm__section_title: {
- color: globalStyles.color.braveOrange,
- fontSize: '1.2em'
- },
-
- commonForm__section_buttons: {
- display: 'flex',
- justifyContent: 'flex-end'
- },
-
- commonForm__section_bottom: {
+ commonFormBottomWrapper: {
margin: 0,
padding: `${globalStyles.spacing.dialogInsideMargin} 30px`,
background: globalStyles.color.commonFormBottomWrapperBackground,
borderRadius: `0 0 ${globalStyles.radius.borderRadius} ${globalStyles.radius.borderRadius}`
- },
-
- commonForm__clickable: {
- color: '#5b5b5b',
-
- ':hover': {
- color: '#000'
- }
}
})
@@ -199,10 +229,17 @@ const commonFormStyles = StyleSheet.create({
module.exports = {
CommonForm,
- CommonFormHanger,
+ CommonFormSmall,
+ CommonFormMedium,
+ CommonFormLarge,
+ CommonFormBookmarkHanger,
CommonFormDropdown,
CommonFormTextbox,
- CommonFormSection,
CommonFormClickable,
+ CommonFormSection,
+ CommonFormTitle,
+ CommonFormSubSection,
+ CommonFormButtonWrapper,
+ CommonFormBottomWrapper,
commonFormStyles
}
diff --git a/app/renderer/components/common/contextMenu/contextMenu.js b/app/renderer/components/common/contextMenu/contextMenu.js
index 0cd139fae4e..b5d024db3b0 100644
--- a/app/renderer/components/common/contextMenu/contextMenu.js
+++ b/app/renderer/components/common/contextMenu/contextMenu.js
@@ -15,8 +15,13 @@ const windowActions = require('../../../../../js/actions/windowActions')
// Constants
const keyCodes = require('../../../../common/constants/keyCodes')
+// State
+const contextMenuState = require('../../../../common/state/contextMenuState')
+const tabState = require('../../../../common/state/tabState')
+const appStore = require('../../../../../js/stores/appStoreRenderer')
+const { getCurrentWindowId } = require('../../../currentWindow')
+
// Utils
-const frameStateUtil = require('../../../../../js/state/frameStateUtil')
const {separatorMenuItem} = require('../../../../common/commonMenu')
const {wrappingClamp} = require('../../../../common/lib/formatUtil')
@@ -216,12 +221,13 @@ class ContextMenu extends React.Component {
mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')
- const activeFrame = frameStateUtil.getActiveFrame(currentWindow) || Immutable.Map()
+
const selectedIndex = currentWindow.getIn(['ui', 'contextMenu', 'selectedIndex'], null)
- const contextMenuDetail = currentWindow.get('contextMenuDetail', Immutable.Map())
+ const contextMenuDetail = contextMenuState.getContextMenu(currentWindow)
const props = {}
- props.lastZoomPercentage = activeFrame.get('lastZoomPercentage')
+ const activeTab = tabState.getActiveTab(appStore.state, getCurrentWindowId())
+ props.lastZoomPercentage = activeTab && activeTab.get('zoomPercent')
props.contextMenuDetail = contextMenuDetail // TODO (nejc) only primitives
props.selectedIndex = typeof selectedIndex === 'object' &&
Array.isArray(selectedIndex) &&
diff --git a/app/renderer/components/common/contextMenu/contextMenuItem.js b/app/renderer/components/common/contextMenu/contextMenuItem.js
index 3d5a0bec824..cd7ba220c69 100644
--- a/app/renderer/components/common/contextMenu/contextMenuItem.js
+++ b/app/renderer/components/common/contextMenu/contextMenuItem.js
@@ -167,11 +167,7 @@ class ContextMenuItem extends ImmutableComponent {
return label
}
if (item.get('labelDataBind') === 'zoomLevel') {
- const activeWebview = document.querySelector('.frameWrapper.isActive webview')
- let percent = 100
- if (activeWebview) {
- percent = activeWebview.getZoomPercent()
- }
+ const percent = this.props.lastZoomPercentage || 100
return `${percent}%`
}
return ''
@@ -304,7 +300,8 @@ const styles = StyleSheet.create({
},
item: {
- maxWidth: '420px',
+ maxWidth: 'inherit',
+ minWidth: 'inherit',
paddingTop: '6px',
paddingRight: '10px',
paddingBottom: '6px',
diff --git a/app/renderer/components/common/flyoutDialog.js b/app/renderer/components/common/flyoutDialog.js
deleted file mode 100644
index a95b4f68053..00000000000
--- a/app/renderer/components/common/flyoutDialog.js
+++ /dev/null
@@ -1,45 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const React = require('react')
-const ImmutableComponent = require('../immutableComponent')
-
-const {StyleSheet, css} = require('aphrodite/no-important')
-const globalStyles = require('../styles/global')
-
-class FlyoutDialog extends ImmutableComponent {
- render () {
- return
- {this.props.children}
-
- }
-}
-
-const styles = StyleSheet.create({
- flyoutDialog: {
- background: globalStyles.color.toolbarBackground,
- borderRadius: globalStyles.radius.borderRadius,
- boxShadow: globalStyles.shadow.flyoutDialogBoxShadow,
- color: '#000',
- fontSize: '13px',
-
- // Issue #7949
- padding: `${globalStyles.spacing.dialogInsideMargin} 30px`,
- position: 'absolute',
- top: globalStyles.spacing.dialogTopOffset,
-
- // Issue #7930
- boxSizing: 'border-box',
- maxWidth: '600px',
- maxHeight: `calc(80vh - ${globalStyles.spacing.downloadsBarHeight})`
- }
-})
-
-module.exports = FlyoutDialog
diff --git a/app/renderer/components/common/longPressButton.js b/app/renderer/components/common/longPressButton.js
index 3b3d3df1a2f..46a7fffec57 100644
--- a/app/renderer/components/common/longPressButton.js
+++ b/app/renderer/components/common/longPressButton.js
@@ -86,7 +86,10 @@ class LongPressButton extends ImmutableComponent {
ref={(node) => { this.buttonNode = node }}
onMouseDown={this.onMouseDown}
onMouseUp={this.onMouseUp}
- onMouseLeave={this.onMouseLeave} />
+ onMouseLeave={this.onMouseLeave}
+ >
+ {this.props.children}
+
}
}
diff --git a/app/renderer/components/common/messageBox.js b/app/renderer/components/common/messageBox.js
index fa937cecf57..ea70445c699 100644
--- a/app/renderer/components/common/messageBox.js
+++ b/app/renderer/components/common/messageBox.js
@@ -9,9 +9,9 @@ const {StyleSheet, css} = require('aphrodite/no-important')
// Components
const ReduxComponent = require('../reduxComponent')
const Dialog = require('./dialog')
-const FlyoutDialog = require('./flyoutDialog')
const BrowserButton = require('../common/browserButton')
const SwitchControl = require('./switchControl')
+const {PromptTextBox} = require('./textbox')
// Actions
const appActions = require('../../../../js/actions/appActions')
@@ -36,12 +36,21 @@ class MessageBox extends React.Component {
super(props)
this.onKeyDown = this.onKeyDown.bind(this)
this.onSuppressChanged = this.onSuppressChanged.bind(this)
+ this.state = {
+ textInput: props.defaultPromptText
+ }
}
componentWillMount () {
document.addEventListener('keydown', this.onKeyDown)
}
+ componentDidMount () {
+ if (this.props.allowInput) {
+ this.inputRef.select()
+ }
+ }
+
componentWillUnmount () {
document.removeEventListener('keydown', this.onKeyDown)
}
@@ -82,6 +91,10 @@ class MessageBox extends React.Component {
response.result = buttonId !== this.props.cancelId
}
+ if (this.props.allowInput) {
+ response.input = this.state.textInput
+ }
+
appActions.tabMessageBoxDismissed(tabId, response)
}
@@ -112,6 +125,8 @@ class MessageBox extends React.Component {
// used in renderer
props.tabId = tabId
props.message = messageBoxDetail.get('message')
+ props.allowInput = messageBoxDetail.get('allowInput')
+ props.defaultPromptText = messageBoxDetail.get('defaultPromptText')
props.suppress = tabMessageBoxState.getSuppress(state, tabId)
props.title = tabMessageBoxState.getTitle(state, tabId)
props.showSuppress = tabMessageBoxState.getShowSuppress(state, tabId)
@@ -126,8 +141,8 @@ class MessageBox extends React.Component {
render () {
return
-
@@ -151,11 +166,26 @@ class MessageBox extends React.Component {
/>
: null
}
+ {
+ this.props.allowInput && (
+
{
+ this.inputRef = ref
+ }}
+ onChange={e => {
+ this.setState({
+ textInput: e.target.value
+ })
+ }}
+ />
+ )
+ }
{this.messageBoxButtons}
-
+
}
}
diff --git a/app/renderer/components/common/settings.js b/app/renderer/components/common/settings.js
index e484ccedba1..70d62c3dba4 100644
--- a/app/renderer/components/common/settings.js
+++ b/app/renderer/components/common/settings.js
@@ -178,7 +178,7 @@ class SettingItemIcon extends ImmutableComponent {
const styles = StyleSheet.create({
icon: {
- backgroundColor: '#5a5a5a',
+ backgroundColor: 'rgb(90, 90, 98)',
height: '16px',
width: '16px',
display: 'inline-block',
diff --git a/app/renderer/components/common/sortableTable.js b/app/renderer/components/common/sortableTable.js
index a1afa10e61c..a9b436e524d 100644
--- a/app/renderer/components/common/sortableTable.js
+++ b/app/renderer/components/common/sortableTable.js
@@ -12,6 +12,7 @@ const globalStyles = require('../styles/global')
// Utils
const cx = require('../../../../js/lib/classSet')
const eventUtil = require('../../../../js/lib/eventUtil')
+const ImmutableUtil = require('../../../common/state/immutableUtil')
tableSort.extend('number', (item) => {
return typeof item === 'number'
@@ -32,16 +33,62 @@ class SortableTable extends React.Component {
}
this.counter = 0
this.sortTable = null
+ this.dimensionCount = null
}
componentDidMount () {
- this.sortTable = tableSort(this.table)
+ this.sortTable = tableSort(this.table, {
+ descending: this.props.defaultHeadingSortOrder === 'desc'
+ })
return this.sortTable
}
componentDidUpdate (prevProps) {
- if (this.props.rows &&
- (!prevProps.rows ||
- prevProps.rows.length !== this.props.rows.length)) {
- this.sortTable.refresh()
+ if (this.isMultiDimensioned) {
+ let count = 0
+ if (this.dimensionCount == null && prevProps.rows) {
+ for (let i = 0; i < prevProps.rows.length; i++) {
+ if (this.props.rows[i].length > 0) {
+ count += this.props.rows[i].length
+ }
+ }
+ this.dimensionCount = count
+ }
+
+ if (!this.props.rows) {
+ this.dimensionCount = null
+ return
+ }
+
+ count = 0
+ for (let i = 0; i < this.props.rows.length; i++) {
+ if (this.props.rows[i].length > 0) {
+ count += this.props.rows[i].length
+ }
+ }
+
+ if (count !== this.dimensionCount) {
+ this.sortTable.refresh()
+ this.dimensionCount = count
+ return
+ }
+ } else {
+ if (
+ this.props.rows &&
+ (
+ !prevProps.rows ||
+ prevProps.rows.length !== this.props.rows.length
+ )
+ ) {
+ this.sortTable.refresh()
+ return
+ }
+ }
+
+ if (this.props.rows && typeof this.props.sortCheck === 'function') {
+ const shouldSort = this.props.sortCheck(prevProps.rows, this.props.rows)
+
+ if (shouldSort) {
+ this.sortTable.refresh()
+ }
}
}
/**
@@ -202,11 +249,11 @@ class SortableTable extends React.Component {
const tableID = parseInt(tableParts[0])
const rowIndex = parseInt(tableParts[1])
const handlerInput = this.props.totalRowObjects
- ? (typeof this.props.totalRowObjects[parseInt(tableID)][rowIndex].toJS === 'function'
+ ? (ImmutableUtil.isImmutable(this.props.totalRowObjects[parseInt(tableID)][rowIndex])
? this.props.totalRowObjects[parseInt(tableID)][rowIndex].toJS()
: this.props.totalRowObjects[parseInt(tableID)][rowIndex])
: (this.props.rowObjects.size > 0 || this.props.rowObjects.length > 0)
- ? (typeof this.props.rowObjects.toJS === 'function'
+ ? (ImmutableUtil.isImmutable(this.props.rowObjects)
? this.props.rowObjects.get(rowIndex).toJS()
: this.props.rowObjects[rowIndex])
: null
@@ -305,23 +352,51 @@ class SortableTable extends React.Component {
// Object bound to this row. Not passed to multi-select handlers.
if (this.isMultiDimensioned) {
// Object bound to this row. Not passed to multi-select handlers.
- handlerInput = this.props.rowObjects[bodyIndex] &&
- (this.props.rowObjects[bodyIndex].size > 0 || this.props.rowObjects[bodyIndex].length > 0)
- ? (typeof this.props.rowObjects[bodyIndex].toJS === 'function'
- ? this.props.rowObjects[bodyIndex].get(index).toJS()
- : (typeof this.props.rowObjects[bodyIndex][index].toJS === 'function'
- ? this.props.rowObjects[bodyIndex][index].toJS()
- : this.props.rowObjects[bodyIndex][index]))
- : row
+ if (
+ this.props.rowObjects[bodyIndex] &&
+ (
+ this.props.rowObjects[bodyIndex].size > 0 ||
+ this.props.rowObjects[bodyIndex].length > 0
+ )
+ ) {
+ let indexObj
+ if (ImmutableUtil.isImmutable(this.props.rowObjects[bodyIndex])) {
+ indexObj = this.props.rowObjects[bodyIndex].get(index)
+ } else {
+ indexObj = this.props.rowObjects[bodyIndex][index]
+ }
+
+ handlerInput = indexObj
+
+ if (ImmutableUtil.isImmutable(indexObj)) {
+ handlerInput = indexObj.toJS()
+ }
+ } else {
+ handlerInput = row
+ }
} else {
- handlerInput = this.props.rowObjects &&
- (this.props.rowObjects.size > 0 || this.props.rowObjects.length > 0)
- ? (typeof this.props.rowObjects.toJS === 'function'
- ? this.props.rowObjects.get(index).toJS()
- : (typeof this.props.rowObjects[index].toJS === 'function'
- ? this.props.rowObjects[index].toJS()
- : this.props.rowObjects[index]))
- : row
+ if (
+ this.props.rowObjects &&
+ (
+ this.props.rowObjects.size > 0 ||
+ this.props.rowObjects.length > 0
+ )
+ ) {
+ let indexObj
+ if (ImmutableUtil.isImmutable(this.props.rowObjects)) {
+ indexObj = this.props.rowObjects.get(index)
+ } else {
+ indexObj = this.props.rowObjects[index]
+ }
+
+ handlerInput = indexObj
+
+ if (ImmutableUtil.isImmutable(indexObj)) {
+ handlerInput = indexObj.toJS()
+ }
+ } else {
+ handlerInput = row
+ }
}
// Allow parent control to optionally specify context
@@ -473,9 +548,10 @@ class SortableTable extends React.Component {
if (dataType === 'object' && firstEntry.value) {
dataType = typeof firstEntry.value
}
+ const defaultSort = (this.sortingDisabled || heading === this.props.defaultHeading) || null
const headerClasses = {
'sort-header': true,
- 'sort-default': this.sortingDisabled || heading === this.props.defaultHeading,
+ 'sort-default': defaultSort,
[css(styles.table__th, this.props.smallRow && styles.table__th_smallRow)]: true
}
const isString = typeof heading === 'string'
@@ -486,8 +562,9 @@ class SortableTable extends React.Component {
return
diff --git a/app/renderer/components/common/textbox.js b/app/renderer/components/common/textbox.js
index 9438744cdce..d9c6d8fc5a0 100644
--- a/app/renderer/components/common/textbox.js
+++ b/app/renderer/components/common/textbox.js
@@ -6,6 +6,9 @@ const React = require('react')
const ImmutableComponent = require('../immutableComponent')
const {StyleSheet, css} = require('aphrodite/no-important')
+const ClipboardButton = require('../common/clipboardButton')
+const appActions = require('../../../../js/actions/appActions')
+
const globalStyles = require('../styles/global')
const commonStyles = require('../styles/commonStyles')
@@ -17,10 +20,17 @@ class Textbox extends ImmutableComponent {
styles.textbox,
(this.props.readonly || this.props.readOnly) ? styles.readOnly : styles.outlineable,
this.props['data-isCommonForm'] && commonStyles.isCommonForm,
- this.props['data-isSettings'] && styles.isSettings
+ this.props['data-isSettings'] && styles.isSettings,
+ this.props['data-isPrompt'] && styles.isPrompt,
+ this.props.customClass && this.props.customClass
)
- return
+ const props = Object.assign({}, this.props)
+ const ref = this.props.inputRef
+ delete props.customClass
+ delete props.inputRef
+
+ return
}
}
@@ -59,6 +69,12 @@ class SettingTextbox extends ImmutableComponent {
}
}
+class PromptTextBox extends ImmutableComponent {
+ render () {
+ return
+ }
+}
+
// TextArea
class TextArea extends ImmutableComponent {
render () {
@@ -77,6 +93,65 @@ class DefaultTextArea extends ImmutableComponent {
}
}
+class WordCountTextArea extends React.Component {
+ constructor () {
+ super()
+ this.handleCopyToClipboard = this.handleCopyToClipboard.bind(this)
+ this.handleOnChange = this.handleOnChange.bind(this)
+ this.state = { wordCount: 0 }
+ }
+
+ handleOnChange (e) {
+ let wordCount = 0
+
+ if (e.target.value.length > 0) {
+ wordCount = e.target.value.trim().replace(/\s+/gi, ' ').split(' ').length
+ }
+
+ this.setState({wordCount})
+
+ if (this.props.onChangeText) {
+ this.props.onChangeText()
+ }
+ }
+
+ handleCopyToClipboard () {
+ if (!this.textAreaBox) {
+ return
+ }
+ appActions.clipboardTextCopied(this.textAreaBox.value)
+ }
+
+ render () {
+ return (
+
+ )
+ }
+}
+
const styles = StyleSheet.create({
// Textbox
textbox: {
@@ -94,6 +169,10 @@ const styles = StyleSheet.create({
isSettings: {
width: '280px'
},
+ isPrompt: {
+ width: '100%',
+ marginBottom: '20px'
+ },
readOnly: {
background: globalStyles.color.lightGray,
boxShadow: 'none',
@@ -144,6 +223,36 @@ const styles = StyleSheet.create({
display: 'flex',
alignItems: 'center',
justifyContent: 'center'
+ },
+
+ wordCountTextArea__main: {
+ background: 'rgba(0, 0, 0, 0.1)',
+ border: '1px solid #000',
+ borderRadius: '4px',
+ padding: '2px',
+ width: '100%'
+ },
+
+ wordCountTextArea__body: {
+ width: '100%',
+ height: '120px',
+ borderTopLeftRadius: '4px',
+ borderTopRightRadius: '4px',
+ borderBottomLeftRadius: 0,
+ borderBottomRightRadius: 0,
+ resize: 'none',
+ fontSize: '18px'
+ },
+
+ wordCountTextArea__footer: {
+ display: 'flex',
+ justifyContent: 'space-between',
+ alignItems: 'center',
+ borderBottomLeftRadius: '4px',
+ borderBottomRightRadius: '4px',
+ padding: '5px 10px',
+ fontSize: '13px',
+ fontWeight: 'bold'
}
})
@@ -152,6 +261,8 @@ module.exports = {
FormTextbox,
GroupedFormTextbox,
SettingTextbox,
+ PromptTextBox,
TextArea,
- DefaultTextArea
+ DefaultTextArea,
+ WordCountTextArea
}
diff --git a/app/renderer/components/frame/frame.js b/app/renderer/components/frame/frame.js
deleted file mode 100644
index 603a717171f..00000000000
--- a/app/renderer/components/frame/frame.js
+++ /dev/null
@@ -1,965 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-const React = require('react')
-const Immutable = require('immutable')
-const ipc = require('electron').ipcRenderer
-
-// Actions
-const appActions = require('../../../../js/actions/appActions')
-const tabActions = require('../../../common/actions/tabActions')
-const windowActions = require('../../../../js/actions/windowActions')
-const webviewActions = require('../../../../js/actions/webviewActions')
-const getSetting = require('../../../../js/settings').getSetting
-
-// Components
-const ReduxComponent = require('../reduxComponent')
-const FullScreenWarning = require('./fullScreenWarning')
-const HrefPreview = require('./hrefPreview')
-const MessageBox = require('../common/messageBox')
-
-// Store
-const windowStore = require('../../../../js/stores/windowStore')
-const appStoreRenderer = require('../../../../js/stores/appStoreRenderer')
-
-// State
-const siteSettings = require('../../../../js/state/siteSettings')
-const siteSettingsState = require('../../../common/state/siteSettingsState')
-const tabState = require('../../../common/state/tabState')
-const tabMessageBoxState = require('../../../common/state/tabMessageBoxState')
-
-// Utils
-const frameStateUtil = require('../../../../js/state/frameStateUtil')
-const UrlUtil = require('../../../../js/lib/urlutil')
-const cx = require('../../../../js/lib/classSet')
-const urlParse = require('../../../common/urlParse')
-const contextMenus = require('../../../../js/contextMenus')
-const domUtil = require('../../lib/domUtil')
-const {
- aboutUrls,
- isSourceMagnetUrl,
- isTargetAboutUrl,
- getTargetAboutUrl,
- getBaseUrl,
- isIntermediateAboutPage
-} = require('../../../../js/lib/appUrlUtil')
-const {isFrameError, isAborted} = require('../../../common/lib/httpUtil')
-const {isFocused} = require('../../currentWindow')
-const debounce = require('../../../../js/lib/debounce')
-const locale = require('../../../../js/l10n')
-const imageUtil = require('../../../../js/lib/imageUtil')
-const historyUtil = require('../../../common/lib/historyUtil')
-
-// Constants
-const settings = require('../../../../js/constants/settings')
-const appConfig = require('../../../../js/constants/appConfig')
-const messages = require('../../../../js/constants/messages')
-const config = require('../../../../js/constants/config')
-
-function isTorrentViewerURL (url) {
- const isEnabled = getSetting(settings.TORRENT_VIEWER_ENABLED)
- return isEnabled && isSourceMagnetUrl(url)
-}
-
-function isPDFJSURL (url) {
- const pdfjsOrigin = `chrome-extension://${config.PDFJSExtensionId}/`
- return url && url.startsWith(pdfjsOrigin)
-}
-
-class Frame extends React.Component {
- constructor (props) {
- super(props)
- this.onCloseFrame = this.onCloseFrame.bind(this)
- this.onUpdateWheelZoom = debounce(this.onUpdateWheelZoom.bind(this), 20)
- this.onFocus = this.onFocus.bind(this)
- // Maps notification message to its callback
- this.notificationCallbacks = {}
- // Counter for detecting PDF URL redirect loops
- this.reloadCounter = {}
- }
-
- get frame () {
- return windowStore.getFrame(this.props.frameKey) || Immutable.fromJS({})
- }
-
- get tab () {
- const frame = this.frame
- if (!appStoreRenderer.state.get('tabs')) {
- return undefined
- }
- return appStoreRenderer.state.get('tabs').find((tab) => tab.get('tabId') === frame.get('tabId'))
- }
-
- onCloseFrame () {
- windowActions.closeFrame(this.props.frameKey)
- }
-
- isAboutPage () {
- return aboutUrls.get(getBaseUrl(this.props.location))
- }
-
- isIntermediateAboutPage () {
- return isIntermediateAboutPage(getBaseUrl(this.props.location))
- }
-
- shouldCreateWebview () {
- return !this.webview
- }
-
- allowRunningWidevinePlugin () {
- if (!this.props.isWidevineEnabled) {
- return false
- }
- if (!this.props.origin) {
- return false
- }
- // Check for at least one CtP allowed on this origin
- if (!this.props.hasAllSiteSettings) {
- return false
- }
- if (typeof this.props.widevine === 'number') {
- return true
- }
- return false
- }
-
- expireContentSettings (props) {
- // Expired Flash settings should be deleted when the webview is
- // navigated or closed. Same for NoScript's allow-once option.
- if (typeof props.flash === 'number') {
- if (props.flash < Date.now()) {
- appActions.removeSiteSetting(props.origin, 'flash', props.isPrivate)
- }
- }
- if (props.widevine === 0) {
- appActions.removeSiteSetting(props.origin, 'widevine', props.isPrivate)
- }
- if (props.noScript === 0) {
- appActions.removeSiteSetting(props.origin, 'noScript', props.isPrivate)
- }
- if (props.noScriptExceptions) {
- appActions.noScriptExceptionsAdded(props.origin, props.noScriptExceptions.map(value => value === 0 ? false : value))
- }
- }
-
- componentWillUnmount () {
- this.expireContentSettings(this.props)
- }
-
- updateWebview (cb, prevProps = {}) {
- if (cb && this.runOnDomReady) {
- // there is already a callback waiting for did-attach
- // so replace it with this callback because it might be a
- // mount callback which is a subset of the update callback
- this.runOnDomReady = cb
- return
- }
-
- // Create the webview dynamically because React doesn't whitelist all
- // of the attributes we need
- if (this.shouldCreateWebview()) {
- this.webview = domUtil.createWebView()
- this.webview.setAttribute('data-frame-key', this.props.frameKey)
-
- this.addEventListeners()
- if (cb) {
- this.runOnDomReady = cb
- let didAttachCallback = (e) => {
- this.webview.removeEventListener(e.type, didAttachCallback)
- this.runOnDomReady()
- delete this.runOnDomReady
- }
- this.webview.addEventListener('will-attach', () => {
- })
- this.webview.addEventListener('did-attach', didAttachCallback, { passive: true })
- }
-
- if (!this.props.guestInstanceId || !this.webview.attachGuest(this.props.guestInstanceId)) {
- // The partition is guaranteed to be initialized by now by the browser process
- this.webview.setAttribute('partition', frameStateUtil.getPartition(this.frame))
- this.webview.setAttribute('src', this.props.location)
- }
- domUtil.appendChild(this.webviewContainer, this.webview)
- } else {
- cb && cb(prevProps)
- }
- }
-
- onPropsChanged (prevProps = {}) {
- if (this.props.isActive && !prevProps.isActive && this.props.isFocused) {
- windowActions.setFocusedFrame(this.props.location, this.props.tabId)
- }
- }
-
- componentDidMount () {
- this.updateWebview(this.onPropsChanged)
- if (this.props.activeShortcut) {
- this.handleShortcut()
- }
- }
-
- get zoomLevel () {
- const zoom = this.props.siteZoomLevel
- appActions.removeSiteSetting(this.props.origin, 'zoomLevel', this.props.isPrivate)
- return zoom
- }
-
- zoomIn () {
- if (this.webview) {
- this.webview.zoomIn()
- windowActions.setLastZoomPercentage(this.frame, this.webview.getZoomPercent())
- }
- }
-
- zoomOut () {
- if (this.webview) {
- this.webview.zoomOut()
- windowActions.setLastZoomPercentage(this.frame, this.webview.getZoomPercent())
- }
- }
-
- zoomReset () {
- if (this.webview) {
- this.webview.zoomReset()
- windowActions.setLastZoomPercentage(this.frame, this.webview.getZoomPercent())
- }
- }
-
- enterHtmlFullScreen () {
- if (this.webview) {
- this.webview.executeScriptInTab(config.braveExtensionId, 'document.documentElement.webkitRequestFullScreen()', {})
- this.webview.focus()
- }
- }
-
- exitHtmlFullScreen () {
- if (this.webview) {
- this.webview.executeScriptInTab(config.braveExtensionId, 'document.webkitExitFullscreen()', {})
- }
- }
-
- componentDidUpdate (prevProps) {
- // TODO: This title should be set in app/browser/tabs.js and then we should use the
- // app state for the tabData everywhere and remove windowState's title completely.
- if (this.props.activeShortcut !== prevProps.activeShortcut) {
- this.handleShortcut()
- }
-
- if (!this.frame.isEmpty() && !this.frame.delete('lastAccessedTime').equals(this.lastFrame)) {
- appActions.frameChanged(this.frame)
- }
-
- this.lastFrame = this.frame.delete('lastAccessedTime')
-
- const cb = (prevProps = {}) => {
- this.onPropsChanged(prevProps)
- if (this.props.isActive && !prevProps.isActive && !this.props.urlBarFocused) {
- this.webview.focus()
- }
-
- // make sure the webview content updates to
- // match the fullscreen state of the frame
- if (prevProps.isFullScreen !== this.props.isFullScreen ||
- (this.props.isFullScreen && !this.props.isActive)) {
- if (this.props.isFullScreen && this.props.isActive) {
- this.enterHtmlFullScreen()
- } else {
- this.exitHtmlFullScreen()
- }
- }
- }
-
- // For cross-origin navigation, clear temp approvals
- if (this.props.origin !== prevProps.origin) {
- this.expireContentSettings(prevProps)
- }
-
- this.updateWebview(cb, prevProps)
- }
-
- handleShortcut () {
- switch (this.props.activeShortcut) {
- case 'stop':
- this.webview.stop()
- break
- case 'reload':
- // Ensure that the webview thinks we're on the same location as the browser does.
- // This can happen for pages which don't load properly.
- // Some examples are basic http auth and bookmarklets.
- // In this case both the user display and the user think they're on this.props.location.
- if (this.props.tabUrl !== this.props.location &&
- !this.isAboutPage() &&
- !isTorrentViewerURL(this.props.location)) {
- } else if (isPDFJSURL(this.props.location)) {
- appActions.loadURLRequested(this.props.tabId,
- UrlUtil.getLocationIfPDF(this.props.location))
- } else {
- tabActions.reload(this.props.tabId)
- }
- break
- case 'clean-reload':
- tabActions.reload(this.props.tabId, true)
- break
- case 'zoom-in':
- this.zoomIn()
- break
- case 'zoom-out':
- this.zoomOut()
- break
- case 'zoom-reset':
- this.zoomReset()
- break
- case 'view-source':
- const sourceLocation = UrlUtil.getViewSourceUrlFromUrl(this.props.tabUrl)
- if (sourceLocation !== null) {
- appActions.createTabRequested({
- url: sourceLocation,
- isPrivate: this.props.isPrivate,
- partitionNumber: this.props.partitionNumber,
- openerTabId: this.props.tabId,
- active: true
- })
- }
- // TODO: Make the URL bar show the view-source: prefix
- break
- case 'save':
- const downloadLocation = getSetting(settings.PDFJS_ENABLED)
- ? UrlUtil.getLocationIfPDF(this.props.tabUrl)
- : this.props.tabUrl
- // TODO: Sometimes this tries to save in a non-existent directory
- this.webview.downloadURL(downloadLocation, true)
- break
- case 'print':
- this.webview.print()
- break
- case 'show-findbar':
- windowActions.setFindbarShown(this.props.frameKey, true)
- break
- case 'focus-webview':
- setImmediate(() => this.webview.focus())
- break
- case 'copy':
- let selection = window.getSelection()
- if (selection && selection.toString()) {
- appActions.clipboardTextCopied(selection.toString())
- } else {
- this.webview.copy()
- }
- break
- case 'find-next':
- this.onFindAgain(true)
- break
- case 'find-prev':
- this.onFindAgain(false)
- break
- }
- if (this.props.activeShortcut) {
- windowActions.frameShortcutChanged(this.frame, null, null)
- }
- }
-
- /**
- * Shows a Widevine CtP notification if Widevine is installed and enabled.
- * If not enabled, alert user that Widevine is installed.
- * @param {string} origin - frame origin that is requesting to run widevine.
- * can either be main frame or subframe.
- * @param {function=} noWidevineCallback - Optional callback to run if Widevine is not
- * installed
- * @param {function=} widevineCallback - Optional callback to run if Widevine is
- * accepted
- */
- showWidevineNotification (noWidevineCallback, widevineCallback) {
- // https://www.nfl.com is said to be a widevine site but it actually uses Flash for me Oct 10, 2016
- const widevineSites = ['https://www.netflix.com',
- 'http://bitmovin.com',
- 'https://www.primevideo.com',
- 'https://www.spotify.com',
- 'https://shaka-player-demo.appspot.com']
- const origin = this.props.origin
- const location = this.props.location
- const isForWidevineTest = process.env.NODE_ENV === 'test' && location.endsWith('/drm.html')
- if (!isForWidevineTest && (!origin || !widevineSites.includes(origin))) {
- noWidevineCallback()
- return
- }
-
- // Generate a random string that is unlikely to collide. Not
- // cryptographically random.
- const nonce = Math.random().toString()
-
- if (this.props.isWidevineEnabled) {
- const message = locale.translation('allowWidevine').replace(/{{\s*origin\s*}}/, origin)
- // Show Widevine notification bar
- appActions.showNotification({
- buttons: [
- {text: locale.translation('deny')},
- {text: locale.translation('allow')}
- ],
- message,
- frameOrigin: origin,
- options: {
- nonce,
- persist: true
- }
- })
- this.notificationCallbacks[message] = (buttonIndex, persist) => {
- if (buttonIndex === 1) {
- if (persist) {
- appActions.changeSiteSetting(origin, 'widevine', 1)
- } else {
- appActions.changeSiteSetting(origin, 'widevine', 0)
- }
- if (widevineCallback) {
- widevineCallback()
- }
- } else {
- if (persist) {
- appActions.changeSiteSetting(origin, 'widevine', false)
- }
- }
- appActions.hideNotification(message)
- }
- } else {
- windowActions.widevineSiteAccessedWithoutInstall()
- }
-
- ipc.once(messages.NOTIFICATION_RESPONSE + nonce, (e, msg, buttonIndex, persist) => {
- const cb = this.notificationCallbacks[msg]
- if (cb) {
- cb(buttonIndex, persist)
- }
- })
- }
-
- addEventListeners () {
- this.webview.addEventListener('tab-id-changed', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
-
- windowActions.frameTabIdChanged(this.frame, this.props.tabId, e.tabID)
- }, { passive: true })
- this.webview.addEventListener('guest-ready', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
-
- windowActions.frameGuestInstanceIdChanged(this.frame, this.props.guestInstanceId, e.guestInstanceId)
- }, { passive: true })
- this.webview.addEventListener('content-blocked', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- if (e.details[0] === 'javascript' && e.details[1]) {
- windowActions.setBlockedBy(this.props.tabId, 'noScript', e.details[1])
- }
- if (e.details[0] === 'autoplay') {
- appActions.autoplayBlocked(this.props.tabId)
- }
- }, { passive: true })
- this.webview.addEventListener('did-block-run-insecure-content', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- windowActions.setBlockedRunInsecureContent(this.frame, e.details[0])
- }, { passive: true })
- this.webview.addEventListener('context-menu', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- contextMenus.onMainContextMenu(e.params, this.frame, this.tab)
- e.preventDefault()
- e.stopPropagation()
- })
- this.webview.addEventListener('update-target-url', (e) => {
- const downloadBarHeight = domUtil.getStyleConstants('download-bar-height')
- let nearBottom = e.y > (window.innerHeight - 150 - downloadBarHeight)
- let mouseOnLeft = e.x < (window.innerWidth / 2)
- let showOnRight = nearBottom && mouseOnLeft
- windowActions.setLinkHoverPreview(e.url, showOnRight)
- }, { passive: true })
- this.webview.addEventListener('focus', this.onFocus, { passive: true })
- this.webview.addEventListener('mouseenter', (e) => {
- windowActions.onFrameMouseEnter(this.props.tabId)
- }, { passive: true })
- this.webview.addEventListener('mouseleave', (e) => {
- windowActions.onFrameMouseLeave(this.props.tabId)
- }, { passive: true })
- this.webview.addEventListener('will-destroy', (e) => {
- this.onCloseFrame()
- }, { passive: true })
- this.webview.addEventListener('page-favicon-updated', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- if (e.favicons &&
- e.favicons.length > 0 &&
- // Favicon changes lead to recalculation of top site data so only fire
- // this when needed. Some sites update favicons very frequently.
- e.favicons[0] !== this.frame.get('icon')) {
- imageUtil.getWorkingImageUrl(e.favicons[0], (error) => {
- windowActions.setFavicon(this.frame, error ? null : e.favicons[0])
- })
- }
- }, { passive: true })
- this.webview.addEventListener('show-autofill-settings', (e) => {
- appActions.createTabRequested({
- url: 'about:autofill',
- active: true
- })
- }, { passive: true })
- this.webview.addEventListener('show-autofill-popup', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- contextMenus.onShowAutofillMenu(e.suggestions, e.rect, this.frame)
- }, { passive: true })
- this.webview.addEventListener('hide-autofill-popup', (e) => {
- if (this.props.isAutFillContextMenu) {
- windowActions.autofillPopupHidden(this.props.tabId)
- }
- }, { passive: true })
- this.webview.addEventListener('ipc-message', (e) => {
- let method = () => {}
- switch (e.channel) {
- case messages.GOT_CANVAS_FINGERPRINTING:
- if (this.frame.isEmpty()) {
- return
- }
- method = (detail) => {
- const description = [detail.type, detail.scriptUrl || this.props.provisionalLocation].join(': ')
- windowActions.setBlockedBy(this.props.tabId, 'fingerprintingProtection', description)
- }
- break
- case messages.THEME_COLOR_COMPUTED:
- if (this.frame.isEmpty()) {
- return
- }
- method = (computedThemeColor) =>
- windowActions.setThemeColor(this.frame, undefined, computedThemeColor || null)
- break
- case messages.CONTEXT_MENU_OPENED:
- if (this.frame.isEmpty()) {
- return
- }
- method = (nodeProps, contextMenuType) => {
- contextMenus.onMainContextMenu(nodeProps, this.frame, this.tab, contextMenuType)
- }
- break
- case messages.STOP_LOAD:
- method = () => this.webview.stop()
- break
- case messages.GO_BACK:
- method = () => appActions.onGoBack(this.props.tabId)
- break
- case messages.GO_FORWARD:
- method = () => appActions.onGoForward(this.props.tabId)
- break
- case messages.RELOAD:
- method = () => {
- this.reloadCounter[this.props.location] = this.reloadCounter[this.props.location] || 0
- if (this.reloadCounter[this.props.location] < 2) {
- tabActions.reload(this.props.tabId)
- this.reloadCounter[this.props.location] = this.reloadCounter[this.props.location] + 1
- }
- }
- break
- case messages.CLEAR_BROWSING_DATA_NOW:
- method = () =>
- windowActions.setClearBrowsingDataPanelVisible(true)
- break
- case messages.AUTOFILL_SET_ADDRESS:
- method = (currentDetail) =>
- windowActions.setAutofillAddressDetail(null, null, currentDetail)
- break
- case messages.AUTOFILL_SET_CREDIT_CARD:
- method = (currentDetail) =>
- windowActions.setAutofillCreditCardDetail(null, null, currentDetail)
- break
- case messages.HIDE_CONTEXT_MENU:
- method = () => windowActions.setContextMenuDetail()
- break
- }
- method.apply(this, e.args)
- }, { passive: true })
-
- const loadStart = (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- if (e.isMainFrame && !e.isErrorPage && !e.isFrameSrcDoc) {
- if (e.url && e.url.startsWith(appConfig.noScript.twitterRedirectUrl) &&
- this.props.noScript === true) {
- // This result will be canceled immediately by sitehacks, so don't
- // update the load state; otherwise it will not show the security
- // icon.
- return
- }
- windowActions.onWebviewLoadStart(this.frame, e.url)
- }
- }
-
- const loadEnd = (savePage, url, inPageNav) => {
- if (this.frame.isEmpty()) {
- return
- }
- windowActions.onWebviewLoadEnd(this.frame, url)
- const parsedUrl = urlParse(url)
- if (!this.allowRunningWidevinePlugin()) {
- this.showWidevineNotification(() => {
- }, () => {
- appActions.loadURLRequested(this.props.tabId, this.props.provisionalLocation)
- })
- }
-
- const protocol = parsedUrl.protocol
- const isError = this.props.aboutDetailsErrorCode
- if (!this.props.isPrivate && (protocol === 'http:' || protocol === 'https:') && !isError && savePage && !inPageNav) {
- // Register the site for recent history for navigation bar
- // calling with setTimeout is an ugly hack for a race condition
- // with setTitle. We either need to delay this call until the title is
- // or add a way to update it
- setTimeout(() => {
- appActions.addHistorySite(historyUtil.getDetailFromFrame(this.frame))
- }, 250)
- }
-
- if (isPDFJSURL(url)) {
- let displayLocation = UrlUtil.getLocationIfPDF(url)
- windowActions.setSecurityState(this.props.tabId, {
- secure: urlParse(displayLocation).protocol === 'https:',
- runInsecureContent: false
- })
- }
- }
-
- const loadFail = (e, provisionLoadFailure, url) => {
- if (this.frame.isEmpty()) {
- return
- }
- if (isFrameError(e.errorCode)) {
- // temporary workaround for https://github.com/brave/browser-laptop/issues/1817
- if (e.validatedURL === aboutUrls.get('about:newtab') ||
- e.validatedURL === aboutUrls.get('about:blank') ||
- e.validatedURL === aboutUrls.get('about:certerror') ||
- e.validatedURL === aboutUrls.get('about:error') ||
- e.validatedURL === aboutUrls.get('about:safebrowsing')) {
- // this will just display a blank page for errors
- // but we don't want to take the user out of the private tab
- return
- } else if (isTargetAboutUrl(e.validatedURL)) {
- // open a new tab for other about urls
- // and send this tab back to wherever it came from
- appActions.onGoBack(this.props.tabId)
- appActions.createTabRequested({
- url: e.validatedURL,
- active: true
- })
- return
- }
-
- windowActions.setFrameError(this.frame, {
- event_type: 'did-fail-load',
- errorCode: e.errorCode,
- url: e.validatedURL
- })
- const key = historyUtil.getKey(this.frame)
- appActions.loadURLRequested(this.props.tabId, 'about:error')
- appActions.removeHistorySite(key)
- } else if (isAborted(e.errorCode)) {
- // just stay put
- } else if (provisionLoadFailure) {
- windowActions.setNavigated(url, this.props.frameKey, true, this.props.tabId)
- }
- }
- this.webview.addEventListener('security-style-changed', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- let isSecure = null
- let runInsecureContent = this.props.runInsecureContent
- let evCert = null
- if (e.securityState === 'secure') {
- isSecure = true
- } else if (e.securityState === 'insecure') {
- // Passive mixed content should not upgrade an insecure connection to a
- // partially-secure connection. It can only downgrade a secure
- // connection.
- isSecure =
- e.securityInfo.mixedContentStatus === 'content-status-displayed' && this.props.isSecure !== false
- ? 1
- : false
- } else if (e.securityState === 'broken') {
- isSecure = false
- const parsedUrl = urlParse(this.props.location)
- ipc.send(messages.CHECK_CERT_ERROR_ACCEPTED, parsedUrl.host, this.props.tabId)
- }
-
- if (e.securityInfo.securityLevel === 'ev-secure') {
- if (e.securityInfo.certificate &&
- e.securityInfo.certificate.organizationNames.length) {
- const countryName = e.securityInfo.certificate.countryName
- const organizationName = e.securityInfo.certificate.organizationNames[0]
- evCert = organizationName
- if (countryName) {
- evCert += ` [${countryName}]`
- }
- }
- }
- windowActions.setSecurityState(this.props.tabId, {
- secure: runInsecureContent ? false : isSecure,
- runInsecureContent,
- evCert
- })
- }, { passive: true })
- this.webview.addEventListener('load-start', (e) => {
- loadStart(e)
- }, { passive: true })
- this.webview.addEventListener('did-navigate', (e) => {
- if (this.props.findbarShown) {
- frameStateUtil.onFindBarHide(this.props.frameKey)
- }
-
- for (let message in this.notificationCallbacks) {
- appActions.hideNotification(message)
- }
- this.notificationCallbacks = {}
- const isNewTabPage = getBaseUrl(e.url) === getTargetAboutUrl('about:newtab')
- // Only take focus away from the urlBar if:
- // The tab is active, it's not the new tab page, and the webview isn't already active.
- if (this.props.isActive && !isNewTabPage && document.activeElement !== this.webview) {
- this.webview.focus()
- }
- if (!this.frame.isEmpty()) {
- windowActions.setNavigated(e.url, this.props.frameKey, false, this.props.tabId)
- }
- }, { passive: true })
- this.webview.addEventListener('did-fail-provisional-load', (e) => {
- if (e.isMainFrame) {
- loadEnd(false, e.validatedURL, false)
- loadFail(e, true, e.currentURL)
- }
- })
- this.webview.addEventListener('did-fail-load', (e) => {
- if (e.isMainFrame) {
- loadEnd(false, e.validatedURL, false)
- loadFail(e, false, e.validatedURL)
- }
- })
- this.webview.addEventListener('did-finish-load', (e) => {
- loadEnd(true, e.validatedURL, false)
- if (this.props.runInsecureContent) {
- appActions.removeSiteSetting(this.props.origin, 'runInsecureContent', this.props.isPrivate)
- }
- })
- this.webview.addEventListener('did-navigate-in-page', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
- if (e.isMainFrame) {
- windowActions.setNavigated(e.url, this.props.frameKey, true, this.props.tabId)
- loadEnd(true, e.url, true)
- }
- })
- this.webview.addEventListener('enter-html-full-screen', () => {
- if (this.frame.isEmpty()) {
- return
- }
- windowActions.setFullScreen(this.props.tabId, true, true)
- // disable the fullscreen warning after 5 seconds
- setTimeout(windowActions.setFullScreen.bind(this, this.props.tabId, undefined, false), 5000)
- })
- this.webview.addEventListener('leave-html-full-screen', () => {
- if (this.frame.isEmpty()) {
- return
- }
- windowActions.setFullScreen(this.props.tabId, false)
- })
- this.webview.addEventListener('did-change-theme-color', ({themeColor}) => {
- if (this.frame.isEmpty()) {
- return
- }
- // Due to a bug in Electron, after navigating to a page with a theme color
- // to a page without a theme color, the background is sent to us as black
- // even know there is no background. To work around this we just ignore
- // the theme color in that case and let the computed theme color take over.
- windowActions.setThemeColor(this.frame, themeColor !== '#000000' ? themeColor : null)
- })
- this.webview.addEventListener('found-in-page', (e) => {
- if (this.frame.isEmpty()) {
- return
- }
-
- if (e.result !== undefined && (e.result.matches !== undefined || e.result.activeMatchOrdinal !== undefined)) {
- if (e.result.matches === 0) {
- windowActions.setFindDetail(this.props.frameKey, Immutable.fromJS({
- numberOfMatches: 0,
- activeMatchOrdinal: 0
- }))
- return
- }
-
- windowActions.setFindDetail(this.props.frameKey, Immutable.fromJS({
- numberOfMatches: e.result.matches || -1,
- activeMatchOrdinal: e.result.activeMatchOrdinal || -1
- }))
- }
- })
- // Handle zoom using Ctrl/Cmd and the mouse wheel.
- this.webview.addEventListener('mousewheel', this.onMouseWheel.bind(this))
- }
-
- onFocus () {
- if (!this.frame.isEmpty()) {
- windowActions.setTabPageIndexByFrame(this.frame)
- windowActions.tabOnFocus(this.props.tabId)
- }
-
- windowActions.setContextMenuDetail()
- windowActions.setPopupWindowDetail()
- }
-
- onFindAgain (forward) {
- if (!this.props.findbarShown) {
- windowActions.setFindbarShown(this.props.frameKey, true)
- }
- const searchString = this.props.findDetailSearchString
- if (searchString) {
- webviewActions.findInPage(searchString, this.props.findDetailCaseSensitivity, forward, this.props.findDetailInternalFindStatePresent, this.webview)
- }
- }
-
- onUpdateWheelZoom () {
- if (this.wheelDeltaY > 0) {
- this.zoomIn()
- } else if (this.wheelDeltaY < 0) {
- this.zoomOut()
- }
- this.wheelDeltaY = 0
- }
-
- onMouseWheel (e) {
- if (e.ctrlKey) {
- e.preventDefault()
- this.wheelDeltaY = (this.wheelDeltaY || 0) + e.wheelDeltaY
- this.onUpdateWheelZoom()
- } else {
- this.wheelDeltaY = 0
- }
- }
-
- mergeProps (state, ownProps) {
- const currentWindow = state.get('currentWindow')
- const frame = frameStateUtil.getFrameByKey(currentWindow, ownProps.frameKey) || Immutable.Map()
- const tabId = frame.get('tabId', tabState.TAB_ID_NONE)
-
- const location = frame.get('location')
- const origin = tabState.getVisibleOrigin(state, tabId)
- const isPrivate = frame.get('isPrivate', false)
-
- const allSiteSettings = siteSettingsState.getAllSiteSettings(state, isPrivate)
- const frameSiteSettings = siteSettings.getSiteSettingsForURL(allSiteSettings, location) || Immutable.Map()
-
- const contextMenu = currentWindow.get('contextMenuDetail')
- const tab = tabId && tabId > -1 && tabState.getByTabId(state, tabId)
-
- const props = {}
- // used in renderer
- props.transitionState = ownProps.transitionState
- props.partition = frameStateUtil.getPartition(frame)
- props.isFullScreen = frame.get('isFullScreen')
- props.isPreview = frame.get('key') === currentWindow.get('previewFrameKey')
- props.isActive = frameStateUtil.isFrameKeyActive(currentWindow, frame.get('key'))
- props.showFullScreenWarning = frame.get('showFullScreenWarning')
- props.location = location
- props.isDefaultNewTabLocation = location === 'about:newtab'
- props.isBlankLocation = location === 'about:blank'
- props.tabId = tabId
- props.showMessageBox = tabMessageBoxState.hasMessageBoxDetail(state, tabId)
- props.isFocused = isFocused(state)
-
- // used in other functions
- props.frameKey = ownProps.frameKey
- props.origin = origin
- props.runInsecureContent = frameSiteSettings.get('runInsecureContent')
- props.noScript = frameSiteSettings.get('noScript')
- props.noScriptExceptions = frameSiteSettings.get('noScriptExceptions')
- props.widevine = frameSiteSettings.get('widevine')
- props.flash = frameSiteSettings.get('flash')
- props.urlBarFocused = frame && frame.getIn(['navbar', 'urlbar', 'focused'])
- props.isAutFillContextMenu = contextMenu && contextMenu.get('type') === 'autofill'
- props.isSecure = frame.getIn(['security', 'isSecure'])
- props.findbarShown = frame.get('findbarShown')
- props.findDetailCaseSensitivity = frame.getIn(['findDetail', 'caseSensitivity'], undefined)
- props.findDetailSearchString = frame.getIn(['findDetail', 'searchString'])
- props.findDetailInternalFindStatePresent = frame.getIn(['findDetail', 'internalFindStatePresent'])
- props.isPrivate = frame.get('isPrivate')
- props.activeShortcut = frame.get('activeShortcut')
- props.shortcutDetailsUsername = frame.getIn(['activeShortcutDetails', 'username'])
- props.shortcutDetailsPassword = frame.getIn(['activeShortcutDetails', 'password'])
- props.shortcutDetailsOrigin = frame.getIn(['activeShortcutDetails', 'origin'])
- props.shortcutDetailsAction = frame.getIn(['activeShortcutDetails', 'action'])
- props.provisionalLocation = frame.get('provisionalLocation')
- props.src = frame.get('src')
- props.guestInstanceId = frame.get('guestInstanceId')
- props.aboutDetailsUrl = frame.getIn(['aboutDetails', 'url'])
- props.aboutDetailsFrameKey = frame.getIn(['aboutDetails', 'frameKey'])
- props.aboutDetailsErrorCode = frame.getIn(['aboutDetails', 'errorCode'])
- props.unloaded = frame.get('unloaded')
- props.isWidevineEnabled = state.get('widevine') && state.getIn(['widevine', 'enabled'])
- props.siteZoomLevel = frameSiteSettings.get('zoomLevel')
- props.hasAllSiteSettings = !!allSiteSettings
- props.tabUrl = tab && tab.get('url')
- props.partitionNumber = frame.get('partitionNumber')
-
- return props
- }
-
- getTransitionStateClassName (stateName) {
- // handle missing data
- if (!stateName) {
- return null
- }
- // convert Transition element state string to a more consistent css classname
- return `is${stateName[0].toUpperCase()}${stateName.slice(1)}`
- }
-
- render () {
- const transitionClassName = this.getTransitionStateClassName(this.props.transitionState)
- return
- {
- this.props.isFullScreen && this.props.showFullScreenWarning
- ?
- : null
- }
-
{ this.webviewContainer = node }}
- className={cx({
- webviewContainer: true,
- isPreview: this.props.isPreview
- })} />
-
- {
- this.props.showMessageBox
- ?
- : null
- }
-
- }
-}
-
-module.exports = ReduxComponent.connect(Frame)
diff --git a/app/renderer/components/frame/fullScreenWarning.js b/app/renderer/components/frame/fullScreenWarning.js
index 77b03d66ecb..9de25db2f62 100644
--- a/app/renderer/components/frame/fullScreenWarning.js
+++ b/app/renderer/components/frame/fullScreenWarning.js
@@ -29,7 +29,8 @@ const styles = StyleSheet.create({
marginRight: 'auto',
padding: '20px',
position: 'absolute',
- textAlign: 'center'
+ textAlign: 'center',
+ zIndex: 30
}
})
diff --git a/app/renderer/components/frame/guestInstanceRenderer.js b/app/renderer/components/frame/guestInstanceRenderer.js
new file mode 100644
index 00000000000..f937743c9b2
--- /dev/null
+++ b/app/renderer/components/frame/guestInstanceRenderer.js
@@ -0,0 +1,215 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const React = require('react')
+const {StyleSheet, css} = require('aphrodite/no-important')
+
+// Components
+const ReduxComponent = require('../reduxComponent')
+// comment out to not use pooled webview (2x webviews):
+const WebviewDisplay = require('../../pooledWebviewDisplay')
+// uncomment in to use 1x webview (for debugging):
+// const WebviewDisplay = require('../../webviewDisplay')
+
+// Actions
+const windowActions = require('../../../../js/actions/windowActions')
+const webviewActions = require('../../../../js/actions/webviewActions')
+const tabActions = require('../../../common/actions/tabActions')
+
+// state
+const frameStateUtil = require('../../../../js/state/frameStateUtil')
+
+// constants
+const settings = require('../../../../js/constants/settings')
+
+// utils
+const {getCurrentWindowId, isFocused} = require('../../currentWindow')
+const {getSetting} = require('../../../../js/settings')
+
+class GuestInstanceRenderer extends React.Component {
+ constructor (props) {
+ super(props)
+ this.setWebviewRef = this.setWebviewRef.bind(this)
+ }
+
+ mergeProps (state, ownProps) {
+ const frameKey = ownProps.frameKey
+ const frame = frameStateUtil.getFrameByKey(state.get('currentWindow'), frameKey)
+ const location = frame && frame.get('location')
+ const frameIsInWindow = frame && frame.get('tabStripWindowId') === getCurrentWindowId()
+
+ const props = {
+ displayDebugInfo: getSetting(settings.DEBUG_VERBOSE_TAB_INFO),
+ debugTabEvents: state.getIn(['currentWindow', 'debugTabEvents']),
+ activeFrameKey: state.getIn(['currentWindow', 'activeFrameKey']),
+ guestInstanceId: frame && frame.get('guestInstanceId'),
+ tabId: frame && frame.get('tabId'),
+ isDefaultNewTabLocation: location === 'about:newtab',
+ isBlankLocation: location === 'about:blank',
+ isPlaceholder: frame && frame.get('isPlaceholder'),
+ windowIsFocused: isFocused(state),
+ frameKey,
+ frameIsInWindow,
+ frameLocation: frame && frame.get('location'),
+ urlBarFocused: frame && frame.getIn(['navbar', 'urlbar', 'focused'])
+ }
+ return props
+ }
+
+ componentDidMount () {
+ this.onPropsChanged()
+ }
+
+ componentDidUpdate (prevProps, prevState) {
+ this.onPropsChanged(prevProps)
+ }
+
+ debugLog (...messages) {
+ if (this.props.debugTabEvents) {
+ console.log(...messages)
+ }
+ }
+
+ getReadyToAttachTabId (props = {}) {
+ return props.frameIsInWindow && props.tabId
+ }
+
+ onPropsChanged (prevProps = {}) {
+ // attach new guest instance
+ this.webviewDisplay.shouldLogEvents = this.props.debugTabEvents
+ const toAttachTabId = this.getReadyToAttachTabId(this.props)
+ const lastAttachTabId = this.getReadyToAttachTabId(prevProps)
+ if (this.webviewDisplay && toAttachTabId && lastAttachTabId !== toAttachTabId) {
+ this.debugLog('guestInstanceRenderer, attach tab', toAttachTabId, 'guest', this.props.guestInstanceId, this.props.isPlaceholder)
+ if (!this.props.isPlaceholder) {
+ this.webviewDisplay.attachActiveTab(this.props.tabId)
+ } else if (this.props.debugTabEvents) {
+ this.debugLog('placeholder, not showing')
+ }
+ }
+ this.webviewDisplay.debugTabEvents = this.props.debugTabEvents
+ // update state of which frame is currently being viewed
+ if (this.props.tabId !== prevProps.tabId && this.props.windowIsFocused) {
+ windowActions.setFocusedFrame(this.props.frameLocation, this.props.tabId)
+ }
+ if (this.props.tabId !== prevProps.tabId && !this.props.urlBarFocused) {
+ webviewActions.setWebviewFocused()
+ }
+ }
+
+ setWebviewRef (containerElement) {
+ // first time, create the webview
+ if (containerElement && !this.webviewDisplay) {
+ this.webviewDisplay = new WebviewDisplay({
+ containerElement,
+ classNameWebview: css(styles.guestInstanceRenderer__webview),
+ classNameWebviewAttached: css(styles.guestInstanceRenderer__webview_attached),
+ classNameWebviewAttaching: css(styles.guestInstanceRenderer__webview_attaching),
+ onZoomChange: this.onUpdateZoom.bind(this),
+ onFocus: this.onFocus.bind(this)
+ })
+ webviewActions.init(this.webviewDisplay)
+ // treat the container as main frame position for mouse position
+ containerElement.addEventListener('mouseenter', (e) => {
+ windowActions.onFrameMouseEnter()
+ }, { passive: true })
+ containerElement.addEventListener('mouseleave', (e) => {
+ windowActions.onFrameMouseLeave()
+ }, { passive: true })
+ }
+ }
+
+ onFocus () {
+ if (this.props.tabId !== null) {
+ windowActions.setTabPageIndexByFrame(this.props.tabId)
+ windowActions.tabOnFocus(this.props.tabId)
+ }
+ }
+
+ onUpdateZoom (zoomPercent) {
+ // TODO: better to respond to a muon Tab event `zoom-changed` via ZoomObserver
+ // if that is provided in the future
+ tabActions.zoomChanged(this.props.tabId, zoomPercent)
+ }
+
+ render () {
+ const debugInfo = this.props.displayDebugInfo
+ ? `WindowId: ${getCurrentWindowId()}, TabId: ${this.props.tabId}, GuestId: ${this.props.guestInstanceId}, FrameKey: ${this.props.frameKey}, guestIsReady: ${this.props.guestIsReady}, frameIsInWindow: ${this.props.frameIsInWindow}, activeFrameKey: ${this.props.activeFrameKey}, windowIsFocused: ${this.props.windowIsFocused}`
+ : null
+ return (
+
+ )
+ }
+}
+
+const styles = StyleSheet.create({
+ guestInstanceRenderer: {
+ display: 'flex',
+ flex: 1,
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ bottom: 0,
+ right: 0,
+ // default frame background
+ // TODO: use theme.frame.defaultBackground
+ '--frame-bg': '#fff'
+ },
+
+ guestInstanceRenderer_isDefaultNewTabLocation: {
+ // matches tab dashboard background
+ // will also show when about:newtab === about:blank or is Private Tab
+ // TODO: use theme.frame.newTabBackground
+ '--frame-bg': '#222'
+ },
+
+ guestInstanceRenderer_isBlankLocation: {
+ },
+
+ guestInstanceRenderer_visualDebug: {
+ ':after': {
+ zIndex: '20',
+ content: 'attr(data-debuginfo)',
+ position: 'absolute',
+ padding: '5px',
+ background: '#111',
+ color: 'white',
+ fontSize: '12px',
+ border: '1px dashed white'
+ }
+ },
+
+ guestInstanceRenderer__webview: {
+ flex: 1,
+ position: 'absolute',
+ top: 0,
+ left: 0,
+ bottom: 0,
+ right: 0,
+ zIndex: 10,
+ backgroundColor: 'var(--frame-bg)',
+ border: 0,
+ outline: 'none'
+ },
+
+ guestInstanceRenderer__webview_attached: {
+ zIndex: 20
+ },
+
+ guestInstanceRenderer__webview_attaching: {
+ // only show the active webview when it is attached, reducing white flash
+ zIndex: 15
+ }
+})
+
+module.exports = ReduxComponent.connect(GuestInstanceRenderer)
diff --git a/app/renderer/components/main/braveryPanel.js b/app/renderer/components/main/braveryPanel.js
index 735868526c7..e8630c47eba 100644
--- a/app/renderer/components/main/braveryPanel.js
+++ b/app/renderer/components/main/braveryPanel.js
@@ -9,7 +9,6 @@ const {StyleSheet, css} = require('aphrodite/no-important')
// Components
const ReduxComponent = require('../reduxComponent')
const Dialog = require('../common/dialog')
-const FlyoutDialog = require('../common/flyoutDialog')
const BrowserButton = require('../common/browserButton')
const SwitchControl = require('../common/switchControl')
const {FormDropdown} = require('../common/dropdown')
@@ -38,6 +37,7 @@ const urlUtil = require('../../../../js/lib/urlutil')
// Styles
const globalStyles = require('../styles/global')
+const commonStyles = require('../styles/commonStyles')
const closeButton = require('../../../../img/toolbar/braveryPanel_btn.svg')
class BraveryPanel extends React.Component {
@@ -249,13 +249,13 @@ class BraveryPanel extends React.Component {
})
return
- e.stopPropagation()}
- testId={this.props.isCompactBraveryPanel ? 'braveryPanelCompact' : 'braveryPanel'}
- >
+ data-test-id={this.props.isCompactBraveryPanel ? 'braveryPanelCompact' : 'braveryPanel'}>
{
this.props.isCompactBraveryPanel
? this.compactBraveryPanelHeader
@@ -649,7 +649,7 @@ class BraveryPanel extends React.Component {
-
+
}
}
diff --git a/app/renderer/components/main/checkDefaultBrowserDialog.js b/app/renderer/components/main/checkDefaultBrowserDialog.js
index 11e7107b61e..f03d90a69d8 100644
--- a/app/renderer/components/main/checkDefaultBrowserDialog.js
+++ b/app/renderer/components/main/checkDefaultBrowserDialog.js
@@ -11,8 +11,9 @@ const Dialog = require('../common/dialog')
const BrowserButton = require('../common/browserButton')
const SwitchControl = require('../common/switchControl')
const {
- CommonForm,
- CommonFormSection
+ CommonFormMedium,
+ CommonFormSection,
+ CommonFormButtonWrapper
} = require('../common/commonForm')
// Actions
@@ -77,7 +78,7 @@ class CheckDefaultBrowserDialog extends React.Component {
render () {
return
-
+
@@ -92,7 +93,7 @@ class CheckDefaultBrowserDialog extends React.Component {
-
+
-
-
+
+
}
}
+module.exports = ReduxComponent.connect(CheckDefaultBrowserDialog)
+
const styles = StyleSheet.create({
flexAlignCenter: {
display: 'flex',
@@ -131,5 +134,3 @@ const styles = StyleSheet.create({
marginTop: `calc(${globalStyles.spacing.dialogInsideMargin} / 2)`
}
})
-
-module.exports = ReduxComponent.connect(CheckDefaultBrowserDialog)
diff --git a/app/renderer/components/main/clearBrowsingDataPanel.js b/app/renderer/components/main/clearBrowsingDataPanel.js
index 6c8d544a6ed..51ea40a9ad7 100644
--- a/app/renderer/components/main/clearBrowsingDataPanel.js
+++ b/app/renderer/components/main/clearBrowsingDataPanel.js
@@ -4,7 +4,7 @@
const React = require('react')
const Immutable = require('immutable')
-const ipc = require('electron').ipcRenderer
+const {StyleSheet, css} = require('aphrodite/no-important')
// Components
const ReduxComponent = require('../reduxComponent')
@@ -12,16 +12,23 @@ const Dialog = require('../common/dialog')
const Button = require('../common/button')
const SwitchControl = require('../common/switchControl')
const {
- CommonForm,
- CommonFormSection
+ CommonFormSmall,
+ CommonFormSection,
+ CommonFormTitle,
+ CommonFormButtonWrapper,
+ CommonFormBottomWrapper
} = require('../common/commonForm')
// Actions
const appActions = require('../../../../js/actions/appActions')
const windowActions = require('../../../../js/actions/windowActions')
+const aboutActions = require('../../../../js/about/aboutActions')
+
+// State
+const ledgerState = require('../../../common/state/ledgerState')
// Constants
-const messages = require('../../../../js/constants/messages')
+const ledgerStatuses = require('../../../common/constants/ledgerStatuses')
class ClearBrowsingDataPanel extends React.Component {
constructor (props) {
@@ -34,6 +41,8 @@ class ClearBrowsingDataPanel extends React.Component {
this.onToggleAutocompleteData = this.onToggleSetting.bind(this, 'autocompleteData')
this.onToggleAutofillData = this.onToggleSetting.bind(this, 'autofillData')
this.onToggleSavedSiteSettings = this.onToggleSetting.bind(this, 'savedSiteSettings')
+ this.onTogglePublishersClear = this.onToggleSetting.bind(this, 'publishersClear')
+ this.onTogglePaymentHistory = this.onToggleSetting.bind(this, 'paymentHistory')
this.onClear = this.onClear.bind(this)
this.onCancel = this.onCancel.bind(this)
}
@@ -51,7 +60,7 @@ class ClearBrowsingDataPanel extends React.Component {
this.props.browserHistory &&
this.props.cachedImagesAndFiles
) {
- ipc.send(messages.PREFS_RESTART)
+ aboutActions.requireRestart()
}
}
@@ -69,6 +78,7 @@ class ClearBrowsingDataPanel extends React.Component {
const data = state.get('clearBrowsingDataDefaults', Immutable.Map()).merge(tempData)
const props = {}
+ props.inProgress = ledgerState.getAboutProp(state, 'status') === ledgerStatuses.IN_PROGRESS
props.allSiteCookies = data.get('allSiteCookies')
props.browserHistory = data.get('browserHistory')
props.downloadHistory = data.get('downloadHistory')
@@ -78,14 +88,16 @@ class ClearBrowsingDataPanel extends React.Component {
props.autocompleteData = data.get('autocompleteData')
props.autofillData = data.get('autofillData')
props.savedSiteSettings = data.get('savedSiteSettings')
+ props.publishersClear = props.inProgress ? false : data.get('publishersClear')
+ props.paymentHistory = props.inProgress ? false : data.get('paymentHistory')
return props
}
render () {
return
- e.stopPropagation()}>
-
+ e.stopPropagation()}>
+
+
+
+ {
+ this.props.inProgress
+ ?
+ : null
+ }
-
+
-
-
+
+
-
-
+
+
}
}
+const styles = StyleSheet.create({
+ footNote: {
+ marginTop: '12px',
+ fontSize: '12px',
+ display: 'block'
+ }
+})
+
module.exports = ReduxComponent.connect(ClearBrowsingDataPanel)
diff --git a/app/renderer/components/main/findbar.js b/app/renderer/components/main/findbar.js
index 5bec63d2b4e..31dcf0cd05a 100644
--- a/app/renderer/components/main/findbar.js
+++ b/app/renderer/components/main/findbar.js
@@ -17,7 +17,7 @@ const settings = require('../../../../js/constants/settings')
// Actions
const windowActions = require('../../../../js/actions/windowActions')
-const webviewActions = require('../../../../js/actions/webviewActions')
+const tabActions = require('../../../common/actions/tabActions')
// Utils
const contextMenus = require('../../../../js/contextMenus')
@@ -167,11 +167,11 @@ class FindBar extends React.Component {
}
onFindHide () {
- frameStateUtil.onFindBarHide(this.props.activeFrameKey)
+ frameStateUtil.onFindBarHide(this.props.activeFrameKey, this.props.activeTabId)
}
onFind (searchString, caseSensitivity, forward, findNext) {
- webviewActions.findInPage(searchString, caseSensitivity, forward, findNext)
+ tabActions.findInPageRequest(this.props.activeTabId, this.props.searchString, caseSensitivity, forward, findNext)
if (!findNext) {
windowActions.setFindDetail(this.props.activeFrameKey, Immutable.fromJS({
internalFindStatePresent: true
@@ -224,6 +224,7 @@ class FindBar extends React.Component {
// used in other functions
props.activeFrameKey = activeFrameKey
+ props.activeTabId = activeFrame.get('tabId')
props.isSelected = activeFrame.get('findbarSelected', false)
props.internalFindStatePresent = activeFrame.getIn(['findDetail', 'internalFindStatePresent'])
props.isPrivate = activeFrame.get('isPrivate', false)
diff --git a/app/renderer/components/main/importBrowserDataPanel.js b/app/renderer/components/main/importBrowserDataPanel.js
index d81ffec9f46..4d3da2aa094 100644
--- a/app/renderer/components/main/importBrowserDataPanel.js
+++ b/app/renderer/components/main/importBrowserDataPanel.js
@@ -14,7 +14,10 @@ const SwitchControl = require('../common/switchControl')
const {
CommonForm,
CommonFormDropdown,
- CommonFormSection
+ CommonFormSection,
+ CommonFormTitle,
+ CommonFormButtonWrapper,
+ CommonFormBottomWrapper
} = require('../common/commonForm')
// Actions
@@ -98,12 +101,12 @@ class ImportBrowserDataPanel extends React.Component {
render () {
return
- e.stopPropagation()}>
- e.stopPropagation()}>
+
-
+
-
+
-
-
+
+
-
+
}
}
+module.exports = ReduxComponent.connect(ImportBrowserDataPanel)
+
const styles = StyleSheet.create({
dropdownWrapper: {
marginBottom: `calc(${globalStyles.spacing.dialogInsideMargin} / 2)`
}
})
-
-module.exports = ReduxComponent.connect(ImportBrowserDataPanel)
diff --git a/app/renderer/components/main/loginRequired.js b/app/renderer/components/main/loginRequired.js
index 213e5022cbc..67271b7419d 100644
--- a/app/renderer/components/main/loginRequired.js
+++ b/app/renderer/components/main/loginRequired.js
@@ -11,7 +11,9 @@ const Button = require('../common/button')
const {
CommonForm,
CommonFormSection,
+ CommonFormTitle,
CommonFormTextbox,
+ CommonFormButtonWrapper,
commonFormStyles
} = require('../common/commonForm')
@@ -93,10 +95,8 @@ class LoginRequired extends React.Component {
}
return
-
-
-
-
+
+
{
+ commonFormStyles.inputWrapper,
+ commonFormStyles.inputWrapper__input
+ )}>
-
+
-
+
}
}
+module.exports = LoginRequired
+
const styles = StyleSheet.create({
sectionWrapper: {
display: 'flex',
justifyContent: 'space-between'
}
})
-
-module.exports = LoginRequired
diff --git a/app/renderer/components/main/main.js b/app/renderer/components/main/main.js
index 8dd21193cb1..326b07fd095 100644
--- a/app/renderer/components/main/main.js
+++ b/app/renderer/components/main/main.js
@@ -17,9 +17,8 @@ const contextMenus = require('../../../../js/contextMenus')
const {getSetting} = require('../../../../js/settings')
// Components
-const { Transition, TransitionGroup } = require('react-transition-group')
const Navigator = require('../navigation/navigator')
-const Frame = require('../frame/frame')
+const GuestInstanceRenderer = require('../frame/guestInstanceRenderer')
const TabPages = require('../tabs/tabPages')
const TabsToolbar = require('../tabs/tabsToolbar')
const FindBar = require('./findbar')
@@ -42,6 +41,9 @@ const ContextMenu = require('../common/contextMenu/contextMenu')
const PopupWindow = require('./popupWindow')
const NoScriptInfo = require('./noScriptInfo')
const CheckDefaultBrowserDialog = require('./checkDefaultBrowserDialog')
+const HrefPreview = require('../frame/hrefPreview')
+const MessageBox = require('../common/messageBox')
+const FullScreenWarning = require('../frame/fullScreenWarning')
// Constants
const appConfig = require('../../../../js/constants/appConfig')
@@ -60,6 +62,7 @@ const menuBarState = require('../../../common/state/menuBarState')
const windowState = require('../../../common/state/windowState')
const updateState = require('../../../common/state/updateState')
const tabState = require('../../../common/state/tabState')
+const tabMessageBoxState = require('../../../common/state/tabMessageBoxState')
// Util
const _ = require('underscore')
@@ -206,7 +209,7 @@ class Main extends React.Component {
exitFullScreen () {
if (this.props.isFullScreen) {
- windowActions.setFullScreen(this.props.tabId, false)
+ appActions.tabSetFullScreen(this.props.tabId, false)
}
}
@@ -343,7 +346,7 @@ class Main extends React.Component {
// If the tab changes or was closed, exit out of full screen to give a better
// picture of what's happening.
if (prevProps.tabId !== this.props.tabId && this.props.isFullScreen) {
- windowActions.setFullScreen(this.props.tabId, false)
+ appActions.tabSetFullScreen(this.props.tabId, false)
}
}
@@ -421,10 +424,6 @@ class Main extends React.Component {
windowActions.setRedirectedBy(details.tabId, ruleset, details.url)
})
- ipc.on(messages.CERT_ERROR, (e, details) => {
- windowActions.onCertError(details.tabId, details.url, details.error)
- })
-
ipc.on(messages.SET_SECURITY_STATE, (e, tabId, securityState) => {
windowActions.setSecurityState(tabId, securityState)
})
@@ -543,7 +542,13 @@ class Main extends React.Component {
const props = {}
// used in renderer
+ props.activeFrameKey = activeFrame.get('key')
+ if (window.activeFrameKey !== props.activeFrameKey) {
+ window.activeFrameKey = props.activeFrameKey
+ }
+ props.previewFrameKey = frameStateUtil.getPreviewFrameKey(currentWindow)
props.isFullScreen = activeFrame.get('isFullScreen', false)
+ props.showFullScreenWarning = activeFrame.get('showFullScreenWarning')
props.isMaximized = isMaximized(state) || isFullScreen(state)
props.captionButtonsVisible = isWindows
props.showContextMenu = currentWindow.has('contextMenuDetail')
@@ -573,7 +578,6 @@ class Main extends React.Component {
props.showNotificationBar = activeOrigin && state.get('notifications').filter((item) =>
item.get('frameOrigin') ? activeOrigin === item.get('frameOrigin') : true).size > 0
props.showFindBar = activeFrame.get('findbarShown') && !activeFrame.get('isFullScreen')
- props.sortedFrames = frameStateUtil.getSortedFrameKeys(currentWindow)
props.showDownloadBar = currentWindow.getIn(['ui', 'downloadsToolbar', 'isVisible']) &&
state.get('downloads') && state.get('downloads').size > 0
props.title = activeFrame.get('title')
@@ -581,6 +585,7 @@ class Main extends React.Component {
props.loginRequiredUrl = loginRequiredDetails
? urlResolve(loginRequiredDetails.getIn(['request', 'url']), '/')
: null
+ props.showMessageBox = tabMessageBoxState.hasMessageBoxDetail(state, activeTabId)
// used in other functions
props.menubarSelectedIndex = currentWindow.getIn(['ui', 'menubar', 'selectedIndex'])
@@ -735,28 +740,23 @@ class Main extends React.Component {
: null
}
-
-
- {
- this.props.sortedFrames.map((frameKey) =>
- component actually being removed
- timeout={150}>
- {
- (transitionState) =>
-
- }
-
- )
- }
-
+
+ {
+ this.props.isFullScreen && this.props.showFullScreenWarning
+ ?
+ : null
+ }
+
+
+ {
+ this.props.showMessageBox
+ ?
+ : null
+ }
{
this.props.showDownloadBar
diff --git a/app/renderer/components/main/releaseNotes.js b/app/renderer/components/main/releaseNotes.js
index 5501197857b..a5b3cab74f9 100644
--- a/app/renderer/components/main/releaseNotes.js
+++ b/app/renderer/components/main/releaseNotes.js
@@ -9,11 +9,13 @@ const Immutable = require('immutable')
// Components
const ReduxComponent = require('../reduxComponent')
const Dialog = require('../common/dialog')
-const FlyoutDialog = require('../common/flyoutDialog')
// Actions
const windowActions = require('../../../../js/actions/windowActions')
+// Styles
+const commonStyles = require('../styles/commonStyles')
+
class ReleaseNotes extends React.Component {
constructor (props) {
super(props)
@@ -39,15 +41,22 @@ class ReleaseNotes extends React.Component {
}
render () {
+ const className = css(
+ commonStyles.flyoutDialog,
+ styles.releaseNotes
+ )
+
return
-
+
{this.props.name}
{this.props.notes}
-
+
}
}
+module.exports = ReduxComponent.connect(ReleaseNotes)
+
const styles = StyleSheet.create({
releaseNotes: {
width: 'auto',
@@ -60,5 +69,3 @@ const styles = StyleSheet.create({
marginBottom: '10px'
}
})
-
-module.exports = ReduxComponent.connect(ReleaseNotes)
diff --git a/app/renderer/components/main/siteInfo.js b/app/renderer/components/main/siteInfo.js
index 425f1458394..5fe9ac28acb 100644
--- a/app/renderer/components/main/siteInfo.js
+++ b/app/renderer/components/main/siteInfo.js
@@ -9,7 +9,6 @@ const {StyleSheet, css} = require('aphrodite/no-important')
// Components
const ReduxComponent = require('../reduxComponent')
const Dialog = require('../common/dialog')
-const FlyoutDialog = require('../common/flyoutDialog')
const Button = require('../common/button')
// Actions
@@ -29,6 +28,7 @@ const urlUtil = require('../../../../js/lib/urlutil')
// Styles
const globalStyles = require('../styles/global')
+const commonStyles = require('../styles/commonStyles')
class SiteInfo extends React.Component {
constructor (props) {
@@ -242,11 +242,12 @@ class SiteInfo extends React.Component {
render () {
return
- e.stopPropagation()}
- custom={[
+ e.stopPropagation()}
+ className={css(
+ commonStyles.flyoutDialog,
styles.siteInfo,
(this.props.isBlockedRunInsecureContent || this.props.runInsecureContent) && styles.siteInfo_large
- ]}>
+ )}>
{
this.secureIcon
}
@@ -256,7 +257,7 @@ class SiteInfo extends React.Component {
{
this.connectionInfo
}
-
+
}
}
diff --git a/app/renderer/components/main/widevinePanel.js b/app/renderer/components/main/widevinePanel.js
index 9ad533ab522..f398237f894 100644
--- a/app/renderer/components/main/widevinePanel.js
+++ b/app/renderer/components/main/widevinePanel.js
@@ -13,8 +13,11 @@ const Button = require('../common/button')
const WidevineInfo = require('./widevineInfo')
const SwitchControl = require('../common/switchControl')
const {
- CommonForm,
- CommonFormSection
+ CommonFormLarge,
+ CommonFormTitle,
+ CommonFormSection,
+ CommonFormButtonWrapper,
+ CommonFormBottomWrapper
} = require('../common/commonForm')
// Constants
@@ -76,12 +79,12 @@ class WidevinePanel extends React.Component {
to be installed on the computer.
*/
return
- e.stopPropagation()}>
-
+ e.stopPropagation()}>
+
-
+
-
-
+
+
{/* TODO: refactor switchControl.js to remove commonStyles.noPadding */}
-
-
+
+
}
}
+module.exports = ReduxComponent.connect(WidevinePanel)
+
const styles = StyleSheet.create({
flexJustifyCenter: {
display: 'flex',
justifyContent: 'center'
}
})
-
-module.exports = ReduxComponent.connect(WidevinePanel)
diff --git a/app/renderer/components/navigation/navigator.js b/app/renderer/components/navigation/navigator.js
index c10c0e41f5a..bdb43469aba 100644
--- a/app/renderer/components/navigation/navigator.js
+++ b/app/renderer/components/navigation/navigator.js
@@ -106,7 +106,7 @@ class Navigator extends React.Component {
const activeTabId = activeFrame.get('tabId', tabState.TAB_ID_NONE)
const activeTab = tabState.getByTabId(state, activeTabId) || Immutable.Map()
const activeTabShowingMessageBox = !!(!activeTab.isEmpty() && tabState.isShowingMessageBox(state, activeTabId))
- const allSiteSettings = siteSettingsState.getAllSiteSettings(state, activeFrame)
+ const allSiteSettings = siteSettingsState.getAllSiteSettings(state, activeFrame.get('isPrivate'))
const activeSiteSettings = siteSettings.getSiteSettingsForURL(allSiteSettings, activeFrame.get('location'))
const braverySettings = siteSettings.activeSettings(activeSiteSettings, state, appConfig)
const enabledExtensions = extensionState.getEnabledExtensions(state)
diff --git a/app/renderer/components/navigation/publisherToggle.js b/app/renderer/components/navigation/publisherToggle.js
index 71f86461339..caf82308b14 100644
--- a/app/renderer/components/navigation/publisherToggle.js
+++ b/app/renderer/components/navigation/publisherToggle.js
@@ -14,10 +14,11 @@ const BrowserButton = require('../common/browserButton')
const appActions = require('../../../../js/actions/appActions')
// State
+const tabState = require('../../../common/state/tabState')
const ledgerState = require('../../../common/state/ledgerState')
// Utils
-const {getHostPattern} = require('../../../../js/lib/urlutil')
+const {getHostPattern, getUrlFromPDFUrl} = require('../../../../js/lib/urlutil')
const {getBaseUrl} = require('../../../../js/lib/appUrlUtil')
const frameStateUtil = require('../../../../js/state/frameStateUtil')
const ledgerUtil = require('../../../common/lib/ledgerUtil')
@@ -32,6 +33,7 @@ const fundUnverifiedPublisherImage = require('../../../extensions/brave/img/urlb
class PublisherToggle extends React.Component {
constructor (props) {
super(props)
+ this.mounted = false
this.onAuthorizePublisher = this.onAuthorizePublisher.bind(this)
}
@@ -51,18 +53,71 @@ class PublisherToggle extends React.Component {
onAuthorizePublisher () {
if (this.props.isVisibleInLedger) {
appActions.changeSiteSetting(this.props.hostPattern, 'ledgerPayments', !this.props.isEnabledForPaymentsPublisher)
+ } else {
+ appActions.addPublisherToLedger(this.props.location, this.props.tabId)
+ appActions.changeSiteSetting(this.props.hostPattern, 'ledgerPayments', true)
+ }
+ }
+
+ setUpdateTimeout () {
+ const shouldSetTimeout = ledgerUtil.hasRequiredVisits(this.props.state, this.props.publisherKey)
+ const updateWait = ledgerUtil.getRemainingRequiredTime(this.props.state, this.props.publisherKey)
+ if (!this.mounted || !shouldSetTimeout) {
+ return
+ }
+ let updateTimeout = setTimeout(() => {
+ appActions.onPublisherToggleUpdate(this.props.viewData)
+ }, updateWait)
+ this.setState({updateTimeout: updateTimeout})
+ }
+
+ clearUpdateTimeout () {
+ this.state && clearTimeout(this.state.updateTimeout)
+ }
+
+ componentDidMount () {
+ this.mounted = true
+ if (!this.props.isVisibleInLedger) {
+ this.setUpdateTimeout()
+ }
+ }
+
+ componentWillUnmount () {
+ this.mounted = false
+ this.clearUpdateTimeout()
+ }
+
+ componentWillReceiveProps (newProps) {
+ if (!this.mounted) {
+ return
+ }
+ if (
+ !newProps.isVisibleInLedger &&
+ (
+ newProps.location !== this.props.location ||
+ newProps.publisherKey !== this.props.publisherKey
+ )
+ ) {
+ this.clearUpdateTimeout()
+ this.setUpdateTimeout()
}
}
mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')
const activeFrame = frameStateUtil.getActiveFrame(currentWindow) || Immutable.Map()
- const location = activeFrame.get('location', '')
+ const tabId = activeFrame.get('tabId', tabState.TAB_ID_NONE)
+ const location = getUrlFromPDFUrl(activeFrame.get('location', ''))
const locationId = getBaseUrl(location)
- const publisherKey = ledgerState.getLocationProp(state, locationId, 'publisher')
+ const publisherKey = ledgerState.getVerifiedPublisherLocation(state, locationId)
const props = {}
// used in renderer
+ props.state = state
+ props.tabId = tabId
+ props.location = location
+ props.publisherKey = publisherKey
+ props.viewData = {location, tabId}
props.isVisibleInLedger = ledgerUtil.visibleP(state, publisherKey)
props.isEnabledForPaymentsPublisher = ledgerUtil.stickyP(state, publisherKey)
props.isVerifiedPublisher = ledgerState.getPublisherOption(state, publisherKey, 'verified')
diff --git a/app/renderer/components/navigation/urlBar.js b/app/renderer/components/navigation/urlBar.js
index 014cb93f492..184da164186 100644
--- a/app/renderer/components/navigation/urlBar.js
+++ b/app/renderer/components/navigation/urlBar.js
@@ -213,6 +213,10 @@ class UrlBar extends React.Component {
}
}
+ onUrlBarIconContainerClick () {
+ windowActions.setSiteInfoVisible(true)
+ }
+
onBlur (e) {
windowActions.urlBarOnBlur(getCurrentWindowId(), e.target.value, this.props.urlbarLocation, eventElHasAncestorWithClasses(e, ['urlBarSuggestions', 'urlbarForm']))
}
@@ -489,7 +493,7 @@ class UrlBar extends React.Component {
}
get showEvCert () {
- if (this.props.titleMode) {
+ if (this.props.titleMode || this.props.isActive) {
return null
}
return
{this.props.evCert}
@@ -497,13 +501,13 @@ class UrlBar extends React.Component {
render () {
const urlbarIconContainer = this.props.evCert
- ? (
+ ? (
{this.showEvCert}
)
- : (
+ : (
diff --git a/app/renderer/components/preferences/payment/addFundsDialog/addFundsDialogFooter.js b/app/renderer/components/preferences/payment/addFundsDialog/addFundsDialogFooter.js
index 952c7a2cdff..44095d28c45 100644
--- a/app/renderer/components/preferences/payment/addFundsDialog/addFundsDialogFooter.js
+++ b/app/renderer/components/preferences/payment/addFundsDialog/addFundsDialogFooter.js
@@ -37,6 +37,7 @@ class AddFundsDialogFooter extends React.Component {
break
case 'addFundsWizardAddress':
appActions.onChangeAddFundsDialogStep('addFundsWizardMain')
+ this.props.onNavigate()
break
default:
break
@@ -59,6 +60,7 @@ class AddFundsDialogFooter extends React.Component {
// and remove the current
// appActions.onChangeAddFundsDialogStep('batContribMatching')
appActions.onChangeAddFundsDialogStep('addFundsWizardMain')
+ this.props.onNavigate()
break
}
}
diff --git a/app/renderer/components/preferences/payment/advancedSettings.js b/app/renderer/components/preferences/payment/advancedSettings.js
index dad7d591f88..d69d5c7ac22 100644
--- a/app/renderer/components/preferences/payment/advancedSettings.js
+++ b/app/renderer/components/preferences/payment/advancedSettings.js
@@ -5,23 +5,27 @@
const React = require('react')
const {StyleSheet, css} = require('aphrodite/no-important')
-// util
-const {changeSetting} = require('../../../lib/settingsUtil')
-const appConfig = require('../../../../../js/constants/appConfig')
-
-// components
+// Components
const BrowserButton = require('../../common/browserButton')
const {SettingsList, SettingItem, SettingCheckbox} = require('../../common/settings')
const {SettingDropdown} = require('../../common/dropdown')
const ImmutableComponent = require('../../immutableComponent')
-// style
-const commonStyles = require('../../styles/commonStyles')
-const globalStyles = require('../../styles/global')
+// Actions
+const appActions = require('../../../../../js/actions/appActions')
-// other
+// Constants
+const appConfig = require('../../../../../js/constants/appConfig')
const settings = require('../../../../../js/constants/settings')
+// Utils
+const {changeSetting} = require('../../../lib/settingsUtil')
+const locale = require('../../../../../js/l10n')
+
+// Style
+const commonStyles = require('../../styles/commonStyles')
+const globalStyles = require('../../styles/global')
+
class AdvancedSettingsContent extends ImmutableComponent {
render () {
const minPublisherDuration = this.props.ledgerData.getIn(['synopsisOptions', 'minPublisherDuration'])
@@ -91,24 +95,51 @@ class AdvancedSettingsContent extends ImmutableComponent {
}
class AdvancedSettingsFooter extends ImmutableComponent {
+ showLedgerBackup () {
+ this.props.showOverlay('ledgerBackup')
+ this.props.setOverlayName('ledgerBackup')
+ }
+
+ showLedgerRecovery () {
+ this.props.showOverlay('ledgerRecovery')
+ this.props.setOverlayName('ledgerRecovery')
+ }
+
+ deleteWallet () {
+ const confMsg = locale.translation('paymentsDeleteWalletConfirmation')
+ if (window.confirm(confMsg)) {
+ this.props.hideOverlay('advancedSettings')
+ appActions.onWalletDelete()
+ }
+ }
+
render () {
- return
+ return
}
}
@@ -134,6 +165,15 @@ const styles = StyleSheet.create({
advancedSettings__switches__listItem__checkboxSwitch: {
padding: 0
+ },
+
+ footer__wrapper: {
+ flex: 1,
+ display: 'flex'
+ },
+
+ footer__wrapper__left: {
+ flex: 1
}
})
diff --git a/app/renderer/components/preferences/payment/captcha.js b/app/renderer/components/preferences/payment/captcha.js
new file mode 100644
index 00000000000..38e18c7a58f
--- /dev/null
+++ b/app/renderer/components/preferences/payment/captcha.js
@@ -0,0 +1,192 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const React = require('react')
+const {StyleSheet, css} = require('aphrodite/no-important')
+
+// Components
+const ImmutableComponent = require('../../immutableComponent')
+
+// Actions
+const appActions = require('../../../../../js/actions/appActions')
+
+// Constants
+const promotionStatuses = require('../../../../common/constants/promotionStatuses')
+
+// Styles
+const closeButton = require('../../../../../img/toolbar/stoploading_btn.svg')
+const dragIcon = require('../../../../extensions/brave/img/ledger/BAT_captcha_dragicon.png')
+const arrowIcon = require('../../../../extensions/brave/img/ledger/BAT_captcha_BG_arrow.png')
+
+// TODO: report when funds are too low
+class Captcha extends ImmutableComponent {
+ constructor (props) {
+ super(props)
+ this.onCaptchaDrop = this.onCaptchaDrop.bind(this)
+ this.onCaptchaDrag = this.onCaptchaDrag.bind(this)
+ this.getText = this.getText.bind(this)
+ this.captchaBox = null
+ this.dndStartPosition = {
+ x: 0,
+ y: 0,
+ width: 0,
+ height: 0
+ }
+ }
+
+ onCaptchaDrop (event) {
+ event.preventDefault()
+ const target = this.captchaBox.getBoundingClientRect()
+
+ const x = event.clientX - target.left - this.dndStartPosition.x + (this.dndStartPosition.height / 2)
+ const y = event.clientY - target.top - this.dndStartPosition.y + (this.dndStartPosition.width / 2)
+
+ appActions.onPromotionClaim(x, y)
+ }
+
+ onCaptchaDrag (event) {
+ const target = event.target.getBoundingClientRect()
+ this.dndStartPosition = {
+ x: event.clientX - target.left,
+ y: event.clientY - target.top,
+ width: target.width,
+ height: target.height
+ }
+ }
+
+ preventDefault (event) {
+ event.preventDefault()
+ }
+
+ closeCaptcha () {
+ appActions.onCaptchaClose()
+ }
+
+ getText () {
+ if (this.props.promo.get('promotionStatus') === promotionStatuses.CAPTCHA_ERROR) {
+ return {
+ title: 'promotionCaptchaErrorTitle',
+ text: 'promotionCaptchaErrorText'
+ }
+ }
+
+ return {
+ title: 'promotionCaptchaTitle',
+ text: 'promotionCaptchaText'
+ }
+ }
+
+ render () {
+ const text = this.getText()
+
+ return
{ this.captchaBox = node }}
+ >
+ {
+
+ }
+
+
+
+
+
+
+
+
+
+
+
+ }
+}
+
+const styles = StyleSheet.create({
+ enabledContent__overlay: {
+ position: 'absolute',
+ zIndex: 3,
+ top: 0,
+ left: 0,
+ width: '805px',
+ height: '180px',
+ padding: '20px',
+ background: '#f3f3f3',
+ borderRadius: '8px',
+ boxSizing: 'border-box',
+ boxShadow: '4px 6px 3px #dadada'
+ },
+
+ enabledContent__overlay_close: {
+ position: 'absolute',
+ right: '15px',
+ top: '15px',
+ height: '15px',
+ width: '15px',
+ cursor: 'pointer',
+ zIndex: 3,
+
+ background: `url(${closeButton}) center no-repeat`,
+ backgroundSize: `15px`,
+
+ ':focus': {
+ outline: 'none'
+ }
+ },
+
+ enabledContent__overlay_title: {
+ color: '#5f5f5f',
+ fontSize: '20px',
+ display: 'block',
+ marginBottom: '10px'
+ },
+
+ enabledContent__overlay_bold: {
+ color: '#ff5500',
+ paddingRight: '5px'
+ },
+
+ enabledContent__overlay_text: {
+ fontSize: '16px',
+ color: '#828282',
+ maxWidth: '700px',
+ lineHeight: '25px',
+ padding: '5px 5px 5px 0',
+ marginTop: '10px'
+ },
+
+ enabledContent__captcha__wrap: {
+ display: 'flex'
+ },
+
+ enabledContent__captcha__drop: {
+ position: 'absolute',
+ width: '400px',
+ height: '180px',
+ top: 0,
+ right: 0,
+ zIndex: 2,
+ display: 'block'
+ },
+
+ enabledContent__captcha__arrow: {
+ height: '62px',
+ flexBasis: '185px',
+ margin: '10px 0 0 -40px',
+ position: 'relative',
+ zIndex: '1'
+ },
+
+ enabledContent__captcha__image: {
+ flexBasis: '66px',
+ height: '62px',
+ marginTop: '10px',
+ position: 'relative',
+ zIndex: '2'
+ }
+})
+
+module.exports = Captcha
diff --git a/app/renderer/components/preferences/payment/deletedSites.js b/app/renderer/components/preferences/payment/deletedSites.js
new file mode 100644
index 00000000000..fb13ee54b73
--- /dev/null
+++ b/app/renderer/components/preferences/payment/deletedSites.js
@@ -0,0 +1,110 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const React = require('react')
+const {StyleSheet, css} = require('aphrodite/no-important')
+
+// Actions
+const aboutActions = require('../../../../../js/about/aboutActions')
+const appActions = require('../../../../../js/actions/appActions')
+
+// Components
+const BrowserButton = require('../../common/browserButton')
+const ImmutableComponent = require('../../immutableComponent')
+
+// Style
+const globalStyles = require('../../styles/global')
+
+class DeletedSitesContent extends ImmutableComponent {
+ constructor (props) {
+ super(props)
+ this.deletePermission = this.deletePermission.bind(this)
+ }
+
+ deletePermission (hostPattern) {
+ appActions.removeSiteSetting(hostPattern, 'ledgerPayments')
+ appActions.removeSiteSetting(hostPattern, 'ledgerPaymentsShown')
+ this.props.onHide()
+ }
+
+ render () {
+ return
+
+ {
+ this.props.sites.map(data => {
+ let siteName = (data.hostPattern || '').replace('?://', '://')
+
+ if (data.siteName) {
+ siteName = data.siteName
+ }
+
+ return
+
+ {siteName}
+
+ })
+ }
+
+
+ }
+}
+
+class DeletedSitesFooter extends ImmutableComponent {
+ clearPermissions () {
+ aboutActions.clearSiteSettings('ledgerPaymentsShown')
+ this.props.onHide()
+ }
+
+ render () {
+ return
+ }
+}
+
+const styles = StyleSheet.create({
+ sitePermissions__list: {
+ listStyle: 'none'
+ },
+
+ sitePermissions__list__item: {
+ display: 'flex',
+ alignItems: 'center',
+ lineHeight: 1.4
+ },
+
+ sitePermissions__list__item__button: {
+ marginRight: '.25rem',
+ color: globalStyles.color.braveOrange,
+
+ ':hover': {
+ color: globalStyles.color.braveOrange
+ }
+ },
+
+ sitePermissions__list__item__status: {
+ marginLeft: '.5ch',
+ fontStyle: 'italic'
+ }
+})
+
+module.exports = {
+ DeletedSitesContent,
+ DeletedSitesFooter
+}
diff --git a/app/renderer/components/preferences/payment/enabledContent.js b/app/renderer/components/preferences/payment/enabledContent.js
index 48daa0dfe2e..c55b30fee32 100644
--- a/app/renderer/components/preferences/payment/enabledContent.js
+++ b/app/renderer/components/preferences/payment/enabledContent.js
@@ -7,42 +7,55 @@ const {StyleSheet, css} = require('aphrodite/no-important')
const addMonths = require('date-fns/add_months')
const Immutable = require('immutable')
-// util
-const {batToCurrencyString, formatCurrentBalance, formattedDateFromTimestamp, walletStatus} = require('../../../../common/lib/ledgerUtil')
-const {l10nErrorText} = require('../../../../common/lib/httpUtil')
-const ledgerUtil = require('../../../../common/lib/ledgerUtil')
-const {changeSetting} = require('../../../lib/settingsUtil')
-const settings = require('../../../../../js/constants/settings')
-const locale = require('../../../../../js/l10n')
-
-// State
-const ledgerState = require('../../../../common/state/ledgerState')
-
-// components
+// Components
const ImmutableComponent = require('../../immutableComponent')
const BrowserButton = require('../../common/browserButton')
-const {FormTextbox} = require('../../common/textbox')
const {FormDropdown} = require('../../common/dropdown')
const LedgerTable = require('./ledgerTable')
+const Captcha = require('./captcha')
-// style
-const globalStyles = require('../../styles/global')
-const {paymentStylesVariables} = require('../../styles/payment')
-const {loaderAnimation} = require('../../styles/animations')
-const closeButton = require('../../../../../img/toolbar/stoploading_btn.svg')
-const cx = require('../../../../../js/lib/classSet')
+// State
+const ledgerState = require('../../../../common/state/ledgerState')
// Actions
const appActions = require('../../../../../js/actions/appActions')
+// Constants
+const ledgerStatuses = require('../../../../common/constants/ledgerStatuses')
+const settings = require('../../../../../js/constants/settings')
+
+// Utils
+const {
+ batToCurrencyString,
+ formatCurrentBalance,
+ formattedDateFromTimestamp,
+ walletStatus
+} = require('../../../../common/lib/ledgerUtil')
+const {l10nErrorText} = require('../../../../common/lib/httpUtil')
+const ledgerUtil = require('../../../../common/lib/ledgerUtil')
+const {changeSetting} = require('../../../lib/settingsUtil')
+const locale = require('../../../../../js/l10n')
+
+// Styles
+const globalStyles = require('../../styles/global')
+const cx = require('../../../../../js/lib/classSet')
+const {paymentStylesVariables} = require('../../styles/payment')
+const closeButton = require('../../../../../img/toolbar/stoploading_btn.svg')
+const promotionStatuses = require('../../../../common/constants/promotionStatuses')
+
// TODO: report when funds are too low
-// TODO: support non-USD currency
class EnabledContent extends ImmutableComponent {
constructor (props) {
super(props)
this.claimButton = this.claimButton.bind(this)
this.onClaimClick = this.onClaimClick.bind(this)
- this.closeClick = this.closeClick.bind(this)
+ this.closePromotionClick = this.closePromotionClick.bind(this)
+ this.recoverStatusClick = this.recoverStatusClick.bind(this)
+ }
+
+ showAddFunds () {
+ this.props.showOverlay('addFunds')
+ this.props.setOverlayName('addFunds')
}
walletButton () {
@@ -51,9 +64,15 @@ class EnabledContent extends ImmutableComponent {
? 'addFundsTitle'
: (ledgerData.get('creating') ? 'creatingWallet' : 'createWallet')
const onButtonClick = ledgerData.get('created')
- ? this.props.showOverlay.bind(this, 'addFunds')
+ ? this.showAddFunds.bind(this)
: (ledgerData.get('creating') ? () => {} : this.createWallet())
+ let buttonDisabled = !ledgerData.get('created')
+
+ if (buttonText === 'createWallet') {
+ buttonDisabled = false
+ }
+
return
+ const total = formatCurrentBalance(ledgerData, ledgerData.get('balance'), false) || ''
+ const userFunded = formatCurrentBalance(ledgerData, ledgerData.get('userFunded')) || ''
+ const grants = ledgerData.get('grants') || Immutable.List()
+
+ return
+
{userFunded}
+ {
+ grants.map(grant => {
+ return
+ {formatCurrentBalance(ledgerData, grant.get('amount'), false)}
+ ( {new Date(grant.get('expirationDate') * 1000).toLocaleDateString()})
+
+ })
+ }
+
+ {total} ( )
+
+
}
lastReconcileMessage () {
@@ -140,7 +175,9 @@ class EnabledContent extends ImmutableComponent {
let prevReconcileDateValue
let text
- if (!walletCreated || !walletHasReconcile || !walletHasTransactions) {
+ if (ledgerData.get('status') === ledgerStatuses.IN_PROGRESS) {
+ text = 'paymentInProgress'
+ } else if (!walletCreated || !walletHasReconcile || !walletHasTransactions) {
text = 'noPaymentHistory'
} else {
text = 'viewPaymentHistory'
@@ -154,8 +191,12 @@ class EnabledContent extends ImmutableComponent {
}
return
-
-
+ {
+ prevReconcileDateValue
+ ?
+ : null
+ }
+
}
@@ -195,16 +236,15 @@ class EnabledContent extends ImmutableComponent {
}
return
}
- closeClick () {
+ closePromotionClick () {
const promo = this.props.ledgerData.get('promotion') || Immutable.Map()
const status = promo.get('promotionStatus')
if (status && !promo.has('claimedTimestamp')) {
- if (status === 'expiredError') {
+ if (status === promotionStatuses.PROMO_EXPIRED) {
appActions.onPromotionRemoval()
} else {
appActions.onPromotionClose()
@@ -214,92 +254,156 @@ class EnabledContent extends ImmutableComponent {
}
}
+ recoverStatusClick () {
+ appActions.loadURLRequested(
+ parseInt(this.props.ledgerData.get('tabId')),
+ 'about:preferences#payments?ledgerRecoveryOverlayVisible',
+ true
+ )
+ }
+
+ captchaOverlay (promo) {
+ return
+ }
+
statusMessage () {
const promo = this.props.ledgerData.get('promotion') || Immutable.Map()
+ const status = this.props.ledgerData.get('status') || ''
const successText = promo.getIn(['panel', 'successText'])
- let status = promo.get('promotionStatus')
+ const promotionStatus = promo.get('promotionStatus')
+ let isPromotion = true
- if ((!successText || !promo.has('claimedTimestamp')) && !status) {
- return
+ if ((!successText || !promo.has('claimedTimestamp')) && !promotionStatus) {
+ isPromotion = false
+ if (status.length === 0) {
+ return
+ }
}
- let title = successText.get('title')
- let message = successText.get('message')
- let text = promo.getIn(['panel', 'disclaimer'])
+ let title, message, text, rightButton, leftButton, showClose
- if (status) {
+ if (isPromotion) {
+ showClose = true
+ title = successText.get('title')
+ message = successText.get('message')
+ text = promo.getIn(['panel', 'disclaimer'])
+ rightButton =
+
+ if (promotionStatus) {
+ switch (promotionStatus) {
+ case promotionStatuses.GENERAL_ERROR:
+ {
+ title = locale.translation('promotionGeneralErrorTitle')
+ message = locale.translation('promotionGeneralErrorMessage')
+ text = locale.translation('promotionGeneralErrorText')
+ break
+ }
+ case promotionStatuses.PROMO_EXPIRED:
+ {
+ title = locale.translation('promotionClaimedErrorTitle')
+ message = locale.translation('promotionClaimedErrorMessage')
+ text = locale.translation('promotionClaimedErrorText')
+ break
+ }
+ case promotionStatuses.CAPTCHA_CHECK:
+ case promotionStatuses.CAPTCHA_ERROR:
+ {
+ return this.captchaOverlay(promo)
+ }
+ }
+ }
+ } else {
switch (status) {
- case 'generalError':
+ case ledgerStatuses.CORRUPTED_SEED:
{
- title = locale.translation('promotionGeneralErrorTitle')
- message = locale.translation('promotionGeneralErrorMessage')
- text = locale.translation('promotionGeneralErrorText')
+ showClose = false
+ title = locale.translation('corruptedOverlayTitle')
+ message = locale.translation('corruptedOverlayMessage')
+ text = locale.translation('corruptedOverlayText')
+ leftButton =
+ rightButton =
break
}
- case 'expiredError':
+ case ledgerStatuses.SERVER_PROBLEM:
{
- title = locale.translation('promotionClaimedErrorTitle')
- message = locale.translation('promotionClaimedErrorMessage')
- text = locale.translation('promotionClaimedErrorText')
+ showClose = false
+ title = locale.translation('ledgerNetworkErrorTitle')
+ message = locale.translation('ledgerNetworkErrorMessage')
+ text = locale.translation('ledgerNetworkErrorText')
break
}
+ default:
+ {
+ return
+ }
}
}
- return
-
-
- {title} {message}
+ return
+ {
+ showClose ?
: null
+ }
+
+ {title}
+ {message}
-
+
{text}
-
+
+
{leftButton}
+
{rightButton}
+
}
+ showDeletedSites () {
+ this.props.showOverlay('deletedSites')
+ this.props.setOverlayName('deletedSites')
+ }
+
+ get deletedSitesLink () {
+ if (this.props.showDeletedSites) {
+ return
+
+ |
+
+ }
+
+ return null
+ }
+
render () {
const ledgerData = this.props.ledgerData
- const walletStatusText = walletStatus(ledgerData)
+ const walletStatusText = walletStatus(ledgerData, this.props.settings)
const contributionAmount = ledgerState.getContributionAmount(null, ledgerData.get('contributionAmount'), this.props.settings)
- const inTransition = ledgerData.getIn(['migration', 'btc2BatTransitionPending']) === true
const amountList = ledgerData.get('monthlyAmounts') || ledgerUtil.defaultMonthlyAmounts
return
-
@@ -330,7 +434,7 @@ class EnabledContent extends ImmutableComponent {
}
-
+
{
ledgerData.get('error') && ledgerData.get('error').get('caller') === 'getWalletProperties'
?
@@ -342,8 +446,6 @@ class EnabledContent extends ImmutableComponent {
{this.lastReconcileMessage()}
-
-
{
ledgerData.get('error') && ledgerData.get('error').get('caller') === 'getWalletProperties'
?
@@ -362,9 +464,10 @@ class EnabledContent extends ImmutableComponent {
onChangeSetting={this.props.onChangeSetting}
siteSettings={this.props.siteSettings} />
+ { this.deletedSitesLink }
@@ -434,6 +537,10 @@ const gridStyles = StyleSheet.create({
gridColumn: 3,
marginRight: globalStyles.spacing.panelPadding,
marginBottom: globalStyles.spacing.panelPadding
+ },
+
+ mergeRow23Col2: {
+ gridRow: '2 / span 2'
}
})
@@ -463,75 +570,17 @@ const styles = StyleSheet.create({
padding: '20px 60px'
},
- enabledContent__tos__link: {
+ enabledContent__footer__link: {
fontSize: '13px',
color: '#666'
},
- enabledContent__loader: {
- background: '#fafafa',
- zIndex: 3,
- position: 'absolute',
- left: 0,
- top: 0,
- width: '100%',
- height: '100%',
- margin: 0,
- opacity: 0,
- transform: 'translateX(-1000%)',
- transition: 'opacity .4s ease-out, transform .1s .4s ease'
- },
-
- enabledContent__loader_show: {
- opacity: 1,
- transform: 'translateX(0)',
- transition: 'opacity .4s ease-out'
- },
-
- enabledContent__loader__text: {
- textAlign: 'center',
- padding: '50px 0 20px',
- display: 'block',
- color: '#444'
- },
-
- enabledContent__loader__wrap: {
- width: '45px',
- left: 0,
- right: 0,
- margin: '50px auto 0'
- },
-
- enabledContent__loader__wrap__line: {
+ enabledContent__footer__separator: {
display: 'inline-block',
- width: '15px',
- height: '15px',
- borderRadius: '15px',
- animationName: [loaderAnimation],
- animationDuration: '.6s',
- animationIterationCount: 'infinite'
- },
-
- enabledContent__loader__wrap__line_1: {
- backgroundColor: '#FF5000',
- animationDelay: '.1s'
- },
-
- enabledContent__loader__wrap__line_2: {
- backgroundColor: '#9E1F63',
- animationDelay: '.2s'
- },
-
- enabledContent__loader__wrap__line_3: {
- backgroundColor: '#662D91',
- animationDelay: '.3s'
+ padding: '0 10px'
},
- enabledContent__loader__wrap__line_off: {
- animationName: 'none'
- },
-
- enabledContent__grant: {
+ enabledContent__overlay: {
position: 'absolute',
zIndex: 3,
top: 0,
@@ -540,12 +589,12 @@ const styles = StyleSheet.create({
minHeight: '159px',
background: '#f3f3f3',
borderRadius: '8px',
- padding: '30px 50px 20px',
+ padding: '27px 50px 17px',
boxSizing: 'border-box',
boxShadow: '4px 6px 3px #dadada'
},
- enabledContent__grant_close: {
+ enabledContent__overlay_close: {
position: 'absolute',
right: '15px',
top: '15px',
@@ -561,27 +610,53 @@ const styles = StyleSheet.create({
}
},
- enabledContent__grant_title: {
+ enabledContent__overlay_title: {
color: '#5f5f5f',
fontSize: '20px',
display: 'block',
marginBottom: '10px'
},
- enabledContent__grant_bold: {
- color: '#ff5500'
+ enabledContent__overlay_bold: {
+ color: '#ff5500',
+ paddingRight: '5px'
},
- enabledContent__grant_text: {
+ enabledContent__overlay_text: {
fontSize: '16px',
- color: '#9b9b9b',
- maxWidth: '600px'
+ color: '#828282',
+ maxWidth: '700px',
+ lineHeight: '25px',
+ padding: '5px 5px 5px 0'
+ },
+
+ enabledContent__overlay_buttons: {
+ display: 'grid',
+ gridTemplateColumns: '1fr 1fr'
+ },
+
+ enabledContent__overlay_buttons_left: {
+ marginLeft: 0
},
- enabledContent__grant_button: {
+ enabledContent__overlay_buttons_right: {
+ marginRight: 0
+ },
+
+ enabledContent__overlay_button: {
float: 'right'
},
+ enabledContent__overlay_link: {
+ color: '#5f5f5f',
+ fontSize: '16px',
+ textDecoration: 'none',
+
+ ':hover': {
+ textDecoration: 'underline'
+ }
+ },
+
enabledContent__walletBar: {
display: 'grid',
gridTemplateColumns: '1fr 1fr 1fr',
@@ -600,6 +675,23 @@ const styles = StyleSheet.create({
fontSize: globalStyles.payments.fontSize.regular,
lineHeight: 1.5,
marginTop: globalStyles.spacing.panelPadding
+ },
+
+ fundsAmount__item: {
+ marginBottom: '4px',
+ width: '215px',
+ fontSize: '14.5px'
+ },
+
+ fundsAmount__total: {
+ marginTop: '10px',
+ paddingTop: '12px',
+ borderTop: '1px solid #999',
+ fontSize: '15px'
+ },
+
+ lastContribution: {
+ paddingRight: '4px'
}
})
diff --git a/app/renderer/components/preferences/payment/ledgerBackup.js b/app/renderer/components/preferences/payment/ledgerBackup.js
index 1149382cb94..12bf57c4e9a 100644
--- a/app/renderer/components/preferences/payment/ledgerBackup.js
+++ b/app/renderer/components/preferences/payment/ledgerBackup.js
@@ -14,10 +14,12 @@ const globalStyles = require('../../styles/global')
// other
const aboutActions = require('../../../../../js/about/aboutActions')
+const appActions = require('../../../../../js/actions/appActions')
class LedgerBackupContent extends ImmutableComponent {
copyToClipboard (text) {
aboutActions.setClipboard(text)
+ appActions.onLedgerBackupSuccess()
}
render () {
diff --git a/app/renderer/components/preferences/payment/ledgerRecovery.js b/app/renderer/components/preferences/payment/ledgerRecovery.js
index f33108a7e2e..966ea32ef39 100644
--- a/app/renderer/components/preferences/payment/ledgerRecovery.js
+++ b/app/renderer/components/preferences/payment/ledgerRecovery.js
@@ -20,6 +20,7 @@ const commonStyles = require('../../styles/commonStyles')
// other
const aboutActions = require('../../../../../js/about/aboutActions')
const appActions = require('../../../../../js/actions/appActions')
+const keyCodes = require('../../../../../app/common/constants/keyCodes')
class LedgerRecoveryContent extends ImmutableComponent {
constructor () {
@@ -27,27 +28,67 @@ class LedgerRecoveryContent extends ImmutableComponent {
this.handleRecoveryKeyChange = this.handleRecoveryKeyChange.bind(this)
}
+ componentDidUpdate () {
+ if (this.refs.ledgerRecoveryOverlay) {
+ this.refs.ledgerRecoveryOverlay.focus()
+ }
+ }
+
handleRecoveryKeyChange (e) {
this.props.handleRecoveryKeyChange(e.target.value)
}
- clearRecoveryStatus () {
- this.props.hideAdvancedOverlays()
+ clearRecoveryStatus (success) {
+ if (success) {
+ this.props.hideAdvancedOverlays()
+ }
appActions.resetRecoverStatus()
}
+ onRecoveryOverlay (success) {
+ this.clearRecoveryStatus(success)
+ this.refs.ledgerRecoveryOverlay = null
+ this.props.setOverlayName('ledgerRecovery')
+ }
+
+ onEscape (e, status) {
+ e.stopPropagation()
+ if (e.keyCode === keyCodes.ESC) {
+ this.onRecoveryOverlay(status)
+ }
+ }
+
render () {
const l10nDataArgs = {
balance: batToCurrencyString(this.props.ledgerData.get('balance'), this.props.ledgerData)
}
const recoverySucceeded = this.props.ledgerData.get('recoverySucceeded')
const recoveryError = this.props.ledgerData.getIn(['error', 'error'])
+ const recoveryInProgress = this.props.ledgerData.get('recoveryInProgress')
+ const recoveryBalanceRecalculated = this.props.ledgerData.get('recoveryBalanceRecalculated') || false
const isNetworkError = typeof recoveryError === 'object'
return
{
- recoverySucceeded === true
- ?
+ recoverySucceeded === true && recoveryBalanceRecalculated === false
+ ? this.onEscape(e, true)} ref='ledgerRecoveryOverlay' tabIndex='0'>
+
+
+
+
+ : null
+ }
+ {
+ recoverySucceeded === true && recoveryBalanceRecalculated === true
+ ? this.onEscape(e, true)} ref='ledgerRecoveryOverlay' tabIndex='0'>
: null
}
{
(recoverySucceeded === false && recoveryError && isNetworkError)
- ?
+ ? this.onEscape(e, false)} ref='ledgerRecoveryOverlay' tabIndex='0'>
: null
}
{
(recoverySucceeded === false && recoveryError && !isNetworkError)
- ?
+ ? this.onEscape(e, false)} ref='ledgerRecoveryOverlay' tabIndex='0'>
+
+ : null
+ }
+ {
+ recoveryInProgress === true
+ ? this.onEscape(e, false)} ref='ledgerRecoveryOverlay' tabIndex='0'>
+
+
+
: null
}
-
-
+
}
}
@@ -122,36 +178,43 @@ class LedgerRecoveryFooter extends ImmutableComponent {
recoverWallet () {
aboutActions.ledgerRecoverWallet(this.props.state.recoveryKey)
+ this.props.setOverlayName('ledgerRecoveryStatus')
}
recoverWalletFromFile () {
aboutActions.ledgerRecoverWalletFromFile()
+ this.props.setOverlayName('ledgerRecoveryStatus')
}
render () {
- return
-
-
-
+ return
}
}
const styles = StyleSheet.create({
recoveryContent__h4: {
- marginBottom: globalStyles.spacing.dialogInsideMargin
+ margin: '15px 0',
+ fontSize: '17px'
},
recoveryContent__h3: {
marginBottom: globalStyles.spacing.modalPanelHeaderMarginBottom
@@ -160,7 +223,9 @@ const styles = StyleSheet.create({
height: '65px'
},
ledgerRecoveryContent: {
- marginBottom: globalStyles.spacing.dialogInsideMargin
+ marginBottom: globalStyles.spacing.dialogInsideMargin,
+ fontSize: '13px',
+ marginTop: '15px'
},
recoveryOverlay: {
@@ -175,13 +240,23 @@ const styles = StyleSheet.create({
left: '-1px',
width: '100%',
height: '100%',
- zIndex: 999
+ zIndex: 999,
+ outline: 'none'
},
recoveryOverlay__textColor: {
color: '#fff'
},
recoveryOverlay__spaceAround: {
margin: '50px auto'
+ },
+
+ footer__wrapper: {
+ flex: 1,
+ display: 'flex'
+ },
+
+ footer__wrapper__left: {
+ flex: 1
}
})
diff --git a/app/renderer/components/preferences/payment/ledgerTable.js b/app/renderer/components/preferences/payment/ledgerTable.js
index 3645bffa8b4..0f31141cdfe 100644
--- a/app/renderer/components/preferences/payment/ledgerTable.js
+++ b/app/renderer/components/preferences/payment/ledgerTable.js
@@ -5,14 +5,28 @@
const React = require('react')
const {StyleSheet, css} = require('aphrodite/no-important')
-// components
+// Components
const ImmutableComponent = require('../../immutableComponent')
const SortableTable = require('../../common/sortableTable')
const SwitchControl = require('../../common/switchControl')
const BrowserButton = require('../../common/browserButton')
const PinnedInput = require('./pinnedInput')
+const {SettingCheckbox, SiteSettingCheckbox} = require('../../common/settings')
+
+// Actions
+const appActions = require('../../../../../js/actions/appActions')
+const aboutActions = require('../../../../../js/about/aboutActions')
+
+// Constants
+const settings = require('../../../../../js/constants/settings')
+
+// Utils
+const getSetting = require('../../../../../js/settings').getSetting
+const urlUtil = require('../../../../../js/lib/urlutil')
+const locale = require('../../../../../js/l10n')
+const ledgerUtil = require('../../../../common/lib/ledgerUtil')
-// style
+// Style
const globalStyles = require('../../styles/global')
const {paymentStylesVariables} = require('../../styles/payment')
const verifiedGreenIcon = require('../../../../extensions/brave/img/ledger/verified_green_icon.svg')
@@ -20,13 +34,6 @@ const verifiedWhiteIcon = require('../../../../extensions/brave/img/ledger/verif
const removeIcon = require('../../../../extensions/brave/img/ledger/icon_remove.svg')
const pinIcon = require('../../../../extensions/brave/img/ledger/icon_pin.svg')
-// other
-const settings = require('../../../../../js/constants/settings')
-const getSetting = require('../../../../../js/settings').getSetting
-const aboutActions = require('../../../../../js/about/aboutActions')
-const urlUtil = require('../../../../../js/lib/urlutil')
-const {SettingCheckbox, SiteSettingCheckbox} = require('../../common/settings')
-
class LedgerTable extends ImmutableComponent {
get synopsis () {
return this.props.ledgerData.get('synopsis')
@@ -38,7 +45,7 @@ class LedgerTable extends ImmutableComponent {
onFaviconError (faviconURL, publisherKey) {
console.log('missing or corrupted favicon file', faviconURL)
- // Set the publishers favicon to null so that it gets refetched
+ // Set the publishers favicon to null so that it gets re-fetched
aboutActions.setLedgerFavicon(publisherKey, null)
}
@@ -99,11 +106,15 @@ class LedgerTable extends ImmutableComponent {
return synopsis.get('pinPercentage')
}
- banSite (hostPattern) {
- aboutActions.changeSiteSetting(hostPattern, 'ledgerPaymentsShown', false)
+ banSite (hostPattern, siteName) {
+ const confMsg = locale.translation('banSiteConfirmation')
+ if (window.confirm(confMsg)) {
+ aboutActions.changeSiteSetting(hostPattern, 'ledgerPaymentsShown', false)
+ aboutActions.changeSiteSetting(hostPattern, 'siteName', siteName)
+ }
}
- togglePinSite (hostPattern, pinned, percentage) {
+ togglePinSite (hostPattern, publisherKey, pinned, percentage) {
if (pinned) {
if (percentage < 1) {
percentage = 1
@@ -111,10 +122,10 @@ class LedgerTable extends ImmutableComponent {
percentage = Math.floor(percentage)
}
- aboutActions.changeSiteSetting(hostPattern, 'ledgerPinPercentage', percentage)
+ appActions.onLedgerPinPublisher(publisherKey, percentage)
aboutActions.changeSiteSetting(hostPattern, 'ledgerPayments', true)
} else {
- aboutActions.changeSiteSetting(hostPattern, 'ledgerPinPercentage', 0)
+ appActions.onLedgerPinPublisher(publisherKey, 0)
}
}
@@ -149,6 +160,25 @@ class LedgerTable extends ImmutableComponent {
]
}
+ getImage (faviconURL, providerName, publisherKey) {
+ if (!faviconURL && providerName) {
+ faviconURL = ledgerUtil.getDefaultMediaFavicon(providerName)
+ }
+
+ if (!faviconURL) {
+ return
+
+
+ }
+
+ return
+ }
+
getRow (synopsis) {
const faviconURL = synopsis.get('faviconURL')
const views = synopsis.get('views')
@@ -158,6 +188,7 @@ class LedgerTable extends ImmutableComponent {
const publisherURL = synopsis.get('publisherURL')
const percentage = pinned ? this.pinPercentageValue(synopsis) : synopsis.get('percentage')
const publisherKey = synopsis.get('publisherKey')
+ const providerName = synopsis.get('providerName')
const siteName = synopsis.get('siteName')
const defaultAutoInclude = this.enabledForSite(synopsis)
@@ -174,12 +205,8 @@ class LedgerTable extends ImmutableComponent {
{
html:
,
value: publisherKey
@@ -216,7 +243,7 @@ class LedgerTable extends ImmutableComponent {
pinned
?
:
{percentage}
}
@@ -230,14 +257,14 @@ class LedgerTable extends ImmutableComponent {
styles.actionIcons__icon_pin,
pinned && styles.actionIcons__icon_pin_isPinned
)}
- onClick={this.togglePinSite.bind(this, this.getHostPattern(synopsis), !pinned, percentage)}
+ onClick={this.togglePinSite.bind(this, this.getHostPattern(synopsis), publisherKey, !pinned, percentage)}
data-test-pinned={pinned}
/>
,
value: ''
@@ -245,6 +272,38 @@ class LedgerTable extends ImmutableComponent {
]
}
+ /**
+ * Function used for determination if table should be sorted or not
+ * For comparison we use publisher percentage, number of views and time spent.
+ * We compare previous values with new values that we received.
+ * @param prevRows - Previous value for the table
+ * @param currentRows - New value for the table
+ * @returns {boolean} - Was something changed and if so let's trigger the sort
+ */
+ sortCheck (prevRows, currentRows) {
+ if (prevRows && currentRows && currentRows.length === prevRows.length) {
+ for (let i = 0; i < currentRows.length; i++) {
+ const newRow = currentRows[i]
+ const oldRow = prevRows[i]
+
+ for (let j = 0; j < newRow.length; j++) {
+ if (
+ newRow[j] &&
+ oldRow[j] &&
+ newRow[j][5] &&
+ newRow[j][3] &&
+ newRow[j][4] &&
+ (
+ newRow[j][5].value !== oldRow[j][5].value || // %
+ newRow[j][3].value !== oldRow[j][3].value || // views
+ newRow[j][4].value !== oldRow[j][4].value // time
+ )
+ ) return true
+ }
+ }
+ }
+ }
+
render () {
if (!this.synopsis || !this.synopsis.size) {
return null
@@ -324,6 +383,7 @@ class LedgerTable extends ImmutableComponent {
pinnedRows.map((synopsis) => this.getRow(synopsis)).toJS(),
unPinnedRows.map((synopsis) => this.getRow(synopsis)).toJS()
]}
+ sortCheck={this.sortCheck}
/>
{
showButton
@@ -408,6 +468,13 @@ const styles = StyleSheet.create({
alignItems: 'center'
},
+ siteData__anchor: {
+ width: '430px',
+ overflow: 'hidden',
+ textOverflow: 'ellipsis',
+ whiteSpace: 'nowrap'
+ },
+
siteData__anchor__icon_favicon: {
width: globalStyles.spacing.iconSize,
height: globalStyles.spacing.iconSize
diff --git a/app/renderer/components/preferences/payment/pinnedInput.js b/app/renderer/components/preferences/payment/pinnedInput.js
index e304fe84e11..3a10d14d9d3 100644
--- a/app/renderer/components/preferences/payment/pinnedInput.js
+++ b/app/renderer/components/preferences/payment/pinnedInput.js
@@ -5,14 +5,14 @@
const React = require('react')
const {StyleSheet, css} = require('aphrodite/no-important')
-// components
+// Components
const ImmutableComponent = require('../../immutableComponent')
-// style
-const globalStyles = require('../../styles/global')
+// Actions
+const appActions = require('../../../../../js/actions/appActions')
-// other
-const aboutActions = require('../../../../../js/about/aboutActions')
+// Style
+const globalStyles = require('../../styles/global')
class PinnedInput extends ImmutableComponent {
componentDidUpdate () {
@@ -25,15 +25,15 @@ class PinnedInput extends ImmutableComponent {
}
}
- pinPercentage (hostPattern, event) {
+ pinPercentage (publisherKey, event) {
let value = parseInt(event.target.value)
- if (value < 1) {
+ if (value < 1 || !value) {
value = 1
this.textInput.value = 1
}
- aboutActions.changeSiteSetting(hostPattern, 'ledgerPinPercentage', value)
+ appActions.onLedgerPinPublisher(publisherKey, value)
this.forceUpdate()
}
render () {
@@ -41,7 +41,7 @@ class PinnedInput extends ImmutableComponent {
data-test-id='pinnedInput'
ref={(input) => { this.textInput = input }}
defaultValue={this.props.defaultValue}
- onBlur={this.pinPercentage.bind(this, this.props.patern)}
+ onBlur={this.pinPercentage.bind(this, this.props.publisherKey)}
onKeyPress={this.keyPress.bind(this)}
className={css(styles.pinnedInput)}
/>
@@ -49,7 +49,7 @@ class PinnedInput extends ImmutableComponent {
}
const styles = StyleSheet.create({
- // Ref: tableTd_percentage on ledgetTable.js
+ // Ref: tableTd_percentage on ledgerTable.js
pinnedInput: {
border: `1px solid #c4c5c5`,
borderRadius: globalStyles.radius.borderRadius,
diff --git a/app/renderer/components/preferences/paymentsTab.js b/app/renderer/components/preferences/paymentsTab.js
index 8a661060ff5..d830ee33c5b 100644
--- a/app/renderer/components/preferences/paymentsTab.js
+++ b/app/renderer/components/preferences/paymentsTab.js
@@ -25,6 +25,7 @@ const AddFundsDialog = require('./payment/addFundsDialog/addFundsDialog')
const AddFundsDialogFooter = require('./payment/addFundsDialog/addFundsDialogFooter')
const {AdvancedSettingsContent, AdvancedSettingsFooter} = require('./payment/advancedSettings')
const {HistoryContent, HistoryFooter} = require('./payment/history')
+const {DeletedSitesFooter, DeletedSitesContent} = require('./payment/deletedSites')
const {LedgerBackupContent, LedgerBackupFooter} = require('./payment/ledgerBackup')
const {LedgerRecoveryContent, LedgerRecoveryFooter} = require('./payment/ledgerRecovery')
@@ -76,12 +77,12 @@ class PaymentsTab extends ImmutableComponent {
return getSetting(settings.PAYMENTS_ENABLED, this.props.settings)
}
- get overlayContent () {
+ get addFundsDialogContent () {
const ledgerData = this.props.ledgerData || Immutable.Map()
const addresses = ledgerData.get('addresses') || Immutable.List()
const walletQR = ledgerData.get('walletQR') || Immutable.List()
const wizardData = ledgerData.get('wizardData') || Immutable.Map()
- const funds = formatCurrentBalance(ledgerData)
+ const funds = formatCurrentBalance(ledgerData, ledgerData.get('balance'))
const budget = ledgerState.getContributionAmount(null, ledgerData.get('contributionAmount'), this.props.settings)
const minAmount = batToCurrencyString(budget, ledgerData)
@@ -94,21 +95,86 @@ class PaymentsTab extends ImmutableComponent {
/>
}
- get overlayFooter () {
+ get addFundsDialogFooter () {
const ledgerData = this.props.ledgerData || Immutable.Map()
const wizardData = ledgerData.get('wizardData') || Immutable.Map()
return (
)
}
- get getOverlayFounds () {
+ get getOverlayFunds () {
const ledgerData = this.props.ledgerData || Immutable.Map()
- return formatCurrentBalance(ledgerData)
+ return formatCurrentBalance(ledgerData, ledgerData.get('balance'))
+ }
+
+ get deletedSitesFooter () {
+ return (
+
+ )
+ }
+
+ get deletedSites () {
+ const permissionName = 'ledgerPaymentsShown'
+ const defaults = (this.props.braveryDefaults || Immutable.Map()).merge({ledgerPaymentsShown: true})
+ const sites = []
+
+ if (!this.props.siteSettings) {
+ return sites
+ }
+
+ this.props.siteSettings.forEach((value, hostPattern) => {
+ if (!value.size) {
+ return
+ }
+
+ const granted = value.get(permissionName)
+ if (
+ defaults &&
+ defaults.get(permissionName) === granted &&
+ granted !== undefined
+ ) {
+ return
+ }
+
+ if (['boolean', 'number'].includes(typeof granted)) {
+ let siteName = null
+ if (value.has('siteName')) {
+ siteName = value.get('siteName')
+ }
+
+ sites.push({
+ siteName,
+ hostPattern
+ })
+ }
+ })
+
+ return sites
+ }
+
+ deletedSitesContent (sites) {
+ return
+ }
+
+ showAdvancedSettings () {
+ this.props.showOverlay('advancedSettings')
+ this.props.setOverlayName('advancedSettings')
+ }
+
+ showPaymentHistory () {
+ this.props.showOverlay('paymentHistory')
+ this.props.setOverlayName('paymentHistory')
}
hideOverlay () {
@@ -118,8 +184,8 @@ class PaymentsTab extends ImmutableComponent {
render () {
const enabled = this.props.ledgerData.get('created')
- const inTransition = this.props.ledgerData.getIn(['migration', 'btc2BatTransitionPending']) === true
- const enableSettings = enabled && !inTransition
+ const deletedSites = this.deletedSites
+ const showDeletedSites = deletedSites.length > 0
return
{
@@ -127,13 +193,24 @@ class PaymentsTab extends ImmutableComponent {
?
: null
}
+ {
+ this.enabled && this.props.deletedSitesOverlayVisible && showDeletedSites
+ ?
+ : null
+ }
{
this.enabled && this.props.paymentHistoryOverlayVisible
?
}
onHide={this.props.hideOverlay.bind(this, 'advancedSettings')}
/>
@@ -179,6 +257,7 @@ class PaymentsTab extends ImmutableComponent {
ledgerData={this.props.ledgerData}
/>}
footer={
}
onHide={this.props.hideOverlay.bind(this, 'ledgerBackup')}
@@ -187,17 +266,21 @@ class PaymentsTab extends ImmutableComponent {
}
{
this.enabled && this.props.ledgerRecoveryOverlayVisible
- ?
}
footer={
}
onHide={this.props.hideOverlay.bind(this, 'ledgerRecovery')}
+ customDialogFooterClasses={css(styles.recoveryFooter)}
/>
: null
}
@@ -268,16 +351,16 @@ class PaymentsTab extends ImmutableComponent {
)}
data-test-id={this.hasWalletTransaction ? 'paymentHistoryButton' : 'disabledPaymentHistoryButton'}
data-l10n-id='paymentHistoryIcon'
- onClick={(enabled && this.hasWalletTransaction) ? this.props.showOverlay.bind(this, 'paymentHistory') : () => {}}
+ onClick={(enabled && this.hasWalletTransaction) ? this.showPaymentHistory.bind(this, 'paymentHistory') : () => {}}
/>
{}}
+ onClick={enabled ? this.showAdvancedSettings.bind(this) : () => {}}
/>
@@ -288,11 +371,14 @@ class PaymentsTab extends ImmutableComponent {
{
this.enabled
- ?
:
({WebkitMask: `url(${icon}) no-repeat 0 0`})
const styles = StyleSheet.create({
prefAside: {
- background: `linear-gradient(${globalStyles.color.gray}, ${globalStyles.color.mediumGray})`,
+ background: theme.preferences.navigationBackground,
boxShadow: globalStyles.shadow.insetShadow,
position: 'fixed',
zIndex: '600',
diff --git a/app/renderer/components/preferences/shieldsTab.js b/app/renderer/components/preferences/shieldsTab.js
new file mode 100644
index 00000000000..2af0b51d673
--- /dev/null
+++ b/app/renderer/components/preferences/shieldsTab.js
@@ -0,0 +1,142 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const ImmutableComponent = require('../immutableComponent')
+
+// Components
+const {SettingsList, SettingItem, SettingCheckbox} = require('../common/settings')
+const {SettingDropdown} = require('../common/dropdown')
+const {DefaultSectionTitle} = require('../common/sectionTitle')
+const BrowserButton = require('../common/browserButton')
+const SitePermissionsPage = require('./sitePermissionsPage')
+
+// Actions
+const appActions = require('../../../../js/actions/appActions')
+
+// Constants
+const settings = require('../../../../js/constants/settings')
+const appConfig = require('../../../../js/constants/appConfig')
+
+const adblock = appConfig.resourceNames.ADBLOCK
+const cookieblock = appConfig.resourceNames.COOKIEBLOCK
+const cookieblockAll = appConfig.resourceNames.COOKIEBLOCK_ALL
+const fingerprintingProtection = appConfig.resourceNames.FINGERPRINTING_PROTECTION
+const fingerprintingProtectionAll = appConfig.resourceNames.FINGERPRINTING_PROTECTION_ALL
+const adInsertion = appConfig.resourceNames.AD_INSERTION
+const trackingProtection = appConfig.resourceNames.TRACKING_PROTECTION
+const httpsEverywhere = appConfig.resourceNames.HTTPS_EVERYWHERE
+const safeBrowsing = appConfig.resourceNames.SAFE_BROWSING
+const noScript = appConfig.resourceNames.NOSCRIPT
+
+const braveryPermissionNames = {
+ 'shieldsUp': ['boolean'],
+ 'adControl': ['string'],
+ 'cookieControl': ['string'],
+ 'safeBrowsing': ['boolean'],
+ 'httpsEverywhere': ['boolean'],
+ 'fingerprintingProtection': ['string'],
+ 'noScript': ['boolean', 'number']
+}
+
+class ShieldsTab extends ImmutableComponent {
+ constructor (props) {
+ super(props)
+ this.onChangeAdControl = this.onChangeAdControl.bind(this)
+ this.onToggleHTTPSE = this.onToggleSetting.bind(this, httpsEverywhere)
+ this.onToggleSafeBrowsing = this.onToggleSetting.bind(this, safeBrowsing)
+ this.onToggleNoScript = this.onToggleSetting.bind(this, noScript)
+ }
+ onChangeAdControl (e) {
+ if (e.target.value === 'showBraveAds') {
+ appActions.setResourceEnabled(adblock, true)
+ appActions.setResourceEnabled(trackingProtection, true)
+ appActions.setResourceEnabled(adInsertion, true)
+ } else if (e.target.value === 'blockAds') {
+ appActions.setResourceEnabled(adblock, true)
+ appActions.setResourceEnabled(trackingProtection, true)
+ appActions.setResourceEnabled(adInsertion, false)
+ } else {
+ appActions.setResourceEnabled(adblock, false)
+ appActions.setResourceEnabled(trackingProtection, false)
+ appActions.setResourceEnabled(adInsertion, false)
+ }
+ }
+ onChangeCookieControl (e) {
+ appActions.setResourceEnabled(cookieblock, e.target.value === 'block3rdPartyCookie')
+ appActions.setResourceEnabled(cookieblockAll, e.target.value === 'blockAllCookies')
+ }
+ onChangeFingerprintingProtection (e) {
+ appActions.setResourceEnabled(fingerprintingProtection, e.target.value === 'block3rdPartyFingerprinting')
+ appActions.setResourceEnabled(fingerprintingProtectionAll, e.target.value === 'blockAllFingerprinting')
+ }
+ onToggleSetting (setting, e) {
+ appActions.setResourceEnabled(setting, e.target.value)
+ }
+ render () {
+ return
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* TODO: move this inline style to Aphrodite once refactored */}
+
+
+
+
+
+
+
+
+
+
+
+ }
+}
+
+module.exports = ShieldsTab
diff --git a/app/renderer/components/preferences/sitePermissionsPage.js b/app/renderer/components/preferences/sitePermissionsPage.js
new file mode 100644
index 00000000000..c40fc79553d
--- /dev/null
+++ b/app/renderer/components/preferences/sitePermissionsPage.js
@@ -0,0 +1,195 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const {StyleSheet, css} = require('aphrodite')
+
+// Components
+const ImmutableComponent = require('../immutableComponent')
+const {DefaultSectionTitle} = require('../common/sectionTitle')
+const BrowserButton = require('../common/browserButton')
+
+// Actions
+const appActions = require('../../../../js/actions/appActions')
+const aboutActions = require('../../../../js/about/aboutActions')
+
+// Style
+const globalStyles = require('../styles/global')
+
+class SitePermissionsPage extends ImmutableComponent {
+ hasEntryForPermission (name) {
+ return this.props.siteSettings.some((value) => {
+ return value.get && this.props.names[name] ? this.props.names[name].includes(typeof value.get(name)) : false
+ })
+ }
+
+ isPermissionsNonEmpty () {
+ // Check whether there is at least one permission set
+ return this.props.siteSettings.some((value) => {
+ if (value && value.get) {
+ for (let name in this.props.names) {
+ const granted = value.get(name)
+ if (this.props.names[name].includes(typeof granted)) {
+ if (this.props.defaults) {
+ return this.props.defaults.get(name) !== granted
+ } else {
+ return true
+ }
+ }
+ }
+ }
+ return false
+ })
+ }
+
+ deletePermission (name, hostPattern) {
+ appActions.removeSiteSetting(hostPattern, name)
+ }
+
+ clearPermissions (name) {
+ aboutActions.clearSiteSettings(name)
+ }
+
+ render () {
+ return this.isPermissionsNonEmpty()
+ ?
+
+
+ {
+ Object.keys(this.props.names).map((name) =>
+ this.hasEntryForPermission(name)
+ ?
+
+
+
+ (
+
+ )
+
+
+
+
+ : null)
+ }
+
+
+ : null
+ }
+}
+
+const styles = StyleSheet.create({
+ sitePermissions: {
+ listStyle: 'none',
+ margin: '20px'
+ },
+
+ sitePermissions__permissionName: {
+ fontWeight: 600
+ },
+
+ sitePermissions__clearAll: {
+ cursor: 'pointer',
+ color: globalStyles.color.gray,
+ textDecoration: 'underline',
+ marginLeft: '.5ch'
+ },
+
+ sitePermissions__clearAll__link: {
+ // override the global value
+ color: globalStyles.color.gray
+ },
+
+ sitePermissions__list: {
+ marginBottom: '1rem'
+ },
+
+ sitePermissions__list__item: {
+ display: 'flex',
+ alignItems: 'center',
+ lineHeight: 1.4
+ },
+
+ sitePermissions__list__item__button: {
+ marginRight: '.25rem',
+ color: globalStyles.color.braveOrange,
+
+ ':hover': {
+ color: globalStyles.color.braveOrange
+ }
+ },
+
+ sitePermissions__list__item__status: {
+ marginLeft: '.5ch',
+ fontStyle: 'italic'
+ }
+})
+
+module.exports = SitePermissionsPage
diff --git a/app/renderer/components/preferences/syncTab.js b/app/renderer/components/preferences/syncTab.js
index 7358e8b0e20..713771b0f6b 100644
--- a/app/renderer/components/preferences/syncTab.js
+++ b/app/renderer/components/preferences/syncTab.js
@@ -65,6 +65,11 @@ class SyncTab extends ImmutableComponent {
}
+ showSyncReset () {
+ this.props.showOverlay('syncReset')
+ this.props.setOverlayName('syncReset')
+ }
+
get clearDataContent () {
return
@@ -73,7 +78,7 @@ class SyncTab extends ImmutableComponent {
?
:
}
+ showSyncStart () {
+ this.props.showOverlay('syncStart')
+ this.props.setOverlayName('syncStart')
+ }
+
+ showSyncAdd () {
+ this.props.showOverlay('syncAdd')
+ this.props.setOverlayName('syncAdd')
+ }
+
get setupContent () {
if (this.setupError) {
return null
@@ -96,12 +111,12 @@ class SyncTab extends ImmutableComponent {
}
@@ -127,7 +142,7 @@ class SyncTab extends ImmutableComponent {
}
@@ -393,6 +408,8 @@ class SyncTab extends ImmutableComponent {
if (window.confirm(msg)) {
aboutActions.resetSync()
this.props.hideOverlay('syncReset')
+ } else {
+ this.props.onNavigate()
}
}
@@ -434,6 +451,11 @@ class SyncTab extends ImmutableComponent {
window.alert('Invalid input code; please try again or create a new profile.')
}
+ showSyncNewDevice () {
+ this.props.showOverlay('syncNewDevice')
+ this.props.setOverlayName('syncNewDevice')
+ }
+
render () {
return
{
diff --git a/app/renderer/components/styles/animations.js b/app/renderer/components/styles/animations.js
index ceef54f3a12..8c10a2ea28a 100644
--- a/app/renderer/components/styles/animations.js
+++ b/app/renderer/components/styles/animations.js
@@ -42,20 +42,6 @@ const widthIncreaseElementKeyframes = (start, end) => ({
width: [start, end]
})
-const loaderAnimation = {
- '0': {
- transform: 'translate(0,0)'
- },
-
- '50%': {
- transform: 'translate(0,15px)'
- },
-
- '100%': {
- transform: 'translate(0,0)'
- }
-}
-
const tabFadeInKeyframes = {
'0%': {
opacity: 0.5
@@ -76,6 +62,5 @@ module.exports = {
opacityIncreaseElementKeyframes,
widthIncreaseKeyframes,
widthIncreaseElementKeyframes,
- tabFadeInKeyframes,
- loaderAnimation
+ tabFadeInKeyframes
}
diff --git a/app/renderer/components/styles/commonStyles.js b/app/renderer/components/styles/commonStyles.js
index 18d0e4fe1ac..466a9495efb 100644
--- a/app/renderer/components/styles/commonStyles.js
+++ b/app/renderer/components/styles/commonStyles.js
@@ -47,6 +47,23 @@ const styles = StyleSheet.create({
fontSize: globalStyles.spacing.textAreaFontSize
},
+ // Dialogs
+ flyoutDialog: {
+ background: globalStyles.color.toolbarBackground,
+ borderRadius: globalStyles.radius.borderRadius,
+ boxShadow: globalStyles.shadow.flyoutDialogBoxShadow,
+ color: '#000',
+ fontSize: '13px',
+ // Issue #7949
+ padding: `${globalStyles.spacing.dialogInsideMargin} 30px`,
+ position: 'absolute',
+ top: globalStyles.spacing.dialogTopOffset,
+ // Issue #7930
+ boxSizing: 'border-box',
+ maxWidth: '600px',
+ maxHeight: `calc(80vh - ${globalStyles.spacing.downloadsBarHeight})`
+ },
+
// itemList.less
listItem: {
cursor: 'default',
diff --git a/app/renderer/components/styles/global.js b/app/renderer/components/styles/global.js
index b5a0d6ad309..8a61a33de0d 100644
--- a/app/renderer/components/styles/global.js
+++ b/app/renderer/components/styles/global.js
@@ -32,14 +32,14 @@ const globalStyles = {
noIntersection: 1,
at75: 0.75,
at60: 0.6,
- at45: 0.45,
+ at46: 0.46,
at40: 0.4,
at30: 0.3,
at20: 0.20,
at12: 0.125
},
color: {
- commonTextColor: '#3b3b3b',
+ commonTextColor: 'rgb(59, 59, 62)',
linkColor: '#0099CC',
highlightBlue: '#37A9FD',
privateTabBackground: '#665296',
@@ -61,18 +61,18 @@ const globalStyles = {
progressBarColor: '#3498DB',
siteInsecureColor: '#C63626',
siteEVColor: 'green',
- buttonColor: '#5a5a5a',
+ buttonColor: 'rgb(90, 90, 98)',
braveOrange: 'rgb(255, 80, 0)',
braveLightOrange: '#FF7A1D',
braveMediumOrange: 'rgb(232, 72, 0)',
braveDarkOrange: '#D44600',
- veryLightGray: 'rgb(250, 250, 250)',
- lightGray: 'rgb(236, 236, 236)',
- gray: 'rgb(153, 153, 153)',
- mediumGray: 'rgb(101, 101, 101)',
- darkGray: 'rgb(68, 68, 68)',
- modalVeryLightGray: 'rgb(247, 247, 247)',
- modalLightGray: 'rgb(231, 231, 231)',
+ veryLightGray: 'rgb(250, 250, 251)',
+ lightGray: 'rgb(236, 236, 239)',
+ gray: 'rgb(153, 153, 157)',
+ mediumGray: 'rgb(101, 101, 107)',
+ darkGray: 'rgb(68, 68, 72)',
+ modalVeryLightGray: 'rgb(247, 247, 249)',
+ modalLightGray: 'rgb(231, 231, 234)',
white25: 'rgba(255, 255, 255, 0.25)',
white50: 'rgba(255, 255, 255, 0.5)',
white100: 'rgba(255, 255, 255, 1)',
@@ -93,7 +93,7 @@ const globalStyles = {
notificationItemColor: '#f1e9e5',
notificationBottomBorderColor: '#ff5500',
almostInvisible: 'rgba(255,255,255,0.01)',
- urlBarOutline: '#bbb',
+ urlBarOutline: 'rgb(187, 187, 191)',
alphaWhite: 'rgba(255,255,255,0.8)'
},
typography: {
@@ -150,11 +150,12 @@ const globalStyles = {
buttonWidth: '25px',
navbarHeight: '36px',
downloadsBarHeight: '60px',
- tabsToolbarHeight: '26px',
+ // This includes the toolbar's borders
+ tabsToolbarHeight: '29px',
tabPagesHeight: '7px',
bookmarkHangerMaxWidth: '350px',
- bookmarksToolbarHeight: '24px',
- bookmarksToolbarWithFaviconsHeight: '24px',
+ bookmarksToolbarHeight: '20px',
+ bookmarksToolbarTextOnlyHeight: '18px',
bookmarksFileIconSize: '13px',
bookmarksFolderIconSize: '15px',
bookmarksItemMaxWidth: '100px',
@@ -165,7 +166,7 @@ const globalStyles = {
bookmarksToolbarPadding: '10px',
bookmarksItemFontSize: '11px',
bookmarksToolbarButtonDraggingMargin: '25px',
- bookmarksToolbarOverflowButtonWidth: '25px',
+ bookmarksToolbarOverflowButtonWidth: '9px',
navbarMenubarMargin: '7px',
navbarButtonSpacing: '4px',
navbarButtonWidth: '20px',
@@ -176,12 +177,12 @@ const globalStyles = {
aboutPageDetailsPageWidth: '704px',
aboutPageSectionPadding: '24px',
aboutPageSectionMargin: '10px',
- defaultTabMargin: '6px',
+ defaultTabMargin: '10px',
defaultIconPadding: '2px',
iconSize: '16px',
- sessionIconSize: '15px',
- closeIconSize: '13px',
- newSessionIconSize: '13px',
+ sessionIconSize: '14px',
+ closeIconSize: '14px',
+ newSessionIconSize: '14px',
narrowIconSize: '12px',
dialogWidth: '422px',
dialogSmallWidth: '350px',
@@ -231,7 +232,6 @@ const globalStyles = {
zindexWindowIsPreview: '1100',
zindexDownloadsBar: '1000',
zindexTabs: '1000',
- zindexTabsAudioTopBorder: '1001',
zindexTabsThumbnail: '1100',
zindexNavigationBar: '2000',
zindexUrlbarNotLegend: '2100',
@@ -253,7 +253,6 @@ const globalStyles = {
prefsPanelHeading: '23px'
},
appIcons: {
- angleDoubleRight: 'fa fa-angle-double-right',
check: 'fa fa-check',
clipboard: 'fa fa-clipboard',
closeTab: 'fa fa-times-circle',
@@ -303,7 +302,7 @@ const globalStyles = {
},
button: {
- color: '#5a5a5a',
+ color: 'rgb(90, 90, 98)',
default: {
color: '#fff',
@@ -322,11 +321,11 @@ const globalStyles = {
secondary: {
gradientColor1: '#fff',
- gradientColor2: '#ececec',
- background: 'linear-gradient(#fff, #ececec)',
- color: '#666',
- hoverColor: '#444',
- borderHoverColor: 'rgb(153, 153, 153)'
+ gradientColor2: 'rgb(236, 236, 239)',
+ background: 'linear-gradient(#fff, rgb(236, 236, 239))',
+ color: 'rgb(101, 101, 107)',
+ hoverColor: 'rgb(68, 68, 72)',
+ borderHoverColor: 'rgb(153, 153, 157)'
},
subtle: {
@@ -339,17 +338,26 @@ const globalStyles = {
hoverColor: '#000'
},
+ alert: {
+ color: '#fff',
+ gradientColor1: '#ff5000',
+ gradientColor2: '#ff001b',
+ background: 'linear-gradient(#ff5000, #ff001b)',
+ hoverColor: '#fff',
+ borderHoverColor: '#fff'
+ },
+
panel: {
width: '180px'
}
},
braveryPanel: {
- color: '#3b3b3b',
+ color: 'rgb(59, 59, 62)',
header: {
- color: '#fafafa',
- background: '#808080',
+ color: '#fff',
+ background: 'rgb(128, 128, 133)',
switchControlTopTextColor: '#d3d3d3',
border: '1px solid #aaa'
},
@@ -359,10 +367,10 @@ const globalStyles = {
},
body: {
- background: '#eee',
+ background: 'rgb(239, 239, 241)',
hr: {
- background: '#ccc'
+ background: 'rgb(204, 204, 214)'
}
}
},
@@ -391,7 +399,6 @@ globalStyles.color.chromeBorderColor = globalStyles.color.chromePrimary
globalStyles.color.chromeControlsWarningBackground = globalStyles.color.chromePrimary
globalStyles.color.audioColor = globalStyles.color.highlightBlue
globalStyles.color.focusUrlbarOutline = globalStyles.color.highlightBlue
-globalStyles.color.siteSecureColor = globalStyles.color.buttonColor
globalStyles.color.loadTimeColor = globalStyles.color.highlightBlue
globalStyles.color.activeTabDefaultColor = globalStyles.color.chromePrimary
diff --git a/app/renderer/components/styles/globalSelectors.js b/app/renderer/components/styles/globalSelectors.js
new file mode 100644
index 00000000000..56f118f7fcf
--- /dev/null
+++ b/app/renderer/components/styles/globalSelectors.js
@@ -0,0 +1,53 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this file,
+* You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const { StyleSheet } = require('aphrodite/no-important')
+const globalStyles = require('./global')
+
+const GLOBALS = '__GLOBAL_STYLES__'
+
+const globalExtension = {
+ selectorHandler: (selector, baseSelector, generateSubtreeStyles) =>
+ (baseSelector.includes(GLOBALS) ? generateSubtreeStyles(selector) : null)
+}
+
+const extended = StyleSheet.extend([globalExtension])
+
+const styles = extended.StyleSheet.create({
+ [GLOBALS]: {
+ '*': {
+ color: globalStyles.color.commonTextColor,
+ fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Roboto, Oxygen, Ubuntu, Cantarell, "Fira Sans", "Droid Sans", sans-serif',
+ fontWeight: 400,
+ margin: 0,
+ padding: 0
+ },
+
+ 'html, body, #appContainer, #appContainer > div': {
+ height: '100%'
+ },
+
+ body: {
+ fontSize: '100%'
+ },
+
+ // used for titles / labels (in *most* cases)
+ '@typography-display': {
+ fontFamily: 'Poppins, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif'
+ },
+
+ // in *most* cases, use this letter-spacing value
+ // when font-size is greater than 30px
+ '@typographyDisplayLargeSpacing': '-0.4px',
+
+ // when font-size is greater than 20px and less than 30px
+ '@typographyDisplayMediumSpacing': '-0.2px',
+
+ // used for body / flowing text
+ '@typography-body': {
+ fontFamily: 'Muli, -apple-system, BlinkMacSystemFont, Segoe UI, Roboto, Oxygen, Ubuntu, Cantarell, Open Sans, Helvetica Neue, sans-serif'
+ }
+ }
+})
+module.exports = extended.css(styles[GLOBALS])
diff --git a/app/renderer/components/styles/theme.js b/app/renderer/components/styles/theme.js
index e889e041f55..e0d7c1b4f73 100644
--- a/app/renderer/components/styles/theme.js
+++ b/app/renderer/components/styles/theme.js
@@ -44,14 +44,14 @@
filter: {
makeWhite: 'brightness(0) invert(1)',
- whiteShadow: 'drop-shadow(0px 0px 2px rgb(255, 255, 255))'
+ whiteShadow: 'drop-shadow(-10px 0px 12px rgb(255, 255, 255))'
},
tabsToolbar: {
- backgroundColor: '#ddd',
+ backgroundColor: '#CDD1D5',
border: {
- color: '#bbb'
+ color: 'rgb(187, 187, 191)'
},
button: {
@@ -64,14 +64,14 @@
tabs: {
navigation: {
- borderColor: '#bbb'
+ borderColor: 'rgb(187, 187, 191)'
}
}
},
tabPage: {
backgroundColor: '#fff',
- borderColor: '#bbb',
+ borderColor: 'rgb(187, 187, 191)',
hover: {
backgroundColor: globalStyles.color.braveOrange,
@@ -99,7 +99,7 @@
item: {
separator: {
hr: {
- backgroundColor: '#bbb'
+ backgroundColor: 'rgb(187, 187, 191)'
}
},
@@ -109,7 +109,7 @@
},
disabled: {
- color: '#bbb'
+ color: 'rgb(187, 187, 191)'
},
icon: {
@@ -130,43 +130,70 @@
},
single: {
- backgroundColor: 'rgba(238, 238, 238, 1)',
+ backgroundColor: 'rgba(238, 238, 240, 1)',
borderColor: 'rgba(204, 204, 204, 0.54)',
boxShadowColor: 'rgba(0, 0, 0, 0.5)'
}
},
tab: {
- transition: `
- background-color 150ms cubic-bezier(0.26, 0.63, 0.39, 0.65),
- color 150ms cubic-bezier(0.26, 0.63, 0.39, 0.65)
- `,
- background: '#ddd',
- borderColor: '#bbb',
- color: '#5a5a5a',
-
- hover: {
- background: 'rgba(255, 255, 255, 0.4)'
+ transitionDurationOut: '400ms',
+ transitionDurationIn: '200ms',
+ transitionEasingOut: 'ease-in',
+ transitionEasingIn: 'ease-out',
+ background: 'rgb(205,209,213)',
+ borderColor: 'rgb(187, 187, 191)',
+ borderWidth: 1,
+ color: '#222',
+ identityHeight: globalStyles.spacing.iconSize,
+ defaultFaviconColor: globalStyles.color.mediumGray,
+ defaultFaviconColorLight: '#fff',
+
+ closeButton: {
+ background: 'transparent',
+ borderRadius: '2px',
+ active: {
+ background: '#cb2c00'
+ },
+ hover: {
+ color: 'white',
+ background: '#fd4f01'
+ }
},
- forWindows: {
- color: '#555'
+ hover: {
+ background: 'rgb(219,221,223)',
+ active: {
+ background: 'rgb(243,243,243)'
+ },
+ private: {
+ background: 'rgb(225,223,238)',
+ borderColor: 'rgba(75, 60, 110, .7)'
+ }
},
active: {
- background: 'rgba(255, 255, 255, 0.8)',
-
+ background: 'rgb(233,233,234)',
+ colorLight: 'rgb(255, 255, 255)',
+ colorDark: '#222',
private: {
- background: '#4b3c6e',
- color: '#fff'
+ background: 'rgb(75,60,110)',
+ color: '#fff',
+ defaultFaviconColor: '#fff'
}
},
private: {
- background: '#d9d6e0',
+ background: 'rgb(217,213,228)',
color: '#4b3c6e'
},
+ preview: {
+ background: 'rgb(240,240,240)',
+ boxShadow: '0 -2px 12px rgba(0, 0, 0, 0.22)',
+ scale: '1.06'
+ },
+
icon: {
default: {
primary: '#fff',
@@ -181,7 +208,8 @@
},
audio: {
- color: '#69B9F9'
+ color: '#2377bb',
+ hoverColor: '#3b566b'
},
close: {
@@ -189,21 +217,13 @@
},
symbol: {
- color: globalStyles.color.black100,
-
- default: {
- backgroundColor: globalStyles.color.mediumGray,
-
- light: {
- backgroundColor: globalStyles.color.white100
- }
- }
+ color: globalStyles.color.black100
}
}
},
findBar: {
- backgroundColor: '#F7F7F7',
+ backgroundColor: globalStyles.color.modalVeryLightGray,
color: globalStyles.color.highlightBlue,
border: {
@@ -219,7 +239,7 @@
},
find: {
- color: '#555'
+ color: 'rgb(85, 85, 90)'
},
close: {
@@ -239,7 +259,7 @@
switchControl: {
label: {
top: {
- color: '#bbb'
+ color: 'rgb(187, 187, 190)'
}
},
@@ -260,5 +280,13 @@
backgroundColor: '#fff'
}
}
+ },
+
+ preferences: {
+ navigationBackground: `linear-gradient(
+ rgb(164, 167, 171),
+ rgb(94, 96, 99)
+ )`,
+ navigationSectionSelectedColor: 'rgb(101, 101, 107)'
}
}
diff --git a/app/renderer/components/tabs/content/audioTabIcon.js b/app/renderer/components/tabs/content/audioTabIcon.js
index 84067b48e53..7e6cc84d843 100644
--- a/app/renderer/components/tabs/content/audioTabIcon.js
+++ b/app/renderer/components/tabs/content/audioTabIcon.js
@@ -5,6 +5,7 @@
const React = require('react')
const ReactDOM = require('react-dom')
const {StyleSheet} = require('aphrodite/no-important')
+const locale = require('../../../../../js/l10n')
// Components
const ReduxComponent = require('../../reduxComponent')
@@ -108,6 +109,7 @@ class AudioTabIcon extends React.Component {
className={styles.icon_audio}
symbol={this.audioIcon}
onClick={this.toggleMute}
+ title={locale.translation(this.props.audioPlaying ? 'muteTab' : 'unmuteTab')}
ref={this.setRef}
/>
}
@@ -116,12 +118,12 @@ class AudioTabIcon extends React.Component {
const styles = StyleSheet.create({
icon_audio: {
overflow: 'hidden',
- margin: '0 -2px 0 2px',
+ margin: '1px -2px 0 2px', // get centered with funky font awesome sizing
color: theme.tab.icon.audio.color,
- fontSize: '13px',
-
- // Override default properties
- zIndex: globalStyles.zindex.zindexTabsAudioTopBorder
+ fontSize: '14px',
+ ':hover': {
+ color: theme.tab.icon.audio.hoverColor
+ }
}
})
diff --git a/app/renderer/components/tabs/content/closeTabIcon.js b/app/renderer/components/tabs/content/closeTabIcon.js
index d6e90ee2d8c..11b1917648a 100644
--- a/app/renderer/components/tabs/content/closeTabIcon.js
+++ b/app/renderer/components/tabs/content/closeTabIcon.js
@@ -4,11 +4,10 @@
const React = require('react')
const ReactDOM = require('react-dom')
-const {StyleSheet} = require('aphrodite/no-important')
+const {StyleSheet, css} = require('aphrodite/no-important')
// Components
const ReduxComponent = require('../../reduxComponent')
-const TabIcon = require('./tabIcon')
// State helpers
const tabState = require('../../../../common/state/tabState')
@@ -19,9 +18,6 @@ const frameStateUtil = require('../../../../../js/state/frameStateUtil')
// Styles
const globalStyles = require('../../styles/global')
const {theme} = require('../../styles/theme')
-const {opacityIncreaseElementKeyframes} = require('../../styles/animations')
-
-const closeTabSvg = require('../../../../extensions/brave/img/tabs/close_btn.svg')
class CloseTabIcon extends React.Component {
constructor (props) {
@@ -49,88 +45,76 @@ class CloseTabIcon extends React.Component {
return props
}
- componentDidMount (props) {
- this.transitionIfRequired()
- }
-
- componentDidUpdate (prevProps) {
- this.transitionIfRequired(prevProps)
- }
-
- transitionIfRequired (prevProps) {
- const shouldTransitionIn = (
- // need to have the element created already
- this.element &&
- // no icon is showing if pinned tab
- !this.props.isPinned &&
- // should show the icon
- // TODO: if we want to animate the unmounting of the component (when
- // tab is unhovered), then we should use https://github.com/reactjs/react-transition-group
- // For now, we'll just not do anything since we can't - the element
- // will have already been removed
- this.props.showCloseIcon &&
- // state has changed
- (!prevProps || this.props.showCloseIcon !== prevProps.showCloseIcon)
- )
- if (shouldTransitionIn) {
- this.element.animate(opacityIncreaseElementKeyframes, {
- duration: 200,
- easing: 'linear'
- })
- }
- }
-
setRef (ref) {
this.element = ReactDOM.findDOMNode(ref)
}
render () {
- if (this.props.isPinned || !this.props.showCloseIcon) {
+ if (this.props.isPinned || !this.props.showCloseIcon) { // <-- comment out to always show, in order to view in inspector
return null
}
- return
+ >
+
+
+
+
}
}
const styles = StyleSheet.create({
- icon_close: {
- marginRight: globalStyles.spacing.defaultTabMargin,
- backgroundImage: `url(${closeTabSvg})`,
-
- // Override default properties
- backgroundSize: globalStyles.spacing.closeIconSize,
+ closeIcon: {
+ '--close-line-color': 'var(--tab-color)',
+ boxSizing: 'border-box',
+ alignSelf: 'center',
+ position: 'relative',
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
+ borderRadius: theme.tab.closeButton.borderRadius,
+ background: theme.tab.closeButton.background,
+ marginRight: `calc(${globalStyles.spacing.defaultTabMargin} - 2px)`,
width: globalStyles.spacing.closeIconSize,
height: globalStyles.spacing.closeIconSize,
-
- // mask icon to gray to avoid calling another icon on hover
- transition: 'filter 150ms linear',
- filter: theme.tab.icon.close.filter,
-
+ zIndex: globalStyles.zindex.zindexTabsThumbnail,
':hover': {
- filter: 'none'
+ '--close-line-color': theme.tab.closeButton.hover.color,
+ background: theme.tab.closeButton.hover.background,
+ '--close-transit-duration': theme.tab.transitionDurationIn,
+ '--close-transit-timing': theme.tab.transitionEasingIn
+ },
+ ':active': {
+ background: theme.tab.closeButton.active.background
}
},
- icon_close_centered: {
+ closeIcon__graphic: {
+ flex: 1
+ },
+
+ closeIcon__line: {
+ stroke: 'var(--close-line-color)'
+ },
+
+ closeIcon_centered: {
position: 'absolute',
- left: 0,
+ left: `calc(50% - (${globalStyles.spacing.closeIconSize} / 2))`,
right: 0,
- top: 0,
+ top: `calc(50% - (${globalStyles.spacing.closeIconSize} / 2))`,
bottom: 0,
- margin: 'auto'
+ margin: 0
}
})
diff --git a/app/renderer/components/tabs/content/favIcon.js b/app/renderer/components/tabs/content/favIcon.js
index 9b9b00353e8..fc564aede3a 100644
--- a/app/renderer/components/tabs/content/favIcon.js
+++ b/app/renderer/components/tabs/content/favIcon.js
@@ -120,8 +120,7 @@ class Favicon extends React.Component {
!this.props.favicon &&
css(
styles.icon__symbol_default,
- this.props.showIconAtReducedSize && styles.icon__symbol_default_reducedSize,
- themeLight && styles.icon__symbol_default_colorLight
+ this.props.showIconAtReducedSize && styles.icon__symbol_default_reducedSize
)
)
} />
@@ -130,7 +129,8 @@ class Favicon extends React.Component {
const styles = StyleSheet.create({
icon_fav: {
- backgroundImage: 'var(--faviconsrc)'
+ backgroundImage: 'var(--faviconsrc)',
+ overflow: 'visible'
},
icon_favLight: {
@@ -151,7 +151,6 @@ const styles = StyleSheet.create({
icon__symbol_loading: {
position: 'absolute',
left: 0,
- willChange: 'transform',
backgroundImage: `url(${loadingIconSvg})`,
backgroundRepeat: 'no-repeat',
backgroundPosition: 'top left',
@@ -170,15 +169,11 @@ const styles = StyleSheet.create({
WebkitMaskPosition: 'center',
WebkitMaskImage: `url(${defaultIconSvg})`,
WebkitMaskSize: '14px',
- backgroundColor: theme.tab.icon.symbol.default.backgroundColor
+ backgroundColor: 'var(--tab-default-icon-color)'
},
icon__symbol_default_reducedSize: {
WebkitMaskSize: '10px'
- },
-
- icon__symbol_default_colorLight: {
- backgroundColor: theme.tab.icon.symbol.default.light.backgroundColor
}
})
diff --git a/app/renderer/components/tabs/content/newSessionIcon.js b/app/renderer/components/tabs/content/newSessionIcon.js
index f759a1e3b4b..575e34db3f7 100644
--- a/app/renderer/components/tabs/content/newSessionIcon.js
+++ b/app/renderer/components/tabs/content/newSessionIcon.js
@@ -66,8 +66,8 @@ class NewSessionIcon extends React.Component {
)
if (shouldTransitionIn) {
this.element.animate(opacityIncreaseElementKeyframes, {
- duration: 200,
- easing: 'linear'
+ duration: 120,
+ easing: 'ease-out'
})
}
}
@@ -85,19 +85,11 @@ class NewSessionIcon extends React.Component {
return null
}
- const newSessionProps = StyleSheet.create({
- newSession__indicator: {
- filter: this.props.isActive && this.props.textIsWhite
- ? 'invert(100%)'
- : 'none'
- }
- })
-
return
@@ -106,7 +98,12 @@ const styles = StyleSheet.create({
// Override default properties
backgroundSize: 0,
height: globalStyles.spacing.sessionIconSize,
- width: globalStyles.spacing.sessionIconSize
+ width: globalStyles.spacing.sessionIconSize,
+ backgroundColor: theme.tab.icon.private.background.notActive
+ },
+
+ icon_private_active: {
+ backgroundColor: theme.tab.icon.private.background.active
}
})
diff --git a/app/renderer/components/tabs/content/tabIcon.js b/app/renderer/components/tabs/content/tabIcon.js
index 2a2131ba979..7cb10ed7fde 100644
--- a/app/renderer/components/tabs/content/tabIcon.js
+++ b/app/renderer/components/tabs/content/tabIcon.js
@@ -32,6 +32,7 @@ class TabIcon extends ImmutableComponent {
draggable={this.props.draggable}
onClick={this.props.onClick}
style={this.props.style}
+ title={this.props.title}
{...altProps}
>
{
@@ -67,6 +68,7 @@ const styles = StyleSheet.create({
alignSelf: 'center',
alignItems: 'center',
justifyContent: 'center',
+ flexShrink: 0, // must keep set width and height and not crop self
// Default background properties
backgroundSize: globalStyles.spacing.iconSize,
@@ -74,7 +76,6 @@ const styles = StyleSheet.create({
backgroundRepeat: 'no-repeat',
// Default animation properties
- willChange: 'opacity',
animationFillMode: 'forwards'
},
@@ -85,8 +86,9 @@ const styles = StyleSheet.create({
},
tabIcon_symbol_content: {
- fontSize: '8px',
+ fontSize: '11px',
fontWeight: 'bold',
+ marginLeft: '4px',
justifyContent: 'flex-end',
color: theme.tab.icon.symbol.color
}
diff --git a/app/renderer/components/tabs/content/tabTitle.js b/app/renderer/components/tabs/content/tabTitle.js
index ecdbaf77b12..885c902277e 100644
--- a/app/renderer/components/tabs/content/tabTitle.js
+++ b/app/renderer/components/tabs/content/tabTitle.js
@@ -14,11 +14,6 @@ const frameStateUtil = require('../../../../../js/state/frameStateUtil')
const tabUIState = require('../../../../common/state/tabUIState')
const tabState = require('../../../../common/state/tabState')
-// Utils
-const platformUtil = require('../../../../common/lib/platformUtil')
-const isWindows = platformUtil.isWindows()
-const isDarwin = platformUtil.isDarwin()
-
// Styles
const globalStyles = require('../../styles/global')
@@ -29,14 +24,10 @@ class TabTitle extends React.Component {
const frameKey = frameStateUtil.getFrameKeyByTabId(currentWindow, tabId)
const props = {}
- props.isWindows = isWindows
- props.isDarwin = isDarwin
props.isPinned = tabState.isTabPinned(state, tabId)
props.showTabTitle = titleState.showTabTitle(currentWindow, frameKey)
props.displayTitle = titleState.getDisplayTitle(currentWindow, frameKey)
props.addExtraGutter = tabUIState.addExtraGutterToTitle(currentWindow, frameKey)
- props.isTextWhite = tabUIState.checkIfTextColor(currentWindow, frameKey, 'white')
- props.gradientColor = tabUIState.getTabEndIconBackgroundColor(currentWindow, frameKey)
props.tabId = tabId
return props
@@ -46,22 +37,12 @@ class TabTitle extends React.Component {
if (this.props.isPinned || !this.props.showTabTitle) {
return null
}
- const perPageGradient = StyleSheet.create({
- tab__title_gradient: {
- '::after': {
- background: this.props.gradientColor
- }
- }
- })
-
- return
{this.props.displayTitle}
@@ -78,35 +59,58 @@ const styles = StyleSheet.create({
flex: 1,
userSelect: 'none',
fontSize: globalStyles.fontSize.tabTitle,
- lineHeight: '1.6',
+ fontWeight: 400,
minWidth: 0, // see https://stackoverflow.com/a/36247448/4902448
- marginLeft: '4px',
+ lineHeight: globalStyles.spacing.tabsToolbarHeight,
+ width: '-webkit-fill-available',
+ marginLeft: '6px',
+ // Fade any overflow text out,
+ // but use a technique which preserves:
+ // 1. Sub-pixel colored antialized text - e.g. background-clip: text does not use this.
+ // (with color - zoom in 20x on mac and you'll see)
+ // 2. Background and text color transition with no artifacts left over due to a
+ // pseudo element gradient fade which cannot transition (cannot transition linear gradient color)
overflow: 'hidden',
-
- // this enable us to have gradient text
- '::after': {
- zIndex: globalStyles.zindex.zindexTabs,
- content: '""',
+ position: 'relative',
+ color: 'transparent',
+ // the text, rendered as normal, but cut off early
+ '::before': {
position: 'absolute',
+ display: 'block',
+ overflow: 'hidden',
+ top: 0,
+ left: 0,
+ right: 'calc(18% - 1px)',
bottom: 0,
+ fontWeight: 'inherit',
+ content: 'attr(data-text)',
+ color: 'var(--tab-color)',
+ transition: `color var(--tab-transit-duration) var(--tab-transit-easing)`
+ },
+ // the fade-out using background gradient clipped to text
+ // and only starting off where actual text is cut off
+ '::after': {
+ position: 'absolute',
+ display: 'block',
+ top: 0,
+ left: 0,
right: 0,
- width: '-webkit-fill-available',
- height: '-webkit-fill-available',
- // add a pixel margin so the box-shadow of the
- // webview is not covered by the gradient
- marginBottom: '1px'
+ bottom: 0,
+ fontWeight: 'inherit',
+ content: 'attr(data-text)',
+ // restrict background-size to a tiny portion of the text as background-clip: text means
+ // no sub-pixel antializing
+ background: `linear-gradient(
+ to right,
+ var(--tab-color) 0,
+ transparent 100%
+ ) right top / 18% 100% no-repeat`,
+ WebkitBackgroundClip: 'text !important', // !important is neccessary because aphrodite will put this at top of ruleset :-(
+ color: 'transparent',
+ transition: `background 0s var(--tab-transit-easing) var(--tab-transit-duration)`
}
},
- tab__title_isDarwin: {
- fontWeight: '400'
- },
-
- tab__title_isWindows: {
- fontWeight: '500',
- fontSize: globalStyles.fontSize.tabTitle
- },
-
tab__title_extraGutter: {
margin: '0 2px'
}
diff --git a/app/renderer/components/tabs/pinnedTabs.js b/app/renderer/components/tabs/pinnedTabs.js
index c8522cc74a3..1d40d4b1f4c 100644
--- a/app/renderer/components/tabs/pinnedTabs.js
+++ b/app/renderer/components/tabs/pinnedTabs.js
@@ -4,7 +4,6 @@
const React = require('react')
const ReactDOM = require('react-dom')
-const Immutable = require('immutable')
const {StyleSheet, css} = require('aphrodite/no-important')
// Components
@@ -20,13 +19,14 @@ const windowStore = require('../../../../js/stores/windowStore')
// Constants
const dragTypes = require('../../../../js/constants/dragTypes')
+const globalStyles = require('../styles/global')
// Utils
const dnd = require('../../../../js/dnd')
const dndData = require('../../../../js/dndData')
const frameStateUtil = require('../../../../js/state/frameStateUtil')
-const pinnedSitesUtil = require('../../../common/lib/pinnedSitesUtil')
const {isIntermediateAboutPage} = require('../../../../js/lib/appUrlUtil')
+const {getCurrentWindowId} = require('../../currentWindow')
class PinnedTabs extends React.Component {
constructor (props) {
@@ -54,18 +54,11 @@ class PinnedTabs extends React.Component {
let droppedOnTab = dnd.closestFromXOffset(this.tabRefs.filter((node) => node && node.props.frameKey !== key), clientX).selectedRef
if (droppedOnTab) {
const isLeftSide = dnd.isLeftSide(ReactDOM.findDOMNode(droppedOnTab), clientX)
+ const sourceIsPinned = sourceDragData.get('pinnedLocation')
+ // TODO: pass in needs-pinning in moveTab, and do nothing else here
windowActions.moveTab(key, droppedOnTab.props.frameKey, isLeftSide)
- if (!sourceDragData.get('pinnedLocation')) {
+ if (!sourceIsPinned) {
appActions.tabPinned(sourceDragData.get('tabId'), true)
- } else {
- const sourceDetails = pinnedSitesUtil.getDetailFromFrame(sourceDragData)
- const droppedOnFrame = this.dropFrame(droppedOnTab.props.frameKey)
- const destinationDetails = pinnedSitesUtil.getDetailFromFrame(droppedOnFrame)
- appActions.onPinnedTabReorder(
- pinnedSitesUtil.getKey(sourceDetails),
- pinnedSitesUtil.getKey(destinationDetails),
- isLeftSide
- )
}
}
}, 0)
@@ -78,19 +71,24 @@ class PinnedTabs extends React.Component {
mergeProps (state, ownProps) {
const currentWindow = state.get('currentWindow')
- const pinnedFrames = frameStateUtil.getPinnedFrames(currentWindow) || Immutable.List()
+ const pinnedFrames = frameStateUtil.getPinnedFrames(currentWindow)
+ .filter(frame => frame.get('tabStripWindowId') === getCurrentWindowId())
+ const previewFrameKey = frameStateUtil.getPreviewFrameKey(currentWindow)
const props = {}
// used in renderer
props.pinnedTabs = pinnedFrames.map((frame) => frame.get('key'))
-
+ props.isPreviewingPinnedTab = previewFrameKey && props.pinnedTabs.some(key => key === previewFrameKey)
return props
}
render () {
this.tabRefs = []
return {
+ this.nextFrameSetTabMouseX = null
+ this.elementRef.style.setProperty('--tab-mouse-x', `${x}px`)
+ })
+ }
+ }
}
onAuxClick (e) {
@@ -189,9 +206,9 @@ class Tab extends React.Component {
const frame = this.frame
if (frame && !frame.isEmpty()) {
- const tabWidth = this.fixTabWidth
// do not mimic tab size if closed tab is a pinned tab
if (!this.props.isPinnedTab) {
+ const tabWidth = this.fixTabWidth
windowActions.onTabClosedWithMouse({
fixTabWidth: tabWidth
})
@@ -216,6 +233,14 @@ class Tab extends React.Component {
}
componentDidMount () {
+ // Workaround the fact that aphrodite will not inject style rules until some time
+ // after css([rules]) is called.
+ // This causes CSS transitions to fire on the changes from the default values to the
+ // specified initial values, which definitely should not happen.
+ // Ensuring styles are written to DOM before this element is rendered
+ // means the element will not be rendered first with 0 rules.
+ // See https://codepen.io/petemill/pen/rdeqqv for a reproduction.
+ aphroditeInject.flushToStyleTag()
// unobserve tabs that we don't need. This will
// likely be made by onObserve method but added again as
// just to double-check
@@ -259,6 +284,7 @@ class Tab extends React.Component {
const currentWindow = state.get('currentWindow')
const frame = frameStateUtil.getFrameByKey(currentWindow, ownProps.frameKey) || Immutable.Map()
const frameKey = ownProps.frameKey
+ const previewFrameKey = frameStateUtil.getPreviewFrameKey(currentWindow)
const tabId = frame.get('tabId', tabState.TAB_ID_NONE)
const isPinned = tabState.isTabPinned(state, tabId)
const partOfFullPageSet = ownProps.partOfFullPageSet
@@ -275,17 +301,26 @@ class Tab extends React.Component {
props.frameKey = frameKey
props.isPinnedTab = isPinned
props.isPrivateTab = privateState.isPrivateTab(currentWindow, frameKey)
- props.isActive = frameStateUtil.isFrameKeyActive(currentWindow, frameKey)
- props.tabWidth = currentWindow.getIn(['ui', 'tabs', 'fixTabWidth'])
+ props.isActive = !!frameStateUtil.isFrameKeyActive(currentWindow, frameKey)
+ props.isPreview = frameKey === previewFrameKey /* || frameKey === 2 */ // <-- uncomment to force 1 preview tab for style inspection
+ props.anyTabIsPreview = previewFrameKey != null
+ props.tabWidth = isPinned ? null : currentWindow.getIn(['ui', 'tabs', 'fixTabWidth'])
props.themeColor = tabUIState.getThemeColor(currentWindow, frameKey)
- props.title = frame.get('title')
+ props.title = titleState.getDisplayTitle(currentWindow, frameKey)
props.tabPageIndex = frameStateUtil.getTabPageIndex(currentWindow)
props.partOfFullPageSet = partOfFullPageSet
props.showAudioTopBorder = audioState.showAudioTopBorder(currentWindow, frameKey, isPinned)
props.centralizeTabIcons = tabUIState.centralizeTabIcons(currentWindow, frameKey, isPinned)
+ props.guestInstanceId = frame.get('guestInstanceId')
// required only so that context menu shows correct state (mute vs unmute)
props.isAudioMuted = audioState.isAudioMuted(currentWindow, frameKey)
props.isAudio = audioState.canPlayAudio(currentWindow, frameKey)
+ props.visualTabIdDebug = getSetting(settings.DEBUG_VERBOSE_TAB_INFO)
+ if (props.visualTabIdDebug) {
+ const tab = tabState.getByTabId(state, tabId)
+ props.tabIndex = tab && tab.get('index')
+ props.frameStateInternalIndex = frameStateUtil.getIndexByTabId(currentWindow, tabId)
+ }
// used in other functions
props.dragData = state.getIn(['dragData', 'type']) === dragTypes.TAB && state.get('dragData')
@@ -295,25 +330,28 @@ class Tab extends React.Component {
return props
}
- componentWillReceiveProps (nextProps) {
- if (this.props.tabWidth && !nextProps.tabWidth) {
- // remember the width so we can transition from it
- this.originalWidth = this.elementRef.getBoundingClientRect().width
- }
- }
-
componentDidUpdate (prevProps) {
- if (prevProps.tabWidth && !this.props.tabWidth) {
+ if (prevProps.tabWidth && !this.props.tabWidth && !this.props.partOfFullPageSet) {
+ this.elementRef.animate([
+ { flexBasis: `${prevProps.tabWidth}px`, flexGrow: 0, flexShrink: 0 },
+ { flexBasis: 0, flexGrow: 1, flexShrink: 1 }
+ ], {
+ duration: 250,
+ iterations: 1,
+ easing: 'ease-in-out'
+ })
+ }
+ // no transition between:
+ // - active <-> inactive state
+ // - no theme color and first theme color
+ if (this.elementRef && prevProps && (
+ prevProps.isActive !== this.props.isActive ||
+ (!prevProps.themeColor && this.props.themeColor)
+ )) {
+ const className = css(styles.tabArea_instantTransition)
+ this.elementRef.classList.add(className)
window.requestAnimationFrame(() => {
- const newWidth = this.elementRef.getBoundingClientRect().width
- this.elementRef.animate([
- { flexBasis: `${this.originalWidth}px`, flexGrow: 0, flexShrink: 0 },
- { flexBasis: `${newWidth}px`, flexGrow: 0, flexShrink: 0 }
- ], {
- duration: 250,
- iterations: 1,
- easing: 'ease-in-out'
- })
+ this.elementRef.classList.remove(className)
})
}
}
@@ -323,8 +361,21 @@ class Tab extends React.Component {
const isThemed = !this.props.isPrivateTab && this.props.isActive && this.props.themeColor
const instanceStyles = { }
if (isThemed) {
- instanceStyles['--theme-color-fg'] = getTextColorForBackground(this.props.themeColor)
+ const lightText = backgroundRequiresLightText(this.props.themeColor)
instanceStyles['--theme-color-bg'] = this.props.themeColor
+ // complementing foreground color
+ instanceStyles['--theme-color-fg'] =
+ lightText
+ ? theme.tab.active.colorLight
+ : theme.tab.active.colorDark
+ // complementing icon color
+ instanceStyles['--theme-color-default-icon'] =
+ lightText
+ ? theme.tab.defaultFaviconColorLight
+ : theme.tab.defaultFaviconColor
+ }
+ if (this.props.tabWidth) {
+ instanceStyles.flex = `0 0 ${this.props.tabWidth}px`
}
return
{ this.elementRef = elementRef }}
>
@@ -354,31 +417,18 @@ class Tab extends React.Component {
ref={(node) => { this.tabNode = node }}
className={css(
styles.tabArea__tab,
-
// tab icon only (on pinned tab / small tab)
this.props.isPinnedTab && styles.tabArea__tab_pinned,
this.props.centralizeTabIcons && styles.tabArea__tab_centered,
- this.props.showAudioTopBorder && styles.tabArea__tab_audioTopBorder,
-
- // Windows specific style (color)
- isWindows && styles.tabArea__tab_forWindows,
-
- // Set background-color and color to active tab and private tab
- this.props.isActive && styles.tabArea__tab_active,
- this.props.isPrivateTab && styles.tabArea__tab_private,
- (this.props.isPrivateTab && this.props.isActive) && styles.tabArea__tab_private_active,
-
- // Apply themeColor if tab is active and not private
- isThemed && styles.tabArea__tab_themed
+ this.props.showAudioTopBorder && styles.tabArea__tab_audioTopBorder
)}
- style={instanceStyles}
data-test-id='tab'
data-test-active-tab={this.props.isActive}
data-test-pinned-tab={this.props.isPinnedTab}
data-test-private-tab={this.props.isPrivateTab}
data-frame-key={this.props.frameKey}
draggable
- title={this.props.title}
+ title={this.props.isPreview ? null : this.props.title}
onDrag={this.onDrag}
onDragStart={this.onDragStart}
onDragEnd={this.onDragEnd}
@@ -396,6 +446,14 @@ class Tab extends React.Component {
)}>
+ {
+ this.props.visualTabIdDebug &&
+
+ [t:{this.props.tabId},(g:{this.props.guestInstanceId})]
+ [f:{this.props.frameKey}]
+ #[fi:{this.props.frameStateInternalIndex},ti:{this.props.tabIndex}]
+
+ }
@@ -409,20 +467,61 @@ class Tab extends React.Component {
const styles = StyleSheet.create({
tabArea: {
boxSizing: 'border-box',
- display: 'inline-block',
position: 'relative',
- verticalAlign: 'top',
overflow: 'hidden',
- height: '-webkit-fill-available',
- flex: 1,
-
+ flex: '1 1 0',
+ '--tab-margin-top': `-${theme.tab.borderWidth}px`,
+ // put the top border underneath tab-stip top border, and
+ // the left border underneath the previous tab's right border
+ margin: `var(--tab-margin-top) 0 0 -${theme.tab.borderWidth}px`,
+ border: `solid var(--tab-border-width, ${theme.tab.borderWidth}px) var(--tab-border-color)`,
+ // Border bottom is added to the tabArea__tab so that we do not get
+ // 45-degree angles when the bottom border is different color from the side borders.
+ // This could change when we can put the tab's background on this element,
+ // which can happen when tab dragging does not introduce a left/right 'space' when a tab
+ // is dragged over.
+ borderBottomWidth: `0 !important`, // aphrodite puts this above the border defined in the previous line, so use important :-(
+ zIndex: 100,
+ transformOrigin: 'bottom center',
+ minWidth: 0,
+ width: 0,
// no-drag is applied to the button and tab area
// ref: tabs__tabStrip__newTabButton on tabs.js
WebkitAppRegion: 'no-drag',
-
// There's a special case that tabs should span the full width
// if there are a full set of them.
- maxWidth: '184px'
+ maxWidth: '184px',
+ // Use css variables for some transition options so that we can change them
+ // with other classes below, without having to re-define the whole property.
+ // Avoid aphrodite bug which will change css variables
+ // to --tab--webkit-transition-duration by calling it 'transit'.
+ '--tab-transit-duration': theme.tab.transitionDurationOut,
+ '--tab-transit-easing': theme.tab.transitionEasingOut,
+ // z-index should be delayed when it changes, so that preview tab stays on top until
+ // its scale transition has completed
+ '--tab-zindex-delay': theme.tab.transitionDurationOut,
+ transition: ['box-shadow', 'transform', 'border', 'margin', 'opacity']
+ .map(prop => `${prop} var(--tab-transit-duration) var(--tab-transit-easing) 0s`)
+ .join(',') +
+ ', z-index var(--tab-zindex-duration, 0s) linear var(--tab-zindex-delay)',
+ '--tab-background': theme.tab.background,
+ '--tab-color': theme.tab.color,
+ '--tab-border-color': theme.tab.borderColor,
+ '--tab-background-hover': theme.tab.hover.background,
+ '--tab-default-icon-color': theme.tab.defaultFaviconColor,
+ ':hover': {
+ '--tab-background': `var(--tab-background-hover)`,
+ '--tab-color': `var(--tab-color-hover, ${theme.tab.color})`,
+ '--tab-default-icon-color': `var(--tab-default-icon-color-hover, ${theme.tab.defaultFaviconColor})`,
+ '--tab-border-color': `var(--tab-border-color-hover, ${theme.tab.borderColor})`,
+ '--tab-transit-duration': theme.tab.transitionDurationIn,
+ '--tab-transit-easing': theme.tab.transitionEasingIn,
+ '--tab-mouse-opacity': '1'
+ }
+ },
+
+ tabArea_instantTransition: {
+ '--tab-transit-duration': '0 !important'
},
tabArea_dragging_left: {
@@ -440,35 +539,119 @@ const styles = StyleSheet.create({
},
tabArea_isPinned: {
- flex: 'initial'
+ flex: 'initial',
+ width: 'auto'
},
tabArea_partOfFullPageSet: {
maxWidth: 'initial'
},
+ tabArea_isActive: {
+ '--tab-color': theme.tab.active.colorDark,
+ '--tab-background': theme.tab.active.background,
+ '--tab-background-hover': theme.tab.hover.active.background,
+ '--tab-border-color-bottom': 'var(--tab-background)',
+ '--tab-mouse-opacity': '0 !important'
+ },
+
+ tabArea_isPreview: {
+ '--tab-background': theme.tab.preview.background,
+ '--tab-background-hover': theme.tab.preview.background,
+ '--tab-color': theme.tab.active.colorDark,
+ '--tab-color-hover': theme.tab.active.colorDark,
+ '--tab-border-color': theme.tab.preview.background,
+ '--tab-border-color-hover': theme.tab.preview.background,
+ zIndex: 110,
+ transform: `scale(${theme.tab.preview.scale})`,
+ boxShadow: theme.tab.preview.boxShadow,
+ // want the zindex to change immediately when previewing, but delay when un-previewing
+ '--tab-zindex-delay': '0s',
+ '--tab-zindex-duration': '0s',
+ '--tab-transit-duration': theme.tab.transitionDurationIn,
+ '--tab-transit-easing': theme.tab.transitionEasingIn
+ },
+
+ tabArea_siblingIsPreview: {
+ // when un-previewing, if there's still another tab previewed
+ // then we want to immediately have that tab on top of the last-previewed tab
+ // but have the last previewed tab wait to be underneath the next tab in the DOM
+ '--tab-zindex-delay': '0s',
+ '--tab-zindex-duration': '2s',
+ willChange: 'transform'
+ },
+
+ tabArea_isActive_siblingIsPreview: {
+ opacity: '.5'
+ },
+
+ tabArea_private: {
+ '--tab-background': theme.tab.private.background,
+ '--tab-background-hover': theme.tab.hover.private.background
+ },
+
+ tabArea_private_active: {
+ '--tab-background': theme.tab.active.private.background,
+ '--tab-background-hover': theme.tab.active.private.background,
+ '--tab-color': theme.tab.active.private.color,
+ '--tab-color-hover': theme.tab.active.private.color,
+ '--tab-default-icon-color': theme.tab.active.private.defaultFaviconColor,
+ '--tab-default-icon-color-hover': theme.tab.active.private.defaultFaviconColor
+ },
+
+ tabArea_themed: {
+ '--tab-background': `var(--theme-color-bg)`,
+ '--tab-background-hover': 'var(--theme-color-bg)',
+ '--tab-color': `var(--theme-color-fg)`,
+ '--tab-color-hover': 'var(--theme-color-fg)',
+ '--tab-default-icon-color': 'var(--theme-color-default-icon)',
+ '--tab-default-icon-color-hover': 'var(--theme-color-default-icon)'
+ },
+
tabArea__tab: {
- borderWidth: '0 1px 0 0',
- borderStyle: 'solid',
- borderColor: theme.tab.borderColor,
boxSizing: 'border-box',
- color: theme.tab.color,
+ background: `var(--tab-background, ${theme.tab.background})`,
+ // make sure the tab element which contains the background color
+ // has a new layer, so that the tab title text is rendered with subpixel antialiasing
+ // that knows about both the foreground and background colors
display: 'flex',
- transition: theme.tab.transition,
- height: '-webkit-fill-available',
- width: '-webkit-fill-available',
+ transition: ['background-color', 'color', 'border']
+ .map(prop => `${prop} var(--tab-transit-duration) var(--tab-transit-easing) 0s`)
+ .join(','),
+ height: '100%',
alignItems: 'center',
justifyContent: 'space-between',
position: 'relative',
+ color: `var(--tab-color, ${theme.tab.color})`,
+ borderBottom: `solid var(--tab-border-width, ${theme.tab.borderWidth}px) var(--tab-border-color-bottom, var(--tab-border-color))`,
- ':hover': {
- background: theme.tab.hover.background
+ // mouse-tracking radial gradient
+ '::before': {
+ content: '" "',
+ position: 'absolute',
+ left: 'var(--tab-mouse-x)',
+ top: 0,
+ bottom: 0,
+ width: 'calc(100% * var(--tab-mouse-opacity, 0))',
+ background: `radial-gradient(
+ circle farthest-corner,
+ var(--tab-background-hover),
+ transparent
+ )`,
+ filter: 'brightness(var(--tab-mouse-brightness, 106%))',
+ transform: 'translateX(-50%)',
+ transition: 'opacity var(--tab-transit-duration) ease, width 0s linear var(--tab-transit-duration)',
+ opacity: 'var(--tab-mouse-opacity, 0)'
+ },
+ ':hover:before': {
+ // Show immediately, and fade-in opacity,
+ // but when leaving, wait for fade-out to finish before hiding.
+ transitionDelay: '0s'
}
},
tabArea__tab_audioTopBorder: {
- '::before': {
- zIndex: globalStyles.zindex.zindexTabsAudioTopBorder,
+ '::after': {
content: `''`,
display: 'block',
position: 'absolute',
@@ -476,7 +659,7 @@ const styles = StyleSheet.create({
left: 0,
right: 0,
height: '2px',
- background: 'lightskyblue'
+ background: theme.tab.icon.audio.color
}
},
@@ -493,47 +676,6 @@ const styles = StyleSheet.create({
margin: 0
},
- // Windows specific style
- tabArea__tab_forWindows: {
- color: theme.tab.forWindows.color
- },
-
- tabArea__tab_active: {
- background: theme.tab.active.background,
-
- ':hover': {
- background: theme.tab.active.background
- }
- },
-
- tabArea__tab_private: {
- background: theme.tab.private.background,
-
- ':hover': {
- color: theme.tab.active.private.color,
- background: theme.tab.active.private.background
- }
- },
-
- tabArea__tab_private_active: {
- background: theme.tab.active.private.background,
- color: theme.tab.active.private.color,
-
- ':hover': {
- background: theme.tab.active.private.background
- }
- },
-
- tabArea__tab_themed: {
- color: `var(--theme-color-fg, inherit)`,
- background: `var(--theme-color-bg, inherit)`,
-
- ':hover': {
- color: `var(--theme-color-fg, inherit)`,
- background: `var(--theme-color-bg, inherit)`
- }
- },
-
// The sentinel is responsible to respond to tabs
// intersection state. This is an empty hidden element
// which `width` value shouldn't be changed unless the intersection
@@ -547,20 +689,30 @@ const styles = StyleSheet.create({
},
tabArea__tab__identity: {
- justifyContent: 'flex-start',
- alignItems: 'center',
- overflow: 'hidden',
- display: 'flex',
flex: '1',
minWidth: '0', // @see https://bugzilla.mozilla.org/show_bug.cgi?id=1108514#c5
- margin: `0 ${globalStyles.spacing.defaultTabMargin}`
+ margin: `calc(var(--tab-border-width, 0) * -1px) 6px 0 ${globalStyles.spacing.defaultTabMargin}`, // bring the right margin closer as we do fade-out
+ // make sure title text is not cut off, but is also vertically centered
+ // by giving it full height of favicon
+ height: theme.tab.identityHeight,
+ display: 'flex',
+ justifyContent: 'flex-start',
+ alignItems: 'center',
+ overflow: 'visible'
},
tabArea__tab__identity_centered: {
- justifyContent: 'center',
flex: 'auto',
+ justifyContent: 'center',
padding: 0,
margin: 0
+ },
+
+ tabArea__tab__tabIdDebug: {
+ fontSize: '8px',
+ display: 'flex',
+ flexDirection: 'column',
+ flexWrap: 'wrap'
}
})
diff --git a/app/renderer/components/tabs/tabs.js b/app/renderer/components/tabs/tabs.js
index afee41bdf53..aafc52b8000 100644
--- a/app/renderer/components/tabs/tabs.js
+++ b/app/renderer/components/tabs/tabs.js
@@ -25,7 +25,6 @@ const dragTypes = require('../../../../js/constants/dragTypes')
const settings = require('../../../../js/constants/settings')
// Utils
-const cx = require('../../../../js/lib/classSet')
const contextMenus = require('../../../../js/contextMenus')
const {getCurrentWindowId, isFocused} = require('../../currentWindow')
const dnd = require('../../../../js/dnd')
@@ -36,8 +35,6 @@ const {getSetting} = require('../../../../js/settings')
const globalStyles = require('../styles/global')
const {theme} = require('../styles/theme')
-const newTabButton = require('../../../../img/toolbar/newtab_btn.svg')
-
class Tabs extends React.Component {
constructor (props) {
super(props)
@@ -138,7 +135,8 @@ class Tabs extends React.Component {
const pageIndex = frameStateUtil.getTabPageIndex(currentWindow)
const tabsPerTabPage = Number(getSetting(settings.TABS_PER_PAGE))
const startingFrameIndex = pageIndex * tabsPerTabPage
- const unpinnedTabs = frameStateUtil.getNonPinnedFrames(currentWindow) || Immutable.List()
+ const unpinnedTabs = frameStateUtil.getNonPinnedFrames(currentWindow)
+ .filter(frame => frame.get('tabStripWindowId') === getCurrentWindowId())
const currentTabs = unpinnedTabs
.slice(startingFrameIndex, startingFrameIndex + tabsPerTabPage)
.map((tab) => tab.get('key'))
@@ -149,6 +147,7 @@ class Tabs extends React.Component {
const props = {}
// used in renderer
props.previewTabPageIndex = currentWindow.getIn(['ui', 'tabs', 'previewTabPageIndex'])
+ props.previewTabFrameKey = frameStateUtil.getPreviewFrameKey(currentWindow)
props.currentTabs = currentTabs
props.partOfFullPageSet = currentTabs.size === tabsPerTabPage
props.onNextPage = currentTabs.size >= tabsPerTabPage && totalPages > pageIndex + 1
@@ -165,6 +164,7 @@ class Tabs extends React.Component {
}
render () {
+ const isTabPreviewing = this.props.previewTabFrameKey != null
this.tabRefs = []
return
+ >
+
+
+
+
}
@@ -232,7 +235,6 @@ const styles = StyleSheet.create({
boxSizing: 'border-box',
display: 'flex',
flex: 1,
- overflow: 'auto',
padding: 0,
height: '-webkit-fill-available',
position: 'relative',
@@ -244,7 +246,11 @@ const styles = StyleSheet.create({
display: 'flex',
flex: 1,
zIndex: globalStyles.zindex.zindexTabs,
- overflow: 'hidden'
+ position: 'relative'
+ },
+
+ tabs__tabStrip_isTabPreviewing: {
+ overflow: 'initial'
},
tabs__tabStrip_isPreview: globalStyles.animations.tabFadeIn,
@@ -255,8 +261,14 @@ const styles = StyleSheet.create({
tabs__tabStrip__navigation: {
fontSize: '21px',
- height: globalStyles.spacing.tabsToolbarHeight,
- lineHeight: globalStyles.spacing.tabsToolbarHeight
+ height: 'auto',
+ display: 'flex',
+ justifyContent: 'center',
+ alignItems: 'center'
+ },
+
+ tabs__tabStrip__navigation__icon: {
+ lineHeight: 0
},
tabs__tabStrip__navigation_prev: {
@@ -273,23 +285,34 @@ const styles = StyleSheet.create({
},
tabs__tabStrip__newTabButton: {
- background: theme.tabsToolbar.button.backgroundColor,
- minWidth: globalStyles.spacing.tabsToolbarHeight,
- minHeight: globalStyles.spacing.tabsToolbarHeight,
- lineHeight: globalStyles.spacing.tabsToolbarHeight,
- WebkitMaskImage: `url(${newTabButton})`,
- WebkitMaskRepeat: 'no-repeat',
- WebkitMaskPosition: 'center',
- WebkitMaskSize: '12px 12px',
- WebkitMaskOrigin: 'border',
-
- // no-drag is applied to the button and tab area
+ '--new-tab-button-line-color': theme.tabsToolbar.button.backgroundColor,
+ // no-drag is applied to each button and tab
WebkitAppRegion: 'no-drag',
-
+ // don't look like a native button
+ WebkitAppearance: 'none',
+ border: 'none',
+ background: 'none',
+ // ensure it's a square
+ width: globalStyles.spacing.tabsToolbarHeight,
+ display: 'flex',
+ alignItems: 'center',
+ justifyContent: 'center',
':hover': {
- opacity: 1.0,
- backgroundColor: theme.tabsToolbar.button.onHover.backgroundColor
+ '--new-tab-button-line-color': theme.tabsToolbar.button.onHover.backgroundColor
}
+ },
+
+ tabs__tabStrip__newTabButton__icon: {
+ width: '12px'
+ },
+
+ tabs__tabStrip__newTabButton__icon__line: {
+ fill: 'none',
+ stroke: 'var(--new-tab-button-line-color)',
+ 'stroke-linecap': 'round',
+ 'stroke-linejoin': 'round',
+ 'stroke-width': '2px',
+ transition: '.12s stroke ease'
}
})
diff --git a/app/renderer/components/tabs/tabsToolbar.js b/app/renderer/components/tabs/tabsToolbar.js
index fb4a008a916..9cf6cc737ad 100644
--- a/app/renderer/components/tabs/tabsToolbar.js
+++ b/app/renderer/components/tabs/tabsToolbar.js
@@ -77,7 +77,7 @@ class TabsToolbar extends React.Component {
{})
+ this.onZoomChange = onZoomChange || (() => {})
+ this.webviewPool = []
+ // when contents are destroyed, don't remove the webview immediately,
+ // wait for a potential new view to be displayed before removing.
+ // Ensures a smooth transition with no 'white flash'
+ this.webviewsPendingRemoval = []
+ this.attachedWebview = null
+ this.ensureWebviewPoolSize()
+ }
+
+ debugLog (...messages) {
+ if (this.shouldLogEvents) {
+ console.log('%cWebviewDisplay', 'color: #ccc', ...messages)
+ }
+ }
+
+ ensureWebviewPoolSize () {
+ // There should be 1 in the pool and 1 attached,
+ // or 2 in the pool.
+ let requiredPoolSize = this.attachedWebview ? 1 : 2
+ const poolDeficit = requiredPoolSize - this.webviewPool.length
+ this.debugLog(`Adding ${poolDeficit} webview(s)`)
+ for (let i = 0; i < poolDeficit; i++) {
+ this.addPooledWebview()
+ }
+ }
+
+ addPooledWebview () {
+ const newWebview = this.createPooledWebview()
+ newWebview.dataset.webviewReplaceCount = i++
+ this.webviewPool.push(newWebview)
+ this.containerElement.appendChild(newWebview)
+ }
+
+ getPooledWebview () {
+ this.ensureWebviewPoolSize()
+ return this.webviewPool.pop()
+ }
+
+ createPooledWebview () {
+ this.debugLog('creating a webview')
+ const webview = document.createElement('webview')
+ webview.classList.add(this.classNameWebview)
+ if (this.onFocus) {
+ webview.addEventListener('focus', this.onFocus)
+ }
+ // support focusing on active tab when navigation complete
+ webview.addEventListener('did-navigate', (e) => {
+ // do not steal focus if is new tab page, or if we're about to
+ // switch away
+ const isNewTabPage = getBaseUrl(e.url) === getTargetAboutUrl('about:newtab')
+ const isSwitchingAway = this.attachingToTabId && this.attachingToTabId !== this.activeTabId
+ if (!isNewTabPage && !isSwitchingAway) {
+ webview.focus()
+ }
+ })
+ let wheelDeltaY
+ const performZoom = debounce(() => {
+ if (wheelDeltaY > 0) {
+ webview.zoomIn()
+ this.onZoomChange(webview.getZoomPercent())
+ } else if (wheelDeltaY < 0) {
+ webview.zoomOut()
+ this.onZoomChange(webview.getZoomPercent())
+ }
+ wheelDeltaY = 0
+ }, 20)
+ webview.addEventListener('mousewheel', (e) => {
+ if (e.ctrlKey) {
+ e.preventDefault()
+ wheelDeltaY = (wheelDeltaY || 0) + e.wheelDeltaY
+ performZoom()
+ } else {
+ wheelDeltaY = 0
+ }
+ })
+ webview.addEventListener('tab-id-changed', (e) => {
+ this.debugLog('webview tab-id-changed to tabId', e.tabID)
+ })
+ webview.addEventListener('tab-detached-at', () => {
+ this.debugLog('webview tab-detached-at')
+ webview.detachGuest()
+ })
+ const debugEvents = ['tab-replaced-at', 'tab-id-changed', 'will-attach', 'did-attach', 'did-detach', 'will-detach']
+ for (const event of debugEvents) {
+ webview.addEventListener(event, () => {
+ this.debugLog(` event ${event}`, webview)
+ })
+ }
+ return webview
+ }
+
+ attachActiveTab (tabId) {
+ this.debugLog(`attachActiveTab`, tabId)
+ if (tabId == null) {
+ throw new Error('tabId is not valid')
+ }
+ // do nothing if repeat call to same guest Id as attached or attaching
+ if (
+ (!this.attachingToTabId && tabId === this.activeTabId) ||
+ tabId === this.attachingToTabId
+ ) {
+ this.debugLog('already attaching this tab, nothing to do.')
+ return
+ }
+ // are we waiting to attach to something different already?
+ if (this.attachingToTabId != null) {
+ // wait for that attach to finish, and queue this one up to then display
+ // if we have something already in the queue, then remove it
+ this.debugLog('attach already in progress, queuing replacement tab')
+ this.attachingToTabId = tabId
+ return
+ }
+ // fresh attach
+ this.swapWebviewOnAttach(tabId, this.getPooledWebview(), this.attachedWebview)
+ }
+
+ swapWebviewOnAttach (tabId, toAttachWebview, lastAttachedWebview) {
+ if (this.shouldLogEvents) {
+ console.group(`swapWebviewOnAttach: attach ${tabId}`)
+ }
+ this.debugLog(`swapWebviewOnAttach: Using webview #${toAttachWebview.dataset.webviewReplaceCount}`)
+
+ this.attachingToTabId = tabId
+ const t0 = window.performance.now()
+ const fnEnd = () => {
+ if (this.shouldLogEvents) {
+ console.groupEnd()
+ }
+ }
+
+ // fn for smoothly hiding the previously active view before showing this one
+ const showAttachedView = async () => {
+ // if we have decided to show a different guest in the time it's taken to attach and show
+ // then do not show the intermediate, instead detach it and wait for the next attach
+ if (tabId !== this.attachingToTabId) {
+ this.debugLog('swapWebviewOnAttach: detaching tab from just-attached view because it was not the desired tab anymore')
+ remote.unregisterEvents(tabId, tabEventHandler)
+ await toAttachWebview.detachGuest()
+ // if it happens to be the webview which is already being shown
+ if (this.attachingToTabId === this.activeTabId) {
+ // release everything and do not continue
+ this.webviewPool.push(toAttachWebview)
+ this.attachingToTabId = null
+ this.debugLog('swapWebviewOnAttach: Asked to show already-attached view, so leaving that alone and returning new attached to pool')
+ fnEnd()
+ return
+ }
+ // start again, but with different guest
+ this.debugLog('swapWebviewOnAttach: Asked to show a different tab than the one we just attached, continuing with that one')
+ fnEnd()
+ this.swapWebviewOnAttach(this.attachingToTabId, toAttachWebview, lastAttachedWebview)
+ return
+ }
+ this.debugLog(`swapWebviewOnAttach: webview waiting for paint ${window.performance.now() - t0}ms`)
+
+ // At the point where we are attached to the guest we *still* want to be displaying.
+ // So, show it.
+ // TODO: remove attaching class name, since we no longer need to
+ // wait for tab to paint and have an async gap between adding attaching
+ // class and attached class.
+ toAttachWebview.classList.add(this.classNameWebviewAttaching)
+ this.debugLog('swapWebviewOnAttach: unregisterEvents', tabId)
+ remote.unregisterEvents(tabId, tabEventHandler)
+ this.debugLog(`swapWebviewOnAttach: webview finished waiting for paint, showing... ${window.performance.now() - t0}ms`)
+ toAttachWebview.classList.add(this.classNameWebviewAttached)
+ // If we are already showing another frame, we wait for this new frame to display before
+ // hiding (and removing) the other frame's webview, so that we avoid a white flicker
+ // between attach.
+ if (lastAttachedWebview) {
+ // finalize display classes
+ lastAttachedWebview.classList.remove(this.classNameWebviewAttached)
+ toAttachWebview.classList.remove(this.classNameWebviewAttaching)
+ this.debugLog('swapWebviewOnAttach: detaching guest from last attached webview...')
+ // TODO: don't neccessarily need to do this, since next attach should detach guest
+ await lastAttachedWebview.detachGuest()
+ // return to the pool,
+ this.webviewPool.push(lastAttachedWebview)
+ }
+ // check again if there's a pending view
+ // since we may have done something async
+ const pendingTabId = this.attachingToTabId
+ // reset state
+ this.activeTabId = tabId
+ this.attachedWebview = toAttachWebview
+ this.attachingToTabId = null
+ // perform next attach if there's one waiting
+ if (pendingTabId !== tabId) {
+ this.debugLog('swapWebviewOnAttach - another attach pending, continuing with that attach request')
+ fnEnd()
+ this.swapWebviewOnAttach(pendingTabId, this.getPooledWebview(), this.attachedWebview)
+ } else {
+ if (this.shouldFocusOnAttach) {
+ this.shouldFocusOnAttach = false
+ toAttachWebview.focus()
+ }
+ fnEnd()
+ }
+ }
+
+ // we may get a will-destroy before a did-attach, if that happens, abandon
+ const onDestroyedInsteadOfAttached = () => {
+ this.debugLog('swapWebviewOnAttach: destroyed instead of attached...')
+ // continue with next attach request if we've had one in the meantime
+ if (this.attachingToTabId !== tabId) {
+ // if it happens to be the webview which is already being shown
+ if (this.attachingToTabId === this.activeTabId) {
+ // release everything and do not continue
+ this.webviewPool.push(toAttachWebview)
+ this.attachingToTabId = null
+ this.debugLog('swapWebviewOnAttach: Asked to show already-attached view, so leaving that alone and returning new attached to pool')
+ fnEnd()
+ return
+ }
+ // start again, but with different tab
+ this.debugLog('swapWebviewOnAttach: Asked to show a different tab than the one we just attached, continuing with that one')
+ fnEnd()
+ this.swapWebviewOnAttach(this.attachingToTabId, toAttachWebview, lastAttachedWebview)
+ return
+ }
+ // reset state and do not continue
+ this.webviewPool.push(toAttachWebview)
+ this.attachingToTabId = null
+ fnEnd()
+ }
+
+ // monitor for destroy or attach after we ask for attach
+ this.debugLog('swapWebviewOnAttach: getting web contents for', tabId, '...')
+ let handled = false
+ const tabEventHandler = (event) => {
+ this.debugLog('pooled got event for tab', tabId, event.type)
+ switch (event.type) {
+ case 'will-destroy':
+ case 'destroyed':
+ // don't need to bump view
+ remote.unregisterEvents(tabId, tabEventHandler)
+ onDestroyedInsteadOfAttached()
+ break
+ case 'did-attach':
+ // only handle once,
+ // tab can attach, detach and attach again for some reason
+ // but we don't remove handler here as we want to know
+ // when did-detach happens after did-attach but before
+ // we're done displaying
+ if (!handled) {
+ handled = true
+ // don't need to bump view
+ showAttachedView()
+ }
+ break
+ case 'did-detach':
+ // we want to know if the tab has detached before we're done
+ if (this.shouldLogEvents) {
+ console.warn('swapWebviewOnAttach: webview detached during/after attach!')
+ }
+ break
+ }
+ }
+
+ remote.registerEvents(tabId, tabEventHandler)
+
+ // check if the contents are already destroyed before we attach
+ remote.getWebContents(tabId, (webContents) => {
+ if (!webContents || webContents.isDestroyed()) {
+ onDestroyedInsteadOfAttached()
+ remote.unregisterEvents(tabId, tabEventHandler)
+ return
+ }
+ // use the guest instance id
+ const guestInstanceId = webContents.guestInstanceId
+ this.debugLog('swapWebviewOnAttach: attaching active guest instance ', guestInstanceId, 'to webview', toAttachWebview)
+ // setImmediate is a bit of a hacky way to ensure that registerEvents handler is registered
+ setImmediate(() => toAttachWebview.attachGuest(guestInstanceId, webContents))
+ this.debugLog(`swapWebviewOnAttach: Waiting.... ${window.performance.now() - t0}ms`)
+ })
+ }
+
+ getActiveWebview () {
+ return this.attachedWebview
+ }
+
+ focusActiveWebview () {
+ if (!this.attachingToTabId && this.attachedWebview) {
+ this.attachedWebview.focus()
+ } else if (this.attachingToTabId) {
+ this.shouldFocusOnAttach = true
+ }
+ }
+
+ removePendingWebviews () {
+ if (this.webviewsPendingRemoval.length) {
+ const webviewsToRemove = this.webviewsPendingRemoval
+ this.webviewsPendingRemoval = []
+ for (const webview of webviewsToRemove) {
+ if (!webview) {
+ continue
+ }
+ // just in case... (don't want to remove a webview with contents still attached
+ // since the contents will be destroyed)
+ webview.detachGuest()
+ // remove from DOM and allow garbage collection / event removal
+ webview.remove()
+ }
+ }
+ }
+}
diff --git a/app/renderer/reducers/contextMenuReducer.js b/app/renderer/reducers/contextMenuReducer.js
index 4f6c02b3f46..de189624937 100644
--- a/app/renderer/reducers/contextMenuReducer.js
+++ b/app/renderer/reducers/contextMenuReducer.js
@@ -55,14 +55,20 @@ const validateState = function (state) {
return state
}
-function generateMuteFrameList (framePropsList, muted) {
- return framePropsList.map((frameProp) => {
- return {
- frameKey: frameProp.get('key'),
- tabId: frameProp.get('tabId'),
- muted: muted && frameProp.get('audioPlaybackActive') && !frameProp.get('audioMuted')
+function generateMuteFrameActions (framePropsList, mute) {
+ return framePropsList.filter(frame => {
+ if (mute) {
+ // only frames which are playing audio and haven't been asked to be muted
+ return frame.get('audioPlaybackActive') && !frame.get('audioMuted')
}
+ // only frames which are not playing audio or have been asked to be muted
+ return frame.get('audioMuted')
})
+ .map(frame => ({
+ tabId: frame.get('tabId'),
+ frameKey: frame.get('key'),
+ muted: mute
+ }))
}
const onTabPageMenu = function (state, action) {
@@ -85,12 +91,12 @@ const onTabPageMenu = function (state, action) {
const template = [{
label: locale.translation('unmuteTabs'),
click: () => {
- windowActions.muteAllAudio(generateMuteFrameList(tabPageFrames, false))
+ windowActions.muteAllAudio(generateMuteFrameActions(tabPageFrames, false))
}
}, {
label: locale.translation('muteTabs'),
click: () => {
- windowActions.muteAllAudio(generateMuteFrameList(tabPageFrames, true))
+ windowActions.muteAllAudio(generateMuteFrameActions(tabPageFrames, true))
}
}, {
label: locale.translation('closeTabPage'),
@@ -402,12 +408,12 @@ const showBookmarkFolderInit = (state, parentBookmarkFolderKey) => {
}
}]
}
- return bookmarkItemsInit(state, items)
+ return bookmarkItemsInit(appState, state, items)
}
-const bookmarkItemsInit = (state, items) => {
+const bookmarkItemsInit = (appState, state, items) => {
const activeFrame = frameStateUtil.getActiveFrame(state) || Immutable.Map()
- const showFavicon = bookmarkUtil.showFavicon()
+ const showFavicon = bookmarkUtil.showFavicon(appState)
const template = []
for (let site of items) {
const siteKey = site.get('key')
@@ -483,7 +489,7 @@ const onMoreBookmarksMenu = (state, action) => {
newSites = newSites.push(bookmarksState.findBookmark(appState, key))
}
- const menuTemplate = bookmarkItemsInit(state, newSites)
+ const menuTemplate = bookmarkItemsInit(appState, state, newSites)
menuTemplate.push({
l10nLabelId: 'moreBookmarks',
diff --git a/app/renderer/reducers/frameReducer.js b/app/renderer/reducers/frameReducer.js
index 1460bfc54f7..ea619e13c38 100644
--- a/app/renderer/reducers/frameReducer.js
+++ b/app/renderer/reducers/frameReducer.js
@@ -18,9 +18,14 @@ const appActions = require('../../../js/actions/appActions')
const frameStateUtil = require('../../../js/state/frameStateUtil')
const {getSourceAboutUrl, getSourceMagnetUrl} = require('../../../js/lib/appUrlUtil')
const {isURL, isPotentialPhishingUrl, getUrlFromInput} = require('../../../js/lib/urlutil')
+const {getCurrentWindowId} = require('../currentWindow')
const setFullScreen = (state, action) => {
const index = frameStateUtil.getIndexByTabId(state, action.tabId)
+ if (index < 0) {
+ console.error('frame not found for setFullScreen: ', index)
+ return state
+ }
return state.mergeIn(['frames', index], {
isFullScreen: action.isFullScreen !== undefined ? action.isFullScreen : state.getIn(['frames', index].concat('isFullScreen')),
showFullScreenWarning: action.showFullScreenWarning
@@ -77,8 +82,57 @@ const getLocation = (location) => {
return location
}
+function setFrameChangedIndex (state, frame, currentIndex, newIndex) {
+ let frames = frameStateUtil.getFrames(state)
+ if (newIndex >= frames.size) {
+ console.error(`Cannot move frame to index ${newIndex} from ${currentIndex} because it is invalid for a frame List of size ${frames.size}!`)
+ return state
+ }
+ // put the frame at the correct index
+ frames = frames
+ .splice(currentIndex, 1)
+ .splice(newIndex, 0, frame)
+ state = state.set('frames', frames)
+ state = frameStateUtil.updateFramesInternalIndex(state, Math.min(currentIndex, newIndex))
+ state = frameStateUtil.moveFrame(state, frame.get('tabId'), newIndex)
+
+ // Since the tab could have changed pages, update the tab page as well
+ const activeFrame = frameStateUtil.getActiveFrame(state)
+ // avoid the race-condition of updating the tabPage
+ // while active frame is not yet defined
+ if (activeFrame) {
+ // Update tab page index to the active tab in case the active tab changed
+ state = frameStateUtil.updateTabPageIndex(state, activeFrame.get('tabId'))
+ // after tabPageIndex is updated we need to update framesInternalIndex too
+ // TODO: really? updateTabPageIndex does not seem to change anything related
+ state = frameStateUtil
+ .updateFramesInternalIndex(state, Math.min(currentIndex, newIndex))
+ }
+ // clear preview
+ state = frameStateUtil.setPreviewFrameKey(state, null)
+ return state
+}
+
const frameReducer = (state, action, immutableAction) => {
switch (action.actionType) {
+ case appConstants.APP_TAB_INSERTED_TO_TAB_STRIP: {
+ const tabId = immutableAction.get('tabId')
+ const index = frameStateUtil.getIndexByTabId(state, tabId)
+ if (index === -1) {
+ console.error(
+ 'frame not found for tab inserted to tab strip',
+ tabId,
+ (state.get('frames') || Immutable.Map()).toJS(),
+ (state.get('framesInternal') || Immutable.Map()).toJS()
+ )
+ break
+ }
+ state = state.mergeIn(['frames', index], {
+ tabStripWindowId: getCurrentWindowId()
+ })
+ break
+ }
+ case windowConstants.WINDOW_REMOVE_FRAME:
case appConstants.APP_TAB_CLOSED: {
const tabId = immutableAction.get('tabId')
const frame = frameStateUtil.getFrameByTabId(state, tabId)
@@ -92,10 +146,27 @@ const frameReducer = (state, action, immutableAction) => {
}
break
}
+ case appConstants.APP_TAB_MOVED: {
+ const tabId = immutableAction.get('tabId')
+ const newIndex = immutableAction.get('toIndex')
+ if (newIndex == null || newIndex === -1) {
+ break
+ }
+ let frame = frameStateUtil.getFrameByTabId(state, tabId)
+ if (!frame) {
+ break
+ }
+ let currentIndex = frameStateUtil.getIndexByTabId(state, tabId)
+ if (currentIndex == null || currentIndex === newIndex) {
+ break
+ }
+ state = setFrameChangedIndex(state, frame, currentIndex, newIndex)
+ break
+ }
case appConstants.APP_TAB_UPDATED:
// This case will be fired for both tab creation and tab update.
const tab = immutableAction.get('tabValue')
- const changeInfo = immutableAction.get('changeInfo')
+ const changeInfo = immutableAction.get('changeInfo') || Immutable.Map()
if (!tab) {
break
}
@@ -107,39 +178,26 @@ const frameReducer = (state, action, immutableAction) => {
if (!frame) {
break
}
- let frames = state.get('frames')
const index = tab.get('index')
+ // stop being fullscreen if made inactive and was fullscreen
+ if (changeInfo.get('active') === false && frame.get('isFullScreen')) {
+ setImmediate(() => appActions.tabSetFullScreen(tabId, false))
+ }
// If front end doesn't know about this tabId, then do nothing!
let sourceFrameIndex = frameStateUtil.getIndexByTabId(state, tabId)
if (sourceFrameIndex == null) {
break
}
if (index != null &&
- sourceFrameIndex !== index &&
- // Only update the index once the frame is known.
- // If it is not known, it will just happen later on the next update.
- index < frameStateUtil.getFrames(state).size) {
- frame = frame.set('index', index)
- frames = frames
- .splice(sourceFrameIndex, 1)
- .splice(index, 0, frame)
- state = state.set('frames', frames)
- // Since the tab could have changed pages, update the tab page as well
- state = frameStateUtil.updateFramesInternalIndex(state, Math.min(sourceFrameIndex, index))
- state = frameStateUtil.moveFrame(state, tabId, index)
-
- const activeFrame = frameStateUtil.getActiveFrame(state)
- // avoid the race-condition of updating the tabPage
- // while active frame is not yet defined
- if (activeFrame) {
- // Update tab page index to the active tab in case the active tab changed
- state = frameStateUtil.updateTabPageIndex(state, activeFrame.get('tabId'))
- // after tabPageIndex is updated we need to update framesInternalIndex too
- state = frameStateUtil
- .updateFramesInternalIndex(state, Math.min(sourceFrameIndex, index))
+ index !== -1 &&
+ sourceFrameIndex !== index
+ ) {
+ const stateWithFrameMoved = setFrameChangedIndex(state, frame, sourceFrameIndex, index)
+ // move forward with new index if index change was valid
+ if (stateWithFrameMoved !== state) {
+ sourceFrameIndex = index
+ state = stateWithFrameMoved
}
- state = frameStateUtil.setPreviewFrameKey(state, null)
- sourceFrameIndex = index
}
const pinned = immutableAction.getIn(['changeInfo', 'pinned'])
@@ -212,24 +270,28 @@ const frameReducer = (state, action, immutableAction) => {
if (!framePath) {
break
}
- state = state.mergeIn(framePath, {
+ const isNewTabUrl = action.location === 'about:newtab'
+ let frameUpdateData = {
location: action.location
- })
+ }
if (!action.isNavigatedInPage) {
- state = state.mergeIn(framePath, {
+ frameUpdateData = {
adblock: {},
audioPlaybackActive: false,
- computedThemeColor: undefined,
httpsEverywhere: {},
icon: undefined,
location: action.location,
noScript: {},
- themeColor: undefined,
title: '',
trackingProtection: {},
fingerprintingProtection: {}
- })
+ }
+ if (!isNewTabUrl) {
+ frameUpdateData.computedThemeColor = undefined
+ frameUpdateData.themeColor = undefined
+ }
}
+ state = state.mergeIn(framePath, frameUpdateData)
// For potential phishing pages, show a warning
state = state.setIn(['ui', 'siteInfo', 'isVisible'],
isPotentialPhishingUrl(action.location) && frameStateUtil.isFrameKeyActive(state, action.key))
@@ -249,11 +311,8 @@ const frameReducer = (state, action, immutableAction) => {
appActions.tabCloseRequested(frame.get('tabId'))
})
break
- case windowConstants.WINDOW_CLOSE_FRAME:
- state = closeFrame(state, action)
- break
- case windowConstants.WINDOW_SET_FULL_SCREEN:
+ case appConstants.APP_TAB_SET_FULL_SCREEN:
state = setFullScreen(state, action)
break
// TODO(bbondy): We should remove this window action completely and just go directly to
diff --git a/app/renderer/rendererFrameTracker.js b/app/renderer/rendererFrameTracker.js
new file mode 100644
index 00000000000..b03ca1a1998
--- /dev/null
+++ b/app/renderer/rendererFrameTracker.js
@@ -0,0 +1,68 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Immutable = require('immutable')
+const windowStore = require('../../js/stores/windowStore')
+const appActions = require('../../js/actions/appActions')
+const debounce = require('../../js/lib/debounce')
+
+function mapFramesByKey (immutableFrameList) {
+ const frames = { }
+ for (const frame of immutableFrameList.values()) {
+ const frameKey = frame.get('key')
+ if (frameKey == null) {
+ console.error('immutableFrameList had frame with invalid key', { frame, immutableFrameList })
+ continue
+ }
+ frames[frameKey] = frame.delete('lastAccessedTime')
+ }
+ return frames
+}
+
+module.exports = function trackFrameChanges () {
+ // relay frame changes back to browser
+ let frames = { }
+ let idleCallbackId = null
+
+ // compare frames to previous state and only send those changed in an action
+ const relayFrameChanges = () => {
+ idleCallbackId = null
+ const state = windowStore.state
+ const shouldDebugStoreActions = state.get('debugStoreActions')
+ let t0
+ if (shouldDebugStoreActions) {
+ t0 = window.performance.now()
+ }
+ const currentFrameState = state.get('frames')
+ if (!currentFrameState) {
+ return
+ }
+ const lastFrames = frames
+ frames = mapFramesByKey(currentFrameState)
+ const changedFrames = []
+ for (const frameKey in frames) {
+ // does it exist in the last version of state?
+ const frame = frames[frameKey]
+ const lastFrame = lastFrames[frameKey]
+ if (!lastFrame || !lastFrame.equals(frame)) {
+ changedFrames.push(Immutable.Map({ frame }))
+ }
+ }
+ if (changedFrames.length) {
+ appActions.framesChanged(changedFrames)
+ }
+ if (shouldDebugStoreActions) {
+ console.log(`%cSpent ${window.performance.now() - t0}ms figuring out frame changes (${changedFrames.length} changed)`, 'color: #bbb')
+ }
+ }
+
+ // compare frames when state changes debounced, and only when thread is idle
+ const onWindowStoreChanged = debounce(() => {
+ if (!idleCallbackId) {
+ idleCallbackId = window.requestIdleCallback(relayFrameChanges, { timeout: 1000 })
+ }
+ }, 250)
+
+ windowStore.addChangeListener(onWindowStoreChanged)
+}
diff --git a/app/renderer/rendererShortcutHandler.js b/app/renderer/rendererShortcutHandler.js
new file mode 100644
index 00000000000..da374918208
--- /dev/null
+++ b/app/renderer/rendererShortcutHandler.js
@@ -0,0 +1,225 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const electron = require('electron')
+
+const windowStore = require('../../js/stores/windowStore')
+const appStore = require('../../js/stores/appStoreRenderer')
+
+const windowActions = require('../../js/actions/windowActions')
+const appActions = require('../../js/actions/appActions')
+const tabActions = require('../common/actions/tabActions')
+const webviewActions = require('../../js/actions/webviewActions')
+
+const tabState = require('../common/state/tabState')
+const frameStateUtil = require('../../js/state/frameStateUtil')
+const getSetting = require('../../js/settings').getSetting
+
+const UrlUtil = require('../../js/lib/urlutil')
+const {
+ aboutUrls,
+ isSourceMagnetUrl,
+ getBaseUrl
+} = require('../../js/lib/appUrlUtil')
+const config = require('../../js/constants/config')
+const settings = require('../../js/constants/settings')
+
+function getWebContents (tabId, cb) {
+ electron.remote.getWebContents(tabId, (webContents) => {
+ if (webContents && !webContents.isDestroyed()) {
+ cb(webContents)
+ } else {
+ cb()
+ }
+ })
+}
+
+function isAboutPageURL (url) {
+ return aboutUrls.get(getBaseUrl(url))
+}
+
+function isTorrentViewerURL (url) {
+ const isEnabled = getSetting(settings.TORRENT_VIEWER_ENABLED)
+ return isEnabled && isSourceMagnetUrl(url)
+}
+
+function isPDFJSURL (url) {
+ const pdfjsOrigin = `chrome-extension://${config.PDFJSExtensionId}/`
+ return url && url.startsWith(pdfjsOrigin)
+}
+
+module.exports = {
+ handleActiveFrameShortcut (shortcut, e, args) {
+ const frameKey = frameStateUtil.getActiveFrame(windowStore.state).get('key')
+ handleShortcut(frameKey, shortcut, e, args)
+ },
+ handleFrameShortcut: handleShortcut
+}
+
+function handleShortcut (frameKey, shortcut, e, args) {
+ switch (shortcut) {
+ case 'toggle-dev-tools': {
+ appActions.toggleDevTools(frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey))
+ break
+ }
+ case 'stop': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ getWebContents(tabId, (webContents) => {
+ if (webContents) {
+ webContents.stop()
+ }
+ })
+ break
+ }
+ case 'zoom-in': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ getWebContents(tabId, (webContents) => {
+ if (webContents) {
+ webContents.zoomIn()
+ // TODO: better to respond to a muon Tab event `zoom-changed` via ZoomObserver
+ // if that is provided in the future
+ tabActions.zoomChanged(tabId, webContents.getZoomPercent())
+ }
+ })
+ break
+ }
+ case 'zoom-out': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ getWebContents(tabId, (webContents) => {
+ if (webContents) {
+ webContents.zoomOut()
+ // TODO: better to respond to a muon Tab event `zoom-changed` via ZoomObserver
+ // if that is provided in the future
+ tabActions.zoomChanged(tabId, webContents.getZoomPercent())
+ }
+ })
+ break
+ }
+ case 'zoom-reset': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ getWebContents(tabId, (webContents) => {
+ if (webContents) {
+ webContents.zoomReset()
+ // TODO: better to respond to a muon Tab event `zoom-changed` via ZoomObserver
+ // if that is provided in the future
+ tabActions.zoomChanged(tabId, webContents.getZoomPercent())
+ }
+ })
+ break
+ }
+ case 'view-source': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ const tab = tabState.getByTabId(appStore.state, tabId)
+ const tabUrl = tab && tab.get('url')
+ const sourceLocation = UrlUtil.getViewSourceUrlFromUrl(tabUrl)
+
+ if (sourceLocation !== null) {
+ const frame = frameStateUtil.getFrameByKey(windowStore.state, frameKey)
+ appActions.createTabRequested({
+ url: sourceLocation,
+ isPrivate: frame.get('isPrivate', false),
+ partitionNumber: frame.get('partitionNumber'),
+ openerTabId: tabId,
+ active: true
+ })
+ }
+ break
+ }
+ case 'reload': {
+ const frame = frameStateUtil.getFrameByKey(windowStore.state, frameKey)
+ const frameLocation = frame.get('location')
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ const tab = tabState.getByTabId(appStore.state, tabId)
+ const tabUrl = tab && tab.get('url')
+ // Ensure that the webview thinks we're on the same location as the browser does.
+ // This can happen for pages which don't load properly.
+ // Some examples are basic http auth and bookmarklets.
+ // In this case both the user display and the user think they're on frameLocation.
+ if (tabUrl !== frameLocation &&
+ !isAboutPageURL(frameLocation) &&
+ !isTorrentViewerURL(frameLocation)) {
+ } else if (isPDFJSURL(frameLocation)) {
+ appActions.loadURLRequested(tabId,
+ UrlUtil.getLocationIfPDF(frameLocation))
+ } else {
+ tabActions.reload(tabId)
+ }
+ break
+ }
+ case 'clean-reload': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ tabActions.reload(tabId, true)
+ break
+ }
+ case 'save': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ // TODO: Sometimes this tries to save in a non-existent directory
+ getWebContents(tabId, (webContents) => {
+ if (webContents) {
+ const tab = tabState.getByTabId(appStore.state, tabId)
+ const tabUrl = tab && tab.get('url')
+ const downloadLocation = getSetting(settings.PDFJS_ENABLED)
+ ? UrlUtil.getLocationIfPDF(tabUrl)
+ : tabUrl
+ webContents.downloadURL(downloadLocation, true)
+ }
+ })
+ break
+ }
+ case 'print': {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ getWebContents(tabId, (webContents) => {
+ if (webContents) {
+ webContents.print()
+ }
+ })
+ break
+ }
+ case 'copy': {
+ let selection = window.getSelection()
+ if (selection && selection.toString()) {
+ appActions.clipboardTextCopied(selection.toString())
+ } else {
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ getWebContents(tabId, (webContents) => {
+ if (webContents) {
+ webContents.copy()
+ }
+ })
+ }
+ break
+ }
+ case 'show-findbar': {
+ windowActions.setFindbarShown(frameKey, true)
+ break
+ }
+ case 'find-next': {
+ onFindAgain(frameKey, true)
+ break
+ }
+ case 'find-prev': {
+ onFindAgain(frameKey, false)
+ break
+ }
+ case 'focus-webview': {
+ webviewActions.setWebviewFocused()
+ break
+ }
+ }
+}
+
+function onFindAgain (frameKey, forward) {
+ const frame = frameStateUtil.getFrameByKey(windowStore.state, frameKey)
+ const findbarShown = frame.get('findbarShown')
+ if (!findbarShown) {
+ windowActions.setFindbarShown(frameKey, true)
+ }
+ const searchString = frame.getIn(['findDetail', 'searchString'])
+ if (searchString) {
+ const caseSensitivity = frame.getIn(['findDetail', 'caseSensitivity'], undefined)
+ const findDetailInternalFindStatePresent = frame.getIn(['findDetail', 'internalFindStatePresent'])
+ const tabId = frameStateUtil.getTabIdByFrameKey(windowStore.state, frameKey)
+ tabActions.findInPageRequest(tabId, searchString, caseSensitivity, forward, findDetailInternalFindStatePresent)
+ }
+}
diff --git a/app/renderer/rendererTabEvents.js b/app/renderer/rendererTabEvents.js
new file mode 100644
index 00000000000..20fc109010a
--- /dev/null
+++ b/app/renderer/rendererTabEvents.js
@@ -0,0 +1,567 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+const Immutable = require('immutable')
+const electron = require('electron')
+
+const windowStore = require('../../js/stores/windowStore')
+const appStore = require('../../js/stores/appStoreRenderer')
+
+const windowActions = require('../../js/actions/windowActions')
+const appActions = require('../../js/actions/appActions')
+const tabActions = require('../common/actions/tabActions')
+
+const tabState = require('../common/state/tabState')
+const frameStateUtil = require('../../js/state/frameStateUtil')
+const contextMenus = require('../../js/contextMenus')
+const siteSettings = require('../../js/state/siteSettings')
+const siteSettingsState = require('../common/state/siteSettingsState')
+const contextMenuState = require('../common/state/contextMenuState')
+
+const domUtil = require('./lib/domUtil')
+const imageUtil = require('../../js/lib/imageUtil')
+const historyUtil = require('../common/lib/historyUtil')
+const UrlUtil = require('../../js/lib/urlutil')
+const {isFrameError, isAborted} = require('../common/lib/httpUtil')
+const {
+ aboutUrls,
+ isTargetAboutUrl
+} = require('../../js/lib/appUrlUtil')
+const urlParse = require('../common/urlParse')
+const locale = require('../../js/l10n')
+const config = require('../../js/constants/config')
+const appConfig = require('../../js/constants/appConfig')
+const messages = require('../../js/constants/messages')
+
+// TODO: cleanup on frame leaving window
+const frameNotificationCallbacks = new Map()
+// Counter for detecting PDF URL redirect loops
+const frameReloadCounter = new Map()
+
+function getFrameByTabId (tabId) {
+ return frameStateUtil.getFrameByTabId(windowStore.state, tabId) || Immutable.Map()
+}
+
+function getTab (tabId) {
+ if (!appStore.state.get('tabs')) {
+ return undefined
+ }
+ return appStore.state.get('tabs').find((tab) => tab.get('tabId') === tabId)
+}
+
+const eventsWithNoAction = ['tab-inserted-at', 'will-destroy', 'destroyed']
+
+const api = module.exports = {
+ handleTabEvent (tabId, eventType, e, shouldDebug = false, frame = getFrameByTabId(tabId)) {
+ // we don't care about certain events
+ if (eventsWithNoAction.includes(eventType)) {
+ return
+ }
+ // If frame is not in state yet, queue the event.
+ // Whilst any actions dispatched by this function will reach the store
+ // *after* the frame creation event, some of these events require the frame to
+ // already exist in order to make some processing decisions,
+ // though that should be refactored so that the state-processing is done in
+ // the reducers.
+ if (!frame || frame.isEmpty()) {
+ if (shouldDebug) {
+ console.debug('%cNo frame for event yet, queueing until later', 'color: red', tabId, eventType)
+ }
+ windowStore.once(`new-frame-${tabId}`, (newFrame) => {
+ if (shouldDebug) {
+ console.debug('%cFrame now exists, re-running event handler', 'color: green', tabId, eventType)
+ }
+ api.handleTabEvent(tabId, eventType, e, shouldDebug, newFrame)
+ })
+ return
+ }
+
+ switch (eventType) {
+ case 'tab-detached-at': {
+ windowActions.removeFrame(tabId)
+ break
+ }
+ case 'content-blocked': {
+ if (e.details[0] === 'javascript' && e.details[1]) {
+ windowActions.setBlockedBy(tabId, 'noScript', e.details[1])
+ }
+ if (e.details[0] === 'autoplay') {
+ appActions.autoplayBlocked(tabId)
+ }
+ break
+ }
+ case 'did-block-run-insecure-content': {
+ windowActions.setBlockedRunInsecureContent(frame, e.details[0])
+ break
+ }
+ case 'context-menu': {
+ contextMenus.onMainContextMenu(e.params, frame, getTab(tabId))
+ e.preventDefault()
+ e.stopPropagation()
+ break
+ }
+ case 'update-target-url': {
+ const downloadBarHeight = domUtil.getStyleConstants('download-bar-height')
+ let nearBottom = e.y > (window.innerHeight - 150 - downloadBarHeight)
+ let mouseOnLeft = e.x < (window.innerWidth / 2)
+ let showOnRight = nearBottom && mouseOnLeft
+ windowActions.setLinkHoverPreview(e.url, showOnRight)
+ break
+ }
+ case 'page-favicon-updated': {
+ if (e.favicons &&
+ e.favicons.length > 0 &&
+ // Favicon changes lead to recalculation of top site data so only fire
+ // this when needed. Some sites update favicons very frequently.
+ e.favicons[0] !== frame.get('icon')) {
+ imageUtil.getWorkingImageUrl(e.favicons[0], (error) => {
+ windowActions.setFavicon(frame, error ? null : e.favicons[0])
+ })
+ }
+ break
+ }
+ case 'show-autofill-settings': {
+ appActions.createTabRequested({
+ url: 'about:autofill',
+ active: true
+ })
+ break
+ }
+ case 'show-autofill-popup': {
+ contextMenus.onShowAutofillMenu(e.suggestions, e.rect, frame)
+ break
+ }
+ case 'hide-autofill-popup': {
+ const contextMenu = contextMenuState.getContextMenu(windowStore.state)
+ const isAutoFillContextMenu = contextMenu && contextMenu.get('type') === 'autofill'
+ if (isAutoFillContextMenu) {
+ windowActions.autofillPopupHidden(tabId)
+ }
+ break
+ }
+ case 'load-start': {
+ if (
+ e.isMainFrame &&
+ !e.isErrorPage &&
+ !e.isFrameSrcDoc
+ ) {
+ if (e.url &&
+ e.url.startsWith(appConfig.noScript.twitterRedirectUrl) &&
+ getSiteSettings(frame).get('noScript')) {
+ // This result will be canceled immediately by sitehacks, so don't
+ // update the load state; otherwise it will not show the security
+ // icon.
+ break
+ }
+ windowActions.onWebviewLoadStart(frame, e.url)
+ }
+ break
+ }
+ case 'did-fail-provisional-load': {
+ if (e.isMainFrame) {
+ loadEnd(tabId, frame, false, e.validatedURL, false)
+ loadFail(tabId, frame, e, true, e.currentURL)
+ }
+ break
+ }
+ case 'did-fail-load': {
+ if (e.isMainFrame) {
+ loadEnd(tabId, frame, false, e.validatedURL, false)
+ loadFail(tabId, frame, e, false, e.validatedURL)
+ }
+ break
+ }
+ case 'did-finish-load': {
+ loadEnd(tabId, frame, true, e.validatedURL, false)
+ if (getSiteSettings(frame).get('runInsecureContent')) {
+ const origin = tabState.getVisibleOrigin(appStore.state, tabId)
+ const isPrivate = frame.get('isPrivate', false)
+ appActions.removeSiteSetting(origin, 'runInsecureContent', isPrivate)
+ }
+ break
+ }
+ case 'did-navigate-in-page': {
+ if (e.isMainFrame) {
+ windowActions.setNavigated(e.url, frame.get('key'), true, tabId)
+ loadEnd(tabId, frame, true, e.url, true)
+ }
+ break
+ }
+ case 'did-navigate': {
+ const frameKey = frame.get('key')
+ const findBarShown = frame.get('findbarShown')
+ // hide the find bar if it's showing
+ if (findBarShown) {
+ frameStateUtil.onFindBarHide(frameKey, tabId)
+ }
+ // hide notifications
+ for (let message in getFrameNotificationCallbacks(frameKey)) {
+ appActions.hideNotification(message)
+ }
+ clearFrameNotificationCallbacks(frameKey)
+ windowActions.setNavigated(e.url, frameKey, false, tabId)
+ break
+ }
+ case 'did-change-theme-color': {
+ const themeColor = e.themeColor
+ // Due to a bug in Electron, after navigating to a page with a theme color
+ // to a page without a theme color, the background is sent to us as black
+ // even know there is no background. To work around this we just ignore
+ // the theme color in that case and let the computed theme color take over.
+ windowActions.setThemeColor(frame, themeColor !== '#000000' ? themeColor : null)
+ break
+ }
+ case 'found-in-page': {
+ if (e.result !== undefined && (e.result.matches !== undefined || e.result.activeMatchOrdinal !== undefined)) {
+ const frameKey = frame.get('key')
+ if (e.result.matches === 0) {
+ windowActions.setFindDetail(frameKey, Immutable.fromJS({
+ numberOfMatches: 0,
+ activeMatchOrdinal: 0
+ }))
+ break
+ }
+
+ windowActions.setFindDetail(frameKey, Immutable.fromJS({
+ numberOfMatches: e.result.matches || -1,
+ activeMatchOrdinal: e.result.activeMatchOrdinal || -1
+ }))
+ }
+ break
+ }
+ case 'security-style-changed': {
+ let isSecure = null
+ let runInsecureContent = getSiteSettings(frame).get('runInsecureContent')
+ let evCert = null
+ if (e.securityState === 'secure') {
+ isSecure = true
+ } else if (e.securityState === 'insecure') {
+ // Passive mixed content should not upgrade an insecure connection to a
+ // partially-secure connection. It can only downgrade a secure
+ // connection.
+ const frameIsSecure = frame.getIn(['security', 'isSecure'])
+ isSecure =
+ e.securityInfo.mixedContentStatus === 'content-status-displayed' && frameIsSecure !== false
+ ? 1
+ : false
+ } else if (e.securityState === 'broken') {
+ isSecure = false
+ const location = frame.get('location')
+ const parsedUrl = urlParse(location)
+ electron.ipcRenderer.send(messages.CHECK_CERT_ERROR_ACCEPTED, parsedUrl.host, tabId)
+ }
+
+ if (e.securityInfo.securityLevel === 'ev-secure') {
+ if (e.securityInfo.certificate &&
+ e.securityInfo.certificate.organizationNames.length) {
+ const countryName = e.securityInfo.certificate.countryName
+ const organizationName = e.securityInfo.certificate.organizationNames[0]
+ evCert = organizationName
+ if (countryName) {
+ evCert += ` [${countryName}]`
+ }
+ }
+ }
+ windowActions.setSecurityState(tabId, {
+ secure: runInsecureContent ? false : isSecure,
+ runInsecureContent,
+ evCert
+ })
+ break
+ }
+ case 'ipc-message': {
+ handleTabIpcMessage(tabId, frame, e)
+ break
+ }
+ }
+ }
+}
+
+function handleTabIpcMessage (tabId, frame, e) {
+ let method = () => {}
+ switch (e.channel) {
+ case messages.GOT_CANVAS_FINGERPRINTING: {
+ method = (detail) => {
+ const provisionalLocation = frame.get('provisionalLocation')
+ const description = [detail.type, detail.scriptUrl || provisionalLocation].join(': ')
+ windowActions.setBlockedBy(tabId, 'fingerprintingProtection', description)
+ }
+ break
+ }
+ case messages.THEME_COLOR_COMPUTED: {
+ method = (computedThemeColor) =>
+ windowActions.setThemeColor(frame, undefined, computedThemeColor || null)
+ break
+ }
+ case messages.CONTEXT_MENU_OPENED: {
+ method = (nodeProps, contextMenuType) => {
+ contextMenus.onMainContextMenu(nodeProps, frame, getTab(tabId), contextMenuType)
+ }
+ break
+ }
+ case messages.STOP_LOAD: {
+ method = () => getWebContents(tabId, (webContents) => webContents && webContents.stop())
+ break
+ }
+ case messages.GO_BACK: {
+ method = () => appActions.onGoBack(tabId)
+ break
+ }
+ case messages.GO_FORWARD: {
+ method = () => appActions.onGoForward(tabId)
+ break
+ }
+ case messages.RELOAD: {
+ method = () => {
+ const location = frame.get('location')
+ const frameKey = frame.get('key')
+ if (!frameReloadCounter.has(frameKey)) {
+ frameReloadCounter.set(frameKey, new Map())
+ }
+ const reloadCounter = frameReloadCounter.get(frameKey)
+ const locationReloadCount = reloadCounter.get(location) || 0
+ if (locationReloadCount < 2) {
+ tabActions.reload(tabId)
+ reloadCounter.set(location, locationReloadCount + 1)
+ }
+ }
+ break
+ }
+ case messages.CLEAR_BROWSING_DATA_NOW: {
+ method = () =>
+ windowActions.setClearBrowsingDataPanelVisible(true)
+ break
+ }
+ case messages.AUTOFILL_SET_ADDRESS: {
+ method = (currentDetail) =>
+ windowActions.setAutofillAddressDetail(null, null, currentDetail)
+ break
+ }
+ case messages.AUTOFILL_SET_CREDIT_CARD: {
+ method = (currentDetail) =>
+ windowActions.setAutofillCreditCardDetail(null, null, currentDetail)
+ break
+ }
+ case messages.HIDE_CONTEXT_MENU: {
+ method = () => windowActions.setContextMenuDetail()
+ break
+ }
+ }
+ method.apply(null, e.args)
+}
+
+function getWebContents (tabId, cb) {
+ electron.remote.getWebContents(tabId, (webContents) => {
+ if (webContents && !webContents.isDestroyed()) {
+ cb(webContents)
+ } else {
+ cb()
+ }
+ })
+}
+
+function isPDFJSURL (url) {
+ const pdfjsOrigin = `chrome-extension://${config.PDFJSExtensionId}/`
+ return url && url.startsWith(pdfjsOrigin)
+}
+
+function loadEnd (tabId, frame, savePage, url, inPageNav) {
+ if (frame.isEmpty()) {
+ return
+ }
+ windowActions.onWebviewLoadEnd(frame, url)
+ const parsedUrl = urlParse(url)
+ if (!allowRunningWidevinePlugin(tabId, frame)) {
+ showWidevineNotification(tabId, frame, () => {
+ }, () => {
+ appActions.loadURLRequested(tabId, frame.get('provisionalLocation'))
+ })
+ }
+
+ const protocol = parsedUrl.protocol
+ const isPrivate = frame.get('isPrivate')
+ const isError = frame.getIn(['aboutDetails', 'errorCode'])
+ if (!isPrivate && (protocol === 'http:' || protocol === 'https:') && !isError && savePage && !inPageNav) {
+ // Register the site for recent history for navigation bar
+ // calling with setTimeout is an ugly hack for a race condition
+ // with setTitle and setFavicon.
+ // We either need to delay this call until the title and favicon are set,
+ // or add a way to update it.
+ // However, it's possible that the frame could be destroyed, or in a bad
+ // way by then, so make sure we do a null check.
+ setTimeout(() => {
+ const currentFrame = getFrameByTabId(tabId)
+ const siteDetail = historyUtil.getDetailFromFrame(currentFrame)
+ if (siteDetail) {
+ appActions.addHistorySite(siteDetail)
+ } else if (process.env.NODE_ENV !== 'production') {
+ // log, in case we decide we want these entries to go in to the history
+ // but do not send a null entry to history as it will be rejected
+ console.error('frame: siteDetail was null when calling addHistorySite')
+ }
+ }, 250)
+ }
+
+ if (isPDFJSURL(url)) {
+ let displayLocation = UrlUtil.getLocationIfPDF(url)
+ windowActions.setSecurityState(tabId, {
+ secure: urlParse(displayLocation).protocol === 'https:',
+ runInsecureContent: false
+ })
+ }
+}
+
+function loadFail (tabId, frame, e, provisionLoadFailure, url) {
+ if (isFrameError(e.errorCode)) {
+ // temporary workaround for https://github.com/brave/browser-laptop/issues/1817
+ if (e.validatedURL === aboutUrls.get('about:newtab') ||
+ e.validatedURL === aboutUrls.get('about:blank') ||
+ e.validatedURL === aboutUrls.get('about:certerror') ||
+ e.validatedURL === aboutUrls.get('about:error') ||
+ e.validatedURL === aboutUrls.get('about:safebrowsing')) {
+ // this will just display a blank page for errors
+ // but we don't want to take the user out of the private tab
+ return
+ } else if (isTargetAboutUrl(e.validatedURL)) {
+ // open a new tab for other about urls
+ // and send this tab back to wherever it came from
+ appActions.onGoBack(tabId)
+ appActions.createTabRequested({
+ url: e.validatedURL,
+ active: true
+ })
+ return
+ }
+
+ windowActions.setFrameError(frame, {
+ event_type: 'did-fail-load',
+ errorCode: e.errorCode,
+ url: e.validatedURL
+ })
+ const key = historyUtil.getKey(frame)
+ appActions.loadURLRequested(tabId, 'about:error')
+ appActions.removeHistorySite(key)
+ } else if (isAborted(e.errorCode)) {
+ // just stay put
+ } else if (provisionLoadFailure) {
+ windowActions.setNavigated(url, frame.get('key'), true, tabId)
+ }
+}
+
+function getSiteSettings (frame) {
+ const location = frame.get('location')
+ const isPrivate = frame.get('isPrivate', false)
+ const allSiteSettings = siteSettingsState.getAllSiteSettings(appStore.state, isPrivate)
+ const frameSiteSettings = siteSettings.getSiteSettingsForURL(allSiteSettings, location) || Immutable.Map()
+ return frameSiteSettings
+}
+
+function allowRunningWidevinePlugin (tabId, frame) {
+ const state = appStore.state
+ const isWidevineEnabled = state.get('widevine') && state.getIn(['widevine', 'enabled'])
+ const origin = tabState.getVisibleOrigin(state, tabId)
+ const frameSiteSettings = getSiteSettings(frame)
+ const isPrivate = frame && frame.get('isPrivate', false)
+ const hasAllSiteSettings = !!siteSettingsState.getAllSiteSettings(appStore.state, isPrivate)
+ const widevine = frameSiteSettings.get('widevine')
+ if (!isWidevineEnabled) {
+ return false
+ }
+ if (!origin) {
+ return false
+ }
+ // Check for at least one CtP allowed on this origin
+ if (!hasAllSiteSettings) {
+ return false
+ }
+ if (typeof widevine === 'number') {
+ return true
+ }
+ return false
+}
+
+/**
+ * Shows a Widevine CtP notification if Widevine is installed and enabled.
+ * If not enabled, alert user that Widevine is installed.
+ * @param {string} origin - frame origin that is requesting to run widevine.
+ * can either be main frame or subframe.
+ * @param {function=} noWidevineCallback - Optional callback to run if Widevine is not
+ * installed
+ * @param {function=} widevineCallback - Optional callback to run if Widevine is
+ * accepted
+ */
+function showWidevineNotification (tabId, frame, noWidevineCallback, widevineCallback) {
+ // https://www.nfl.com is said to be a widevine site but it actually uses Flash for me Oct 10, 2016
+ const widevineSites = ['https://www.netflix.com',
+ 'http://bitmovin.com',
+ 'https://www.primevideo.com',
+ 'https://www.spotify.com',
+ 'https://shaka-player-demo.appspot.com']
+ const state = appStore.state
+ const origin = tabState.getVisibleOrigin(state, tabId)
+ const location = frame.get('location')
+ const isForWidevineTest = process.env.NODE_ENV === 'test' && location.endsWith('/drm.html')
+ if (!isForWidevineTest && (!origin || !widevineSites.includes(origin))) {
+ noWidevineCallback()
+ return
+ }
+
+ // Generate a random string that is unlikely to collide. Not
+ // cryptographically random.
+ const nonce = Math.random().toString()
+ const isWidevineEnabled = state.get('widevine') && state.getIn(['widevine', 'enabled'])
+ if (isWidevineEnabled) {
+ const message = locale.translation('allowWidevine').replace(/{{\s*origin\s*}}/, origin)
+ // Show Widevine notification bar
+ appActions.showNotification({
+ buttons: [
+ {text: locale.translation('deny')},
+ {text: locale.translation('allow')}
+ ],
+ message,
+ frameOrigin: origin,
+ options: {
+ nonce,
+ persist: true
+ }
+ })
+ getFrameNotificationCallbacks(frame.get('key'))[message] = (buttonIndex, persist) => {
+ if (buttonIndex === 1) {
+ if (persist) {
+ appActions.changeSiteSetting(origin, 'widevine', 1)
+ } else {
+ appActions.changeSiteSetting(origin, 'widevine', 0)
+ }
+ if (widevineCallback) {
+ widevineCallback()
+ }
+ } else {
+ if (persist) {
+ appActions.changeSiteSetting(origin, 'widevine', false)
+ }
+ }
+ appActions.hideNotification(message)
+ }
+ } else {
+ windowActions.widevineSiteAccessedWithoutInstall()
+ }
+
+ electron.ipcRenderer.once(messages.NOTIFICATION_RESPONSE + nonce, (e, msg, buttonIndex, persist) => {
+ const cb = getFrameNotificationCallbacks(frame.get('key'))[msg]
+ if (cb) {
+ cb(buttonIndex, persist)
+ }
+ })
+}
+
+function getFrameNotificationCallbacks (frameKey, message, cb) {
+ if (!frameNotificationCallbacks.has(frameKey)) {
+ frameNotificationCallbacks.set(frameKey, { })
+ }
+ return frameNotificationCallbacks.get(frameKey)
+}
+
+function clearFrameNotificationCallbacks (frameKey) {
+ frameNotificationCallbacks.delete(frameKey)
+}
diff --git a/app/renderer/webviewDisplay.js b/app/renderer/webviewDisplay.js
new file mode 100644
index 00000000000..455f4e6eaa4
--- /dev/null
+++ b/app/renderer/webviewDisplay.js
@@ -0,0 +1,37 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+module.exports = class SingleWebviewDisplay {
+ constructor ({containerElement, classNameWebview}) {
+ this.isAttached = false
+ this.webview = this.createWebview()
+ this.webview.classList.add(classNameWebview)
+ containerElement.appendChild(this.webview)
+ }
+
+ attachActiveTab (tabId) {
+ console.log('webviewDisplay: attaching tab id', tabId)
+ require('electron').remote.getWebContents(tabId, (webContents) => {
+ if (!webContents || webContents.isDestroyed()) {
+ return
+ }
+ this.webview.attachGuest(webContents.guestInstanceId, webContents)
+ })
+ this.isAttached = true
+ }
+
+ createWebview () {
+ console.log('creating a webview')
+ const webview = document.createElement('webview')
+ return webview
+ }
+
+ focusActiveWebview () {
+
+ }
+
+ getActiveWebview () {
+ return this.webview
+ }
+}
diff --git a/app/sessionStore.js b/app/sessionStore.js
index 62a4e55c881..f28f0e7ce7a 100644
--- a/app/sessionStore.js
+++ b/app/sessionStore.js
@@ -19,16 +19,19 @@ const Immutable = require('immutable')
const app = electron.app
const compareVersions = require('compare-versions')
const merge = require('deepmerge')
+const {execSync} = require('child_process')
// Constants
const UpdateStatus = require('../js/constants/updateStatus')
const settings = require('../js/constants/settings')
const siteTags = require('../js/constants/siteTags')
const downloadStates = require('../js/constants/downloadStates')
+const ledgerStatuses = require('./common/constants/ledgerStatuses')
// State
const tabState = require('./common/state/tabState')
const windowState = require('./common/state/windowState')
+const ledgerState = require('./common/state/ledgerState')
// Utils
const locale = require('./locale')
@@ -231,10 +234,7 @@ module.exports.cleanPerWindowData = (immutablePerWindowData, isShutdown) => {
// currently get re-generated when session store is
// restored. We will be able to keep this once we
// don't regenerate new frame keys when opening storage.
- 'parentFrameKey',
- // Delete the active shortcut details
- 'activeShortcut',
- 'activeShortcutDetails'
+ 'parentFrameKey'
])
if (immutableFrame.get('navbar') && immutableFrame.getIn(['navbar', 'urlbar'])) {
@@ -246,6 +246,7 @@ module.exports.cleanPerWindowData = (immutablePerWindowData, isShutdown) => {
}
return immutableFrame
}
+
const clearHistory = isShutdown && getSetting(settings.SHUTDOWN_CLEAR_HISTORY) === true
if (clearHistory) {
immutablePerWindowData = immutablePerWindowData.set('closedFrames', Immutable.List())
@@ -328,6 +329,13 @@ module.exports.cleanAppData = (immutableData, isShutdown) => {
console.error('cleanAppData: error calling autofill.clearAutocompleteData: ', e)
}
}
+
+ const clearSynopsis = isShutdown && getSetting(settings.SHUTDOWN_CLEAR_PUBLISHERS) === true
+ const inProgress = ledgerState.getAboutProp(immutableData, 'status') === ledgerStatuses.IN_PROGRESS
+ if (clearSynopsis && immutableData.has('ledger') && !inProgress) {
+ immutableData = ledgerState.resetPublishers(immutableData)
+ }
+
const clearAutofillData = isShutdown && getSetting(settings.SHUTDOWN_CLEAR_AUTOFILL_DATA) === true
if (clearAutofillData) {
autofill.clearAutofillData()
@@ -452,6 +460,11 @@ module.exports.cleanAppData = (immutableData, isShutdown) => {
console.error('cleanAppData: error cleaning up data: urls', e)
}
+ // delete the window ready state (gets set again on program start)
+ if (immutableData.has('windowReady')) {
+ immutableData = immutableData.delete('windowReady')
+ }
+
return immutableData
}
@@ -821,11 +834,61 @@ module.exports.runPreMigrations = (data) => {
delete data.sites
}
- if (data.lastAppVersion) {
+ if (data.lastAppVersion || data.quarantineNeeded) {
+ // with version 0.22.13, any file downloaded (including the update itself) would get
+ // quarantined on macOS (per work done with https://github.com/brave/muon/pull/484)
+ // this functionality was then reverted with https://github.com/brave/muon/pull/570
+ //
+ // To fix the executable, we need to manually un-quarantine the Brave executable so that it works as expected
+ if (process.platform === 'darwin' && (compareVersions(data.lastAppVersion, '0.22.13') === 0 || data.quarantineNeeded)) {
+ const unQuarantine = (appPath) => {
+ try {
+ execSync(`xattr -d com.apple.quarantine "${appPath}"`)
+ console.log(`Quarantine attribute has been removed from ${appPath}`)
+ } catch (e) {
+ console.error(`Failed to remove quarantine attribute from ${appPath}: `, e)
+ }
+ }
+
+ console.log('Update was downloaded from 0.22.13' + data.quarantineNeeded ? ' (first launch after auto-update)' : '')
+
+ // Un-quarantine default path
+ const defaultAppPath = '/Applications/Brave.app'
+ unQuarantine(defaultAppPath)
+
+ // Un-quarantine custom path
+ const appPath = app.getPath('exe')
+ const appIndex = appPath.indexOf('.app') + '.app'.length
+ if (appPath && appIndex > 4) {
+ // Remove the `Contents`/`MacOS`/`Brave` parts from path
+ const runningAppPath = appPath.substring(0, appIndex)
+ if (runningAppPath.startsWith('/private/var/folders')) {
+ // This is true when Squirrel re-launches Brave after an auto-update
+ // File system is read-only; the xattr command would fail
+ data.quarantineNeeded = true
+ } else if (runningAppPath !== defaultAppPath) {
+ // Path is the installed location
+ unQuarantine(runningAppPath)
+ data.quarantineNeeded = false
+ }
+ }
+ }
+
+ let runHSTSCleanup = false
+ try { runHSTSCleanup = compareVersions(data.lastAppVersion, '0.22.13') < 1 } catch (e) {}
+
+ if (runHSTSCleanup) {
+ filtering.clearHSTSData()
+ }
+
// Force WidevineCdm to be upgraded when last app version <= 0.18.25
let runWidevineCleanup = false
+ let formatPublishers = false
- try { runWidevineCleanup = compareVersions(data.lastAppVersion, '0.18.25') < 1 } catch (e) {}
+ try {
+ runWidevineCleanup = compareVersions(data.lastAppVersion, '0.18.25') < 1
+ formatPublishers = compareVersions(data.lastAppVersion, '0.22.3') < 1
+ } catch (e) {}
if (runWidevineCleanup) {
const fs = require('fs-extra')
@@ -837,6 +900,23 @@ module.exports.runPreMigrations = (data) => {
})
}
+ if (formatPublishers) {
+ const publishers = data.ledger.synopsis.publishers
+
+ if (publishers && Object.keys(publishers).length > 0) {
+ Object.entries(publishers).forEach((item) => {
+ const publisherKey = item[0]
+ const publisher = item[1]
+ const siteKey = `https?://${publisherKey}`
+ if (data.siteSettings[siteKey] == null || publisher.faviconName == null) {
+ return
+ }
+
+ data.siteSettings[siteKey].siteName = publisher.faviconName
+ })
+ }
+ }
+
// Bookmark cache was generated wrongly on and before 0.20.25 from 0.19.x upgrades
let runCacheClean = false
try { runCacheClean = compareVersions(data.lastAppVersion, '0.20.25') < 1 } catch (e) {}
@@ -844,11 +924,17 @@ module.exports.runPreMigrations = (data) => {
if (data.cache) {
delete data.cache.bookmarkLocation
}
+ }
+
+ // pinned top sites were stored in the wrong position in 0.19.x
+ // and on some updates ranging from 0.20.x/0.21.x
+ // allowing duplicated items. See #12941
+ let pinnedTopSitesCleanup = false
+ try {
+ pinnedTopSitesCleanup = compareVersions(data.lastAppVersion, '0.22.00') < 1
+ } catch (e) {}
- // pinned top sites were stored in the wrong position in 0.19.x
- // allowing duplicated items. See #12941
- // in this case eliminate pinned items so they can be properly
- // populated in their own indexes
+ if (pinnedTopSitesCleanup) {
if (data.about.newtab.pinnedTopSites) {
// Empty array is currently set to include default pinned sites
// which we avoid given the user already have a profile
@@ -857,6 +943,11 @@ module.exports.runPreMigrations = (data) => {
}
}
+ // TODO: consider moving all of the above logic into here
+ // see https://github.com/brave/browser-laptop/issues/10488
+ const runMigrations = require('./migrations/pre')
+ runMigrations(data)
+
return data
}
@@ -1050,8 +1141,9 @@ module.exports.defaultAppState = () => {
ignoredTopSites: [],
pinnedTopSites: []
},
+ preferences: {},
welcome: {
- showOnLoad: !['test', 'development'].includes(process.env.NODE_ENV)
+ showOnLoad: !['test', 'development'].includes(process.env.NODE_ENV) || process.env.BRAVE_SHOW_FIRST_RUN_WELCOME
}
},
trackingProtection: {
@@ -1085,12 +1177,7 @@ module.exports.defaultAppState = () => {
},
promotion: {}
},
- migrations: {
- batMercuryTimestamp: now,
- btc2BatTimestamp: now,
- btc2BatNotifiedTimestamp: now,
- btc2BatTransitionPending: false
- }
+ windowReady: false
}
}
diff --git a/app/sessionStoreShutdown.js b/app/sessionStoreShutdown.js
index 5a4c40d765e..09edf2ca884 100644
--- a/app/sessionStoreShutdown.js
+++ b/app/sessionStoreShutdown.js
@@ -218,7 +218,10 @@ ipcMain.on(messages.RESPONSE_WINDOW_STATE, (evt, mem) => {
})
ipcMain.on(messages.LAST_WINDOW_STATE, (evt, data) => {
- if (data) {
+ // Remember last window (that was not buffer window, i.e. had frames).
+ // When the last tab of a window closes, the window is closed before the tab closes, so
+ // a used closing window will almost always have at least 1 frame.
+ if (data && data.frames && data.frames.length) {
immutableLastWindowClosedState = Immutable.fromJS(data)
}
})
diff --git a/app/siteHacks.js b/app/siteHacks.js
index 5de2315e709..c770dacc775 100644
--- a/app/siteHacks.js
+++ b/app/siteHacks.js
@@ -8,78 +8,148 @@ const urlParse = require('./common/urlParse')
const Filtering = require('./filtering')
const {siteHacks} = require('../js/data/siteHacks')
const appConfig = require('../js/constants/appConfig')
+const {makeJS} = require('./common/state/immutableUtil')
const resourceName = 'siteHacks'
+let referralHeaders = null
-module.exports.init = () => {
- if (!appConfig[resourceName].enabled) {
- return
+const beforeHeaders = (details, isPrivate) => {
+ const mainFrameUrl = Filtering.getMainFrameUrl(details)
+ if (!mainFrameUrl) {
+ return {
+ resourceName
+ }
}
- Filtering.registerBeforeSendHeadersFilteringCB((details, isPrivate) => {
- const mainFrameUrl = Filtering.getMainFrameUrl(details)
- if (!mainFrameUrl) {
- return {
- resourceName
+ const domain = urlParse(mainFrameUrl).hostname.split('.').slice(-2).join('.')
+ const hack = siteHacks[domain]
+ let customCookie
+ let requestHeaders
+ let cancel
+ if (hack && hack.onBeforeSendHeaders &&
+ domain === urlParse(details.url).hostname.split('.').slice(-2).join('.')) {
+ const result = hack.onBeforeSendHeaders.call(this, details)
+ if (result) {
+ customCookie = result.customCookie
+ requestHeaders = result.requestHeaders
+ if (Filtering.isResourceEnabled(appConfig.resourceNames.NOSCRIPT, 'https://twitter.com/', isPrivate) &&
+ result.cancel) {
+ // cancel is only called on Twitter where noscript is enabled
+ cancel = true
}
}
+ }
- const domain = urlParse(mainFrameUrl).hostname.split('.').slice(-2).join('.')
- const hack = siteHacks[domain]
- let customCookie
- let requestHeaders
- let cancel
- if (hack && hack.onBeforeSendHeaders &&
- domain === urlParse(details.url).hostname.split('.').slice(-2).join('.')) {
- const result = hack.onBeforeSendHeaders.call(this, details)
- if (result) {
- customCookie = result.customCookie
- requestHeaders = result.requestHeaders
- if (Filtering.isResourceEnabled(appConfig.resourceNames.NOSCRIPT, 'https://twitter.com/', isPrivate) &&
- result.cancel) {
- // cancel is only called on Twitter where noscript is enabled
- cancel = true
+ // Referral custom headers
+ if (referralHeaders == null) {
+ const appStore = require('../js/stores/appStore')
+ const appState = appStore.getState()
+ if (appState) {
+ setReferralHeaders(appState.getIn(['updates', 'referralHeaders']))
+ }
+ }
+
+ if (referralHeaders != null && Array.isArray(referralHeaders)) {
+ referralHeaders.forEach((referralHeader) => {
+ const domains = referralHeader.domains || []
+ if (domains && domains.includes(domain)) {
+ const headers = referralHeader.headers
+ if (headers) {
+ if (requestHeaders == null) {
+ requestHeaders = details.requestHeaders
+ }
+
+ Object.keys(headers).forEach((key) => {
+ requestHeaders[key] = headers[key]
+ })
}
}
- }
+ })
+ }
+
+ return {
+ resourceName,
+ requestHeaders,
+ customCookie,
+ cancel
+ }
+}
+
+const beforeRequest = (details, isPrivate) => {
+ let domain = urlParse(details.url).hostname
+ let hack = siteHacks[domain]
+
+ let redirectURL
+ let cancel
+ const mainFrameUrl = Filtering.getMainFrameUrl(details)
+ // this can happen if the tab is closed and the webContents is no longer available
+ if (!mainFrameUrl) {
return {
- resourceName,
- requestHeaders,
- customCookie,
- cancel
+ resourceName: module.exports.resourceName
}
- })
-
- Filtering.registerBeforeRequestFilteringCB((details, isPrivate) => {
- let domain = urlParse(details.url).hostname
- let hack = siteHacks[domain]
-
- let redirectURL
- let cancel
- const mainFrameUrl = Filtering.getMainFrameUrl(details)
- // this can happen if the tab is closed and the webContents is no longer available
- if (!mainFrameUrl) {
- return {
- resourceName: module.exports.resourceName
- }
+ }
+
+ if (hack && hack.onBeforeRequest &&
+ (hack.enableForAll ||
+ (hack.enableForAdblock && Filtering.isResourceEnabled(appConfig.resourceNames.ADBLOCK, mainFrameUrl, isPrivate)) ||
+ (hack.enableForTrackingProtection && Filtering.isResourceEnabled(appConfig.resourceNames.TRACKING_PROTECTION, mainFrameUrl, isPrivate)))) {
+ const result = hack.onBeforeRequest.call(this, details)
+ if (result && result.redirectURL) {
+ redirectURL = result.redirectURL
+ }
+ if (result && typeof result.cancel === 'boolean') {
+ cancel = result.cancel
+ }
+ }
+ return {
+ resourceName,
+ redirectURL,
+ cancel
+ }
+}
+
+const init = () => {
+ if (!appConfig[resourceName].enabled) {
+ return
+ }
+
+ Filtering.registerBeforeSendHeadersFilteringCB(beforeHeaders)
+
+ Filtering.registerBeforeRequestFilteringCB(beforeRequest)
+}
+
+const setReferralHeaders = (headers) => {
+ if (headers) {
+ headers = makeJS(headers) || []
+ if (!Array.isArray(headers)) {
+ headers = [headers]
}
- if (hack && hack.onBeforeRequest &&
- (hack.enableForAll ||
- (hack.enableForAdblock && Filtering.isResourceEnabled(appConfig.resourceNames.ADBLOCK, mainFrameUrl, isPrivate)) ||
- (hack.enableForTrackingProtection && Filtering.isResourceEnabled(appConfig.resourceNames.TRACKING_PROTECTION, mainFrameUrl, isPrivate)))) {
- const result = hack.onBeforeRequest.call(this, details)
- if (result && result.redirectURL) {
- redirectURL = result.redirectURL
- }
- if (result && typeof result.cancel === 'boolean') {
- cancel = result.cancel
+ referralHeaders = headers
+ }
+}
+
+const getMethods = () => {
+ const publicMethods = {
+ init,
+ setReferralHeaders
+ }
+
+ let privateMethods = {}
+
+ if (process.env.NODE_ENV === 'test') {
+ privateMethods = {
+ beforeHeaders,
+ getReferralHeaders: () => {
+ return referralHeaders
+ },
+ resetReferralHeaders: () => {
+ referralHeaders = null
}
}
- return {
- resourceName,
- redirectURL,
- cancel
- }
- })
+ }
+
+ return Object.assign({}, publicMethods, privateMethods)
}
+
+module.exports = getMethods()
diff --git a/build/pkg-scripts/postinstall b/build/pkg-scripts/postinstall
index 5af84b1743b..2ec447e697f 100755
--- a/build/pkg-scripts/postinstall
+++ b/build/pkg-scripts/postinstall
@@ -8,7 +8,7 @@ installationPath=$2
# TODO: ugly to assume the name of the app, especially with multi-channel.
# Luckily for now, release channel is the only channel with a pkg installer.
installationAppPath="$installationPath/Brave.app"
-installerPathPromoCodeRegex='.+-([a-zA-Z0-9]{3}[0-9]{3})([[:blank:]]?\([0-9]+\))?\.pkg$'
+installerPathPromoCodeRegex='.+-(([a-zA-Z0-9]{3}[0-9]{3})|([a-zA-Z]{1,}-[a-zA-Z]{1,}))([[:blank:]]?\([0-9]+\))?\.pkg$'
userDataDir="$HOME/Library/Application Support/brave"
promoCodePath="$userDataDir/promoCode"
# pkg runs this script as root so we need to get current username
diff --git a/build/pkg-scripts/postinstall-test.sh b/build/pkg-scripts/postinstall-test.sh
new file mode 100644
index 00000000000..78ed29080c8
--- /dev/null
+++ b/build/pkg-scripts/postinstall-test.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+installerPath=$1
+installerPathPromoCodeRegex='.+-(([a-zA-Z0-9]{3}[0-9]{3})|([a-zA-Z]{1,}-[a-zA-Z]{1,}))([[:blank:]]?\([0-9]+\))?\.pkg$'
+echo "Installer path is: $installerPath"
+
+if [[ $installerPath =~ $installerPathPromoCodeRegex ]]; then
+ echo "Installer path matched for promo code"
+ n=${#BASH_REMATCH[*]}
+ if [ $n -ge 1 ]; then
+ promoCode=${BASH_REMATCH[1]}
+ echo "Got promo code: $promoCode"
+ fi
+else
+ echo "Installer path did not match for promo code"
+fi
+
+exit 0
diff --git a/docs/linuxInstall.md b/docs/linuxInstall.md
index 7ed7189c20b..3dc35e80a67 100644
--- a/docs/linuxInstall.md
+++ b/docs/linuxInstall.md
@@ -20,7 +20,7 @@ Once `snapd` is installed, installing Brave looks like this:
snap install brave
```
-## Debian (Jessie) and Ubuntu (Artful, Zesty, Yakkety, Xenial, and Trusty) AMD64:
+## Debian (Jessie, Stretch) and Ubuntu (Artful, Zesty, Yakkety, Xenial, and Trusty) AMD64:
In the terminal to be used for the below commands, prime the `sudo` command (enter your password once).
```
@@ -40,12 +40,18 @@ Verify the `/etc/apt/sources.list.d/brave-*.list` file lists a new repository an
grep lsb_release /etc/apt/sources.list.d/brave*
```
+
Finally, install Brave:
```
sudo apt update
sudo apt install brave
```
+If you get this error when updating, you need an additional package.
+> E: Some files failed to download. They have been ignored, or old ones used instead.
+ ```
+sudo apt-get install apt-transport-https
+ ```
To install the latest `brave-beta` which often has early staging builds:
```
@@ -132,6 +138,13 @@ install the dependency for you:
sudo apt-get -f install
```
+## Solus
+
+Install Brave through eopkg:
+```
+sudo eopkg install brave
+```
+
## Fedora x86_64:
To install Brave using dnf:
@@ -159,7 +172,7 @@ To install Brave using zypper:
```
sudo rpmkeys --import https://s3-us-west-2.amazonaws.com/brave-rpm-release/keys.asc
sudo zypper install lsb
-sudo zypper addrepo https://s3-us-west-2.amazonaws.com/brave-rpm-release/x86_64/ brave-rpm-release
+sudo zypper addrepo --type yast2 https://s3-us-west-2.amazonaws.com/brave-rpm-release/x86_64/ brave-rpm-release
sudo zypper ref
sudo zypper install brave
```
@@ -170,6 +183,14 @@ sudo zypper ref
sudo zypper update brave
```
+If zypper throws an error similar to
+```
+Problem: nothing provides GConf2 needed by brave-*
+ Solution 1: do not install brave-*
+ Solution 2: break brave-* by ignoring some of its dependencies
+```
+Choose solution 2 and install gconf2 just to be safe. (`sudo zypper in gconf2`)
+
Alternatively you can install the rpm directly, but then you won't get automatic upgrades:
```
wget -O brave.rpm https://laptop-updates.brave.com/latest/openSUSE64
diff --git a/docs/state.md b/docs/state.md
index f02a7ce1799..7b7bf1d31d0 100644
--- a/docs/state.md
+++ b/docs/state.md
@@ -36,6 +36,10 @@ AppStore
updatedStamp: number // timestamp for when the data was last updated
},
preferences: {
+ backupNotifyCount: number, // number of times user has been reminded to backup wallet
+ backupNotifyTimestamp: number, // number of milliseconds from the last reminder until the next
+ backupSucceeded: (boolean|undefined), // was last backup successful?
+ recoveryBalanceRecalculated: (boolean|undefined),
recoverySucceeded: (boolean|undefined),
updatedStamp: number
}
@@ -63,8 +67,7 @@ AppStore
parentFolderId: number,
partitionNumber: number, // optionally specifies a specific session
skipSync: boolean,
- title: string,
- width: float // bookmark text width
+ title: string
}
},
bookmarkFolders: {
@@ -75,8 +78,7 @@ AppStore
originalSeed: Array., // only set for bookmarks that have been synced before a sync profile reset
parentFolderId: number, // set for bookmarks and bookmark folders only
skipSync: boolean, // Set for objects FETCHed by sync
- title: string,
- width: float // bookmark folder text width
+ title: string
}
},
cache: {
@@ -93,6 +95,10 @@ AppStore
ledgerVideos: {
[mediaKey]: {
publisher: string // publisher key
+ // Twitch
+ event: string, // event that was send to Twitch
+ time: number, // timestamp that we will log in the ledger
+ status: string // playing status: playing or paused
}
}
}
@@ -103,6 +109,8 @@ AppStore
browserHistory: boolean,
cachedImagesAndFiles: boolean,
downloadHistory: boolean,
+ paymentHistory: boolean,
+ publishersClear: boolean,
savedPasswords: boolean,
savedSiteSettings: boolean
},
@@ -206,6 +214,10 @@ AppStore
created, boolean, // wallet is created
creating: boolean, // wallet is being created
currentRate: number,
+ grants: [{
+ amount: number,
+ expirationDate: number
+ }]
hasBitcoinHandler: boolean, // brave browser has a `bitcoin:` URI handler
monthlyAmounts: Array // list of all monthly amounts for the contribution
passphrase: string, // the BAT wallet passphrase
@@ -238,7 +250,9 @@ AppStore
submissionStamp: number, // timestamp for this contribution
viewingId: string, // UUIDv4 for this contribution
}],
- unconfirmed: string // unconfirmed balance in BAT.toFixed(2)
+ unconfirmed: string, // unconfirmed balance in BAT.toFixed(2)
+ userFunded: number, // amount funded by the user
+ userHasFunded: boolean // permanently true once user funds wallet
},
locations: {
[url]: {
@@ -329,6 +343,7 @@ AppStore
}
}
publisherTimestamp: number, // timestamp of last publisher update in the database
+ status: string, // ledger status
synopsis: {
options: {
emptyScores: {
@@ -346,6 +361,7 @@ AppStore
publishers: {
[publisherId]: {
duration: number,
+ faviconName: string,
faviconURL: string,
options: {
exclude: boolean,
@@ -355,6 +371,8 @@ AppStore
},
pinPercentage: number,
protocol: string,
+ publisherURL: string,
+ providerName: string,
scores: {
concave: number,
visits: number
@@ -374,12 +392,6 @@ AppStore
}
}
},
- migrations: {
- batMercuryTimestamp: integer, // when session is upgraded (and this new schema added)
- btc2BatTimestamp: integer, // when call was made to backend to convert BTC => BAT
- btc2BatNotifiedTimestamp: integer, // when user was shown "wallet upgraded" notification
- btc2BatTransitionPending: boolean // true if user is being shown transition screen
- },
menu: {
template: object // used on Windows and by our tests: template object with Menubar control
},
@@ -512,6 +524,7 @@ AppStore
siteSettings: {
[hostPattern]: {
adControl: string, // (showBraveAds | blockAds | allowAdsAndTracking)
+ autoplay: boolean,
cookieControl: string, // (block3rdPartyCookie | allowAllCookies | blockAllCookies)
fingerprintingProtection: string, // (block3rdPartyFingerprinting | allowAllFingerprinting | blockAllFingerprinting)
flash: (number|boolean), // approval expiration time if allowed, false if never allow
@@ -520,7 +533,6 @@ AppStore
httpsEverywhere: boolean,
ledgerPayments: boolean, // false if site should not be paid by the ledger. Defaults to true.
ledgerPaymentsShown: boolean, // false if site should not be paid by the ledger and should not be shown in the UI. Defaults to true.
- ledgerPinPercentage: number, // 0 if not pinned, otherwise is pinned with defined percentage
mediaPermission: boolean,
midiSysexPermission: boolean,
notificationsPermission: boolean,
@@ -530,14 +542,14 @@ AppStore
openExternalPermission: boolean,
pointerLockPermission: boolean,
protocolRegistrationPermission: boolean,
- skipSync: boolean, // Set for objects FETCHed by sync
runInsecureContent: boolean, // allow active mixed content
safeBrowsing: boolean,
+ siteName: string, // display name of the publisher
+ skipSync: boolean, // Set for objects FETCHed by sync
savePasswords: boolean, // only false or undefined/null
shieldsUp: boolean,
widevine: (number|boolean), // false = block widevine, 0 = allow once, 1 = allow always
- zoomLevel: number,
- autoplay: boolean,
+ zoomLevel: number
}
},
defaultSiteSettingsListImported: boolean,
@@ -585,7 +597,8 @@ AppStore
suppress: boolean, // if true, show a suppress checkbox (defaulted to not checked)
title: string, // title is the source; ex: "brave.com says:"
},
- muted: boolean, // is the tab muted
+ muted: boolean, // is the tab muted,
+ zoomPercent: number, // current zoom levellast
windowId: number // the windowId that contains the tab
guestInstanceId: number,
tabId: number
@@ -601,7 +614,19 @@ AppStore
notes: string // release notes for the active update
},
referralDownloadId: string, // download ID that is returned from the referral server
+ referralHeaders: [{
+ domains: Array,
+ headers: [{
+ domains: Array,
+ headers: { [headerName]: string },
+ cookieNames: Array,
+ expiration: number
+ }],
+ cookieNames: Array,
+ expiration: number
+ }],
referralTimestamp: number, // timestamp when referral was accumulated (after ~30 days)
+ referralPage: string, // page that we open when browser starts
referralPromoCode: string, // promo code for the referral
status: string, // updateStatus from js/constants/updateStatus.js
verbose: boolean // whether to show update UI for checking, downloading, and errors
@@ -617,10 +642,6 @@ AppStore
},
windows: [{
// persistent properties
- bookmarksToolbar: {
- toolbar: Array, // bookmark and folder keys that we want to display
- other: Array // bookmark and folder keys that we display in more menu (limited to 100)
- },
focused: boolean,
height: number,
left: number,
@@ -635,6 +656,7 @@ AppStore
autocompleteURL: string, // ditto re: {searchTerms}
searchURL: string // with replacement var in string: {searchTerms}
},
+ windowReady: boolean // set to false on start; set to true when first window is ready
}
```
@@ -676,7 +698,7 @@ WindowStore
},
cleanedOnShutdown: boolean, // whether app data was successfully cleared on shutdown
closedFrames: [], // holds the same type of frame objects as frames
- contextMenuDetail: {
+ contextMenuDetail: { // currently using uuid hack to avoid serializing click function in template
bottom: number, // the bottom position of the context menu
left: number, // the left position of the context menu
maxHeight: number, // the maximum height of the context menu
@@ -696,8 +718,6 @@ WindowStore
createdFaviconDirectory: boolean, // whether the ledger-favicons directory has been created already in the appData directory
frames: [{
aboutDetails: object, // details for about pages
- activeShortcut: string, // set by the application store when the component should react to a shortcut
- activeShortcutDetails: object, // additional parameters for the active shortcut action if any
adblock: {
blocked: Array
},
@@ -729,7 +749,6 @@ WindowStore
isPrivate: boolean, // private browsing tab
key: number,
lastAccessedTime: datetime,
- lastZoomPercentage: number, // last value that was used for zooming
loading: boolean,
location: string, // the currently navigated location
modalPromptDetail: object,
@@ -816,6 +835,7 @@ WindowStore
top: number // the top position of the popup window
},
previewFrameKey: number,
+ quarantineNeeded: boolean, // true if quarantine needed after auto-launching
searchResults: array, // autocomplete server results if enabled
ui: {
bookmarksToolbar: {
diff --git a/docs/style.md b/docs/style.md
index 57a968abb8e..a738089297b 100644
--- a/docs/style.md
+++ b/docs/style.md
@@ -6,7 +6,7 @@ All applicable styles should be colocated with their corresponding JavaScript co
## Legacy
-All legacy styles are processed with [LESS](http://lesscss.org/) and can be found in the `/less` directory. These should still be maintained but all future CSS should be written in JavaScript and kept inside the appropriate component file.
+All legacy styles are processed with [LESS](http://lesscss.org/) and can be found in the `/less` directory. These should still be maintained but all future CSS should be written in JavaScript and kept inside the appropriate component file.
## Note
@@ -54,7 +54,7 @@ Also, note that this style guide was re-made after some code has being refactore
### Where to put my code
-The best practice regarding components is to split them into separate files, and that's what you should do with styles as well. Styles should be bound to the component whenever possible. For places where several styles apply (such as tab), that's OK to create a separated file for that. Styles files lives inside `app/renderer/components/styles`.
+The best practice regarding components is to split them into separate files, and that's what you should do with styles as well. Styles should be bound to the component whenever possible. For places where several styles apply (such as tab), that's OK to create a separated file for that. Styles files lives inside `app/renderer/components/styles`.
#### The global file
@@ -413,7 +413,7 @@ const styles = StyleSheet.create({
### Dealing with pseudo-states
-Aphrodite works ok with pseudo-states like `:hover` and `:active`, `:before`, `:after`, as well with `:nth-child()`.
+Aphrodite works ok with pseudo-states like `:hover` and `:active`, `:before`, `:after`, as well with `:nth-child()`.
There's no strict rule here, but you should avoid calling numbered children, being the only exception `:nth-child(even)` or `:nth-child(odd)`.
@@ -509,7 +509,7 @@ const styles = StyleSheet.create({
### Dealing with vendor prefixes
-Sometimes we'll need to flag `-webkit-` prefix. Prever camel-case instead of quoted objects (more below):
+Sometimes we'll need to flag `-webkit-` prefix. Prefer camel-case instead of quoted objects (more below):
**Bad**
```js
@@ -557,7 +557,7 @@ styles = StyleSheet.create({
#### Having to parse integers
-Sometimes you'll have to get the number of a given property written in pixels. You're incouraged of parsing that value instead of creating a new class:
+Sometimes you'll have to get the number of a given property written in pixels. You're encouraged to parse that value instead of creating a new class:
```js
// global.js
@@ -577,7 +577,7 @@ const globalStyles = {
someClassINeed: {
// hard-coded, but we have that value already
- something: 1000
+ something: 1000
}
```
@@ -642,9 +642,9 @@ const {isWindows} = require('../../app/common/lib/platformUtil')
### Descendant selection of pseudo-state
-Aphrodite don't deal well with that. However, that's a good thing and makes codebase more consise avoiding nested-styles hell.
+Aphrodite don't deal well with that. However, that's a good thing and makes codebase more concise avoiding nested-styles hell.
-If that's strictly necessary, please make use of an `action` to dispatch changes you need so your className can be changed. A good example can be found looking at `windowActions.setTabHoverState()`, which we use to check if a tab is being hovered. If so, our closeTab icon is fired.
+If that's strictly necessary, please make use of an `action` to dispatch changes you need so your className can be changed. A good example can be found looking at `windowActions.setTabHoverState()`, which we use to check if a tab is being hovered. If so, our closeTab icon is fired.
If you look at how it was done before using Aphrodite:
diff --git a/img/mediaProviders/twitch.svg b/img/mediaProviders/twitch.svg
new file mode 100644
index 00000000000..905e364f500
--- /dev/null
+++ b/img/mediaProviders/twitch.svg
@@ -0,0 +1 @@
+Glitch
\ No newline at end of file
diff --git a/img/mediaProviders/youtube.png b/img/mediaProviders/youtube.png
new file mode 100644
index 00000000000..b0c05d07169
Binary files /dev/null and b/img/mediaProviders/youtube.png differ
diff --git a/img/toolbar/newtab_btn.svg b/img/toolbar/newtab_btn.svg
deleted file mode 100644
index 4c67f570e4f..00000000000
--- a/img/toolbar/newtab_btn.svg
+++ /dev/null
@@ -1 +0,0 @@
-newtab_btn
\ No newline at end of file
diff --git a/img/windows/win10_close.svg b/img/windows/win10_close.svg
index 4b13c389c2e..623e749f9a8 100644
--- a/img/windows/win10_close.svg
+++ b/img/windows/win10_close.svg
@@ -1 +1 @@
-win10_close
\ No newline at end of file
+win10_close
diff --git a/img/windows/win10_close_white.svg b/img/windows/win10_close_white.svg
index 06a79e1480d..92a12b9d766 100644
--- a/img/windows/win10_close_white.svg
+++ b/img/windows/win10_close_white.svg
@@ -1 +1 @@
-win10_close_white
\ No newline at end of file
+win10_close_white
diff --git a/img/windows/win10_expand.svg b/img/windows/win10_expand.svg
index db90536216c..8963d2f205f 100644
--- a/img/windows/win10_expand.svg
+++ b/img/windows/win10_expand.svg
@@ -1 +1 @@
-win10_expand
\ No newline at end of file
+win10_expand
diff --git a/img/windows/win10_minimize.svg b/img/windows/win10_minimize.svg
index 194eb2cfa40..240bae94661 100644
--- a/img/windows/win10_minimize.svg
+++ b/img/windows/win10_minimize.svg
@@ -1 +1 @@
-win10_minimize
\ No newline at end of file
+win10_minimize
diff --git a/img/windows/win10_restore.svg b/img/windows/win10_restore.svg
index 88bd3851d09..73694077ce1 100644
--- a/img/windows/win10_restore.svg
+++ b/img/windows/win10_restore.svg
@@ -1 +1 @@
-win10_restore
\ No newline at end of file
+win10_restore
diff --git a/js/about/aboutActions.js b/js/about/aboutActions.js
index fe511ca4072..b4abf9069ac 100644
--- a/js/about/aboutActions.js
+++ b/js/about/aboutActions.js
@@ -102,6 +102,13 @@ const aboutActions = {
ipc.send(messages.RESET_SYNC)
},
+ /**
+ * Dispatches a message to trigger a browser restart notification
+ */
+ requireRestart: function (key = null, value = null) {
+ ipc.send(messages.PREFS_RESTART, key, value)
+ },
+
/**
* Dispatched when an extension has been uninstalled
*
diff --git a/js/about/entry.js b/js/about/entry.js
index ee701405e14..996808bfdaa 100644
--- a/js/about/entry.js
+++ b/js/about/entry.js
@@ -31,6 +31,9 @@ switch (getBaseUrl(getSourceAboutUrl(window.location.href))) {
case 'about:bookmarks':
getElementOp = import('../../app/renderer/about/bookmarks/bookmarks')
break
+ case 'about:printkeys':
+ getElementOp = import('../../app/renderer/about/ledger/printKeys')
+ break
case 'about:certerror':
getElementOp = import('./certerror')
break
diff --git a/js/about/passwords.js b/js/about/passwords.js
index 5f8a195c157..3c829ecfe8f 100644
--- a/js/about/passwords.js
+++ b/js/about/passwords.js
@@ -161,8 +161,8 @@ class AboutPasswords extends React.Component {
}
onClear () {
- const msg = 'Are you sure you want to delete all saved passwords? ' +
- 'This cannot be undone.'
+ const locale = require('../../js/l10n')
+ const msg = locale.translation('confirmClearPasswords')
if (window.confirm(msg)) {
aboutActions.clearPasswords()
}
diff --git a/js/about/preferences.js b/js/about/preferences.js
index 3a8ce1bc973..d60d81bb2a3 100644
--- a/js/about/preferences.js
+++ b/js/about/preferences.js
@@ -17,10 +17,12 @@ const {SettingTextbox} = require('../../app/renderer/components/common/textbox')
const {SettingDropdown} = require('../../app/renderer/components/common/dropdown')
const {DefaultSectionTitle} = require('../../app/renderer/components/common/sectionTitle')
const BrowserButton = require('../../app/renderer/components/common/browserButton')
+const SitePermissionsPage = require('../../app/renderer/components/preferences/sitePermissionsPage')
// Tabs
const PaymentsTab = require('../../app/renderer/components/preferences/paymentsTab')
const TabsTab = require('../../app/renderer/components/preferences/tabsTab')
+const ShieldsTab = require('../../app/renderer/components/preferences/shieldsTab')
const SyncTab = require('../../app/renderer/components/preferences/syncTab')
const PluginsTab = require('../../app/renderer/components/preferences/pluginsTab')
const ExtensionsTab = require('../../app/renderer/components/preferences/extensionsTab')
@@ -33,6 +35,7 @@ const appConfig = require('../constants/appConfig')
const preferenceTabs = require('../constants/preferenceTabs')
const messages = require('../constants/messages')
const settings = require('../constants/settings')
+const webrtcConstants = require('../constants/webrtcConstants')
const {changeSetting} = require('../../app/renderer/lib/settingsUtil')
const {passwordManagers, extensionIds} = require('../constants/passwordManagers')
const {startsWithOption, newTabMode, bookmarksToolbarMode, fullscreenOption, autoplayOption} = require('../../app/common/constants/settingsEnums')
@@ -42,18 +45,9 @@ const appActions = require('../actions/appActions')
const getSetting = require('../settings').getSetting
const SortableTable = require('../../app/renderer/components/common/sortableTable')
const searchProviders = require('../data/searchProviders')
+const keyCodes = require('../../app/common/constants/keyCodes')
-const adblock = appConfig.resourceNames.ADBLOCK
-const cookieblock = appConfig.resourceNames.COOKIEBLOCK
-const cookieblockAll = appConfig.resourceNames.COOKIEBLOCK_ALL
-const fingerprintingProtection = appConfig.resourceNames.FINGERPRINTING_PROTECTION
-const fingerprintingProtectionAll = appConfig.resourceNames.FINGERPRINTING_PROTECTION_ALL
-const adInsertion = appConfig.resourceNames.AD_INSERTION
-const trackingProtection = appConfig.resourceNames.TRACKING_PROTECTION
-const httpsEverywhere = appConfig.resourceNames.HTTPS_EVERYWHERE
-const safeBrowsing = appConfig.resourceNames.SAFE_BROWSING
-const noScript = appConfig.resourceNames.NOSCRIPT
-const flash = appConfig.resourceNames.FLASH
+const firewall = appConfig.resourceNames.FIREWALL
const isDarwin = navigator.platform === 'MacIntel'
@@ -82,17 +76,6 @@ const permissionNames = {
'autoplay': ['boolean']
}
-const braveryPermissionNames = {
- 'ledgerPaymentsShown': ['boolean', 'number'],
- 'shieldsUp': ['boolean'],
- 'adControl': ['string'],
- 'cookieControl': ['string'],
- 'safeBrowsing': ['boolean'],
- 'httpsEverywhere': ['boolean'],
- 'fingerprintingProtection': ['string'],
- 'noScript': ['boolean', 'number']
-}
-
class GeneralTab extends ImmutableComponent {
constructor (e) {
super()
@@ -320,253 +303,18 @@ class SearchTab extends ImmutableComponent {
}
}
-class SitePermissionsPage extends React.Component {
- hasEntryForPermission (name) {
- return this.props.siteSettings.some((value) => {
- return value.get && this.props.names[name] ? this.props.names[name].includes(typeof value.get(name)) : false
- })
- }
-
- isPermissionsNonEmpty () {
- // Check whether there is at least one permission set
- return this.props.siteSettings.some((value) => {
- if (value && value.get) {
- for (let name in this.props.names) {
- const granted = value.get(name)
- if (this.props.names[name].includes(typeof granted)) {
- if (this.props.defaults) {
- return this.props.defaults.get(name) !== granted
- } else {
- return true
- }
- }
- }
- }
- return false
- })
- }
-
- deletePermission (name, hostPattern) {
- aboutActions.removeSiteSetting(hostPattern, name)
- }
-
- clearPermissions (name) {
- aboutActions.clearSiteSettings(name)
- }
-
- render () {
- return this.isPermissionsNonEmpty()
- ?
-
-
- {
- Object.keys(this.props.names).map((name) =>
- this.hasEntryForPermission(name)
- ?
-
-
-
- (
-
- )
-
-
-
-
- : null)
- }
-
-
- : null
- }
-}
-
-class ShieldsTab extends ImmutableComponent {
- constructor () {
- super()
- this.onChangeAdControl = this.onChangeAdControl.bind(this)
- this.onToggleHTTPSE = this.onToggleSetting.bind(this, httpsEverywhere)
- this.onToggleSafeBrowsing = this.onToggleSetting.bind(this, safeBrowsing)
- this.onToggleNoScript = this.onToggleSetting.bind(this, noScript)
- }
- onChangeAdControl (e) {
- if (e.target.value === 'showBraveAds') {
- aboutActions.setResourceEnabled(adblock, true)
- aboutActions.setResourceEnabled(trackingProtection, true)
- aboutActions.setResourceEnabled(adInsertion, true)
- } else if (e.target.value === 'blockAds') {
- aboutActions.setResourceEnabled(adblock, true)
- aboutActions.setResourceEnabled(trackingProtection, true)
- aboutActions.setResourceEnabled(adInsertion, false)
- } else {
- aboutActions.setResourceEnabled(adblock, false)
- aboutActions.setResourceEnabled(trackingProtection, false)
- aboutActions.setResourceEnabled(adInsertion, false)
- }
- }
- onChangeCookieControl (e) {
- aboutActions.setResourceEnabled(cookieblock, e.target.value === 'block3rdPartyCookie')
- aboutActions.setResourceEnabled(cookieblockAll, e.target.value === 'blockAllCookies')
- }
- onChangeFingerprintingProtection (e) {
- aboutActions.setResourceEnabled(fingerprintingProtection, e.target.value === 'block3rdPartyFingerprinting')
- aboutActions.setResourceEnabled(fingerprintingProtectionAll, e.target.value === 'blockAllFingerprinting')
- }
- onToggleSetting (setting, e) {
- aboutActions.setResourceEnabled(setting, e.target.value)
- }
- render () {
- return
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {/* TODO: move this inline style to Aphrodite once refactored */}
-
-
-
-
-
-
-
-
-
-
-
- }
-}
-
class SecurityTab extends ImmutableComponent {
constructor (e) {
super()
this.clearBrowsingDataNow = this.clearBrowsingDataNow.bind(this)
+ this.onToggleFirewall = this.onToggleFirewall.bind(this)
+ }
+ onToggleFirewall (e) {
+ aboutActions.setResourceEnabled(firewall, e.target.value)
}
clearBrowsingDataNow () {
aboutActions.clearBrowsingDataNow()
}
- onToggleFlash (e) {
- aboutActions.setResourceEnabled(flash, e.target.value)
- if (e.target.value !== true) {
- // When flash is disabled, clear flash approvals
- aboutActions.clearSiteSettings('flash', {
- temporary: true
- })
- aboutActions.clearSiteSettings('flash', {
- temporary: false
- })
- }
- }
render () {
const lastPassPreferencesUrl = ('chrome-extension://' + extensionIds[passwordManagers.LAST_PASS] + '/tabDialog.html?dialog=preferences&cmd=open')
@@ -580,6 +328,7 @@ class SecurityTab extends ImmutableComponent {
+
{/* TODO: move this inline style to Aphrodite once refactored */}
+
+
+
+ {
+ Object.keys(webrtcConstants)
+ .map((policy) => )
+ }
+
+
+
+
+
+
+
@@ -677,10 +454,14 @@ class SecurityTab extends ImmutableComponent {
class AboutPreferences extends React.Component {
constructor (props) {
super(props)
+ this.focusElement = null
+ this.overlayName = ''
+ this.setFocusElement = element => {
+ this.focusElement = element
+ }
this.state = {
- bitcoinOverlayVisible: false,
- qrcodeOverlayVisible: false,
paymentHistoryOverlayVisible: false,
+ deletedSitesOverlayVisible: false,
advancedSettingsOverlayVisible: false,
ledgerBackupOverlayVisible: false,
ledgerRecoveryOverlayVisible: false,
@@ -700,9 +481,7 @@ class AboutPreferences extends React.Component {
siteSettings: Immutable.Map(),
braveryDefaults: Immutable.Map(),
ledgerData: Immutable.Map(),
- syncData: Immutable.Map(),
- firstRecoveryKey: '',
- secondRecoveryKey: ''
+ syncData: Immutable.Map()
}
// Similar to tabFromCurrentHash, this allows to set
@@ -747,6 +526,7 @@ class AboutPreferences extends React.Component {
ledgerRecoveryOverlayVisible: false
})
this.forceUpdate()
+ this.removeParams()
}
enableSyncRestore (enabled) {
@@ -776,6 +556,16 @@ class AboutPreferences extends React.Component {
this.setState(newState)
}
+ /**
+ * Using the history API, this removes any parameters
+ * from the current URL, leaving only the needed hash (ex #payments)
+ * This does not reload the page, it only modifies the browser history state,
+ * which replaces what is entered in the address bar
+ */
+ removeParams () {
+ window.history.replaceState(null, null, `#${this.hash}`)
+ }
+
/**
* Parses a query string like:
* about:preferences#payments?ledgerBackupOverlayVisible
@@ -849,25 +639,59 @@ class AboutPreferences extends React.Component {
settings.SPELLCHECK_LANGUAGES
]
if (settingsRequiringRestart.includes(key)) {
- ipc.send(messages.PREFS_RESTART, key, value)
+ aboutActions.requireRestart(key, value)
}
if (key === settings.PAYMENTS_ENABLED && value === true) {
this.createWallet()
}
}
+ /**
+ * Sets the overlay name listened to on escape key
+ * @param {string} name - Prefix name of the overlay
+ * @returns {void}
+ */
+ setOverlayName = (name) => {
+ this.overlayName = name
+ this.focusElement.focus()
+ }
+
+ /**
+ * Executes when navigating back and forth through a wizard dialog
+ * @returns {void}
+ */
+ onNavigate = () => {
+ this.focusElement.focus()
+ }
+
+ /**
+ * Listens for when 'escape' is pressed
+ * @param {event} e - current event
+ * @returns {void}
+ */
+ onEscape = (e) => {
+ if (e.keyCode === keyCodes.ESC && this.overlayName !== '') {
+ e.stopPropagation()
+ this.setOverlayVisible(false, this.overlayName)
+ }
+ }
+
setOverlayVisible (isVisible, overlayName) {
let stateDiff = {}
stateDiff[`${overlayName}OverlayVisible`] = isVisible
- if (overlayName === 'addFunds' && isVisible === false) {
- // Hide the child overlays when the parent is closed
- stateDiff['bitcoinOverlayVisible'] = false
- stateDiff['qrcodeOverlayVisible'] = false
- }
this.setState(stateDiff)
- // Tell ledger when Add Funds overlay is closed
- if (isVisible === false && overlayName === 'addFunds') {
- appActions.onAddFundsClosed()
+ if (isVisible === false) {
+ // Tell ledger when Add Funds overlay is closed
+ if (overlayName === 'addFunds') {
+ appActions.onAddFundsClosed()
+ appActions.onChangeAddFundsDialogStep('addFundsWizardMain')
+ } else if (overlayName === 'ledgerBackup' || overlayName === 'ledgerRecovery') {
+ this.setOverlayName('advancedSettings')
+ this.focusElement.focus()
+ } else {
+ this.setOverlayName('')
+ }
+ this.removeParams()
}
}
@@ -912,15 +736,19 @@ class AboutPreferences extends React.Component {
syncAddOverlayVisible={this.state.syncAddOverlayVisible}
syncNewDeviceOverlayVisible={this.state.syncNewDeviceOverlayVisible}
syncQRVisible={this.state.syncQRVisible}
+ setOverlayName={this.setOverlayName}
+ onNavigate={this.onNavigate}
showQR={() => {
this.setState({
syncQRVisible: true
})
+ this.onNavigate()
}}
hideQR={() => {
this.setState({
syncQRVisible: false
})
+ this.onNavigate()
}}
syncPassphraseVisible={this.state.syncPassphraseVisible}
showPassphrase={() => {
@@ -943,18 +771,18 @@ class AboutPreferences extends React.Component {
tab =
+ hideAdvancedOverlays={this.hideAdvancedOverlays.bind(this)}
+ setOverlayName={this.setOverlayName}
+ onNavigate={this.onNavigate}
+ />
break
case preferenceTabs.EXTENSIONS:
tab =
@@ -974,7 +802,7 @@ class AboutPreferences extends React.Component {
changeTab={this.changeTab.bind(this)}
refreshHint={this.refreshHint.bind(this)}
getNextHintNumber={this.getNextHintNumber.bind(this)} />
-
+
this.onEscape(e)} ref={this.setFocusElement} tabIndex='0'>
{tab}
@@ -988,51 +816,6 @@ const styles = StyleSheet.create({
marginLeft: '5px'
},
- sitePermissions: {
- listStyle: 'none',
- margin: '20px'
- },
-
- sitePermissions__permissionName: {
- fontWeight: 600
- },
-
- sitePermissions__clearAll: {
- cursor: 'pointer',
- color: globalStyles.color.gray,
- textDecoration: 'underline',
- marginLeft: '.5ch'
- },
-
- sitePermissions__clearAll__link: {
- // override the global value
- color: globalStyles.color.gray
- },
-
- sitePermissions__list: {
- marginBottom: '1rem'
- },
-
- sitePermissions__list__item: {
- display: 'flex',
- alignItems: 'center',
- lineHeight: 1.4
- },
-
- sitePermissions__list__item__button: {
- marginRight: '.25rem',
- color: globalStyles.color.braveOrange,
-
- ':hover': {
- color: globalStyles.color.braveOrange
- }
- },
-
- sitePermissions__list__item__status: {
- marginLeft: '.5ch',
- fontStyle: 'italic'
- },
-
sortableTable_searchTab: {
width: '704px',
marginBottom: globalStyles.spacing.settingsListContainerMargin // See syncTab.js for use cases
@@ -1058,6 +841,13 @@ const styles = StyleSheet.create({
searchShortcutEntry: {
fontSize: '1rem'
+ },
+
+ link: {
+ cursor: 'pointer',
+ fontSize: '14px',
+ lineHeight: '3em',
+ textDecoration: 'underline'
}
})
diff --git a/js/about/safebrowsing.js b/js/about/safebrowsing.js
index 8fb9b487e11..549bbd6dec3 100644
--- a/js/about/safebrowsing.js
+++ b/js/about/safebrowsing.js
@@ -7,9 +7,8 @@ const BrowserButton = require('../../app/renderer/components/common/browserButto
const {StyleSheet, css} = require('aphrodite/no-important')
-require('../../less/button.less')
-require('../../less/window.less')
-require('../../less/about/error.less')
+const globalStyles = require('../../app/renderer/components/styles/global')
+require('../../app/renderer/components/styles/globalSelectors')
class SafebrowsingPage extends React.Component {
constructor (props) {
@@ -19,54 +18,87 @@ class SafebrowsingPage extends React.Component {
}
}
- onAdvancedToggle () {
+ onAdvancedToggle = () => {
this.setState({advanced: !this.state.advanced})
}
render () {
- return
-
-
-
-
-
-
-
- {this.state.advanced
- ?
-
+ return
+
+
+
+
+
+
+
+
+ {this.state.advanced
+ ?
+ :
-
-
- :
- }
-
+
+ }
+
+
}
}
const styles = StyleSheet.create({
+ appContainer: {
+ backgroundColor: 'red',
+ overflow: 'auto'
+ },
+
+ error__content: {
+ background: globalStyles.color.veryLightGray,
+ display: 'flex',
+ width: '60vw',
+ maxWidth: '600px',
+ margin: '20vh auto',
+ lineHeight: '1.6em',
+ flexDirection: 'column',
+ padding: '40px',
+ height: 'auto !important' // TODO: override #appcontainer > div
+ },
+
+ error__logo: {
+ marginBottom: '2rem'
+ },
+
+ error__logo__inner: {
+ fill: globalStyles.color.braveOrange
+ },
+
safebrowsingErrorText__wrapper: {
marginBottom: '1rem'
},
+ buttons__wrapper: {
+ display: 'flex',
+ flexFlow: 'row wrap'
+ },
+
subtleText: {
marginTop: '1rem'
},
+
subtleText__p: {
marginTop: '1rem'
}
diff --git a/js/about/styles.js b/js/about/styles.js
index 736392fd288..809c0678de1 100644
--- a/js/about/styles.js
+++ b/js/about/styles.js
@@ -10,7 +10,12 @@ const globalStyles = require('../../app/renderer/components/styles/global')
require('../../node_modules/font-awesome/css/font-awesome.css')
const {Textbox, FormTextbox, SettingTextbox} = require('../../app/renderer/components/common/textbox')
-const {TextArea, DefaultTextArea} = require('../../app/renderer/components/common/textbox')
+
+const {
+ TextArea,
+ DefaultTextArea,
+ WordCountTextArea
+} = require('../../app/renderer/components/common/textbox')
const {
Dropdown,
@@ -31,9 +36,13 @@ const {
const {
CommonForm,
+ CommonFormTitle,
CommonFormSection,
CommonFormDropdown,
- CommonFormClickable
+ CommonFormClickable,
+ CommonFormSubSection,
+ CommonFormButtonWrapper,
+ CommonFormBottomWrapper
} = require('../../app/renderer/components/common/commonForm')
class Container extends ImmutableComponent {
@@ -174,6 +183,15 @@ class AboutStyle extends ImmutableComponent {
+
+ Word Count textarea
+ console.log('changed!!')} />
+
+ const { '{WordCountTextArea}' } = require('../../app/renderer/components/common/textbox'){'\n'}
+ <WordCountTextArea />
+
+
+
@@ -390,7 +408,7 @@ class AboutStyle extends ImmutableComponent {
bottom: '40px'
}}>
- Title
+ CommonFormTitle
CommonFormSection - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua.
@@ -401,37 +419,41 @@ class AboutStyle extends ImmutableComponent {
- Sub Section
-
+ CommonFormSubSection
+
CommonFormDropdown
-
+
CommonFormSection - Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut
labore et dolore magna aliqua.
-
+
-
-
+
+
CommonFormClickable
-
+
const {{'\n'}
CommonForm,{'\n'}
+ CommonFormTitle,{'\n'}
CommonFormSection,{'\n'}
CommonFormDropdown,{'\n'}
- CommonFormClickable{'\n'}
+ CommonFormClickable,{'\n'}
+ CommonFormSubSection,{'\n'}
+ CommonFormButtonWrapper,{'\n'}
+ CommonFormBottomWrapper{'\n'}
} = require('../../app/renderer/components/common/commonForm'){'\n'}
{'\n'}
<CommonForm>{'\n'}
- <CommonFormSection title>Title</CommonFormSection>{'\n'}
+ <CommonFormTitle>CommonFormTitle</CommonFormTitle>{'\n'}
<CommonFormSection>{'\n'}
CommonFormSection - Lorem ipsum dolor sit amet, consectetur adipisicing elit,{'\n'}
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.{'\n'}
@@ -442,24 +464,24 @@ class AboutStyle extends ImmutableComponent {
</CommonFormDropdown>{'\n'}
</CommonFormSection>{'\n'}
<CommonFormSection>{'\n'}
- <CommonFormSection subSection>Sub Section</CommonFormSection>{'\n'}
- <CommonFormSection subSection>{'\n'}
+ <CommonFormSubSection>CommonFormSubSection</CommonFormSubSection>{'\n'}
+ <CommonFormSubSection>{'\n'}
<CommonFormDropdown>{'\n'}
<option value='CommonFormDropdown'>CommonFormDropdown</option>{'\n'}
</CommonFormDropdown>{'\n'}
- </CommonFormSection>{'\n'}
+ </CommonFormSubSection>{'\n'}
</CommonFormSection>{'\n'}
<CommonFormSection>{'\n'}
CommonFormSection - Lorem ipsum dolor sit amet, consectetur adipisicing elit,{'\n'}
sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.{'\n'}
</CommonFormSection>{'\n'}
- <CommonFormSection buttons>{'\n'}
+ <CommonFormButtonWrapper>{'\n'}
<BrowserButton groupedItem secondaryColor l10nId='Cancel' />{'\n'}
<BrowserButton groupedItem primaryColor l10nId='Done' />{'\n'}
- </CommonFormSection>{'\n'}
- <CommonFormSection bottom>{'\n'}
+ </CommonFormButtonWrapper>{'\n'}
+ <CommonFormBottomWrapper>{'\n'}
<CommonFormClickable>CommonFormClickable</CommonFormClickable>{'\n'}
- </CommonFormSection>{'\n'}
+ </CommonFormBottomWrapper>{'\n'}
</CommonForm>{'\n'}
@@ -482,18 +504,18 @@ class AboutStyle extends ImmutableComponent {
bottom: '40px'
}}>
- Title
+ CommonFormTitle
const {{'\n'}
CommonForm,{'\n'}
- CommonFormSection{'\n'}
+ CommonFormTitle{'\n'}
} = require('../../app/renderer/components/common/commonForm'){'\n'}
{'\n'}
<CommonForm>{'\n'}
- <CommonFormSection title>Title</CommonFormSection>{'\n'}
+ <CommonFormTitle>CommonFormTitle</CommonFormTitle>{'\n'}
</CommonForm>{'\n'}
@@ -570,12 +592,12 @@ class AboutStyle extends ImmutableComponent {
}}>
- Sub Section
-
+ CommonFormSubSection
+
CommonFormDropdown
-
+
@@ -584,17 +606,18 @@ class AboutStyle extends ImmutableComponent {
const {{'\n'}
CommonForm,{'\n'}
CommonFormSection,{'\n'}
+
CommonFormSubSection,{'\n'}
CommonFormDropdown{'\n'}
} = require('../../app/renderer/components/common/commonForm'){'\n'}
{'\n'}
<CommonForm>{'\n'}
<CommonFormSection>{'\n'}
-
<CommonFormSection subSection>Sub Section</CommonFormSection>{'\n'}
-
<CommonFormSection subSection>{'\n'}
+
<CommonFormSubSection>CommonFormSubSection</CommonFormSubSection>{'\n'}
+
<CommonFormSubSection>{'\n'}
<CommonFormDropdown>{'\n'}
<option value='CommonFormDropdown'>CommonFormDropdown</option>{'\n'}
</CommonFormDropdown>{'\n'}
-
</CommonFormSection>{'\n'}
+
</CommonFormSubSection>{'\n'}
</CommonFormSection>{'\n'}
</CommonForm>{'\n'}
@@ -608,24 +631,24 @@ class AboutStyle extends ImmutableComponent {
bottom: '40px'
}}>
-
+
-
+
const {{'\n'}
CommonForm,{'\n'}
- CommonFormSection{'\n'}
+ CommonFormButtonWrapper{'\n'}
} = require('../../app/renderer/components/common/commonForm'){'\n'}
{'\n'}
<CommonForm>{'\n'}
- <CommonFormSection buttons>{'\n'}
+ <CommonFormButtonWrapper>{'\n'}
<BrowserButton groupedItem secondaryColor l10nId='Cancel' />{'\n'}
<BrowserButton groupedItem primaryColor l10nId='Done' />{'\n'}
- </CommonFormSection>{'\n'}
+ </CommonFormButtonWrapper>{'\n'}
</CommonForm>{'\n'}
@@ -638,23 +661,23 @@ class AboutStyle extends ImmutableComponent {
bottom: '40px'
}}>
-
+
CommonFormClickable
-
+
const {{'\n'}
CommonForm,{'\n'}
- CommonFormSection,{'\n'}
+ CommonFormBottomWrapper,{'\n'}
CommonFormClickable{'\n'}
} = require('../../app/renderer/components/common/commonForm'){'\n'}
{'\n'}
<CommonForm>{'\n'}
- <CommonFormSection bottom>{'\n'}
+ <CommonFormBottomWrapper>{'\n'}
<CommonFormClickable>CommonFormClickable</CommonFormClickable>{'\n'}
- </CommonFormSection>{'\n'}
+ </CommonFormBottomWrapper>{'\n'}
</CommonForm>{'\n'}
diff --git a/js/actions/appActions.js b/js/actions/appActions.js
index 3e4e0d7cc2f..7f214fded00 100644
--- a/js/actions/appActions.js
+++ b/js/actions/appActions.js
@@ -37,6 +37,16 @@ const appActions = {
})
},
+ /**
+ * Dispatches an event to the main process to focus the active window,
+ * or create a new one if there is no active window.
+ */
+ focusOrCreateWindow: function () {
+ dispatch({
+ actionType: appConstants.APP_FOCUS_OR_CREATE_WINDOW
+ })
+ },
+
windowReady: function (windowId, windowValue) {
dispatch({
actionType: appConstants.APP_WINDOW_READY,
@@ -97,10 +107,10 @@ const appActions = {
* Frame props changed
* @param {Object} frame
*/
- frameChanged: function (frame) {
+ framesChanged: function (frames) {
dispatch({
- actionType: appConstants.APP_FRAME_CHANGED,
- frame
+ actionType: appConstants.APP_FRAMES_CHANGED,
+ frames
})
},
@@ -130,10 +140,15 @@ const appActions = {
* Tab moved event fired from muon
* @param {Object} tabValue
*/
- tabMoved: function (tabId) {
+ tabMoved: function (tabId, fromIndex, toIndex, windowId) {
dispatch({
actionType: appConstants.APP_TAB_MOVED,
- tabId
+ tabId,
+ fromIndex,
+ toIndex,
+ queryInfo: {
+ windowId
+ }
})
},
@@ -188,6 +203,25 @@ const appActions = {
})
},
+ /**
+ * Dispatches a message to the store to indicate that the webview entered full screen mode.
+ *
+ * @param {Object} tabId - Tab id of the frame to put in full screen
+ * @param {boolean} isFullScreen - true if the webview is entering full screen mode.
+ * @param {boolean} showFullScreenWarning - true if a warning about entering full screen should be shown.
+ */
+ tabSetFullScreen: function (tabId, isFullScreen, showFullScreenWarning, windowId) {
+ dispatch({
+ actionType: appConstants.APP_TAB_SET_FULL_SCREEN,
+ tabId,
+ isFullScreen,
+ showFullScreenWarning,
+ queryInfo: {
+ windowId
+ }
+ })
+ },
+
/**
* Menu item for closing tabs to the left has been clicked.
* @param {Number} tabId The tabId woh's tabs to the left should be closed.
@@ -235,12 +269,13 @@ const appActions = {
* switch to it instead of creating a new one
* @param {Boolean} isRestore when true, won't try to activate the new tab, even if the user preference indicates to
*/
- createTabRequested: function (createProperties, activateIfOpen = false, isRestore = false) {
+ createTabRequested: function (createProperties, activateIfOpen = false, isRestore = false, focusWindow = false) {
dispatch({
actionType: appConstants.APP_CREATE_TAB_REQUESTED,
createProperties,
activateIfOpen,
- isRestore
+ isRestore,
+ focusWindow
})
},
@@ -255,12 +290,14 @@ const appActions = {
* A request for a URL load
* @param {number} tabId - the tab ID to load the URL inside of
* @param {string} url - The url to load
+ * @param {boolean} reloadMatchingUrl - would you like to force reload provided tab
*/
- loadURLRequested: function (tabId, url) {
+ loadURLRequested: function (tabId, url, reloadMatchingUrl) {
dispatch({
actionType: appConstants.APP_LOAD_URL_REQUESTED,
tabId,
- url
+ url,
+ reloadMatchingUrl
})
},
@@ -305,6 +342,18 @@ const appActions = {
})
},
+ tabReplaced: function (oldTabId, newTabValue, windowId, isPermanent) {
+ dispatch({
+ actionType: appConstants.APP_TAB_REPLACED,
+ oldTabId,
+ newTabValue,
+ isPermanent,
+ queryInfo: {
+ windowId
+ }
+ })
+ },
+
/**
* Dispatches a message to the store to set a new frame as the active frame.
*
@@ -372,7 +421,7 @@ const appActions = {
/**
* Removes a site from the site list
- * @param {string|Immutable.List} historyKey - Hisotry item key that we want to remove, can be list of keys as well
+ * @param {string|Immutable.List} historyKey - History item key that we want to remove, can be list of keys as well
*/
removeHistorySite: function (historyKey) {
dispatch({
@@ -381,6 +430,17 @@ const appActions = {
})
},
+ /**
+ * Removes all sites for the given domain from the site list
+ * @param {string} domain - Domain of the sites we want to remove
+ */
+ removeHistoryDomain: function (domain) {
+ dispatch({
+ actionType: appConstants.APP_REMOVE_HISTORY_DOMAIN,
+ domain
+ })
+ },
+
/**
* Dispatches a message to add/edit download details
* If set, also indicates that add/edit is shown
@@ -1140,23 +1200,6 @@ const appActions = {
})
},
- /**
- * Dispatches a message when a web contents is added
- * @param {number} windowId - The windowId of the host window
- * @param {object} frameOpts - frame options for the added web contents
- * @param {object} tabValue - the created tab state
- */
- newWebContentsAdded: function (windowId, frameOpts, tabValue) {
- dispatch({
- actionType: appConstants.APP_NEW_WEB_CONTENTS_ADDED,
- queryInfo: {
- windowId
- },
- frameOpts,
- tabValue
- })
- },
-
/**
* Notifies the app that a drag operation started from within the app
* @param {number} windowId - The source windowId the drag is starting from
@@ -1659,6 +1702,13 @@ const appActions = {
})
},
+ onPublishersOptionUpdate: function (publishersArray) {
+ dispatch({
+ actionType: appConstants.APP_ON_PUBLISHERS_OPTION_UPDATE,
+ publishersArray
+ })
+ },
+
onLedgerWalletCreate: function () {
dispatch({
actionType: appConstants.APP_ON_LEDGER_WALLET_CREATE
@@ -1772,37 +1822,6 @@ const appActions = {
})
},
- onPinnedTabReorder: function (siteKey, destinationKey, prepend) {
- dispatch({
- actionType: appConstants.APP_ON_PINNED_TAB_REORDER,
- siteKey,
- destinationKey,
- prepend
- })
- },
-
- /**
- * Dispatches a message that bookmark calculation was done
- * @param bookmarkList {Object} - Object is a list of bookmarks with key, width and parentFolderId as a property
- */
- onBookmarkWidthChanged: function (bookmarkList) {
- dispatch({
- actionType: appConstants.APP_ON_BOOKMARK_WIDTH_CHANGED,
- bookmarkList
- })
- },
-
- /**
- * Dispatches a message that bookmark calculation was done
- * @param folderList {Object} - Object is a list of folders with key, width and parentFolderId as a property
- */
- onBookmarkFolderWidthChanged: function (folderList) {
- dispatch({
- actionType: appConstants.APP_ON_BOOKMARK_FOLDER_WIDTH_CHANGED,
- folderList
- })
- },
-
/**
* Dispatches a message that window was resized
* @param windowValue - window properties
@@ -1818,42 +1837,51 @@ const appActions = {
})
},
- onBitcoinToBatNotified: function () {
+ /**
+ * Dispatches a message to add a given publisher to the ledger.
+ * @param location - the URL of the publisher
+ */
+ addPublisherToLedger: function (location, tabId = false) {
dispatch({
- actionType: appConstants.APP_ON_BTC_TO_BAT_NOTIFIED
+ actionType: appConstants.APP_ADD_PUBLISHER_TO_LEDGER,
+ location,
+ tabId
})
},
- onBitcoinToBatTransitioned: function () {
+ onPublisherTimestamp: function (timestamp, updateList) {
dispatch({
- actionType: appConstants.APP_ON_BTC_TO_BAT_TRANSITIONED
+ actionType: appConstants.APP_ON_PUBLISHER_TIMESTAMP,
+ timestamp,
+ updateList
})
},
- onBitcoinToBatBeginTransition: function () {
+ saveLedgerPromotion: function (promotion) {
dispatch({
- actionType: appConstants.APP_ON_BTC_TO_BAT_BEGIN_TRANSITION
+ actionType: appConstants.APP_SAVE_LEDGER_PROMOTION,
+ promotion
})
},
- onPublisherTimestamp: function (timestamp, updateList) {
+ onPromotionClick: function () {
dispatch({
- actionType: appConstants.APP_ON_PUBLISHER_TIMESTAMP,
- timestamp,
- updateList
+ actionType: appConstants.APP_ON_PROMOTION_CLICK
})
},
- saveLedgerPromotion: function (promotion) {
+ onCaptchaResponse: function (body) {
dispatch({
- actionType: appConstants.APP_SAVE_LEDGER_PROMOTION,
- promotion
+ actionType: appConstants.APP_ON_CAPTCHA_RESPONSE,
+ body
})
},
- onPromotionClaim: function () {
+ onPromotionClaim: function (x, y) {
dispatch({
- actionType: appConstants.APP_ON_PROMOTION_CLAIM
+ actionType: appConstants.APP_ON_PROMOTION_CLAIM,
+ x,
+ y
})
},
@@ -1894,12 +1922,12 @@ const appActions = {
})
},
- onLedgerMediaData: function (url, type, tabId) {
+ onLedgerMediaData: function (url, type, details) {
dispatch({
actionType: appConstants.APP_ON_LEDGER_MEDIA_DATA,
url,
type,
- tabId
+ details
})
},
@@ -1910,11 +1938,10 @@ const appActions = {
})
},
- onReferralCodeRead: function (downloadId, promoCode) {
+ onReferralCodeRead: function (body) {
dispatch({
actionType: appConstants.APP_ON_REFERRAL_CODE_READ,
- downloadId,
- promoCode
+ body
})
},
@@ -1924,6 +1951,22 @@ const appActions = {
})
},
+ onFetchReferralHeaders: function (error, response, body) {
+ dispatch({
+ actionType: appConstants.APP_ON_FETCH_REFERRAL_HEADERS,
+ error,
+ response,
+ body
+ })
+ },
+
+ onFileRecoveryKeys: function (file) {
+ dispatch({
+ actionType: appConstants.APP_ON_FILE_RECOVERY_KEYS,
+ file
+ })
+ },
+
checkReferralActivity: function () {
dispatch({
actionType: appConstants.APP_CHECK_REFERRAL_ACTIVITY
@@ -1942,6 +1985,14 @@ const appActions = {
})
},
+ onLedgerPinPublisher: function (publisherKey, value) {
+ dispatch({
+ actionType: appConstants.APP_ON_LEDGER_PIN_PUBLISHER,
+ publisherKey,
+ value
+ })
+ },
+
onLedgerMediaPublisher: function (mediaKey, response, duration, revisited) {
dispatch({
actionType: appConstants.APP_ON_LEDGER_MEDIA_PUBLISHER,
@@ -1950,6 +2001,64 @@ const appActions = {
duration,
revisited
})
+ },
+
+ onLedgerFuzzing: function (newStamp) {
+ dispatch({
+ actionType: appConstants.APP_ON_LEDGER_FUZZING,
+ newStamp
+ })
+ },
+
+ onLedgerBackupSuccess: function () {
+ dispatch({
+ actionType: appConstants.APP_ON_LEDGER_BACKUP_SUCCESS
+ })
+ },
+
+ onWalletPropertiesError: function () {
+ dispatch({
+ actionType: appConstants.APP_ON_WALLET_PROPERTIES_ERROR
+ })
+ },
+
+ onWalletDelete: function () {
+ dispatch({
+ actionType: appConstants.APP_ON_WALLET_DELETE
+ })
+ },
+
+ onPublisherToggleUpdate: function (viewData) {
+ dispatch({
+ actionType: appConstants.APP_ON_PUBLISHER_TOGGLE_UPDATE,
+ viewData
+ })
+ },
+
+ onCaptchaClose: function () {
+ dispatch({
+ actionType: appConstants.APP_ON_CAPTCHA_CLOSE
+ })
+ },
+
+ tabInsertedToTabStrip: function (windowId, tabId, index) {
+ dispatch({
+ actionType: appConstants.APP_TAB_INSERTED_TO_TAB_STRIP,
+ queryInfo: {
+ windowId
+ },
+ tabId,
+ index,
+ windowId
+ })
+ },
+
+ tabDetachedFromTabStrip: function (windowId, index) {
+ dispatch({
+ actionType: appConstants.APP_TAB_DETACHED_FROM_TAB_STRIP,
+ index,
+ windowId
+ })
}
}
diff --git a/js/actions/webviewActions.js b/js/actions/webviewActions.js
index 8d349ab932e..bdf74771968 100644
--- a/js/actions/webviewActions.js
+++ b/js/actions/webviewActions.js
@@ -4,20 +4,20 @@
'use strict'
-const getWebview = (key) =>
- key
- ? document.querySelector(`webview[data-frame-key="${key}"]`)
- : document.querySelector('.frameWrapper.isActive webview')
+let webviewDisplay
+const getWebview = () => webviewDisplay && webviewDisplay.getActiveWebview()
const webviewActions = {
+
+ init: function (mainWindowWebviewDisplay) {
+ webviewDisplay = mainWindowWebviewDisplay
+ },
+
/**
* Puts the webview in focus
*/
setWebviewFocused: function () {
- const webview = getWebview()
- if (webview) {
- webview.focus()
- }
+ webviewDisplay && webviewDisplay.focusActiveWebview()
},
/**
@@ -38,31 +38,6 @@ const webviewActions = {
if (webview) {
webview.showDefinitionForSelection()
}
- },
-
- findInPage: function (searchString, caseSensitivity, forward, findNext, webview) {
- webview = webview || getWebview()
- if (!webview) {
- return
- }
-
- if (searchString) {
- webview.findInPage(searchString, {
- matchCase: caseSensitivity,
- forward,
- findNext
- })
- } else {
- webview.stopFindInPage('clearSelection')
- }
- },
-
- stopFindInPage: function (webview) {
- webview = webview || getWebview()
- if (!webview) {
- return
- }
- webview.stopFindInPage('keepSelection')
}
}
diff --git a/js/actions/windowActions.js b/js/actions/windowActions.js
index ca02820f052..6966cddc849 100644
--- a/js/actions/windowActions.js
+++ b/js/actions/windowActions.js
@@ -52,36 +52,6 @@ const windowActions = {
})
},
- /**
- * Dispatches a message to change the frame tabId
- * @param {Object} frameProps - The frame properties
- * @param {Number} oldTabId - the current tabId
- * @param {Number} newTabId - the new tabId
- */
- frameTabIdChanged: function (frameProps, oldTabId, newTabId) {
- dispatch({
- actionType: windowConstants.WINDOW_FRAME_TAB_ID_CHANGED,
- frameProps,
- oldTabId,
- newTabId
- })
- },
-
- /**
- * Dispatches a message when the guestInstanceId changes for a frame
- * @param {Object} frameProps - The frame properties
- * @param {Number} oldGuestInstanceId - the current guestInstanceId
- * @param {Number} newGuestInstanceId - the new guestInstanceId
- */
- frameGuestInstanceIdChanged: function (frameProps, oldGuestInstanceId, newGuestInstanceId) {
- dispatch({
- actionType: windowConstants.WINDOW_FRAME_GUEST_INSTANCE_ID_CHANGED,
- frameProps,
- oldGuestInstanceId,
- newGuestInstanceId
- })
- },
-
/**
* Dispatches a message to set the frame error state
* @param {Object} frameProps - The frame properties
@@ -148,19 +118,11 @@ const windowActions = {
})
},
- /**
- * Dispatches a message to the store to indicate that the webview entered full screen mode.
- *
- * @param {Object} tabId - Tab id of the frame to put in full screen
- * @param {boolean} isFullScreen - true if the webview is entering full screen mode.
- * @param {boolean} showFullScreenWarning - true if a warning about entering full screen should be shown.
- */
- setFullScreen: function (tabId, isFullScreen, showFullScreenWarning) {
+ newFrame: function (frameOpts, tabValue) {
dispatch({
- actionType: windowConstants.WINDOW_SET_FULL_SCREEN,
- tabId,
- isFullScreen,
- showFullScreenWarning
+ actionType: windowConstants.WINDOW_NEW_FRAME,
+ frameOpts,
+ tabValue
})
},
@@ -169,10 +131,10 @@ const windowActions = {
*
* @param {Object} frameKey - Frame key of the frame to close
*/
- closeFrame: function (frameKey) {
+ removeFrame: function (tabId) {
dispatch({
- actionType: windowConstants.WINDOW_CLOSE_FRAME,
- frameKey
+ actionType: windowConstants.WINDOW_REMOVE_FRAME,
+ tabId
})
},
@@ -290,10 +252,10 @@ const windowActions = {
*
* @param {number} frameProps - The frame props to center around
*/
- setTabPageIndexByFrame: function (frameProps) {
+ setTabPageIndexByFrame: function (tabId) {
dispatch({
actionType: windowConstants.WINDOW_SET_TAB_PAGE_INDEX,
- frameProps
+ tabId
})
},
@@ -435,23 +397,6 @@ const windowActions = {
})
},
- /**
- * Dispatches a message to the store to indicate that the pending frame shortcut info should be updated.
- *
- * @param {Object} frameProps - Properties of the frame in question
- * @param {string} activeShortcut - The text for the new shortcut. Usually this is null to clear info which was previously
- * set from an IPC call.
- * @param {string} activeShortcutDetails - Parameters for the shortcut action
- */
- frameShortcutChanged: function (frameProps, activeShortcut, activeShortcutDetails) {
- dispatch({
- actionType: windowConstants.WINDOW_FRAME_SHORTCUT_CHANGED,
- frameProps,
- activeShortcut,
- activeShortcutDetails
- })
- },
-
/**
* Dispatches a message to set the find-in-page details.
* @param {Object} frameKey - Frame key of the frame in question
@@ -550,9 +495,16 @@ const windowActions = {
* @param {Object} detail - The context menu detail
*/
setContextMenuDetail: function (detail) {
+ // TODO(darkdh): This is a hack to prevent dispatch from serializing
+ // click function in template. `contextMenuDetail` is just a uuid to trigger
+ // state update for new menu
+ const Immutable = require('immutable')
+ const contextMenuState = require('../../app/common/state/contextMenuState')
+ let state = contextMenuState.setContextMenu(Immutable.Map(), detail)
+ const contextMenuDetail = state.get('contextMenuDetail')
dispatch({
actionType: windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL,
- detail
+ contextMenuDetail
})
},
@@ -627,21 +579,6 @@ const windowActions = {
})
},
- /**
- * Dispatches a message to store the last zoom percentage.
- * This is mainly just used to trigger updates throughout React.
- *
- * @param {object} frameProps - The frame to set blocked info on
- * @param {number} percentage - The new zoom percentage
- */
- setLastZoomPercentage: function (frameProps, percentage) {
- dispatch({
- actionType: windowConstants.WINDOW_SET_LAST_ZOOM_PERCENTAGE,
- frameProps,
- percentage
- })
- },
-
/**
* Saves the position of the window in the window state
* @param {Array} position - [x, y]
@@ -955,20 +892,6 @@ const windowActions = {
})
},
- /**
- * Used to get response details (such as the HTTP response code) from a response
- * See `eventStore.js` for an example use-case
- * @param {number} tabId - the tab id to set
- * @param {Object} details - object containing response details
- */
- gotResponseDetails: function (tabId, details) {
- dispatch({
- actionType: windowConstants.WINDOW_GOT_RESPONSE_DETAILS,
- tabId,
- details
- })
- },
-
/**
* Fired when the mouse clicks or hovers over a bookmark folder in the bookmarks toolbar
* @param {number} folderId - from the siteDetail for the bookmark folder
@@ -1112,15 +1035,6 @@ const windowActions = {
})
},
- onCertError: function (tabId, url, error) {
- dispatch({
- actionType: windowConstants.WINDOW_ON_CERT_ERROR,
- tabId,
- url,
- error
- })
- },
-
onTabPageContextMenu: function (index) {
dispatch({
actionType: windowConstants.WINDOW_ON_TAB_PAGE_CONTEXT_MENU,
diff --git a/js/constants/appConfig.js b/js/constants/appConfig.js
index 54684d2d086..1d1373392be 100644
--- a/js/constants/appConfig.js
+++ b/js/constants/appConfig.js
@@ -3,6 +3,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
const Immutable = require('immutable')
const {getTargetAboutUrl} = require('../lib/appUrlUtil')
+const webrtcConstants = require('./webrtcConstants')
// BRAVE_UPDATE_HOST should be set to the host name for the auto-updater server
const updateHost = process.env.BRAVE_UPDATE_HOST || 'https://laptop-updates.brave.com'
@@ -19,7 +20,7 @@ module.exports = {
name: 'Brave',
contactUrl: 'mailto:support+laptop@brave.com',
quitTimeout: isTest ? 3 * 1000 : 10 * 1000,
- sessionSaveInterval: 1000 * 60 * 5,
+ sessionSaveInterval: process.env.BRAVE_SESSION_SAVE_INTERVAL * 1000 || 1000 * 60 * 5,
resourceNames: {
ADBLOCK: 'adblock',
SAFE_BROWSING: 'safeBrowsing',
@@ -34,7 +35,8 @@ module.exports = {
COOKIEBLOCK: 'cookieblock', // block 3p cookies and referer
COOKIEBLOCK_ALL: 'cookieblockAll', // block all cookies and referer
SITEHACK: 'siteHacks',
- WEBTORRENT: 'webtorrent'
+ WEBTORRENT: 'webtorrent',
+ FIREWALL: 'firewall'
// ... other optional resource files are identified by uuid such as for regional adblock
},
cookieblock: {
@@ -96,6 +98,9 @@ module.exports = {
webtorrent: {
enabled: true
},
+ firewall: {
+ enabled: false
+ },
adInsertion: {
enabled: false,
url: adHost
@@ -213,6 +218,7 @@ module.exports = {
'advanced.toolbar-ui-scale': 'normal',
'advanced.swipe-nav-distance': 101,
'advanced.payments-allow-promotions': true,
+ 'advanced.webrtc.policy': webrtcConstants.default,
'shutdown.clear-history': false,
'shutdown.clear-downloads': false,
'shutdown.clear-cache': false,
@@ -220,6 +226,7 @@ module.exports = {
'shutdown.clear-autocomplete-data': false,
'shutdown.clear-autofill-data': false,
'shutdown.clear-site-settings': false,
+ 'shutdown.clear-publishers': false,
'extensions.pocket.enabled': false,
'extensions.vimium.enabled': false,
'extensions.honey.enabled': false,
@@ -232,6 +239,8 @@ module.exports = {
'notification-reconcile-soon-timestamp': null,
// debug
'debug.manual-tab-discard.enabled': false,
+ 'debug.verbose-tab-info.enabled': false,
+
// DEPRECATED settings
// DO NOT REMOVE OR CHANGE THESE VALUES
// ########################
diff --git a/js/constants/appConstants.js b/js/constants/appConstants.js
index 3d303216de0..0b1abaef653 100644
--- a/js/constants/appConstants.js
+++ b/js/constants/appConstants.js
@@ -12,12 +12,17 @@ const appConstants = {
APP_WINDOW_CLOSED: _,
APP_WINDOW_CREATED: _,
APP_WINDOW_UPDATED: _,
+ APP_FOCUS_OR_CREATE_WINDOW: _,
+ APP_TAB_INSERTED_TO_TAB_STRIP: _,
+ APP_TAB_DETACHED_FROM_TAB_STRIP: _,
APP_TAB_STRIP_EMPTY: _,
APP_TAB_CLOSED: _,
APP_TAB_UPDATED: _,
+ APP_TAB_REPLACED: _,
APP_ADD_HISTORY_SITE: _,
APP_SET_STATE: _,
APP_REMOVE_HISTORY_SITE: _,
+ APP_REMOVE_HISTORY_DOMAIN: _,
APP_MERGE_DOWNLOAD_DETAIL: _, // Sets an individual download detail
APP_CLEAR_COMPLETED_DOWNLOADS: _, // Removes all completed downloads
APP_SET_DATA_FILE_ETAG: _,
@@ -49,7 +54,7 @@ const appConstants = {
APP_NETWORK_CONNECTED: _,
APP_NETWORK_DISCONNECTED: _,
APP_CHANGE_NEW_TAB_DETAIL: _,
- APP_FRAME_CHANGED: _,
+ APP_FRAMES_CHANGED: _,
APP_TAB_CREATED: _,
APP_TAB_MOVED: _,
APP_TAB_DETACH_MENU_ITEM_CLICKED: _,
@@ -63,11 +68,11 @@ const appConstants = {
APP_TAB_ACTIVATE_REQUESTED: _,
APP_TAB_INDEX_CHANGE_REQUESTED: _,
APP_TAB_CLOSE_REQUESTED: _,
+ APP_TAB_SET_FULL_SCREEN: _,
APP_CREATE_TAB_REQUESTED: _,
APP_LOAD_URL_REQUESTED: _,
APP_LOAD_URL_IN_ACTIVE_TAB_REQUESTED: _,
APP_SIMPLE_SHARE_ACTIVE_TAB_REQUESTED: _,
- APP_NEW_WEB_CONTENTS_ADDED: _,
APP_SET_MENUBAR_TEMPLATE: _,
APP_UPDATE_ADBLOCK_DATAFILES: _,
APP_UPDATE_ADBLOCK_CUSTOM_RULES: _,
@@ -147,7 +152,6 @@ const appConstants = {
APP_LEARN_SPELLING: _,
APP_FORGET_LEARNED_SPELLING: _,
APP_SET_VERSION_INFO: _,
- APP_ON_PINNED_TAB_REORDER: _,
APP_ADD_BOOKMARK_FOLDER: _,
APP_EDIT_BOOKMARK_FOLDER: _,
APP_REMOVE_BOOKMARK_FOLDER: _,
@@ -156,11 +160,10 @@ const appConstants = {
APP_MOVE_BOOKMARK: _,
APP_ENABLE_PEPPER_MENU: _,
APP_INSPECT_ELEMENT: _,
- APP_ON_BOOKMARK_WIDTH_CHANGED: _,
- APP_ON_BOOKMARK_FOLDER_WIDTH_CHANGED: _,
APP_WINDOW_RESIZED: _,
APP_ON_FAVICON_RECEIVED: _,
APP_ON_PUBLISHER_OPTION_UPDATE: _,
+ APP_ON_PUBLISHERS_OPTION_UPDATE: _,
APP_ON_LEDGER_OPTION_UPDATE: _,
APP_ON_LEDGER_WALLET_CREATE: _,
APP_ON_BOOT_STATE_FILE: _,
@@ -174,30 +177,39 @@ const appConstants = {
APP_ON_LEDGER_CALLBACK: _,
APP_ON_TIME_UNTIL_RECONCILE: _,
APP_ON_LEDGER_RUN: _,
+ APP_ON_FILE_RECOVERY_KEYS: _,
APP_ON_NETWORK_CONNECTED: _,
APP_ON_RESET_RECOVERY_STATUS: _,
APP_ON_LEDGER_INIT_READ: _,
- APP_ON_BTC_TO_BAT_NOTIFIED: _,
- APP_ON_BTC_TO_BAT_TRANSITIONED: _,
APP_ON_LEDGER_QR_GENERATED: _,
- APP_ON_BTC_TO_BAT_BEGIN_TRANSITION: _,
APP_ON_PUBLISHER_TIMESTAMP: _,
APP_SAVE_LEDGER_PROMOTION: _,
APP_ON_PROMOTION_CLAIM: _,
+ APP_ON_PROMOTION_CLICK: _,
+ APP_ON_CAPTCHA_RESPONSE: _,
+ APP_ON_CAPTCHA_CLOSE: _,
APP_ON_PROMOTION_RESPONSE: _,
+ APP_ON_FETCH_REFERRAL_HEADERS: _,
APP_ON_PROMOTION_REMIND: _,
APP_ON_PROMOTION_REMOVAL: _,
APP_ON_PROMOTION_GET: _,
APP_ON_PROMOTION_CLOSE: _,
+ APP_ON_LEDGER_PIN_PUBLISHER: _,
APP_ON_LEDGER_NOTIFICATION_INTERVAL: _,
APP_ON_LEDGER_MEDIA_DATA: _,
+ APP_ON_LEDGER_FUZZING: _,
APP_ON_PRUNE_SYNOPSIS: _,
APP_ON_HISTORY_LIMIT: _,
APP_ON_REFERRAL_CODE_READ: _,
APP_ON_REFERRAL_CODE_FAIL: _,
APP_CHECK_REFERRAL_ACTIVITY: _,
APP_ON_REFERRAL_ACTIVITY: _,
- APP_ON_LEDGER_MEDIA_PUBLISHER: _
+ APP_ON_LEDGER_MEDIA_PUBLISHER: _,
+ APP_ON_LEDGER_BACKUP_SUCCESS: _,
+ APP_ADD_PUBLISHER_TO_LEDGER: _,
+ APP_ON_WALLET_DELETE: _,
+ APP_ON_WALLET_PROPERTIES_ERROR: _,
+ APP_ON_PUBLISHER_TOGGLE_UPDATE: _
}
module.exports = mapValuesByKeys(appConstants)
diff --git a/js/constants/messages.js b/js/constants/messages.js
index bd714c146c6..66f80436c47 100644
--- a/js/constants/messages.js
+++ b/js/constants/messages.js
@@ -96,6 +96,7 @@ const messages = {
EXTENSIONS_UPDATED: _,
ADBLOCK_UPDATED: _,
DOWNLOADS_UPDATED: _,
+ PRINTKEYS_UPDATED: _,
NEWTAB_DATA_UPDATED: _,
VERSION_INFORMATION_UPDATED: _,
// About pages from contentScript
diff --git a/js/constants/settings.js b/js/constants/settings.js
index 60947eb2089..6b37f57b5d6 100644
--- a/js/constants/settings.js
+++ b/js/constants/settings.js
@@ -48,6 +48,7 @@ const settings = {
SHUTDOWN_CLEAR_AUTOCOMPLETE_DATA: 'shutdown.clear-autocomplete-data',
SHUTDOWN_CLEAR_AUTOFILL_DATA: 'shutdown.clear-autofill-data',
SHUTDOWN_CLEAR_SITE_SETTINGS: 'shutdown.clear-site-settings',
+ SHUTDOWN_CLEAR_PUBLISHERS: 'shutdown.clear-publishers',
FLASH_INSTALLED: 'security.flash.installed',
FULLSCREEN_CONTENT: 'security.fullscreen.content',
AUTOPLAY_MEDIA: 'security.autoplay.media',
@@ -83,6 +84,7 @@ const settings = {
TOOLBAR_UI_SCALE: 'advanced.toolbar-ui-scale',
SWIPE_NAV_DISTANCE: 'advanced.swipe-nav-distance',
PAYMENTS_ALLOW_PROMOTIONS: 'advanced.payments-allow-promotions',
+ WEBRTC_POLICY: 'advanced.webrtc.policy',
// Sync settings
SYNC_ENABLED: 'sync.enabled',
SYNC_DEVICE_NAME: 'sync.device-name',
@@ -99,6 +101,7 @@ const settings = {
METAMASK_PROMPT_DISMISSED: 'extensions.metamask.promptDismissed',
// Debug settings
DEBUG_ALLOW_MANUAL_TAB_DISCARD: 'debug.manual-tab-discard.enabled',
+ DEBUG_VERBOSE_TAB_INFO: 'debug.verbose-tab-info.enabled',
// DEPRECATED settings
// DO NOT REMOVE OR CHANGE THESE VALUES
diff --git a/js/constants/webrtcConstants.js b/js/constants/webrtcConstants.js
new file mode 100644
index 00000000000..3e91abeef78
--- /dev/null
+++ b/js/constants/webrtcConstants.js
@@ -0,0 +1,21 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// https://developer.chrome.com/extensions/privacy#type-IPHandlingPolicy
+// see src/content/public/common/webrtc_ip_handling_policy.h for descriptions
+module.exports = {
+ // This is the default behavior of Chrome. Currently, WebRTC has the right to
+ // enumerate all interfaces and bind them to discover public interfaces.
+ default: 'default',
+ // WebRTC should only use the default route used by http. This also exposes
+ // the associated default private address. Default route is the route chosen
+ // by the OS on a multi-homed endpoint.
+ publicPrivate: 'default_public_and_private_interfaces',
+ // WebRTC should only use the default route used by http. This doesn't
+ // expose any local addresses.
+ publicOnly: 'default_public_interface_only',
+ // WebRTC should only use TCP to contact peers or servers unless the proxy
+ // server supports UDP. This doesn't expose any local addresses either.
+ disableNonProxiedUdp: 'disable_non_proxied_udp'
+}
diff --git a/js/constants/windowConstants.js b/js/constants/windowConstants.js
index 9318e2bcb89..00afb09d9ed 100644
--- a/js/constants/windowConstants.js
+++ b/js/constants/windowConstants.js
@@ -6,8 +6,9 @@ const mapValuesByKeys = require('../lib/functional').mapValuesByKeys
const _ = null
const windowConstants = {
+ WINDOW_NEW_FRAME: _,
WINDOW_SET_NAVBAR_INPUT: _,
- WINDOW_CLOSE_FRAME: _,
+ WINDOW_REMOVE_FRAME: _,
WINDOW_CLOSE_FRAMES: _,
WINDOW_SET_FOCUSED_FRAME: _,
WINDOW_SET_PREVIEW_TAB_PAGE_INDEX: _,
@@ -19,7 +20,6 @@ const windowConstants = {
WINDOW_TAB_MOVE_INCREMENTAL_REQUESTED: _,
WINDOW_SET_THEME_COLOR: _,
WINDOW_WEBVIEW_LOAD_END: _,
- WINDOW_SET_FULL_SCREEN: _,
WINDOW_SET_LINK_HOVER_PREVIEW: _,
WINDOW_SET_RENDER_URL_BAR_SUGGESTIONS: _,
WINDOW_URL_BAR_AUTOCOMPLETE_ENABLED: _,
@@ -30,8 +30,6 @@ const windowConstants = {
WINDOW_WEBVIEW_LOAD_START: _,
WINDOW_ADD_HISTORY: _,
WINDOW_SET_FRAME_ERROR: _,
- WINDOW_FRAME_TAB_ID_CHANGED: _,
- WINDOW_FRAME_GUEST_INSTANCE_ID_CHANGED: _,
WINDOW_SET_NAVIGATED: _,
WINDOW_SET_URL_BAR_ACTIVE: _, // whether the URL bar is being typed in
WINDOW_UNDO_CLOSED_FRAME: _,
@@ -61,7 +59,6 @@ const windowConstants = {
WINDOW_SET_REDIRECTED_BY: _, // Whether or not to show site info like redirected resources
WINDOW_SET_SECURITY_STATE: _,
WINDOW_SET_STATE: _,
- WINDOW_SET_LAST_ZOOM_PERCENTAGE: _,
WINDOW_SET_CLEAR_BROWSING_DATA_VISIBLE: _,
WINDOW_SET_IMPORT_BROWSER_DATA_DETAIL: _,
WINDOW_SET_IMPORT_BROWSER_DATA_SELECTED: _,
@@ -73,7 +70,6 @@ const windowConstants = {
WINDOW_RESET_MENU_STATE: _,
WINDOW_SET_MENUBAR_SELECTED_INDEX: _,
WINDOW_SET_LAST_FOCUSED_SELECTOR: _,
- WINDOW_GOT_RESPONSE_DETAILS: _,
WINDOW_SET_BOOKMARKS_TOOLBAR_SELECTED_FOLDER_ID: _,
WINDOW_SET_MODAL_DIALOG_DETAIL: _,
WINDOW_WIDEVINE_SITE_ACCESSED_WITHOUT_INSTALL: _,
@@ -93,7 +89,6 @@ const windowConstants = {
WINDOW_SET_ALL_AUDIO_MUTED: _,
WINDOW_ON_GO_BACK_LONG: _,
WINDOW_ON_GO_FORWARD_LONG: _,
- WINDOW_ON_CERT_ERROR: _,
WINDOW_ON_TAB_PAGE_CONTEXT_MENU: _,
WINDOW_ON_STOP: _,
WINDOW_ON_MORE_BOOKMARKS_MENU: _,
diff --git a/js/contextMenus.js b/js/contextMenus.js
index 994e3cc94ea..9046c84279f 100644
--- a/js/contextMenus.js
+++ b/js/contextMenus.js
@@ -38,6 +38,7 @@ const platformUtil = require('../app/common/lib/platformUtil')
const bookmarkFoldersUtil = require('../app/common/lib/bookmarkFoldersUtil')
const historyUtil = require('../app/common/lib/historyUtil')
const {makeImmutable} = require('../app/common/state/immutableUtil')
+const ledgerUtil = require('../app/common/lib/ledgerUtil')
const isDarwin = platformUtil.isDarwin()
const isLinux = platformUtil.isLinux()
@@ -296,6 +297,7 @@ const siteMultipleDetailTemplate = (data, type, activeFrame) => {
const siteSingleDetailTemplate = (siteKey, type, activeFrame) => {
const template = []
const state = appStoreRenderer.state
+ const paymentsEnabled = getSetting(settings.PAYMENTS_ENABLED)
let isFolder = type === siteTags.BOOKMARK_FOLDER
let siteDetail
@@ -355,6 +357,14 @@ const siteSingleDetailTemplate = (siteKey, type, activeFrame) => {
}
}
})
+
+ template.push({
+ label: locale.translation('deleteDomainFromHistory'),
+ click: () => {
+ const domain = urlParse(siteDetail.get('location')).hostname
+ appActions.removeHistoryDomain(domain)
+ }
+ })
}
if (type !== siteTags.HISTORY) {
@@ -368,6 +378,17 @@ const siteSingleDetailTemplate = (siteKey, type, activeFrame) => {
)
}
+ if (paymentsEnabled && (type === siteTags.HISTORY || type === siteTags.BOOKMARK)) {
+ let location = siteDetail.get('location')
+ let enabled = ledgerUtil.shouldShowMenuOption(state, location)
+ if (enabled) {
+ template.push(
+ CommonMenu.separatorMenuItem,
+ addToPublisherListMenuItem(location)
+ )
+ }
+ }
+
return template
}
@@ -487,20 +508,21 @@ function tabTemplateInit (frameProps) {
// }
// })
- const frameToSkip = frameProps.get('key')
- const frameList = frames.map((frame) => {
- return {
- frameKey: frame.get('key'),
- tabId: frame.get('tabId'),
- muted: frame.get('key') !== frameToSkip && frame.get('audioPlaybackActive')
- }
- })
-
template.push(CommonMenu.separatorMenuItem,
{
label: locale.translation('muteOtherTabs'),
click: () => {
- windowActions.muteAllAudio(frameList)
+ // only select frames which are not the current frame and are not muted
+ const otherFrames = frames.filter(frame =>
+ frame.get('key') !== frameProps.get('key') &&
+ frame.get('audioPlaybackActive') === true
+ )
+ const actionCommands = otherFrames.map(frame => ({
+ tabId: frame.get('tabId'),
+ frameKey: frame.get('key'),
+ muted: true
+ }))
+ windowActions.muteAllAudio(actionCommands)
}
})
@@ -894,6 +916,15 @@ const showDefinitionMenuItem = (selectionText) => {
}
}
+const addToPublisherListMenuItem = (location) => {
+ return {
+ label: locale.translation('addToPublisherList'),
+ click: () => {
+ appActions.addPublisherToLedger(location)
+ }
+ }
+}
+
function addLinkMenu (link, frame) {
const template = []
if (!frame.get('isPrivate')) {
diff --git a/js/data/backgrounds.js b/js/data/backgrounds.js
index 808de1aa49a..0eda42cb3b3 100644
--- a/js/data/backgrounds.js
+++ b/js/data/backgrounds.js
@@ -79,7 +79,7 @@ module.exports = [
"author": "Serge Ramelli",
"link": "https://www.photoserge.com/"
}, {
- "name": "Paris:Conciergeri",
+ "name": "Paris:Conciergerie",
"source": "https://s3.amazonaws.com/brave-backgrounds/Phoyoserge_ParisConciergeri.jpg",
"author": "Serge Ramelli",
"link": "https://www.photoserge.com/"
@@ -89,7 +89,7 @@ module.exports = [
"author": "Serge Ramelli",
"link": "https://www.photoserge.com/"
}, {
- "name": "Paris:The Seant",
+ "name": "Paris:The Senate",
"source": "https://s3.amazonaws.com/brave-backgrounds/Phoyoserge_TheSeantParis.jpg",
"author": "Serge Ramelli",
"link": "https://www.photoserge.com/"
diff --git a/js/data/newTabData.js b/js/data/newTabData.js
index db1b11fe4d7..53adf1f7227 100644
--- a/js/data/newTabData.js
+++ b/js/data/newTabData.js
@@ -26,19 +26,19 @@ module.exports.topSites = [
'title': 'Brave Software (@brave) | Twitter'
},
{
- 'key': 'https://www.facebook.com/BraveSoftware/|0',
+ 'key': 'https://github.com/brave/|0',
'count': 0,
- 'favicon': `${iconPath}/facebook.png`,
- 'location': 'https://www.facebook.com/BraveSoftware/',
- 'themeColor': 'rgb(59, 89, 152)',
- 'title': 'Brave Software | Facebook'
+ 'favicon': `${iconPath}/github.png`,
+ 'location': 'https://github.com/brave/',
+ 'themeColor': 'rgb(255, 255, 255)',
+ 'title': 'Brave Software | GitHub'
},
{
- 'key': 'https://www.youtube.com/bravesoftware/|0',
+ 'key': 'https://youtube.com/bravesoftware/|0',
'count': 0,
'favicon': `${iconPath}/youtube.png`,
- 'location': 'https://www.youtube.com/bravesoftware/',
- 'themeColor': '#E62117',
+ 'location': 'https://youtube.com/bravesoftware/',
+ 'themeColor': 'rgb(255, 255, 255)',
'title': 'Brave Browser - YouTube'
},
{
@@ -63,6 +63,6 @@ module.exports.topSites = [
'favicon': `${iconPath}/playstore.png`,
'location': 'https://play.google.com/store/apps/details?id=com.brave.browser',
'themeColor': 'rgb(241, 241, 241)',
- 'title': 'Brave Browser: Fast AdBlock – Apps para Android no Google Play'
+ 'title': 'Brave Browser: Fast AdBlocker - Apps on Google Play'
}
]
diff --git a/js/data/searchProviders.js b/js/data/searchProviders.js
index f663a1d49fc..61a604e9216 100644
--- a/js/data/searchProviders.js
+++ b/js/data/searchProviders.js
@@ -42,6 +42,15 @@ module.exports = { "providers" :
"autocomplete" : "https://ac.duckduckgo.com/ac/?q={searchTerms}&type=list",
"shortcut" : ":d"
},
+ {
+ "name" : "Fireball",
+ "base" : "https://fireball.com",
+ "image" : "https://fireball.com/favicon.ico",
+ "localImage" : getFaviconUrl('fireball'),
+ "search" : "https://fireball.com/?q={searchTerms}",
+ "autocomplete" : "https://fireball.com/search/?q={searchTerms}",
+ "shortcut" : ":f"
+ },
{
"name" : "GitHub",
"base" : "https://github.com/search",
diff --git a/js/data/siteSettingsList.js b/js/data/siteSettingsList.js
index 50694d68d15..8b587e71c64 100644
--- a/js/data/siteSettingsList.js
+++ b/js/data/siteSettingsList.js
@@ -11,5 +11,10 @@ module.exports.defaultSiteSettingsList = [
"name" : "autoplay",
"pattern" : "https://www.twitch.tv",
"value" : true,
+ },
+ {
+ "name" : "fingerprintingProtection",
+ "pattern" : "https?://uphold.com",
+ "value" : "allowAllFingerprinting"
}
]
diff --git a/js/entry.js b/js/entry.js
index bac1ef427bc..88378a6cade 100644
--- a/js/entry.js
+++ b/js/entry.js
@@ -37,6 +37,7 @@ const messages = require('./constants/messages')
const l10n = require('./l10n')
const currentWindow = require('../app/renderer/currentWindow')
+let shouldDebugTabEvents = false
webFrame.setPageScaleLimits(1, 1)
l10n.init()
@@ -60,8 +61,8 @@ if (process.env.NODE_ENV === 'test') {
ipc.on(messages.APP_STATE_CHANGE, (e, action) => {
appStoreRenderer.state = action.stateDiff
- ? appStoreRenderer.state = patch(appStoreRenderer.state, Immutable.fromJS(action.stateDiff))
- : appStoreRenderer.state = Immutable.fromJS(action.state)
+ ? patch(appStoreRenderer.state, Immutable.fromJS(action.stateDiff))
+ : Immutable.fromJS(action.state)
})
ipc.on(messages.CLEAR_CLOSED_FRAMES, (e, location) => {
@@ -77,11 +78,15 @@ ipc.on(messages.INITIALIZE_WINDOW, (e, mem) => {
const windowValue = message.windowValue
currentWindow.setWindowId(windowValue.id)
- const newState = Immutable.fromJS(message.windowState) || windowStore.getState()
+ if (process.env.NODE_ENV === 'development') {
+ console.debug(`This Window's ID is:`, windowValue.id)
+ }
+ const newState = Immutable.fromJS(message.windowState) || windowStore.getState()
appStoreRenderer.state = Immutable.fromJS(message.appState)
windowStore.state = newState
- generateTabs(newState, message.frames, windowValue.id)
+ shouldDebugTabEvents = message.windowState.debugTabEvents
+
appActions.windowReady(windowValue.id, windowValue)
ReactDOM.render(
, document.getElementById('appContainer'), fireOnReactRender.bind(null, windowValue))
})
@@ -90,24 +95,44 @@ const fireOnReactRender = (windowValue) => {
appActions.windowRendered(windowValue.id)
}
-const generateTabs = (windowState, frames, windowId) => {
- const activeFrameKey = windowState.get('activeFrameKey')
- if (frames && frames.length) {
- frames.forEach((frame, i) => {
- if (frame.guestInstanceId) {
- appActions.newWebContentsAdded(windowId, frame)
- } else {
- appActions.createTabRequested({
- url: frame.location || frame.src || frame.provisionalLocation || frame.url,
- partitionNumber: frame.partitionNumber,
- isPrivate: frame.isPrivate,
- active: activeFrameKey ? frame.key === activeFrameKey : true,
- discarded: frame.unloaded,
- title: frame.title,
- faviconUrl: frame.icon,
- index: i
- }, false, true /* isRestore */)
- }
+// listen for tab events
+const rendererTabEvents = require('../app/renderer/rendererTabEvents')
+
+electron.remote.registerAllWindowTabEvents(e => {
+ const eventName = e.type
+ const tabId = e.eventTabId
+ if (shouldDebugTabEvents) {
+ console.log(`%ctab event %d %c${eventName + (eventName === 'ipc-message' ? `: ${e.channel}` : '')}`, 'color: #8b8bb1', tabId, 'color: #4545d4; font-weight: bold', e)
+ }
+ try {
+ rendererTabEvents.handleTabEvent(tabId, eventName, e, shouldDebugTabEvents)
+ } catch (e) {
+ console.error(`Error handling event ${eventName} for tab ${tabId}`)
+ console.error(e)
+ }
+})
+
+ipc.on('new-web-contents-added', (e, frameOpts, newTabValue) => {
+ if (shouldDebugTabEvents) {
+ console.log(`ipc new-web-contents-added`, frameOpts, newTabValue)
+ }
+ windowActions.newFrame(frameOpts, newTabValue)
+})
+
+// listen for shortcuts
+const rendererShortcutHandler = require('../app/renderer/rendererShortcutHandler')
+const frameShortcuts = ['stop', 'reload', 'zoom-in', 'zoom-out', 'zoom-reset', 'toggle-dev-tools', 'clean-reload', 'view-source', 'mute', 'save', 'print', 'show-findbar', 'find-next', 'find-prev']
+frameShortcuts.forEach((shortcut) => {
+ // Listen for actions on the active frame
+ ipc.on(`shortcut-active-frame-${shortcut}`, rendererShortcutHandler.handleActiveFrameShortcut.bind(null, shortcut))
+ // Listen for actions on frame N
+ if (['reload', 'mute'].includes(shortcut)) {
+ ipc.on(`shortcut-frame-${shortcut}`, (e, frameKey, args) => {
+ rendererShortcutHandler.handleFrameShortcut(frameKey, shortcut, e, args)
})
}
-}
+})
+
+// emit frame changes back to browser
+const renderFrameTracker = require('../app/renderer/rendererFrameTracker')
+renderFrameTracker()
diff --git a/js/lib/appUrlUtil.js b/js/lib/appUrlUtil.js
index 3543b9c83f3..599ab1356b2 100644
--- a/js/lib/appUrlUtil.js
+++ b/js/lib/appUrlUtil.js
@@ -6,6 +6,7 @@ const Immutable = require('immutable')
const path = require('path')
const UrlUtil = require('./urlutil')
const config = require('../constants/config')
+const isDarwin = require('../../app/common/lib/platformUtil').isDarwin()
module.exports.fileUrl = (filePath) => {
// It's preferrable to call path.resolve but it's not available
@@ -62,6 +63,14 @@ module.exports.getExtensionsPath = function (extensionDir) {
: path.join(__dirname, '..', '..', 'app', 'extensions', extensionDir)
}
+module.exports.getComponentExtensionsPath = function (extensionDir) {
+ if (isDarwin) {
+ return path.join(process.resourcesPath, '../Frameworks/Brave Framework.framework/Resources/', extensionDir)
+ } else {
+ return path.join(process.resourcesPath, extensionDir)
+ }
+}
+
module.exports.getGenDir = function (url) {
const genDirRoots = [
module.exports.getBraveIndexPath,
@@ -115,6 +124,7 @@ module.exports.aboutUrls = new Immutable.Map({
'about:safebrowsing': module.exports.getBraveExtUrl('about-safebrowsing.html'),
'about:styles': module.exports.getBraveExtUrl('about-styles.html'),
'about:contributions': module.exports.getBraveExtUrl('about-contributions.html'),
+ 'about:printkeys': module.exports.getBraveExtUrl('about-printkeys.html'),
'about:welcome': module.exports.getBraveExtUrl('about-welcome.html')
})
diff --git a/js/lib/baseDomain.js b/js/lib/baseDomain.js
index 1d0769070aa..46e0c93b5a0 100644
--- a/js/lib/baseDomain.js
+++ b/js/lib/baseDomain.js
@@ -25,7 +25,10 @@ const checkASCII = function (str) {
* Returns base domain for specified host based on Public Suffix List.
* Derived from Privacy Badger Chrome
,
* Copyright (C) 2015 Electronic Frontier Foundation and other contributors
- * @param {string} hostname The name of the host to get the base domain for
+ * TODO: Consider refactoring this into isThirdPartyHost since it's only used
+ * for that.
+ * @param {string} hostname The name of the host to get the base domain for.
+ * The caller must validate that this is a valid, non-IP hostname string!!
*/
module.exports.getBaseDomain = function (hostname) {
@@ -44,6 +47,11 @@ module.exports.getBaseDomain = function (hostname) {
return baseDomain
}
+ // If the hostname is a TLD, return '' for the base domain
+ if (hostname in publicSuffixes) {
+ return ''
+ }
+
// search through PSL
var prevDomains = []
var curDomain = hostname
diff --git a/js/lib/color.js b/js/lib/color.js
index 4fa57ea2b19..e5707383f2d 100644
--- a/js/lib/color.js
+++ b/js/lib/color.js
@@ -5,10 +5,17 @@
module.exports.parseColor = (color) => {
const div = document.createElement('div')
div.style.color = color
- return div.style.color.split('(')[1].split(')')[0].split(',')
+ const normalizedColor = div.style.color
+ if (typeof normalizedColor === 'string' &&
+ normalizedColor.includes('(') &&
+ normalizedColor.includes(')') &&
+ normalizedColor.includes(',')) {
+ return div.style.color.split('(')[1].split(')')[0].split(',')
+ }
+ return null
}
-module.exports.getTextColorForBackground = (color) => {
+module.exports.backgroundRequiresLightText = (color) => {
// Calculate text color based on contrast with background:
// https://24ways.org/2010/calculating-color-contrast/
const rgb = module.exports.parseColor(color)
@@ -17,5 +24,32 @@ module.exports.getTextColorForBackground = (color) => {
}
const [r, g, b] = rgb
const yiq = ((r * 299) + (g * 587) + (b * 114)) / 1000
- return yiq >= 128 ? 'black' : 'white'
+ return yiq < 128
+}
+
+module.exports.getTextColorForBackground = (color) => {
+ return module.exports.backgroundRequiresLightText(color) ? 'white' : 'black'
+}
+
+module.exports.removeAlphaChannelForBackground = (color, bR, bG, bB) => {
+ const rgba = module.exports.parseColor(color)
+ if (!rgba) {
+ return null
+ }
+ // handle no alpha channel
+ if (rgba.length !== 4 || Number.isNaN(rgba[3])) {
+ return color
+ }
+
+ // remove alpha channel, blending color with background
+ const [oR, oG, oB, oA] = rgba
+
+ const newR = blendChannel(oR, bR, oA)
+ const newG = blendChannel(oG, bG, oA)
+ const newB = blendChannel(oB, bB, oA)
+ return `rgb(${newR}, ${newG}, ${newB})`
+}
+
+function blendChannel (original, background, alpha) {
+ return Math.round((original * alpha) + ((1 - alpha) * background))
}
diff --git a/js/lib/psl.js b/js/lib/psl.js
index 8569ce7ee9b..e351c0d8341 100644
--- a/js/lib/psl.js
+++ b/js/lib/psl.js
@@ -11,18 +11,33 @@ module.exports = {
"0.bg": 1,
"0emm.com": 2,
"1.bg": 1,
+ "12hp.at": 1,
+ "12hp.ch": 1,
+ "12hp.de": 1,
+ "1337.pictures": 1,
"1kapp.com": 1,
+ "1password.ca": 1,
+ "1password.com": 1,
+ "1password.eu": 1,
"2.bg": 1,
"2000.hu": 1,
+ "2038.io": 1,
+ "2ix.at": 1,
+ "2ix.ch": 1,
+ "2ix.de": 1,
"3.bg": 1,
"3utilities.com": 1,
"4.bg": 1,
+ "4lima.at": 1,
+ "4lima.ch": 1,
+ "4lima.de": 1,
"4u.com": 1,
"5.bg": 1,
"6.bg": 1,
"7.bg": 1,
"8.bg": 1,
"9.bg": 1,
+ "9guacu.br": 1,
"a.bg": 1,
"a.prod.fastly.net": 1,
"a.se": 1,
@@ -32,9 +47,11 @@ module.exports = {
"aarborte.no": 1,
"ab.ca": 1,
"abashiri.hokkaido.jp": 1,
+ "abc.br": 1,
"abeno.osaka.jp": 1,
"abiko.chiba.jp": 1,
"abira.hokkaido.jp": 1,
+ "abkhazia.su": 1,
"abo.pa": 1,
"abr.it": 1,
"abruzzo.it": 1,
@@ -47,12 +64,14 @@ module.exports = {
"ac.cr": 1,
"ac.cy": 1,
"ac.gn": 1,
+ "ac.gov.br": 1,
"ac.id": 1,
"ac.il": 1,
"ac.im": 1,
"ac.in": 1,
"ac.ir": 1,
"ac.jp": 1,
+ "ac.ke": 1,
"ac.kr": 1,
"ac.leg.br": 1,
"ac.lk": 1,
@@ -78,8 +97,11 @@ module.exports = {
"ac.vn": 1,
"ac.za": 1,
"ac.zm": 1,
+ "ac.zw": 1,
"aca.pro": 1,
+ "academia.bo": 1,
"academy.museum": 1,
+ "accesscam.org": 1,
"accident-investigation.aero": 1,
"accident-prevention.aero": 1,
"acct.pro": 1,
@@ -92,6 +114,7 @@ module.exports = {
"adult.ht": 1,
"adv.br": 1,
"adv.mz": 1,
+ "advisor.ws": 2,
"adygeya.ru": 1,
"adygeya.su": 1,
"ae.org": 1,
@@ -116,6 +139,7 @@ module.exports = {
"agriculture.museum": 1,
"agrigento.it": 1,
"agrinet.tn": 1,
+ "agro.bo": 1,
"agro.pl": 1,
"aguni.okinawa.jp": 1,
"ah.cn": 1,
@@ -141,6 +165,7 @@ module.exports = {
"aizumi.tokushima.jp": 1,
"aizumisato.fukushima.jp": 1,
"aizuwakamatsu.fukushima.jp": 1,
+ "aju.br": 1,
"ak.us": 1,
"akabira.hokkaido.jp": 1,
"akagi.shimane.jp": 1,
@@ -155,8 +180,10 @@ module.exports = {
"aknoluokta.no": 1,
"ako.hyogo.jp": 1,
"akrehamn.no": 1,
+ "aktyubinsk.su": 1,
"akune.kagoshima.jp": 1,
"al.eu.org": 1,
+ "al.gov.br": 1,
"al.it": 1,
"al.leg.br": 1,
"al.no": 1,
@@ -174,12 +201,12 @@ module.exports = {
"alstahaug.no": 1,
"alt.za": 1,
"alta.no": 1,
- "altai.ru": 1,
"alto-adige.it": 1,
"altoadige.it": 1,
"alvdal.no": 1,
- "alwaysdata.net": 2,
+ "alwaysdata.net": 1,
"am.br": 1,
+ "am.gov.br": 1,
"am.leg.br": 1,
"ama.aichi.jp": 1,
"ama.shimane.jp": 1,
@@ -197,13 +224,12 @@ module.exports = {
"amli.no": 1,
"amot.no": 1,
"amsterdam.museum": 1,
- "amur.ru": 1,
- "amursk.ru": 1,
"amusement.aero": 1,
"an.it": 1,
"anamizu.ishikawa.jp": 1,
"anan.nagano.jp": 1,
"anan.tokushima.jp": 1,
+ "anani.br": 1,
"ancona.it": 1,
"and.museum": 1,
"andasuolo.no": 1,
@@ -216,6 +242,7 @@ module.exports = {
"andriatranibarletta.it": 1,
"and\u00f8y.no": 1,
"anjo.aichi.jp": 1,
+ "ann-arbor.mi.us": 1,
"annaka.gunma.jp": 1,
"annefrank.museum": 1,
"anpachi.gifu.jp": 1,
@@ -232,15 +259,22 @@ module.exports = {
"aosta.it": 1,
"aostavalley.it": 1,
"aoste.it": 1,
- "ap-northeast-1.compute.amazonaws.com": 1,
- "ap-northeast-2.compute.amazonaws.com": 1,
- "ap-southeast-1.compute.amazonaws.com": 1,
- "ap-southeast-2.compute.amazonaws.com": 1,
+ "ap-northeast-1.elasticbeanstalk.com": 1,
+ "ap-northeast-2.elasticbeanstalk.com": 1,
+ "ap-south-1.elasticbeanstalk.com": 1,
+ "ap-southeast-1.elasticbeanstalk.com": 1,
+ "ap-southeast-2.elasticbeanstalk.com": 1,
+ "ap.gov.br": 1,
"ap.gov.pl": 1,
"ap.it": 1,
"ap.leg.br": 1,
- "api.githubcloud.com": 2,
+ "aparecida.br": 1,
+ "app.os.fedoraproject.org": 1,
+ "app.os.stg.fedoraproject.org": 1,
+ "appchizi.com": 1,
+ "applinzi.com": 1,
"apps.fbsbx.com": 1,
+ "apps.lair.io": 1,
"appspot.com": 1,
"aq.it": 1,
"aquarium.museum": 1,
@@ -264,8 +298,8 @@ module.exports = {
"arida.wakayama.jp": 1,
"aridagawa.wakayama.jp": 1,
"arita.saga.jp": 1,
- "arkhangelsk.ru": 1,
"arkhangelsk.su": 1,
+ "armenia.su": 1,
"arna.no": 1,
"arq.br": 1,
"art.br": 1,
@@ -278,6 +312,7 @@ module.exports = {
"artanddesign.museum": 1,
"artcenter.museum": 1,
"artdeco.museum": 1,
+ "arte.bo": 1,
"arteducation.museum": 1,
"artgallery.museum": 1,
"arts.co": 1,
@@ -302,6 +337,7 @@ module.exports = {
"ascoli-piceno.it": 1,
"ascolipiceno.it": 1,
"aseral.no": 1,
+ "ashgabad.su": 1,
"ashibetsu.hokkaido.jp": 1,
"ashikaga.tochigi.jp": 1,
"ashiya.fukuoka.jp": 1,
@@ -337,7 +373,6 @@ module.exports = {
"association.aero": 1,
"association.museum": 1,
"asti.it": 1,
- "astrakhan.ru": 1,
"astronomy.museum": 1,
"asuke.aichi.jp": 1,
"at-band-camp.net": 1,
@@ -375,12 +410,14 @@ module.exports = {
"avocat.pro": 1,
"avoues.fr": 1,
"awaji.hyogo.jp": 1,
+ "awdev.ca": 2,
"axis.museum": 1,
"aya.miyazaki.jp": 1,
"ayabe.kyoto.jp": 1,
"ayagawa.kagawa.jp": 1,
"ayase.kanagawa.jp": 1,
"az.us": 1,
+ "azerbaijan.su": 1,
"azumino.nagano.jp": 1,
"azure-mobile.net": 1,
"azurewebsites.net": 1,
@@ -389,6 +426,7 @@ module.exports = {
"b.br": 1,
"b.se": 1,
"b.ssl.fastly.net": 1,
+ "ba.gov.br": 1,
"ba.it": 1,
"ba.leg.br": 1,
"babia-gora.pl": 1,
@@ -400,7 +438,6 @@ module.exports = {
"bahccavuotna.no": 1,
"bahn.museum": 1,
"baidar.no": 1,
- "baikal.ru": 1,
"bajddar.no": 1,
"balashov.su": 1,
"balat.no": 1,
@@ -423,6 +460,14 @@ module.exports = {
"barreau.bj": 1,
"barrel-of-knowledge.info": 1,
"barrell-of-knowledge.info": 1,
+ "barsy.bg": 1,
+ "barsy.de": 1,
+ "barsy.eu": 1,
+ "barsy.in": 1,
+ "barsy.net": 1,
+ "barsy.online": 1,
+ "barsy.support": 1,
+ "barsyonline.com": 1,
"barum.no": 1,
"bas.it": 1,
"baseball.museum": 1,
@@ -449,7 +494,7 @@ module.exports = {
"beiarn.no": 1,
"bel.tr": 1,
"belau.pw": 1,
- "belgorod.ru": 1,
+ "belem.br": 1,
"bellevue.museum": 1,
"belluno.it": 1,
"benevento.it": 1,
@@ -469,6 +514,7 @@ module.exports = {
"better-than.tv": 1,
"bg.eu.org": 1,
"bg.it": 1,
+ "bhz.br": 1,
"bi.it": 1,
"bialowieza.pl": 1,
"bialystok.pl": 1,
@@ -491,6 +537,7 @@ module.exports = {
"birdart.museum": 1,
"birkenes.no": 1,
"birthplace.museum": 1,
+ "bitballoon.com": 1,
"biz.at": 1,
"biz.az": 1,
"biz.bb": 1,
@@ -519,11 +566,13 @@ module.exports = {
"bjerkreim.no": 1,
"bjugn.no": 1,
"bl.it": 1,
+ "blog.bo": 1,
"blog.br": 1,
"blogdns.com": 1,
"blogdns.net": 1,
"blogdns.org": 1,
"blogsite.org": 1,
+ "blogsite.xyz": 1,
"blogspot.ae": 1,
"blogspot.al": 1,
"blogspot.am": 1,
@@ -608,16 +657,19 @@ module.exports = {
"bo.it": 1,
"bo.nordland.no": 1,
"bo.telemark.no": 1,
+ "boavista.br": 1,
"bodo.no": 1,
"bod\u00f8.no": 1,
"bokn.no": 1,
"boldlygoingnowhere.org": 1,
"boleslawiec.pl": 1,
+ "bolivia.bo": 1,
"bologna.it": 1,
"bolt.hu": 1,
"bolzano.it": 1,
"bomlo.no": 1,
"bonn.museum": 1,
+ "boomla.net": 1,
"boston.museum": 1,
"botanical.museum": 1,
"botanicalgarden.museum": 1,
@@ -627,6 +679,9 @@ module.exports = {
"bounty-full.com": 1,
"boxfuse.io": 1,
"bozen.it": 1,
+ "bplaced.com": 1,
+ "bplaced.de": 1,
+ "bplaced.net": 1,
"br.com": 1,
"br.it": 1,
"brand.se": 1,
@@ -650,21 +705,21 @@ module.exports = {
"brussel.museum": 1,
"brussels.museum": 1,
"bruxelles.museum": 1,
- "bryansk.ru": 1,
"bryansk.su": 1,
"bryne.no": 1,
"br\u00f8nn\u00f8y.no": 1,
"br\u00f8nn\u00f8ysund.no": 1,
"bs.it": 1,
+ "bsb.br": 1,
"bt.it": 1,
"bu.no": 1,
"budejju.no": 1,
"building.museum": 1,
+ "bukhara.su": 1,
"bungoono.oita.jp": 1,
"bungotakada.oita.jp": 1,
"bunkyo.tokyo.jp": 1,
"burghof.museum": 1,
- "buryatia.ru": 1,
"bus.museum": 1,
"busan.kr": 1,
"bushey.museum": 1,
@@ -672,6 +727,7 @@ module.exports = {
"buzen.fukuoka.jp": 1,
"bv.nl": 1,
"bydgoszcz.pl": 1,
+ "byen.site": 1,
"bygland.no": 1,
"bykle.no": 1,
"bytom.pl": 1,
@@ -691,6 +747,8 @@ module.exports = {
"c.cdn77.org": 1,
"c.la": 1,
"c.se": 1,
+ "c66.me": 1,
+ "ca-central-1.elasticbeanstalk.com": 1,
"ca.eu.org": 1,
"ca.it": 1,
"ca.na": 1,
@@ -706,9 +764,12 @@ module.exports = {
"caltanissetta.it": 1,
"cam.it": 1,
"cambridge.museum": 1,
+ "camdvr.org": 1,
"campania.it": 1,
"campidano-medio.it": 1,
"campidanomedio.it": 1,
+ "campinagrande.br": 1,
+ "campinas.br": 1,
"campobasso.it": 1,
"can.museum": 1,
"canada.museum": 1,
@@ -720,6 +781,7 @@ module.exports = {
"carraramassa.it": 1,
"carrier.museum": 1,
"cartoonart.museum": 1,
+ "casacam.net": 1,
"casadelamoneda.museum": 1,
"caserta.it": 1,
"casino.hu": 1,
@@ -728,6 +790,7 @@ module.exports = {
"catania.it": 1,
"catanzaro.it": 1,
"catering.aero": 1,
+ "caxias.br": 1,
"cb.it": 1,
"cbg.ru": 1,
"cc.ak.us": 1,
@@ -778,6 +841,7 @@ module.exports = {
"cc.sd.us": 1,
"cc.tn.us": 1,
"cc.tx.us": 1,
+ "cc.ua": 1,
"cc.ut.us": 1,
"cc.va.us": 1,
"cc.vi.us": 1,
@@ -789,6 +853,7 @@ module.exports = {
"cci.fr": 1,
"cd.eu.org": 1,
"cdn77-ssl.net": 1,
+ "ce.gov.br": 1,
"ce.it": 1,
"ce.leg.br": 1,
"cechire.com": 1,
@@ -802,11 +867,10 @@ module.exports = {
"ch.it": 1,
"chambagri.fr": 1,
"championship.aero": 1,
+ "channelsdvr.net": 1,
"charter.aero": 1,
"chattanooga.museum": 1,
- "chel.ru": 1,
"cheltenham.museum": 1,
- "chelyabinsk.ru": 1,
"cherkassy.ua": 1,
"cherkasy.ua": 1,
"chernigov.ua": 1,
@@ -832,6 +896,7 @@ module.exports = {
"children.museum": 1,
"childrens.museum": 1,
"childrensgarden.museum": 1,
+ "chimkent.su": 1,
"chino.nagano.jp": 1,
"chippubetsu.hokkaido.jp": 1,
"chiropractic.museum": 1,
@@ -839,7 +904,6 @@ module.exports = {
"chirurgiens-dentistes.fr": 1,
"chiryu.aichi.jp": 1,
"chita.aichi.jp": 1,
- "chita.ru": 1,
"chitose.hokkaido.jp": 1,
"chiyoda.gunma.jp": 1,
"chiyoda.tokyo.jp": 1,
@@ -852,7 +916,6 @@ module.exports = {
"choyo.kumamoto.jp": 1,
"christiansburg.museum": 1,
"chtr.k12.ma.us": 1,
- "chukotka.ru": 1,
"chungbuk.kr": 1,
"chungnam.kr": 1,
"chuo.chiba.jp": 1,
@@ -860,14 +923,15 @@ module.exports = {
"chuo.osaka.jp": 1,
"chuo.tokyo.jp": 1,
"chuo.yamanashi.jp": 1,
- "chuvashia.ru": 1,
"ci.it": 1,
+ "ciencia.bo": 1,
"cieszyn.pl": 1,
"cim.br": 1,
"cincinnati.museum": 1,
"cinema.museum": 1,
"circus.museum": 1,
"ciscofreak.com": 1,
+ "cistron.nl": 1,
"city.hu": 1,
"city.kawasaki.jp": 0,
"city.kitakyushu.jp": 0,
@@ -883,8 +947,15 @@ module.exports = {
"ck": 2,
"ck.ua": 1,
"cl.it": 1,
+ "clan.rip": 1,
"clinton.museum": 1,
"clock.museum": 1,
+ "cloud.fedoraproject.org": 1,
+ "cloud.goog": 1,
+ "cloud.metacentrum.cz": 1,
+ "cloud66.ws": 1,
+ "cloudaccess.host": 1,
+ "cloudaccess.net": 1,
"cloudapp.net": 1,
"cloudcontrolapp.com": 1,
"cloudcontrolled.com": 1,
@@ -903,8 +974,7 @@ module.exports = {
"cloudns.us": 1,
"club.aero": 1,
"club.tw": 1,
- "cmw.ru": 1,
- "cn-north-1.compute.amazonaws.com.cn": 1,
+ "cn-north-1.eb.amazonaws.com.cn": 1,
"cn.com": 1,
"cn.eu.org": 1,
"cn.it": 1,
@@ -939,6 +1009,7 @@ module.exports = {
"co.it": 1,
"co.je": 1,
"co.jp": 1,
+ "co.ke": 1,
"co.kr": 1,
"co.krd": 1,
"co.lc": 1,
@@ -976,10 +1047,12 @@ module.exports = {
"co.vi": 1,
"co.za": 1,
"co.zm": 1,
+ "co.zw": 1,
"coal.museum": 1,
"coastaldefence.museum": 1,
"codespot.com": 1,
"cody.museum": 1,
+ "cog.mi.us": 1,
"coldwar.museum": 1,
"collection.museum": 1,
"collegefan.org": 1,
@@ -1122,9 +1195,9 @@ module.exports = {
"communications.museum": 1,
"community.museum": 1,
"como.it": 1,
- "compute-1.amazonaws.com": 1,
- "compute.amazonaws.com": 1,
- "compute.amazonaws.com.cn": 1,
+ "compute-1.amazonaws.com": 2,
+ "compute.amazonaws.com": 2,
+ "compute.amazonaws.com.cn": 2,
"compute.estate": 2,
"computer.museum": 1,
"computerhistory.museum": 1,
@@ -1135,6 +1208,7 @@ module.exports = {
"consulado.st": 1,
"consultant.aero": 1,
"consulting.aero": 1,
+ "contagem.br": 1,
"contemporary.museum": 1,
"contemporaryart.museum": 1,
"control.aero": 1,
@@ -1146,6 +1220,7 @@ module.exports = {
"coop.mw": 1,
"coop.py": 1,
"coop.tt": 1,
+ "cooperativa.bo": 1,
"copenhagen.museum": 1,
"corporation.museum": 1,
"correios-e-telecomunica\u00e7\u00f5es.museum": 1,
@@ -1165,6 +1240,7 @@ module.exports = {
"creation.museum": 1,
"cremona.it": 1,
"crew.aero": 1,
+ "cri.br": 1,
"cri.nz": 1,
"crimea.ua": 1,
"crotone.it": 1,
@@ -1172,13 +1248,22 @@ module.exports = {
"cs.it": 1,
"ct.it": 1,
"ct.us": 1,
+ "cuiaba.br": 1,
"cultural.museum": 1,
"culturalcenter.museum": 1,
"culture.museum": 1,
"cuneo.it": 1,
"cupcake.is": 1,
+ "curitiba.br": 1,
+ "cust.dev.thingdust.io": 1,
+ "cust.disrec.thingdust.io": 1,
+ "cust.prod.thingdust.io": 1,
+ "cust.testing.thingdust.io": 1,
+ "custom.metacentrum.cz": 1,
+ "customer.enonic.io": 1,
"cv.ua": 1,
"cy.eu.org": 1,
+ "cya.gg": 1,
"cyber.museum": 1,
"cymru.museum": 1,
"cyon.link": 1,
@@ -1209,23 +1294,36 @@ module.exports = {
"davvesiida.no": 1,
"dazaifu.fukuoka.jp": 1,
"dc.us": 1,
+ "dd-dns.de": 1,
"ddns.me": 1,
"ddns.net": 1,
+ "ddnsfree.com": 1,
+ "ddnsgeek.com": 1,
"ddnsking.com": 1,
+ "ddnss.de": 1,
+ "ddnss.org": 1,
"ddr.museum": 1,
"de.com": 1,
+ "de.cool": 1,
"de.eu.org": 1,
"de.us": 1,
"deatnu.no": 1,
+ "debian.net": 1,
"decorativearts.museum": 1,
"dedyn.io": 1,
+ "def.br": 1,
"defense.tn": 1,
+ "definima.io": 1,
+ "definima.net": 1,
"delaware.museum": 1,
"dell-ogliastra.it": 1,
"dellogliastra.it": 1,
"delmenhorst.museum": 1,
+ "democracia.bo": 1,
+ "demon.nl": 1,
"denmark.museum": 1,
"dep.no": 1,
+ "deporte.bo": 1,
"depot.museum": 1,
"desa.id": 1,
"design.aero": 1,
@@ -1233,12 +1331,16 @@ module.exports = {
"detroit.museum": 1,
"dev-myqnapcloud.com": 1,
"dev.static.land": 1,
+ "devices.resinstaging.io": 1,
+ "df.gov.br": 1,
"df.leg.br": 1,
"dgca.aero": 1,
"dielddanuorri.no": 1,
"dinosaur.museum": 1,
"discovery.museum": 1,
+ "diskstation.eu": 1,
"diskstation.me": 1,
+ "diskstation.org": 1,
"ditchyourip.com": 1,
"divtasvuodna.no": 1,
"divttasvuotna.no": 1,
@@ -1257,6 +1359,7 @@ module.exports = {
"dnsfor.me": 1,
"dnshome.de": 1,
"dnsiskinky.com": 1,
+ "dnsupdater.de": 1,
"does-it.net": 1,
"doesntexist.com": 1,
"doesntexist.org": 1,
@@ -1277,6 +1380,9 @@ module.exports = {
"dr.tr": 1,
"drammen.no": 1,
"drangedal.no": 1,
+ "dray-dns.de": 1,
+ "drayddns.com": 1,
+ "draydns.de": 1,
"dreamhosters.com": 1,
"drobak.no": 1,
"drud.io": 1,
@@ -1288,16 +1394,23 @@ module.exports = {
"dsmynas.com": 1,
"dsmynas.net": 1,
"dsmynas.org": 1,
+ "dst.mi.us": 1,
"duckdns.org": 1,
- "dudinka.ru": 1,
"durham.museum": 1,
"dvrcam.info": 1,
"dvrdns.org": 1,
"dy.fi": 1,
+ "dyn-ip24.de": 1,
"dyn-o-saur.com": 1,
+ "dyn-vpn.de": 1,
+ "dyn.cosidns.de": 1,
+ "dyn.ddnss.de": 1,
+ "dyn.home-webserver.de": 1,
"dynalias.com": 1,
"dynalias.net": 1,
"dynalias.org": 1,
+ "dynamic-dns.info": 1,
+ "dynamisches-dns.de": 1,
"dynathome.net": 1,
"dyndns-at-home.com": 1,
"dyndns-at-work.com": 1,
@@ -1314,24 +1427,29 @@ module.exports = {
"dyndns-wiki.com": 1,
"dyndns-work.com": 1,
"dyndns.biz": 1,
+ "dyndns.ddnss.de": 1,
"dyndns.info": 1,
"dyndns.org": 1,
"dyndns.tv": 1,
"dyndns.ws": 1,
+ "dyndns1.de": 1,
"dynns.com": 1,
+ "dynu.net": 1,
"dynv6.net": 1,
+ "dynvpn.de": 1,
"dyroy.no": 1,
"dyr\u00f8y.no": 1,
"d\u00f8nna.no": 1,
- "e-burg.ru": 1,
"e.bg": 1,
"e.se": 1,
"e12.ve": 1,
"e164.arpa": 1,
"e4.cz": 1,
+ "east-kazakhstan.su": 1,
"eastafrica.museum": 1,
"eastcoast.museum": 1,
"eating-organic.net": 1,
+ "eaton.mi.us": 1,
"ebetsu.hokkaido.jp": 1,
"ebina.kanagawa.jp": 1,
"ebino.miyazaki.jp": 1,
@@ -1339,6 +1457,8 @@ module.exports = {
"echizen.fukui.jp": 1,
"ecn.br": 1,
"eco.br": 1,
+ "ecologia.bo": 1,
+ "economia.bo": 1,
"ed.ao": 1,
"ed.ci": 1,
"ed.cr": 1,
@@ -1482,7 +1602,8 @@ module.exports = {
"eisenbahn.museum": 1,
"ekloges.cy": 1,
"elasticbeanstalk.com": 1,
- "elb.amazonaws.com": 1,
+ "elb.amazonaws.com": 2,
+ "elb.amazonaws.com.cn": 2,
"elblag.pl": 1,
"elburg.museum": 1,
"elk.pl": 1,
@@ -1495,6 +1616,7 @@ module.exports = {
"emilia-romagna.it": 1,
"emiliaromagna.it": 1,
"emp.br": 1,
+ "empresa.bo": 1,
"emr.it": 1,
"en.it": 1,
"ena.gifu.jp": 1,
@@ -1511,6 +1633,7 @@ module.exports = {
"england.museum": 1,
"eniwa.hokkaido.jp": 1,
"enna.it": 1,
+ "enonic.io": 1,
"ens.tn": 1,
"entertainment.aero": 1,
"entomology.museum": 1,
@@ -1523,6 +1646,7 @@ module.exports = {
"erotica.hu": 1,
"erotika.hu": 1,
"es.eu.org": 1,
+ "es.gov.br": 1,
"es.kr": 1,
"es.leg.br": 1,
"esan.hokkaido.jp": 1,
@@ -1543,8 +1667,12 @@ module.exports = {
"etnedal.no": 1,
"eu-1.evennode.com": 1,
"eu-2.evennode.com": 1,
- "eu-central-1.compute.amazonaws.com": 1,
- "eu-west-1.compute.amazonaws.com": 1,
+ "eu-3.evennode.com": 1,
+ "eu-4.evennode.com": 1,
+ "eu-central-1.elasticbeanstalk.com": 1,
+ "eu-west-1.elasticbeanstalk.com": 1,
+ "eu-west-2.elasticbeanstalk.com": 1,
+ "eu-west-3.elasticbeanstalk.com": 1,
"eu.com": 1,
"eu.int": 1,
"eu.meteorapp.com": 1,
@@ -1558,9 +1686,9 @@ module.exports = {
"exchange.aero": 1,
"exeter.museum": 1,
"exhibition.museum": 1,
+ "exnet.su": 1,
"experts-comptables.fr": 1,
"express.aero": 1,
- "ext.githubcloud.com": 2,
"f.bg": 1,
"f.se": 1,
"fam.pk": 1,
@@ -1570,12 +1698,12 @@ module.exports = {
"familyds.org": 1,
"fantasyleague.cc": 1,
"far.br": 1,
- "fareast.ru": 1,
"farm.museum": 1,
"farmequipment.museum": 1,
"farmers.museum": 1,
"farmstead.museum": 1,
"farsund.no": 1,
+ "fastlylb.net": 1,
"fauske.no": 1,
"fbx-os.fr": 1,
"fbxos.fr": 1,
@@ -1584,8 +1712,12 @@ module.exports = {
"fed.us": 1,
"federation.aero": 1,
"fedje.no": 1,
+ "fedorainfracloud.org": 1,
+ "fedorapeople.org": 1,
+ "feira.br": 1,
"fermo.it": 1,
"ferrara.it": 1,
+ "feste-ip.net": 1,
"fet.no": 1,
"fetsund.no": 1,
"fg.it": 1,
@@ -1601,6 +1733,7 @@ module.exports = {
"field.museum": 1,
"figueres.museum": 1,
"filatelia.museum": 1,
+ "filegear.me": 1,
"film.hu": 1,
"film.museum": 1,
"fin.ec": 1,
@@ -1612,6 +1745,9 @@ module.exports = {
"finn\u00f8y.no": 1,
"firebaseapp.com": 1,
"firenze.it": 1,
+ "firewall-gateway.com": 1,
+ "firewall-gateway.de": 1,
+ "firewall-gateway.net": 1,
"firm.co": 1,
"firm.dk": 1,
"firm.ht": 1,
@@ -1637,8 +1773,10 @@ module.exports = {
"flora.no": 1,
"florence.it": 1,
"florida.museum": 1,
+ "floripa.br": 1,
"floro.no": 1,
"flor\u00f8.no": 1,
+ "flynnhosting.net": 1,
"flynnhub.com": 1,
"fl\u00e5.no": 1,
"fm.br": 1,
@@ -1660,12 +1798,14 @@ module.exports = {
"forli-cesena.it": 1,
"forlicesena.it": 1,
"forsand.no": 1,
+ "fortal.br": 1,
"fortmissoula.museum": 1,
"fortworth.museum": 1,
"forum.hu": 1,
"fosnes.no": 1,
"fot.br": 1,
"foundation.museum": 1,
+ "foz.br": 1,
"fr.eu.org": 1,
"fr.it": 1,
"frana.no": 1,
@@ -1677,7 +1817,10 @@ module.exports = {
"freebox-os.fr": 1,
"freeboxos.com": 1,
"freeboxos.fr": 1,
+ "freeddns.org": 1,
"freemasonry.museum": 1,
+ "freesite.host": 1,
+ "freetls.fastly.net": 1,
"frei.no": 1,
"freiburg.museum": 1,
"freight.aero": 1,
@@ -1812,6 +1955,8 @@ module.exports = {
"futaba.fukushima.jp": 1,
"futsu.nagasaki.jp": 1,
"futtsu.chiba.jp": 1,
+ "futurecms.at": 2,
+ "futurehosting.at": 1,
"futuremailing.at": 1,
"fvg.it": 1,
"fylkesbibl.no": 1,
@@ -1851,6 +1996,7 @@ module.exports = {
"geisei.kochi.jp": 1,
"gemological.museum": 1,
"gen.in": 1,
+ "gen.mi.us": 1,
"gen.nz": 1,
"gen.tr": 1,
"genkai.saga.jp": 1,
@@ -1859,6 +2005,7 @@ module.exports = {
"geology.museum": 1,
"geometre-expert.fr": 1,
"georgia.museum": 1,
+ "georgia.su": 1,
"getmyip.com": 1,
"gets-it.net": 1,
"ggf.br": 1,
@@ -1866,16 +2013,15 @@ module.exports = {
"giessen.museum": 1,
"gifu.gifu.jp": 1,
"gifu.jp": 1,
+ "giize.com": 1,
"gildeskal.no": 1,
"gildesk\u00e5l.no": 1,
"ginan.gifu.jp": 1,
"ginowan.okinawa.jp": 1,
"ginoza.okinawa.jp": 1,
"giske.no": 1,
- "gist.githubcloud.com": 1,
+ "git-repos.de": 1,
"github.io": 1,
- "githubcloud.com": 1,
- "githubcloudusercontent.com": 2,
"githubusercontent.com": 1,
"gitlab.io": 1,
"gjemnes.no": 1,
@@ -1886,6 +2032,7 @@ module.exports = {
"gj\u00f8vik.no": 1,
"glas.museum": 1,
"glass.museum": 1,
+ "gleeze.com": 1,
"gliding.aero": 1,
"gliwice.pl": 1,
"global.prod.fastly.net": 1,
@@ -1897,9 +2044,11 @@ module.exports = {
"go.ci": 1,
"go.cr": 1,
"go.dyndns.org": 1,
+ "go.gov.br": 1,
"go.id": 1,
"go.it": 1,
"go.jp": 1,
+ "go.ke": 1,
"go.kr": 1,
"go.leg.br": 1,
"go.pw": 1,
@@ -1924,6 +2073,7 @@ module.exports = {
"gob.ve": 1,
"gobo.wakayama.jp": 1,
"godo.gifu.jp": 1,
+ "goiania.br": 1,
"goip.de": 1,
"gojome.akita.jp": 1,
"gok.pk": 1,
@@ -1970,7 +2120,6 @@ module.exports = {
"gov.bf": 1,
"gov.bh": 1,
"gov.bm": 1,
- "gov.bo": 1,
"gov.br": 1,
"gov.bs": 1,
"gov.bt": 1,
@@ -2077,6 +2226,7 @@ module.exports = {
"gov.ws": 1,
"gov.za": 1,
"gov.zm": 1,
+ "gov.zw": 1,
"government.aero": 1,
"govt.nz": 1,
"gr.com": 1,
@@ -2103,6 +2253,7 @@ module.exports = {
"grozny.ru": 1,
"grozny.su": 1,
"grp.lk": 1,
+ "gru.br": 1,
"grue.no": 1,
"gs.aa.no": 1,
"gs.ah.no": 1,
@@ -2221,6 +2372,7 @@ module.exports = {
"hayakawa.yamanashi.jp": 1,
"hayashima.okayama.jp": 1,
"hazu.aichi.jp": 1,
+ "hb.cldmail.ru": 1,
"hb.cn": 1,
"he.cn": 1,
"health-carereform.com": 1,
@@ -2323,7 +2475,6 @@ module.exports = {
"hitachinaka.ibaraki.jp": 1,
"hitachiomiya.ibaraki.jp": 1,
"hitachiota.ibaraki.jp": 1,
- "hitoyoshi.kumamoto.jp": 1,
"hitra.no": 1,
"hizen.saga.jp": 1,
"hjartdal.no": 1,
@@ -2351,15 +2502,18 @@ module.exports = {
"holmestrand.no": 1,
"holtalen.no": 1,
"holt\u00e5len.no": 1,
+ "home-webserver.de": 1,
"home.dyndns.org": 1,
"homebuilt.aero": 1,
"homedns.org": 1,
"homeftp.net": 1,
"homeftp.org": 1,
"homeip.net": 1,
+ "homelink.one": 1,
"homelinux.com": 1,
"homelinux.net": 1,
"homelinux.org": 1,
+ "homeoffice.gov.uk": 1,
"homesecuritymac.com": 1,
"homesecuritypc.com": 1,
"homeunix.com": 1,
@@ -2379,6 +2533,7 @@ module.exports = {
"horology.museum": 1,
"horonobe.hokkaido.jp": 1,
"horten.no": 1,
+ "hosting-cluster.nl": 1,
"hotel.hu": 1,
"hotel.lk": 1,
"hotel.tz": 1,
@@ -2512,19 +2667,25 @@ module.exports = {
"indiana.museum": 1,
"indianapolis.museum": 1,
"indianmarket.museum": 1,
+ "indigena.bo": 1,
+ "industria.bo": 1,
"ine.kyoto.jp": 1,
"inf.br": 1,
"inf.cu": 1,
"inf.mk": 1,
+ "inf.ua": 1,
"info.at": 1,
"info.au": 1,
"info.az": 1,
"info.bb": 1,
+ "info.bo": 1,
"info.co": 1,
+ "info.cx": 1,
"info.ec": 1,
"info.et": 1,
"info.ht": 1,
"info.hu": 1,
+ "info.ke": 1,
"info.ki": 1,
"info.la": 1,
"info.mv": 1,
@@ -2569,13 +2730,14 @@ module.exports = {
"int.vn": 1,
"intelligence.museum": 1,
"interactive.museum": 1,
+ "internet-dns.de": 1,
"intl.tn": 1,
"inuyama.aichi.jp": 1,
"inzai.chiba.jp": 1,
"ip6.arpa": 1,
+ "ipifony.net": 1,
"iraq.museum": 1,
"iris.arpa": 1,
- "irkutsk.ru": 1,
"iron.museum": 1,
"iruma.saitama.jp": 1,
"is-a-anarchist.com": 1,
@@ -2694,7 +2856,6 @@ module.exports = {
"itoman.okinawa.jp": 1,
"its.me": 1,
"ivano-frankivsk.ua": 1,
- "ivanovo.ru": 1,
"ivanovo.su": 1,
"iveland.no": 1,
"ivgu.no": 1,
@@ -2716,7 +2877,6 @@ module.exports = {
"iyo.ehime.jp": 1,
"iz.hr": 1,
"izena.okinawa.jp": 1,
- "izhevsk.ru": 1,
"izu.shizuoka.jp": 1,
"izumi.kagoshima.jp": 1,
"izumi.osaka.jp": 1,
@@ -2727,11 +2887,14 @@ module.exports = {
"izumozaki.niigata.jp": 1,
"izunokuni.shizuoka.jp": 1,
"j.bg": 1,
- "jamal.ru": 1,
+ "jab.br": 1,
+ "jambyl.su": 1,
"jamison.museum": 1,
+ "jampa.br": 1,
"jan-mayen.no": 1,
- "jar.ru": 1,
"jaworzno.pl": 1,
+ "jdevcloud.com": 1,
+ "jdf.br": 1,
"jefferson.museum": 1,
"jeju.kr": 1,
"jelenia-gora.pl": 1,
@@ -2753,11 +2916,11 @@ module.exports = {
"joetsu.niigata.jp": 1,
"jogasz.hu": 1,
"johana.toyama.jp": 1,
+ "joinville.br": 1,
"jolster.no": 1,
"jondal.no": 1,
"jor.br": 1,
"jorpeland.no": 1,
- "joshkar-ola.ru": 1,
"joso.ibaraki.jp": 1,
"journal.aero": 1,
"journalism.museum": 1,
@@ -2777,7 +2940,6 @@ module.exports = {
"jx.cn": 1,
"j\u00f8lster.no": 1,
"j\u00f8rpeland.no": 1,
- "k-uralsk.ru": 1,
"k.bg": 1,
"k.se": 1,
"k12.ak.us": 1,
@@ -2863,12 +3025,10 @@ module.exports = {
"kalisz.pl": 1,
"kalmykia.ru": 1,
"kalmykia.su": 1,
- "kaluga.ru": 1,
"kaluga.su": 1,
"kamagaya.chiba.jp": 1,
"kamaishi.iwate.jp": 1,
"kamakura.kanagawa.jp": 1,
- "kamchatka.ru": 1,
"kameoka.kyoto.jp": 1,
"kameyama.mie.jp": 1,
"kami.kochi.jp": 1,
@@ -2914,12 +3074,13 @@ module.exports = {
"kanra.gunma.jp": 1,
"kanuma.tochigi.jp": 1,
"kanzaki.saga.jp": 1,
+ "karacol.su": 1,
+ "karaganda.su": 1,
"karasjohka.no": 1,
"karasjok.no": 1,
"karasuyama.tochigi.jp": 1,
"karate.museum": 1,
"karatsu.saga.jp": 1,
- "karelia.ru": 1,
"karelia.su": 1,
"karikatur.museum": 1,
"kariwa.niigata.jp": 1,
@@ -2939,7 +3100,6 @@ module.exports = {
"kashiba.nara.jp": 1,
"kashihara.nara.jp": 1,
"kashima.ibaraki.jp": 1,
- "kashima.kumamoto.jp": 1,
"kashima.saga.jp": 1,
"kashiwa.chiba.jp": 1,
"kashiwara.osaka.jp": 1,
@@ -2988,15 +3148,11 @@ module.exports = {
"kawaue.gifu.jp": 1,
"kawazu.shizuoka.jp": 1,
"kayabe.hokkaido.jp": 1,
- "kazan.ru": 1,
"kazimierz-dolny.pl": 1,
"kazo.saitama.jp": 1,
"kazuno.akita.jp": 1,
- "kchr.ru": 1,
- "ke": 2,
"keisen.fukuoka.jp": 1,
"kembuchi.hokkaido.jp": 1,
- "kemerovo.ru": 1,
"kep.tr": 1,
"kepno.pl": 1,
"ketrzyn.pl": 1,
@@ -3004,15 +3160,12 @@ module.exports = {
"kg.kr": 1,
"kh": 2,
"kh.ua": 1,
- "khabarovsk.ru": 1,
- "khakassia.ru": 1,
"khakassia.su": 1,
"kharkiv.ua": 1,
"kharkov.ua": 1,
"kherson.ua": 1,
"khmelnitskiy.ua": 1,
"khmelnytskyi.ua": 1,
- "khv.ru": 1,
"kibichuo.okayama.jp": 1,
"kicks-ass.net": 1,
"kicks-ass.org": 1,
@@ -3033,7 +3186,6 @@ module.exports = {
"kinokawa.wakayama.jp": 1,
"kira.aichi.jp": 1,
"kirkenes.no": 1,
- "kirov.ru": 1,
"kirovograd.ua": 1,
"kiryu.gunma.jp": 1,
"kisarazu.chiba.jp": 1,
@@ -3077,9 +3229,9 @@ module.exports = {
"kl\u00e6bu.no": 1,
"km.ua": 1,
"kmpsp.gov.pl": 1,
- "kms.ru": 1,
"knightpoint.systems": 1,
"knowsitall.info": 1,
+ "knx-server.net": 1,
"kobayashi.miyazaki.jp": 1,
"kobe.jp": 2,
"kobierzyce.pl": 1,
@@ -3088,7 +3240,6 @@ module.exports = {
"kodaira.tokyo.jp": 1,
"koebenhavn.museum": 1,
"koeln.museum": 1,
- "koenig.ru": 1,
"kofu.yamanashi.jp": 1,
"koga.fukuoka.jp": 1,
"koga.ibaraki.jp": 1,
@@ -3104,7 +3255,6 @@ module.exports = {
"komatsu.ishikawa.jp": 1,
"komatsushima.tokushima.jp": 1,
"komforb.se": 1,
- "komi.ru": 1,
"kommunalforbund.se": 1,
"kommune.no": 1,
"komono.mie.jp": 1,
@@ -3128,7 +3278,6 @@ module.exports = {
"koshigaya.saitama.jp": 1,
"koshimizu.hokkaido.jp": 1,
"koshu.yamanashi.jp": 1,
- "kostroma.ru": 1,
"kosuge.yamanashi.jp": 1,
"kota.aichi.jp": 1,
"koto.shiga.jp": 1,
@@ -3143,6 +3292,7 @@ module.exports = {
"koza.wakayama.jp": 1,
"kozagawa.wakayama.jp": 1,
"kozaki.chiba.jp": 1,
+ "kozow.com": 1,
"kppsp.gov.pl": 1,
"kr.com": 1,
"kr.eu.org": 1,
@@ -3153,7 +3303,6 @@ module.exports = {
"krager\u00f8.no": 1,
"krakow.pl": 1,
"krasnodar.su": 1,
- "krasnoyarsk.ru": 1,
"kristiansand.no": 1,
"kristiansund.no": 1,
"krodsherad.no": 1,
@@ -3163,7 +3312,6 @@ module.exports = {
"kr\u00f8dsherad.no": 1,
"ks.ua": 1,
"ks.us": 1,
- "kuban.ru": 1,
"kuchinotsu.nagasaki.jp": 1,
"kudamatsu.yamaguchi.jp": 1,
"kudoyama.wakayama.jp": 1,
@@ -3196,7 +3344,6 @@ module.exports = {
"kurashiki.okayama.jp": 1,
"kurate.fukuoka.jp": 1,
"kure.hiroshima.jp": 1,
- "kurgan.ru": 1,
"kurgan.su": 1,
"kuriyama.hokkaido.jp": 1,
"kurobe.toyama.jp": 1,
@@ -3205,7 +3352,6 @@ module.exports = {
"kuroiso.tochigi.jp": 1,
"kuromatsunai.hokkaido.jp": 1,
"kurotaki.nara.jp": 1,
- "kursk.ru": 1,
"kurume.fukuoka.jp": 1,
"kusatsu.gunma.jp": 1,
"kusatsu.shiga.jp": 1,
@@ -3213,11 +3359,11 @@ module.exports = {
"kushimoto.wakayama.jp": 1,
"kushiro.hokkaido.jp": 1,
"kustanai.ru": 1,
+ "kustanai.su": 1,
"kusu.oita.jp": 1,
"kutchan.hokkaido.jp": 1,
"kutno.pl": 1,
"kuwana.mie.jp": 1,
- "kuzbass.ru": 1,
"kuzumaki.iwate.jp": 1,
"kv.ua": 1,
"kvafjord.no": 1,
@@ -3246,6 +3392,7 @@ module.exports = {
"kyuragi.saga.jp": 1,
"k\u00e1r\u00e1\u0161johka.no": 1,
"k\u00e5fjord.no": 1,
+ "l-o-g-i-n.de": 1,
"l.bg": 1,
"l.se": 1,
"la-spezia.it": 1,
@@ -3277,6 +3424,7 @@ module.exports = {
"laz.it": 1,
"lazio.it": 1,
"lc.it": 1,
+ "lcube-server.de": 1,
"le.it": 1,
"leangaviika.no": 1,
"leasing.aero": 1,
@@ -3368,13 +3516,19 @@ module.exports = {
"likescandy.com": 1,
"lillehammer.no": 1,
"lillesand.no": 1,
+ "lima-city.at": 1,
+ "lima-city.ch": 1,
+ "lima-city.de": 1,
+ "lima-city.rocks": 1,
+ "lima.zone": 1,
"limanowa.pl": 1,
"lincoln.museum": 1,
"lindas.no": 1,
"lindesnes.no": 1,
"lind\u00e5s.no": 1,
+ "linkyard-cloud.ch": 1,
+ "linkyard.cloud": 1,
"linz.museum": 1,
- "lipetsk.ru": 1,
"living.museum": 1,
"livinghistory.museum": 1,
"livorno.it": 1,
@@ -3383,6 +3537,7 @@ module.exports = {
"loabat.no": 1,
"loab\u00e1t.no": 1,
"localhistory.museum": 1,
+ "localhost.daplie.me": 1,
"lodi.it": 1,
"lodingen.no": 1,
"loginto.me": 1,
@@ -3395,9 +3550,11 @@ module.exports = {
"lombardy.it": 1,
"lomza.pl": 1,
"london.museum": 1,
+ "londrina.br": 1,
"loppa.no": 1,
"lorenskog.no": 1,
"losangeles.museum": 1,
+ "loseyourip.com": 1,
"loten.no": 1,
"louvre.museum": 1,
"lowicz.pl": 1,
@@ -3410,6 +3567,7 @@ module.exports = {
"ltd.gi": 1,
"ltd.hk": 1,
"ltd.lk": 1,
+ "ltd.ua": 1,
"ltd.uk": 1,
"lu.eu.org": 1,
"lu.it": 1,
@@ -3440,14 +3598,16 @@ module.exports = {
"l\u00f8ten.no": 1,
"m.bg": 1,
"m.se": 1,
+ "ma.gov.br": 1,
"ma.leg.br": 1,
"ma.us": 1,
+ "macapa.br": 1,
+ "maceio.br": 1,
"macerata.it": 1,
"machida.tokyo.jp": 1,
"mad.museum": 1,
"madrid.museum": 1,
"maebashi.gunma.jp": 1,
- "magadan.ru": 1,
"magazine.aero": 1,
"magentosite.cloud": 2,
"maibara.shiga.jp": 1,
@@ -3463,8 +3623,10 @@ module.exports = {
"malselv.no": 1,
"malvik.no": 1,
"mamurogawa.yamagata.jp": 1,
+ "manaus.br": 1,
"manchester.museum": 1,
"mandal.no": 1,
+ "mangyshlak.su": 1,
"maniwa.okayama.jp": 1,
"manno.kagawa.jp": 1,
"mansion.museum": 1,
@@ -3472,12 +3634,13 @@ module.exports = {
"mantova.it": 1,
"manx.museum": 1,
"maori.nz": 1,
+ "map.fastly.net": 1,
+ "map.fastlylb.net": 1,
"mar.it": 1,
"marburg.museum": 1,
"marche.it": 1,
- "mari-el.ru": 1,
- "mari.ru": 1,
"marine.ru": 1,
+ "maringa.br": 1,
"maritime.museum": 1,
"maritimo.museum": 1,
"marker.no": 1,
@@ -3524,6 +3687,7 @@ module.exports = {
"md.us": 1,
"me.eu.org": 1,
"me.it": 1,
+ "me.ke": 1,
"me.tz": 1,
"me.uk": 1,
"me.us": 1,
@@ -3545,11 +3709,13 @@ module.exports = {
"media.museum": 1,
"media.pl": 1,
"medical.museum": 1,
+ "medicina.bo": 1,
"medio-campidano.it": 1,
"mediocampidano.it": 1,
"medizinhistorisches.museum": 1,
"meeres.museum": 1,
"meguro.tokyo.jp": 1,
+ "mein-vigor.de": 1,
"meiwa.gunma.jp": 1,
"meiwa.mie.jp": 1,
"meland.no": 1,
@@ -3565,6 +3731,7 @@ module.exports = {
"messina.it": 1,
"meteorapp.com": 1,
"mex.com": 1,
+ "mg.gov.br": 1,
"mg.leg.br": 1,
"mi.it": 1,
"mi.th": 1,
@@ -3652,6 +3819,7 @@ module.exports = {
"mil.ve": 1,
"mil.za": 1,
"mil.zm": 1,
+ "mil.zw": 1,
"milan.it": 1,
"milano.it": 1,
"military.museum": 1,
@@ -3755,6 +3923,7 @@ module.exports = {
"moareke.no": 1,
"mobara.chiba.jp": 1,
"mobi.gp": 1,
+ "mobi.ke": 1,
"mobi.na": 1,
"mobi.ng": 1,
"mobi.tt": 1,
@@ -3782,8 +3951,10 @@ module.exports = {
"monzabrianza.it": 1,
"monzaebrianza.it": 1,
"monzaedellabrianza.it": 1,
+ "moonscale.net": 1,
"mordovia.ru": 1,
"mordovia.su": 1,
+ "morena.br": 1,
"moriguchi.osaka.jp": 1,
"morimachi.shizuoka.jp": 1,
"morioka.iwate.jp": 1,
@@ -3804,10 +3975,12 @@ module.exports = {
"motorcycle.museum": 1,
"motosu.gifu.jp": 1,
"motoyama.kochi.jp": 1,
+ "movimiento.bo": 1,
"mo\u00e5reke.no": 1,
"mp.br": 1,
"mr.no": 1,
"mragowo.pl": 1,
+ "ms.gov.br": 1,
"ms.it": 1,
"ms.kr": 1,
"ms.leg.br": 1,
@@ -3815,6 +3988,7 @@ module.exports = {
"msk.ru": 1,
"msk.su": 1,
"mt.eu.org": 1,
+ "mt.gov.br": 1,
"mt.it": 1,
"mt.leg.br": 1,
"mt.us": 1,
@@ -3834,11 +4008,11 @@ module.exports = {
"murakami.niigata.jp": 1,
"murata.miyagi.jp": 1,
"murayama.yamagata.jp": 1,
- "murmansk.ru": 1,
"murmansk.su": 1,
"muroran.hokkaido.jp": 1,
"muroto.kochi.jp": 1,
"mus.br": 1,
+ "mus.mi.us": 1,
"musashimurayama.tokyo.jp": 1,
"musashino.tokyo.jp": 1,
"museet.museum": 1,
@@ -3850,24 +4024,34 @@ module.exports = {
"museumcenter.museum": 1,
"museumvereniging.museum": 1,
"music.museum": 1,
+ "musica.ar": 1,
+ "musica.bo": 1,
"mutsu.aomori.jp": 1,
"mutsuzawa.chiba.jp": 1,
"mw.gov.pl": 1,
"mx.na": 1,
+ "my-firewall.org": 1,
+ "my-gateway.de": 1,
+ "my-router.de": 1,
+ "my-vigor.de": 1,
+ "my-wan.de": 1,
"my.eu.org": 1,
"my.id": 1,
"myactivedirectory.com": 1,
"myasustor.com": 1,
"mycd.eu": 1,
+ "myddns.rocks": 1,
"mydissent.net": 1,
"mydrobo.com": 1,
"myds.me": 1,
"myeffect.net": 1,
+ "myfirewall.org": 1,
"myfritz.net": 1,
"myftp.biz": 1,
"myftp.org": 1,
- "myfusion.cloud": 1,
+ "myhome-server.de": 1,
"mykolaiv.ua": 1,
+ "mymailer.com.tw": 1,
"mymediapc.net": 1,
"myoko.niigata.jp": 1,
"mypep.link": 1,
@@ -3880,7 +4064,9 @@ module.exports = {
"mysecuritycamera.org": 1,
"myshopblocks.com": 1,
"mytis.ru": 1,
+ "mytuleap.com": 1,
"myvnc.com": 1,
+ "mywire.org": 1,
"m\u00e1latvuopmi.no": 1,
"m\u00e1tta-v\u00e1rjjat.no": 1,
"m\u00e5lselv.no": 1,
@@ -3937,7 +4123,6 @@ module.exports = {
"nakatombetsu.hokkaido.jp": 1,
"nakatsugawa.gifu.jp": 1,
"nakayama.yamagata.jp": 1,
- "nakhodka.ru": 1,
"nakijin.okinawa.jp": 1,
"naklo.pl": 1,
"nalchik.ru": 1,
@@ -3995,11 +4180,13 @@ module.exports = {
"nasu.tochigi.jp": 1,
"nasushiobara.tochigi.jp": 1,
"nat.tn": 1,
+ "natal.br": 1,
"national.museum": 1,
"nationalfirearms.museum": 1,
"nationalheritage.museum": 1,
"nativeamerican.museum": 1,
"natori.miyagi.jp": 1,
+ "natural.bo": 1,
"naturalhistory.museum": 1,
"naturalhistorymuseum.museum": 1,
"naturalsciences.museum": 1,
@@ -4011,6 +4198,7 @@ module.exports = {
"naustdal.no": 1,
"naval.museum": 1,
"navigation.aero": 1,
+ "navoi.su": 1,
"navuotna.no": 1,
"nayoro.hokkaido.jp": 1,
"nb.ca": 1,
@@ -4018,6 +4206,7 @@ module.exports = {
"nc.us": 1,
"nd.us": 1,
"ne.jp": 1,
+ "ne.ke": 1,
"ne.kr": 1,
"ne.pw": 1,
"ne.tz": 1,
@@ -4163,6 +4352,7 @@ module.exports = {
"net.ws": 1,
"net.za": 1,
"net.zm": 1,
+ "netlify.com": 1,
"neues.museum": 1,
"newhampshire.museum": 1,
"newjersey.museum": 1,
@@ -4180,6 +4370,7 @@ module.exports = {
"ngo.ph": 1,
"ngo.za": 1,
"ngrok.io": 1,
+ "nh-serv.co.uk": 1,
"nh.us": 1,
"nhlfan.net": 1,
"nhs.uk": 1,
@@ -4227,16 +4418,15 @@ module.exports = {
"nishiwaki.hyogo.jp": 1,
"nissedal.no": 1,
"nisshin.aichi.jp": 1,
+ "niteroi.br": 1,
"nittedal.no": 1,
"niyodogawa.kochi.jp": 1,
"nj.us": 1,
- "nkz.ru": 1,
"nl.ca": 1,
"nl.eu.org": 1,
"nl.no": 1,
"nm.cn": 1,
"nm.us": 1,
- "nnov.ru": 1,
"no-ip.biz": 1,
"no-ip.ca": 1,
"no-ip.co.uk": 1,
@@ -4250,27 +4440,51 @@ module.exports = {
"noboribetsu.hokkaido.jp": 1,
"noda.chiba.jp": 1,
"noda.iwate.jp": 1,
+ "nodum.co": 1,
+ "nodum.io": 1,
"nogata.fukuoka.jp": 1,
"nogi.tochigi.jp": 1,
"noheji.aomori.jp": 1,
"noip.me": 1,
"noip.us": 1,
"nom.ad": 1,
+ "nom.ae": 1,
"nom.ag": 1,
+ "nom.ai": 1,
+ "nom.al": 1,
"nom.br": 2,
+ "nom.cl": 1,
"nom.co": 1,
"nom.es": 1,
"nom.fr": 1,
+ "nom.gd": 1,
+ "nom.gl": 1,
+ "nom.gt": 1,
+ "nom.hn": 1,
+ "nom.im": 1,
"nom.km": 1,
+ "nom.li": 1,
"nom.mg": 1,
+ "nom.mk": 1,
+ "nom.nc": 1,
"nom.ni": 1,
+ "nom.nu": 1,
"nom.pa": 1,
"nom.pe": 1,
"nom.pl": 1,
+ "nom.pw": 1,
+ "nom.qa": 1,
"nom.re": 1,
"nom.ro": 1,
+ "nom.rs": 1,
+ "nom.si": 1,
"nom.tm": 1,
+ "nom.ug": 1,
+ "nom.uy": 1,
+ "nom.vc": 1,
+ "nom.vg": 1,
"nom.za": 1,
+ "nombre.bo": 1,
"nome.pt": 1,
"nomi.ishikawa.jp": 1,
"nonoichi.ishikawa.jp": 1,
@@ -4283,7 +4497,7 @@ module.exports = {
"nordreisa.no": 1,
"nore-og-uvdal.no": 1,
"norfolk.museum": 1,
- "norilsk.ru": 1,
+ "north-kazakhstan.su": 1,
"north.museum": 1,
"nose.osaka.jp": 1,
"nosegawa.nara.jp": 1,
@@ -4291,6 +4505,7 @@ module.exports = {
"not.br": 1,
"notaires.fr": 1,
"notaires.km": 1,
+ "noticias.bo": 1,
"noto.ishikawa.jp": 1,
"notodden.no": 1,
"notogawa.shiga.jp": 1,
@@ -4298,13 +4513,12 @@ module.exports = {
"nov.ru": 1,
"nov.su": 1,
"novara.it": 1,
- "novosibirsk.ru": 1,
+ "now.sh": 1,
"nowaruda.pl": 1,
"nozawaonsen.nagano.jp": 1,
"np": 2,
"nrw.museum": 1,
"ns.ca": 1,
- "nsk.ru": 1,
"nsn.us": 1,
"nsupdate.info": 1,
"nsw.au": 1,
@@ -4328,6 +4542,23 @@ module.exports = {
"ny.us": 1,
"nyc.mn": 1,
"nyc.museum": 1,
+ "nym.by": 1,
+ "nym.bz": 1,
+ "nym.gr": 1,
+ "nym.kz": 1,
+ "nym.la": 1,
+ "nym.li": 1,
+ "nym.lt": 1,
+ "nym.lu": 1,
+ "nym.me": 1,
+ "nym.mx": 1,
+ "nym.nz": 1,
+ "nym.pe": 1,
+ "nym.pt": 1,
+ "nym.sk": 1,
+ "nym.su": 1,
+ "nym.sx": 1,
+ "nym.tw": 1,
"nyny.museum": 1,
"nysa.pl": 1,
"nyuzen.toyama.jp": 1,
@@ -4363,6 +4594,7 @@ module.exports = {
"of.no": 1,
"off.ai": 1,
"office-on-the.net": 1,
+ "official.academy": 1,
"ofunato.iwate.jp": 1,
"og.ao": 1,
"og.it": 1,
@@ -4440,11 +4672,11 @@ module.exports = {
"omitama.ibaraki.jp": 1,
"omiya.saitama.jp": 1,
"omotego.fukushima.jp": 1,
- "omsk.ru": 1,
"omura.nagasaki.jp": 1,
"omuta.fukuoka.jp": 1,
"on-aptible.com": 1,
"on-the-web.tv": 1,
+ "on-web.fr": 1,
"on.ca": 1,
"onagawa.miyagi.jp": 1,
"onga.fukuoka.jp": 1,
@@ -4458,6 +4690,7 @@ module.exports = {
"onomichi.hiroshima.jp": 1,
"ontario.museum": 1,
"onthewifi.com": 1,
+ "ooguy.com": 1,
"ookuwa.nagano.jp": 1,
"ooshika.nagano.jp": 1,
"openair.museum": 1,
@@ -4475,6 +4708,7 @@ module.exports = {
"or.id": 1,
"or.it": 1,
"or.jp": 1,
+ "or.ke": 1,
"or.kr": 1,
"or.mu": 1,
"or.na": 1,
@@ -4486,7 +4720,6 @@ module.exports = {
"ora.gunma.jp": 1,
"oregon.museum": 1,
"oregontrail.museum": 1,
- "orenburg.ru": 1,
"org.ac": 1,
"org.ae": 1,
"org.af": 1,
@@ -4628,26 +4861,26 @@ module.exports = {
"org.ws": 1,
"org.za": 1,
"org.zm": 1,
+ "org.zw": 1,
"oristano.it": 1,
"orkanger.no": 1,
"orkdal.no": 1,
"orland.no": 1,
"orskog.no": 1,
"orsta.no": 1,
- "oryol.ru": 1,
"os.hedmark.no": 1,
"os.hordaland.no": 1,
"osaka.jp": 1,
"osakasayama.osaka.jp": 1,
"osaki.miyagi.jp": 1,
"osakikamijima.hiroshima.jp": 1,
+ "osasco.br": 1,
"osen.no": 1,
"oseto.nagasaki.jp": 1,
"oshima.tokyo.jp": 1,
"oshima.yamaguchi.jp": 1,
"oshino.yamanashi.jp": 1,
"oshu.iwate.jp": 1,
- "oskol.ru": 1,
"oslo.no": 1,
"osoyro.no": 1,
"osteroy.no": 1,
@@ -4704,6 +4937,7 @@ module.exports = {
"ozu.kumamoto.jp": 1,
"p.bg": 1,
"p.se": 1,
+ "pa.gov.br": 1,
"pa.gov.pl": 1,
"pa.it": 1,
"pa.leg.br": 1,
@@ -4715,9 +4949,9 @@ module.exports = {
"pagefrontapp.com": 1,
"pagespeedmobilizer.com": 1,
"palace.museum": 1,
- "palana.ru": 1,
"paleo.museum": 1,
"palermo.it": 1,
+ "palmas.br": 1,
"palmsprings.museum": 1,
"panama.museum": 1,
"pantheonsite.io": 1,
@@ -4732,22 +4966,23 @@ module.exports = {
"parti.se": 1,
"pasadena.museum": 1,
"passenger-association.aero": 1,
+ "patria.bo": 1,
"pavia.it": 1,
"pb.ao": 1,
+ "pb.gov.br": 1,
"pb.leg.br": 1,
"pc.it": 1,
"pc.pl": 1,
"pd.it": 1,
"pe.ca": 1,
+ "pe.gov.br": 1,
"pe.it": 1,
"pe.kr": 1,
"pe.leg.br": 1,
- "penza.ru": 1,
"penza.su": 1,
"per.la": 1,
"per.nf": 1,
"per.sg": 1,
- "perm.ru": 1,
"perso.ht": 1,
"perso.sn": 1,
"perso.tn": 1,
@@ -4767,6 +5002,7 @@ module.exports = {
"philately.museum": 1,
"phoenix.museum": 1,
"photography.museum": 1,
+ "pi.gov.br": 1,
"pi.it": 1,
"pi.leg.br": 1,
"piacenza.it": 1,
@@ -4783,21 +5019,25 @@ module.exports = {
"pisz.pl": 1,
"pittsburgh.museum": 1,
"piw.gov.pl": 1,
+ "pixolino.com": 1,
"pl.eu.org": 1,
"pl.ua": 1,
"planetarium.museum": 1,
"plantation.museum": 1,
"plants.museum": 1,
"platform.sh": 2,
+ "platformsh.site": 2,
"plaza.museum": 1,
"plc.co.im": 1,
"plc.ly": 1,
"plc.uk": 1,
"plo.ps": 1,
+ "plurinacional.bo": 1,
"pmn.it": 1,
"pn.it": 1,
"po.gov.pl": 1,
"po.it": 1,
+ "poa.br": 1,
"podhale.pl": 1,
"podlasie.pl": 1,
"podzone.net": 1,
@@ -4810,6 +5050,7 @@ module.exports = {
"pol.ht": 1,
"pol.tr": 1,
"police.uk": 1,
+ "politica.bo": 1,
"polkowice.pl": 1,
"poltava.ua": 1,
"pomorskie.pl": 1,
@@ -4833,6 +5074,7 @@ module.exports = {
"pp.se": 1,
"pp.ua": 1,
"ppg.br": 1,
+ "pr.gov.br": 1,
"pr.it": 1,
"pr.leg.br": 1,
"pr.us": 1,
@@ -4873,6 +5115,7 @@ module.exports = {
"prochowice.pl": 1,
"production.aero": 1,
"prof.pr": 1,
+ "profesional.bo": 1,
"project.museum": 1,
"protonet.io": 1,
"pruszkow.pl": 1,
@@ -4884,18 +5127,19 @@ module.exports = {
"pt.eu.org": 1,
"pt.it": 1,
"ptplus.fit": 1,
- "ptz.ru": 1,
"pu.it": 1,
"pub.sa": 1,
"publ.pt": 1,
"public.museum": 1,
"publishproxy.com": 1,
"pubol.museum": 1,
+ "pueblo.bo": 1,
"pug.it": 1,
"puglia.it": 1,
"pulawy.pl": 1,
"pup.gov.pl": 1,
"pv.it": 1,
+ "pvh.br": 1,
"pvt.ge": 1,
"pvt.k12.ma.us": 1,
"pyatigorsk.ru": 1,
@@ -4912,6 +5156,7 @@ module.exports = {
"qsl.br": 1,
"quebec.museum": 1,
"quicksytes.com": 1,
+ "quipelements.com": 2,
"r.bg": 1,
"r.cdn77.net": 1,
"r.se": 1,
@@ -4952,6 +5197,7 @@ module.exports = {
"rec.ro": 1,
"rec.ve": 1,
"recht.pro": 1,
+ "recife.br": 1,
"recreation.aero": 1,
"red.sv": 1,
"redirectme.net": 1,
@@ -4963,6 +5209,7 @@ module.exports = {
"reklam.hu": 1,
"rel.ht": 1,
"rel.pl": 1,
+ "remotewd.com": 1,
"rendalen.no": 1,
"rennebu.no": 1,
"rennesoy.no": 1,
@@ -4973,11 +5220,14 @@ module.exports = {
"res.in": 1,
"research.aero": 1,
"research.museum": 1,
+ "resindevice.io": 1,
"resistance.museum": 1,
+ "revista.bo": 1,
"rg.it": 1,
"rhcloud.com": 1,
"ri.it": 1,
"ri.us": 1,
+ "ribeirao.br": 1,
"rieti.it": 1,
"rifu.miyagi.jp": 1,
"riik.ee": 1,
@@ -4988,7 +5238,10 @@ module.exports = {
"ringebu.no": 1,
"ringerike.no": 1,
"ringsaker.no": 1,
+ "rio.br": 1,
+ "riobranco.br": 1,
"riodejaneiro.museum": 1,
+ "riopreto.br": 1,
"rishiri.hokkaido.jp": 1,
"rishirifuji.hokkaido.jp": 1,
"risor.no": 1,
@@ -4996,17 +5249,18 @@ module.exports = {
"ris\u00f8r.no": 1,
"ritto.shiga.jp": 1,
"rivne.ua": 1,
+ "rj.gov.br": 1,
"rj.leg.br": 1,
"rl.no": 1,
"rm.it": 1,
+ "rn.gov.br": 1,
"rn.it": 1,
"rn.leg.br": 1,
- "rnd.ru": 1,
"rnrt.tn": 1,
"rns.tn": 1,
"rnu.tn": 1,
- "ro.com": 1,
"ro.eu.org": 1,
+ "ro.gov.br": 1,
"ro.im": 1,
"ro.it": 1,
"ro.leg.br": 1,
@@ -5029,16 +5283,17 @@ module.exports = {
"rovno.ua": 1,
"royken.no": 1,
"royrvik.no": 1,
+ "rr.gov.br": 1,
"rr.leg.br": 1,
+ "rs.gov.br": 1,
"rs.leg.br": 1,
"rsc.cdn77.org": 1,
"ru.com": 1,
"ru.eu.org": 1,
- "rubtsovsk.ru": 1,
+ "ru.net": 1,
"ruovat.no": 1,
"russia.museum": 1,
"rv.ua": 1,
- "ryazan.ru": 1,
"rybnik.pl": 1,
"rygge.no": 1,
"ryokami.saitama.jp": 1,
@@ -5061,22 +5316,60 @@ module.exports = {
"s.se": 1,
"s3-ap-northeast-1.amazonaws.com": 1,
"s3-ap-northeast-2.amazonaws.com": 1,
+ "s3-ap-south-1.amazonaws.com": 1,
"s3-ap-southeast-1.amazonaws.com": 1,
"s3-ap-southeast-2.amazonaws.com": 1,
+ "s3-ca-central-1.amazonaws.com": 1,
"s3-eu-central-1.amazonaws.com": 1,
"s3-eu-west-1.amazonaws.com": 1,
+ "s3-eu-west-2.amazonaws.com": 1,
+ "s3-eu-west-3.amazonaws.com": 1,
"s3-external-1.amazonaws.com": 1,
- "s3-external-2.amazonaws.com": 1,
"s3-fips-us-gov-west-1.amazonaws.com": 1,
"s3-sa-east-1.amazonaws.com": 1,
+ "s3-us-east-2.amazonaws.com": 1,
"s3-us-gov-west-1.amazonaws.com": 1,
"s3-us-west-1.amazonaws.com": 1,
"s3-us-west-2.amazonaws.com": 1,
+ "s3-website-ap-northeast-1.amazonaws.com": 1,
+ "s3-website-ap-southeast-1.amazonaws.com": 1,
+ "s3-website-ap-southeast-2.amazonaws.com": 1,
+ "s3-website-eu-west-1.amazonaws.com": 1,
+ "s3-website-sa-east-1.amazonaws.com": 1,
+ "s3-website-us-east-1.amazonaws.com": 1,
+ "s3-website-us-west-1.amazonaws.com": 1,
+ "s3-website-us-west-2.amazonaws.com": 1,
+ "s3-website.ap-northeast-2.amazonaws.com": 1,
+ "s3-website.ap-south-1.amazonaws.com": 1,
+ "s3-website.ca-central-1.amazonaws.com": 1,
+ "s3-website.eu-central-1.amazonaws.com": 1,
+ "s3-website.eu-west-2.amazonaws.com": 1,
+ "s3-website.eu-west-3.amazonaws.com": 1,
+ "s3-website.us-east-2.amazonaws.com": 1,
"s3.amazonaws.com": 1,
"s3.ap-northeast-2.amazonaws.com": 1,
+ "s3.ap-south-1.amazonaws.com": 1,
+ "s3.ca-central-1.amazonaws.com": 1,
"s3.cn-north-1.amazonaws.com.cn": 1,
+ "s3.dualstack.ap-northeast-1.amazonaws.com": 1,
+ "s3.dualstack.ap-northeast-2.amazonaws.com": 1,
+ "s3.dualstack.ap-south-1.amazonaws.com": 1,
+ "s3.dualstack.ap-southeast-1.amazonaws.com": 1,
+ "s3.dualstack.ap-southeast-2.amazonaws.com": 1,
+ "s3.dualstack.ca-central-1.amazonaws.com": 1,
+ "s3.dualstack.eu-central-1.amazonaws.com": 1,
+ "s3.dualstack.eu-west-1.amazonaws.com": 1,
+ "s3.dualstack.eu-west-2.amazonaws.com": 1,
+ "s3.dualstack.eu-west-3.amazonaws.com": 1,
+ "s3.dualstack.sa-east-1.amazonaws.com": 1,
+ "s3.dualstack.us-east-1.amazonaws.com": 1,
+ "s3.dualstack.us-east-2.amazonaws.com": 1,
"s3.eu-central-1.amazonaws.com": 1,
- "sa-east-1.compute.amazonaws.com": 1,
+ "s3.eu-west-2.amazonaws.com": 1,
+ "s3.eu-west-3.amazonaws.com": 1,
+ "s3.us-east-2.amazonaws.com": 1,
+ "s5y.io": 2,
+ "sa-east-1.elasticbeanstalk.com": 1,
"sa.au": 1,
"sa.com": 1,
"sa.cr": 1,
@@ -5112,7 +5405,6 @@ module.exports = {
"sakata.yamagata.jp": 1,
"sakawa.kochi.jp": 1,
"sakegawa.yamagata.jp": 1,
- "sakhalin.ru": 1,
"saku.nagano.jp": 1,
"sakuho.nagano.jp": 1,
"sakura.chiba.jp": 1,
@@ -5125,11 +5417,13 @@ module.exports = {
"salem.museum": 1,
"salerno.it": 1,
"saltdal.no": 1,
+ "salud.bo": 1,
+ "salvador.br": 1,
"salvadordali.museum": 1,
"salzburg.museum": 1,
- "samara.ru": 1,
"samegawa.fukushima.jp": 1,
"samnanger.no": 1,
+ "sampa.br": 1,
"samukawa.kanagawa.jp": 1,
"sanagochi.tokushima.jp": 1,
"sanda.hyogo.jp": 1,
@@ -5154,11 +5448,14 @@ module.exports = {
"santabarbara.museum": 1,
"santacruz.museum": 1,
"santafe.museum": 1,
+ "santamaria.br": 1,
+ "santoandre.br": 1,
"sanuki.kagawa.jp": 1,
+ "saobernardo.br": 1,
+ "saogonca.br": 1,
"saotome.st": 1,
"sapporo.jp": 2,
"sar.it": 1,
- "saratov.ru": 1,
"sardegna.it": 1,
"sardinia.it": 1,
"saroma.hokkaido.jp": 1,
@@ -5183,6 +5480,8 @@ module.exports = {
"sayo.hyogo.jp": 1,
"sb.ua": 1,
"sc.cn": 1,
+ "sc.gov.br": 1,
+ "sc.ke": 1,
"sc.kr": 1,
"sc.leg.br": 1,
"sc.tz": 1,
@@ -5201,6 +5500,7 @@ module.exports = {
"sch.zm": 1,
"schlesisches.museum": 1,
"schoenbrunn.museum": 1,
+ "schokokeks.net": 1,
"schokoladen.museum": 1,
"school.museum": 1,
"school.na": 1,
@@ -5221,11 +5521,13 @@ module.exports = {
"scotland.museum": 1,
"scrapper-site.net": 1,
"scrapping.cc": 1,
+ "scrysec.com": 1,
"sd.cn": 1,
"sd.us": 1,
"sdn.gov.pl": 1,
"se.com": 1,
"se.eu.org": 1,
+ "se.gov.br": 1,
"se.leg.br": 1,
"se.net": 1,
"seaport.museum": 1,
@@ -5258,6 +5560,7 @@ module.exports = {
"semine.miyagi.jp": 1,
"sendai.jp": 2,
"sennan.osaka.jp": 1,
+ "sensiosite.cloud": 2,
"seoul.kr": 1,
"sera.hiroshima.jp": 1,
"seranishi.hiroshima.jp": 1,
@@ -5309,6 +5612,7 @@ module.exports = {
"shibuya.tokyo.jp": 1,
"shichikashuku.miyagi.jp": 1,
"shichinohe.aomori.jp": 1,
+ "shiftedit.io": 1,
"shiga.jp": 1,
"shiiba.miyazaki.jp": 1,
"shijonawate.osaka.jp": 1,
@@ -5408,12 +5712,12 @@ module.exports = {
"sigdal.no": 1,
"siljan.no": 1,
"silk.museum": 1,
- "simbirsk.ru": 1,
"simple-url.com": 1,
"sinaapp.com": 1,
"siracusa.it": 1,
"sirdal.no": 1,
"sites.static.land": 1,
+ "sjc.br": 1,
"sk.ca": 1,
"sk.eu.org": 1,
"skanit.no": 1,
@@ -5445,16 +5749,15 @@ module.exports = {
"sld.pa": 1,
"slg.br": 1,
"slupsk.pl": 1,
+ "slz.br": 1,
"sm.ua": 1,
"smola.no": 1,
- "smolensk.ru": 1,
"sm\u00f8la.no": 1,
"sn.cn": 1,
"snaase.no": 1,
"snasa.no": 1,
"snillfjord.no": 1,
"snoasa.no": 1,
- "snz.ru": 1,
"sn\u00e5ase.no": 1,
"sn\u00e5sa.no": 1,
"so.gov.pl": 1,
@@ -5487,6 +5790,7 @@ module.exports = {
"sor-odal.no": 1,
"sor-varanger.no": 1,
"sorfold.no": 1,
+ "sorocaba.br": 1,
"sorreisa.no": 1,
"sortland.no": 1,
"sorum.no": 1,
@@ -5497,6 +5801,7 @@ module.exports = {
"southcarolina.museum": 1,
"southwest.museum": 1,
"sowa.ibaraki.jp": 1,
+ "sp.gov.br": 1,
"sp.it": 1,
"sp.leg.br": 1,
"space-to-rent.com": 1,
@@ -5504,11 +5809,17 @@ module.exports = {
"spacekit.io": 1,
"spb.ru": 1,
"spb.su": 1,
+ "spdns.de": 1,
+ "spdns.eu": 1,
+ "spdns.org": 1,
"spjelkavik.no": 1,
"sport.hu": 1,
"spy.museum": 1,
"spydeberg.no": 1,
"square.museum": 1,
+ "square7.ch": 1,
+ "square7.de": 1,
+ "square7.net": 1,
"sr.gov.pl": 1,
"sr.it": 1,
"srv.br": 1,
@@ -5517,6 +5828,7 @@ module.exports = {
"st.no": 1,
"stackspace.space": 1,
"stadt.museum": 1,
+ "stage.nodeart.io": 1,
"stalbans.museum": 1,
"stalowa-wola.pl": 1,
"stange.no": 1,
@@ -5528,11 +5840,12 @@ module.exports = {
"state.museum": 1,
"stateofdelaware.museum": 1,
"stathelle.no": 1,
+ "static-access.net": 1,
"static.land": 1,
+ "statics.cloud": 2,
"station.museum": 1,
"stavanger.no": 1,
"stavern.no": 1,
- "stavropol.ru": 1,
"steam.museum": 1,
"steiermark.museum": 1,
"steigen.no": 1,
@@ -5544,6 +5857,7 @@ module.exports = {
"stj\u00f8rdalshalsen.no": 1,
"stockholm.museum": 1,
"stokke.no": 1,
+ "stolos.io": 2,
"stor-elvdal.no": 1,
"stord.no": 1,
"stordal.no": 1,
@@ -5554,6 +5868,7 @@ module.exports = {
"store.st": 1,
"store.ve": 1,
"storfjord.no": 1,
+ "storj.farm": 1,
"stpetersburg.museum": 1,
"strand.no": 1,
"stranda.no": 1,
@@ -5563,7 +5878,6 @@ module.exports = {
"stuff-4-sale.us": 1,
"stufftoread.com": 1,
"stuttgart.museum": 1,
- "stv.ru": 1,
"sue.fukuoka.jp": 1,
"suedtirol.it": 1,
"suginami.tokyo.jp": 1,
@@ -5585,7 +5899,6 @@ module.exports = {
"sund.no": 1,
"sunndal.no": 1,
"surgeonshall.museum": 1,
- "surgut.ru": 1,
"surnadal.no": 1,
"surrey.museum": 1,
"susaki.kochi.jp": 1,
@@ -5600,6 +5913,7 @@ module.exports = {
"sveio.no": 1,
"svelvik.no": 1,
"svizzera.museum": 1,
+ "svn-repos.de": 1,
"sweden.museum": 1,
"sweetpepper.org": 1,
"swidnica.pl": 1,
@@ -5608,9 +5922,11 @@ module.exports = {
"sx.cn": 1,
"sydney.museum": 1,
"sykkylven.no": 1,
+ "syno-ds.de": 1,
+ "synology-diskstation.de": 1,
+ "synology-ds.de": 1,
"synology.me": 1,
"sytes.net": 1,
- "syzran.ru": 1,
"szczecin.pl": 1,
"szczytno.pl": 1,
"szex.hu": 1,
@@ -5629,6 +5945,7 @@ module.exports = {
"s\u00f8rum.no": 1,
"t.bg": 1,
"t.se": 1,
+ "t3l3p0rt.net": 1,
"ta.it": 1,
"taa.it": 1,
"tabayama.yamanashi.jp": 1,
@@ -5701,7 +6018,6 @@ module.exports = {
"tamatsukuri.ibaraki.jp": 1,
"tamayu.shimane.jp": 1,
"tamba.hyogo.jp": 1,
- "tambov.ru": 1,
"tana.no": 1,
"tanabe.kyoto.jp": 1,
"tanabe.wakayama.jp": 1,
@@ -5719,7 +6035,7 @@ module.exports = {
"tas.au": 1,
"tas.edu.au": 1,
"tas.gov.au": 1,
- "tatarstan.ru": 1,
+ "tashkent.su": 1,
"tatebayashi.gunma.jp": 1,
"tateshina.nagano.jp": 1,
"tateyama.chiba.jp": 1,
@@ -5732,11 +6048,15 @@ module.exports = {
"te.it": 1,
"te.ua": 1,
"teaches-yoga.com": 1,
+ "tec.mi.us": 1,
"tec.ve": 1,
"technology.museum": 1,
+ "tecnologia.bo": 1,
"tel.tr": 1,
+ "tele.amune.org": 1,
"telekommunikation.museum": 1,
"television.museum": 1,
+ "temp-dns.com": 1,
"tempio-olbia.it": 1,
"tempioolbia.it": 1,
"tendo.yamagata.jp": 1,
@@ -5745,6 +6065,7 @@ module.exports = {
"tenri.nara.jp": 1,
"teo.br": 1,
"teramo.it": 1,
+ "termez.su": 1,
"terni.it": 1,
"ternopil.ua": 1,
"teshikaga.hokkaido.jp": 1,
@@ -5753,7 +6074,9 @@ module.exports = {
"texas.museum": 1,
"textile.museum": 1,
"tgory.pl": 1,
+ "the.br": 1,
"theater.museum": 1,
+ "theworkpc.com": 1,
"thruhere.net": 1,
"time.museum": 1,
"time.no": 1,
@@ -5764,6 +6087,7 @@ module.exports = {
"tjeldsund.no": 1,
"tjome.no": 1,
"tj\u00f8me.no": 1,
+ "tksat.bo": 1,
"tm.cy": 1,
"tm.fr": 1,
"tm.hu": 1,
@@ -5778,6 +6102,7 @@ module.exports = {
"tmp.br": 1,
"tn.it": 1,
"tn.us": 1,
+ "to.gov.br": 1,
"to.it": 1,
"to.leg.br": 1,
"toba.mie.jp": 1,
@@ -5813,7 +6138,6 @@ module.exports = {
"tokuyama.yamaguchi.jp": 1,
"tokyo.jp": 1,
"tolga.no": 1,
- "tom.ru": 1,
"tomakomai.hokkaido.jp": 1,
"tomari.hokkaido.jp": 1,
"tome.miyagi.jp": 1,
@@ -5824,7 +6148,6 @@ module.exports = {
"tomisato.chiba.jp": 1,
"tomiya.miyagi.jp": 1,
"tomobe.ibaraki.jp": 1,
- "tomsk.ru": 1,
"tonaki.okinawa.jp": 1,
"tonami.toyama.jp": 1,
"tondabayashi.osaka.jp": 1,
@@ -5881,6 +6204,7 @@ module.exports = {
"trader.aero": 1,
"trading.aero": 1,
"traeumtgerade.de": 1,
+ "trafficplex.cloud": 1,
"trainer.aero": 1,
"trana.no": 1,
"tranby.no": 1,
@@ -5890,6 +6214,7 @@ module.exports = {
"tranibarlettaandria.it": 1,
"tranoy.no": 1,
"transport.museum": 1,
+ "transporte.bo": 1,
"transurl.be": 2,
"transurl.eu": 2,
"transurl.nl": 2,
@@ -5938,8 +6263,7 @@ module.exports = {
"tr\u00e6na.no": 1,
"tr\u00f8gstad.no": 1,
"ts.it": 1,
- "tsaritsyn.ru": 1,
- "tsk.ru": 1,
+ "tselinograd.su": 1,
"tsu.mie.jp": 1,
"tsubame.niigata.jp": 1,
"tsubata.ishikawa.jp": 1,
@@ -5968,7 +6292,6 @@ module.exports = {
"tsuwano.shimane.jp": 1,
"tsuyama.okayama.jp": 1,
"tt.im": 1,
- "tula.ru": 1,
"tula.su": 1,
"tunk.org": 1,
"tur.ar": 1,
@@ -5978,7 +6301,6 @@ module.exports = {
"turin.it": 1,
"turystyka.pl": 1,
"tuscany.it": 1,
- "tuva.ru": 1,
"tuva.su": 1,
"tuxfamily.org": 1,
"tv.bb": 1,
@@ -5991,8 +6313,10 @@ module.exports = {
"tv.tr": 1,
"tv.tz": 1,
"tvedestrand.no": 1,
- "tver.ru": 1,
"tw.cn": 1,
+ "twmail.cc": 1,
+ "twmail.net": 1,
+ "twmail.org": 1,
"tx.us": 1,
"tychy.pl": 1,
"tydal.no": 1,
@@ -6001,20 +6325,19 @@ module.exports = {
"tysnes.no": 1,
"tysvar.no": 1,
"tysv\u00e6r.no": 1,
- "tyumen.ru": 1,
"t\u00f8nsberg.no": 1,
"u.bg": 1,
"u.se": 1,
"ube.yamaguchi.jp": 1,
+ "uber.space": 1,
"uchihara.ibaraki.jp": 1,
"uchiko.ehime.jp": 1,
"uchinada.ishikawa.jp": 1,
"uchinomi.kagawa.jp": 1,
"ud.it": 1,
"uda.nara.jp": 1,
+ "udi.br": 1,
"udine.it": 1,
- "udm.ru": 1,
- "udmurtia.ru": 1,
"udono.mie.jp": 1,
"ueda.nagano.jp": 1,
"ueno.gunma.jp": 1,
@@ -6031,7 +6354,6 @@ module.exports = {
"uk.net": 1,
"uki.kumamoto.jp": 1,
"ukiha.fukuoka.jp": 1,
- "ulan-ude.ru": 1,
"ullensaker.no": 1,
"ullensvang.no": 1,
"ulm.museum": 1,
@@ -6066,15 +6388,20 @@ module.exports = {
"urbinopesaro.it": 1,
"ureshino.mie.jp": 1,
"uri.arpa": 1,
+ "url.tw": 1,
"urn.arpa": 1,
"uruma.okinawa.jp": 1,
"uryu.hokkaido.jp": 1,
"us-1.evennode.com": 1,
"us-2.evennode.com": 1,
+ "us-3.evennode.com": 1,
+ "us-4.evennode.com": 1,
"us-east-1.amazonaws.com": 1,
- "us-gov-west-1.compute.amazonaws.com": 1,
- "us-west-1.compute.amazonaws.com": 1,
- "us-west-2.compute.amazonaws.com": 1,
+ "us-east-1.elasticbeanstalk.com": 1,
+ "us-east-2.elasticbeanstalk.com": 1,
+ "us-gov-west-1.elasticbeanstalk.com": 1,
+ "us-west-1.elasticbeanstalk.com": 1,
+ "us-west-2.elasticbeanstalk.com": 1,
"us.com": 1,
"us.eu.org": 1,
"us.gov.pl": 1,
@@ -6087,6 +6414,7 @@ module.exports = {
"uscountryestate.museum": 1,
"usculture.museum": 1,
"usdecorativearts.museum": 1,
+ "user.party.eus": 1,
"usgarden.museum": 1,
"ushiku.ibaraki.jp": 1,
"ushistory.museum": 1,
@@ -6110,6 +6438,7 @@ module.exports = {
"uz.ua": 1,
"uzhgorod.ua": 1,
"uzs.gov.pl": 1,
+ "v-info.info": 1,
"v.bg": 1,
"va.it": 1,
"va.no": 1,
@@ -6141,6 +6470,8 @@ module.exports = {
"vantaa.museum": 1,
"vanylven.no": 1,
"vao.it": 1,
+ "vapor.cloud": 1,
+ "vaporcloud.io": 1,
"vardo.no": 1,
"vard\u00f8.no": 1,
"varese.it": 1,
@@ -6149,7 +6480,6 @@ module.exports = {
"vb.it": 1,
"vc.it": 1,
"vda.it": 1,
- "vdonsk.ru": 1,
"ve.it": 1,
"vefsn.no": 1,
"vega.no": 1,
@@ -6200,31 +6530,27 @@ module.exports = {
"virtueeldomein.nl": 1,
"virtuel.museum": 1,
"viterbo.it": 1,
+ "vix.br": 1,
"vlaanderen.museum": 1,
"vladikavkaz.ru": 1,
"vladikavkaz.su": 1,
"vladimir.ru": 1,
"vladimir.su": 1,
- "vladivostok.ru": 1,
"vlog.br": 1,
"vn.ua": 1,
"voagat.no": 1,
"volda.no": 1,
- "volgograd.ru": 1,
"volkenkunde.museum": 1,
- "vologda.ru": 1,
"vologda.su": 1,
"volyn.ua": 1,
- "voronezh.ru": 1,
"voss.no": 1,
"vossevangen.no": 1,
+ "vpnplus.to": 1,
"vr.it": 1,
- "vrn.ru": 1,
"vs.it": 1,
"vt.it": 1,
"vt.us": 1,
"vv.it": 1,
- "vyatka.ru": 1,
"v\u00e1rgg\u00e1t.no": 1,
"v\u00e5gan.no": 1,
"v\u00e5gs\u00f8y.no": 1,
@@ -6257,6 +6583,7 @@ module.exports = {
"warmia.pl": 1,
"warszawa.pl": 1,
"washingtondc.museum": 1,
+ "washtenaw.mi.us": 1,
"wassamu.hokkaido.jp": 1,
"watarai.mie.jp": 1,
"watari.miyagi.jp": 1,
@@ -6264,6 +6591,8 @@ module.exports = {
"watchandclock.museum": 1,
"waw.pl": 1,
"wazuka.kyoto.jp": 1,
+ "we.bs": 1,
+ "web.bo": 1,
"web.co": 1,
"web.do": 1,
"web.id": 1,
@@ -6280,6 +6609,12 @@ module.exports = {
"webhop.me": 1,
"webhop.net": 1,
"webhop.org": 1,
+ "webhosting.be": 1,
+ "webredirect.org": 1,
+ "webspace.rocks": 1,
+ "wedeploy.io": 1,
+ "wedeploy.me": 1,
+ "wedeploy.sh": 1,
"wegrow.pl": 1,
"wellbeingzone.co.uk": 1,
"wellbeingzone.eu": 1,
@@ -6290,6 +6625,7 @@ module.exports = {
"wielun.pl": 1,
"wif.gov.pl": 1,
"wiih.gov.pl": 1,
+ "wiki.bo": 1,
"wiki.br": 1,
"wildlife.museum": 1,
"williamsburg.museum": 1,
@@ -6310,6 +6646,7 @@ module.exports = {
"works.aero": 1,
"workshop.museum": 1,
"worse-than.tv": 1,
+ "wpdevcloud.com": 1,
"writesthisblog.com": 1,
"wroc.pl": 1,
"wroclaw.pl": 1,
@@ -6327,6 +6664,7 @@ module.exports = {
"xen.prgmr.com": 1,
"xenapponazure.com": 1,
"xj.cn": 1,
+ "xs4all.space": 1,
"xz.cn": 1,
"y.bg": 1,
"y.se": 1,
@@ -6343,7 +6681,6 @@ module.exports = {
"yakage.okayama.jp": 1,
"yakumo.hokkaido.jp": 1,
"yakumo.shimane.jp": 1,
- "yakutia.ru": 1,
"yalta.ua": 1,
"yamada.fukuoka.jp": 1,
"yamada.iwate.jp": 1,
@@ -6356,7 +6693,6 @@ module.exports = {
"yamagata.yamagata.jp": 1,
"yamaguchi.jp": 1,
"yamakita.kanagawa.jp": 1,
- "yamal.ru": 1,
"yamamoto.miyagi.jp": 1,
"yamanakako.yamanashi.jp": 1,
"yamanashi.jp": 1,
@@ -6376,7 +6712,6 @@ module.exports = {
"yanaizu.fukushima.jp": 1,
"yao.osaka.jp": 1,
"yaotsu.gifu.jp": 1,
- "yaroslavl.ru": 1,
"yasaka.nagano.jp": 1,
"yashio.saitama.jp": 1,
"yashiro.hyogo.jp": 1,
@@ -6391,8 +6726,12 @@ module.exports = {
"yawata.kyoto.jp": 1,
"yawatahama.ehime.jp": 1,
"yazu.tottori.jp": 1,
+ "ybo.faith": 1,
+ "ybo.party": 1,
+ "ybo.review": 1,
+ "ybo.science": 1,
+ "ybo.trade": 1,
"ye": 2,
- "yekaterinburg.ru": 1,
"yk.ca": 1,
"yn.cn": 1,
"yoichi.hokkaido.jp": 1,
@@ -6407,6 +6746,7 @@ module.exports = {
"yokote.akita.jp": 1,
"yokoze.saitama.jp": 1,
"yolasite.com": 1,
+ "yombo.me": 1,
"yomitan.okinawa.jp": 1,
"yonabaru.okinawa.jp": 1,
"yonago.tottori.jp": 1,
@@ -6440,9 +6780,6 @@ module.exports = {
"yuu.yamaguchi.jp": 1,
"yuza.yamagata.jp": 1,
"yuzawa.niigata.jp": 1,
- "yuzhno-sakhalinsk.ru": 1,
- "z-1.compute-1.amazonaws.com": 1,
- "z-2.compute-1.amazonaws.com": 1,
"z.bg": 1,
"z.se": 1,
"za.bz": 1,
@@ -6462,7 +6799,6 @@ module.exports = {
"zentsuji.kagawa.jp": 1,
"zgora.pl": 1,
"zgorzelec.pl": 1,
- "zgrad.ru": 1,
"zhitomir.ua": 1,
"zhytomyr.ua": 1,
"zj.cn": 1,
@@ -6473,7 +6809,6 @@ module.exports = {
"zp.ua": 1,
"zt.ua": 1,
"zushi.kanagawa.jp": 1,
- "zw": 2,
"\u00e1k\u014boluokta.no": 1,
"\u00e1laheadju.no": 1,
"\u00e1lt\u00e1.no": 1,
@@ -6508,6 +6843,12 @@ module.exports = {
"\u05d9\u05e8\u05d5\u05e9\u05dc\u05d9\u05dd.museum": 1,
"\u0627\u064a\u0631\u0627\u0646.ir": 1,
"\u0627\u06cc\u0631\u0627\u0646.ir": 1,
+ "\u0e17\u0e2b\u0e32\u0e23.\u0e44\u0e17\u0e22": 1,
+ "\u0e18\u0e38\u0e23\u0e01\u0e34\u0e08.\u0e44\u0e17\u0e22": 1,
+ "\u0e23\u0e31\u0e10\u0e1a\u0e32\u0e25.\u0e44\u0e17\u0e22": 1,
+ "\u0e28\u0e36\u0e01\u0e29\u0e32.\u0e44\u0e17\u0e22": 1,
+ "\u0e2d\u0e07\u0e04\u0e4c\u0e01\u0e23.\u0e44\u0e17\u0e22": 1,
+ "\u0e40\u0e19\u0e47\u0e15.\u0e44\u0e17\u0e22": 1,
"\u4e09\u91cd.jp": 1,
"\u4e2a\u4eba.hk": 1,
"\u4eac\u90fd.jp": 1,
diff --git a/js/lib/request.js b/js/lib/request.js
index b7cc6420daa..0bbd21f1f1d 100644
--- a/js/lib/request.js
+++ b/js/lib/request.js
@@ -8,8 +8,16 @@ const electron = require('electron')
const session = electron.session
const underscore = require('underscore')
const urlParse = require('../../app/common/urlParse')
+const ipc = electron.ipcMain
var cachedDefaultSession = null
+var backgroundPageWebContents = null
+
+if (ipc) {
+ ipc.on('got-background-page-webcontents', (e) => {
+ backgroundPageWebContents = e.sender
+ })
+}
const getDefaultSession = () => {
if (!cachedDefaultSession) {
@@ -41,6 +49,10 @@ module.exports.request = (options, callback) => {
})
}
+ if (typeof options.url !== 'string') {
+ return callback(new Error('URL is not valid'))
+ }
+
if (process.env.NODE_ENV === 'development' &&
urlParse(options.url).protocol === 'http:') {
console.log('WARNING: requesting non-HTTPS URL', options.url)
@@ -84,3 +96,24 @@ module.exports.requestDataFile = (url, headers, path, reject, resolve) => {
})
}
}
+
+/**
+ * Fetches url, title, and image for a publishers site (Youtube, Twitch, etc.)
+ * See
+ * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/fetch
+ * WARNING: the output of this function is untrusted. You should be careful not
+ * to execute it as code!
+ * @param {string} url - url to fetch
+ * @param {Object} options - options to pass to window.fetch
+ * @param {Function({url: string, title: string, image: string, error: string})} callback
+ */
+module.exports.fetchPublisherInfo = (url, options, callback) => {
+ if (!backgroundPageWebContents) {
+ callback(new Error('Background page web contents not initialized.'), { url })
+ return
+ }
+ backgroundPageWebContents.send('fetch-publisher-info', url, options)
+ ipc.once('got-publisher-info-' + url, (e, response) => {
+ callback(response.error, response.body)
+ })
+}
diff --git a/js/lib/urlutil.js b/js/lib/urlutil.js
index 9abdd1bbd2f..9f7a8543fb2 100644
--- a/js/lib/urlutil.js
+++ b/js/lib/urlutil.js
@@ -15,6 +15,8 @@ const punycode = require('punycode/')
const urlParse = require('../../app/common/urlParse')
const urlFormat = require('url').format
const pdfjsExtensionId = require('../constants/config').PDFJSExtensionId
+const ip = require('ip')
+const pdfjsBaseUrl = `chrome-extension://${pdfjsExtensionId}/`
/**
* A simple class for parsing and dealing with URLs.
@@ -157,7 +159,7 @@ const UrlUtil = {
}
try {
- return new window.URL(input).href
+ return (typeof window === 'undefined') ? input : new window.URL(input).href
} catch (e) {
return input
}
@@ -334,7 +336,7 @@ const UrlUtil = {
* @return {string}
*/
getLocationIfPDF: function (url) {
- if (!url || url.indexOf(`chrome-extension://${pdfjsExtensionId}/`) === -1) {
+ if (!UrlUtil.isUrlPDF(url)) {
return url
}
@@ -346,11 +348,22 @@ const UrlUtil = {
return query.file
}
}
- return url.replace(`chrome-extension://${pdfjsExtensionId}/`, '')
+ return UrlUtil.getUrlFromPDFUrl(url)
+ },
+
+ isUrlPDF: function (url) {
+ return (url && url.startsWith(pdfjsBaseUrl)) || false
+ },
+
+ getUrlFromPDFUrl: function (url) {
+ if (!UrlUtil.isUrlPDF(url)) {
+ return url
+ }
+
+ return url.replace(pdfjsBaseUrl, '')
},
getPDFViewerUrl: function (url) {
- const pdfjsBaseUrl = `chrome-extension://${pdfjsExtensionId}/`
const viewerBaseUrl = `${pdfjsBaseUrl}content/web/viewer.html`
return `${viewerBaseUrl}?file=${encodeURIComponent(url)}`
},
@@ -387,7 +400,9 @@ const UrlUtil = {
parsed.hostname = punycode.toASCII(parsed.hostname)
return urlFormat(parsed)
} catch (e) {
- return punycode.toASCII(url)
+ var splitUrl = url.split('@')
+ splitUrl = splitUrl.map(str => punycode.toASCII(str))
+ return splitUrl.join('@')
}
},
@@ -466,11 +481,12 @@ const UrlUtil = {
// parsed.origin is specific to muon.url.parse
if (parsed.origin !== undefined) {
if (parsed.protocol === 'about:') {
- return [parsed.protocol, parsed.path].join('')
+ return [parsed.protocol, parsed.path.replace(/\/.*/, '')].join('')
}
return parsed.origin.replace(/\/+$/, '')
}
if (parsed.host && parsed.protocol) {
+ // parsed.slashes is specific to node's url.parse
return parsed.slashes ? [parsed.protocol, parsed.host].join('//') : [parsed.protocol, parsed.host].join('')
}
return null
@@ -484,6 +500,27 @@ const UrlUtil = {
return url
.replace(/((#?\/?)|(\/#?))$/, '') // remove trailing # and /
.trim() // remove whitespaces
+ },
+
+ /**
+ * Whether a URL is an internal address
+ * @param {string} url
+ * @returns {boolean}
+ */
+ isInternalUrl: (url) => {
+ if (!url) {
+ return false
+ }
+ // TODO: make these user-configurable
+ const whitelistSuffixes = ['local', 'localhost']
+ let hostname = urlParse(url).hostname
+ if (hostname && hostname.startsWith('[') && hostname.endsWith(']')) {
+ // Strip brackets from ipv6 address for ip.isPrivate
+ hostname = hostname.slice(1, hostname.length - 1)
+ }
+ return ip.isPrivate(hostname) || hostname === 'localhost' || whitelistSuffixes.some((suffix) => {
+ return hostname && hostname.endsWith(`.${suffix}`)
+ })
}
}
diff --git a/js/muonTest.entry.js b/js/muonTest.entry.js
index d449a61a192..1245f5b7f39 100644
--- a/js/muonTest.entry.js
+++ b/js/muonTest.entry.js
@@ -1,81 +1,49 @@
-const urlParse = require('../app/common/urlParse')
-const urlUtil = require('./lib/urlutil')
-const suggestion = require('../app/common/lib/suggestion')
const assert = require('assert')
-
-const assertEqual = (actual, expected, name) => {
- const elem = document.createElement('div')
- elem.id = name
- elem.innerText = 'fail'
-
- try {
- assert.deepEqual(actual, expected)
- elem.innerText = 'success'
- } catch (e) {
- elem.innerText = JSON.stringify(actual)
+const tests = require('../test/muon-native/').run
+
+const testRunner = (successKey) => {
+ const failures = []
+ let assertCount = 0
+
+ const assertWrap = (assertType, assertion, failText) => {
+ assertCount++
+ try {
+ assertion()
+ } catch (e) {
+ failures.push({ assertCount, assertType, failText })
+ }
}
- document.body.appendChild(elem)
-}
-
-const defaultParsedUrl = {
- hash: '',
- host: '',
- hostname: '',
- href: '',
- origin: '',
- path: '/',
- pathname: '/',
- port: '',
- protocol: 'http:',
- query: '',
- search: ''
-}
-
-const runTests = () => {
- assertEqual(urlParse('http://bing.com'),
- Object.assign(defaultParsedUrl, {
- host: 'bing.com',
- hostname: 'bing.com',
- origin: 'http://bing.com/',
- href: 'http://bing.com/'
- }), 'urlParseSimple')
- assertEqual(urlParse('https://brave.com:333/test?abc=123&def#fff'),
- {
- host: 'brave.com:333',
- hostname: 'brave.com',
- origin: 'https://brave.com:333/',
- protocol: 'https:',
- port: '333',
- hash: '#fff',
- pathname: '/test',
- path: '/test?abc=123&def',
- search: '?abc=123&def',
- query: 'abc=123&def',
- href: 'https://brave.com:333/test?abc=123&def#fff'
- }, 'urlParseComplex')
-
- assertEqual(urlParse('http://brave.com%60x.code-fu.org/'),
- Object.assign(defaultParsedUrl, {
- host: 'brave.com%60x.code-fu.org',
- hostname: 'brave.com%60x.code-fu.org',
- href: 'http://brave.com%60x.code-fu.org/',
- origin: 'http://brave.com%60x.code-fu.org/'
- }), 'urlParseIssue10270')
+ const done = () => {
+ const elem = document.createElement('div')
+ // selector must match the pattern used in muonTest.js
+ elem.id = successKey.replace(/[^a-zA-Z0-9_-]/g, '_')
+ // passFail is the critical element, it has to contain either 'PASS' or 'FAIL'
+ const passFail = document.createElement('span')
+ passFail.className = 'passFail'
+ passFail.innerText = 'PASS'
+ const desc = document.createElement('span')
+ desc.innerText = ` ${successKey}`
+ const failure = document.createElement('div')
+ failure.className = 'failure'
+ if (failures.length) {
+ passFail.innerText = 'FAIL'
+ for (let fail of failures) {
+ failure.innerText += `#${fail.assertCount} ${fail.assertType}: ${fail.failText}\n`
+ }
+ }
+ elem.appendChild(passFail)
+ elem.appendChild(desc)
+ elem.appendChild(failure)
+ document.body.appendChild(elem)
+ }
- assertEqual(urlUtil.getOrigin('http://www.brave.com/foo'), 'http://www.brave.com', 'getOriginSimple')
- assertEqual(urlUtil.getOrigin('file:///aaa'), 'file:///', 'getOriginFile')
- assertEqual(urlUtil.getOrigin('http://brave.com:333/foo'), 'http://brave.com:333', 'getOriginWithPort')
- assertEqual(urlUtil.getOrigin('http://127.0.0.1:443/?test=1#abc'), 'http://127.0.0.1:443', 'getOriginIP')
- assertEqual(urlUtil.getOrigin('about:preferences#abc'), 'about:preferences', 'getOriginAbout')
- assertEqual(urlUtil.getOrigin('http://http/test'), 'http://http', 'getOriginSchemeHost')
- assertEqual(urlUtil.getOrigin(''), null, 'getOriginNull')
- assertEqual(urlUtil.getOrigin('abc'), null, 'getOriginInvalid')
- console.log(suggestion.isSimpleDomainNameValue('http://http/test'))
- assertEqual(suggestion.isSimpleDomainNameValue('http://test.com') &&
- suggestion.isSimpleDomainNameValue('http://test.com/') &&
- suggestion.isSimpleDomainNameValue('http://test.com#') &&
- !suggestion.isSimpleDomainNameValue('http://test.com/test'), true, 'suggestionSimpleCheck')
+ return [ 'ok', 'equal', 'deepEqual', 'strictEqual' ].reduce((wrappedAssert, fn) => {
+ wrappedAssert[fn] = (actual, expected) => {
+ assertWrap(fn, () => { assert[fn](actual, expected) }, actual)
+ }
+ return wrappedAssert
+ }, { done })
}
-runTests()
+tests(testRunner)
diff --git a/js/settings.js b/js/settings.js
index 4eac90fa183..de6d97cd368 100644
--- a/js/settings.js
+++ b/js/settings.js
@@ -61,7 +61,7 @@ const getDefaultSetting = (settingKey, settingsCollection) => {
}
const resolveValue = (settingKey, settingsCollection) => {
- if (settingsCollection && settingsCollection.constructor === Immutable.Map &&
+ if (settingsCollection && Immutable.Map.isMap(settingsCollection) &&
settingsCollection.get(settingKey) !== undefined) {
return settingsCollection.get(settingKey)
}
diff --git a/js/state/contentSettings.js b/js/state/contentSettings.js
index e51bcea7450..b7b011700f2 100644
--- a/js/state/contentSettings.js
+++ b/js/state/contentSettings.js
@@ -19,6 +19,9 @@ const {getSetting} = require('../settings')
const {autoplayOption} = require('../../app/common/constants/settingsEnums')
const {getFlashResourceId} = require('../flash')
+// Widevine not supported yet on linux
+const widevineResourceId = `widevinecdmadapter.${process.platform === 'darwin' ? 'plugin' : 'dll'}`
+
// backward compatibility with appState siteSettings
const parseSiteSettingsPattern = (pattern) => {
if (pattern === 'file:///') {
@@ -152,7 +155,7 @@ const getDefaultPluginSettings = (braveryDefaults, appSettings, appConfig) => {
},
{
setting: 'block',
- resourceId: appConfig.widevine.resourceId,
+ resourceId: widevineResourceId,
primaryPattern: '*'
},
// allow autodetction of flash install by adobe
@@ -317,7 +320,7 @@ const siteSettingsToContentSettings = (currentSiteSettings, defaultContentSettin
contentSettings = addContentSettings(contentSettings, 'flashAllowed', primaryPattern, '*', 'allow', getFlashResourceId())
}
if (typeof siteSetting.get('widevine') === 'number' && braveryDefaults.get('widevine')) {
- contentSettings = addContentSettings(contentSettings, 'plugins', primaryPattern, '*', 'allow', appConfig.widevine.resourceId)
+ contentSettings = addContentSettings(contentSettings, 'plugins', primaryPattern, '*', 'allow', widevineResourceId)
}
if (typeof siteSetting.get('autoplay') === 'boolean') {
contentSettings = addContentSettings(contentSettings, 'autoplay', primaryPattern, '*', siteSetting.get('autoplay') ? 'allow' : 'block')
diff --git a/js/state/frameStateUtil.js b/js/state/frameStateUtil.js
index 510e024039d..f8069d97dc7 100644
--- a/js/state/frameStateUtil.js
+++ b/js/state/frameStateUtil.js
@@ -10,7 +10,7 @@ const settings = require('../constants/settings')
// Actions
const windowActions = require('../actions/windowActions')
-const webviewActions = require('../actions/webviewActions')
+const tabActions = require('../../app/common/actions/tabActions')
// State
const {makeImmutable} = require('../../app/common/state/immutableUtil')
@@ -48,6 +48,10 @@ function getFrames (state) {
return state.get('frames')
}
+function getFrameKeys (state) {
+ return state.get('frames', Immutable.List()).map(frame => frame.get('key'))
+}
+
function getSortedFrames (state) {
return state.get('frames', Immutable.List()).sort(comparatorByKeyAsc)
}
@@ -320,8 +324,6 @@ const frameOptsFromFrame = (frame) => {
return frame
.delete('key')
.delete('parentFrameKey')
- .delete('activeShortcut')
- .delete('activeShortcutDetails')
.delete('index')
.deleteIn(['navbar', 'urlbar', 'suggestions'])
}
@@ -344,6 +346,8 @@ function addFrame (state, frameOpts, newKey, partitionNumber, openInForeground,
const isPinned = frameOpts.isPinned
delete frameOpts.isPinned
+ delete frameOpts.index
+
// TODO: longer term get rid of parentFrameKey completely instead of
// calculating it here.
let parentFrameKey = frameOpts.parentFrameKey
@@ -432,9 +436,9 @@ function getFrameTabPageIndex (state, tabId, tabsPerTabPage = getSetting(setting
return Math.floor(index / tabsPerTabPage)
}
-function onFindBarHide (frameKey) {
+function onFindBarHide (frameKey, tabId) {
windowActions.setFindbarShown(frameKey, false)
- webviewActions.stopFindInPage()
+ tabActions.stopFindInPageRequest(tabId)
windowActions.setFindDetail(frameKey, Immutable.fromJS({
internalFindStatePresent: false,
numberOfMatches: -1,
@@ -770,6 +774,7 @@ module.exports = {
isPrivatePartition,
isSessionPartition,
getFrames,
+ getFrameKeys,
getSortedFrames,
getPinnedFrames,
getNonPinnedFrames,
diff --git a/js/state/syncUtil.js b/js/state/syncUtil.js
index c651ceb3762..aa337f3369d 100644
--- a/js/state/syncUtil.js
+++ b/js/state/syncUtil.js
@@ -48,8 +48,7 @@ module.exports.siteSettingDefaults = {
httpsEverywhere: true,
fingerprintingProtection: false, // boolean for backwards compatibility
ledgerPayments: true,
- ledgerPaymentsShown: true,
- ledgerPinPercentage: 0
+ ledgerPaymentsShown: true
}
// Whitelist of valid browser-laptop site fields. In browser-laptop, site
diff --git a/js/stores/appStore.js b/js/stores/appStore.js
index 1b009ab61bb..3104175102a 100644
--- a/js/stores/appStore.js
+++ b/js/stores/appStore.js
@@ -34,9 +34,10 @@ const {HrtimeLogger} = require('../../app/common/lib/logUtil')
const platformUtil = require('../../app/common/lib/platformUtil')
const urlUtil = require('../lib/urlutil')
const buildConfig = require('../constants/buildConfig')
+const {shouldDebugStoreActions} = require('../../app/cmdLine')
// state helpers
-const {makeImmutable} = require('../../app/common/state/immutableUtil')
+const {makeImmutable, findNullKeyPaths} = require('../../app/common/state/immutableUtil')
const basicAuthState = require('../../app/common/state/basicAuthState')
const extensionState = require('../../app/common/state/extensionState')
const aboutNewTabState = require('../../app/common/state/aboutNewTabState')
@@ -45,7 +46,6 @@ const tabState = require('../../app/common/state/tabState')
const bookmarksState = require('../../app/common/state/bookmarksState')
const bookmarkFoldersState = require('../../app/common/state/bookmarkFoldersState')
const historyState = require('../../app/common/state/historyState')
-const bookmarkToolbarState = require('../../app/common/state/bookmarkToolbarState')
// Only used internally
const CHANGE_EVENT = 'app-state-change'
@@ -68,6 +68,14 @@ if (SHOULD_LOG_TIME) {
}
const timeLogger = new HrtimeLogger(TIME_LOG_PATH, TIME_LOG_THRESHOLD)
+function shouldIgnoreStateDiffForWindow (stateOp) {
+ const path = stateOp.get('path')
+ // remove tabs[].frame since it comes from the windowState anyway
+ // TODO: do we need to store this in the appState? It's expensive.
+ const shouldIgnore = (path.startsWith('/tabs/') && path.includes('/frame/'))
+ return shouldIgnore
+}
+
class AppStore extends EventEmitter {
constructor () {
super()
@@ -80,15 +88,37 @@ class AppStore extends EventEmitter {
emitChanges () {
if (this.lastEmittedState && this.lastEmittedState !== appState) {
- const d = diff(this.lastEmittedState, appState)
- if (!d.isEmpty()) {
+ let d
+ try {
+ d = diff(this.lastEmittedState, appState)
+ // remove paths the window does not care about
+ .filterNot(shouldIgnoreStateDiffForWindow)
+ } catch (e) {
+ console.error('Error getting a diff from latest state.')
+ // one possible reason immutablediff can throw an error
+ // is due to null keys, so let's log any that we find
+ const nullKeyPaths = findNullKeyPaths(appState)
+ const error = (typeof e === 'object')
+ ? e
+ : (typeof e === 'string')
+ ? new Error(e)
+ : new Error()
+ for (let keyPath of nullKeyPaths) {
+ keyPath = keyPath.map(key => key === null ? 'null' : key)
+ const message = ` State path had null entry! Path was: [${keyPath.join(', ')}].`
+ error.message += message
+ }
+ throw error
+ }
+ if (d && !d.isEmpty()) {
+ const stateDiff = d.toJS()
BrowserWindow.getAllWindows().forEach((wnd) => {
if (wnd.webContents && !wnd.webContents.isDestroyed()) {
- wnd.webContents.send(messages.APP_STATE_CHANGE, { stateDiff: d.toJS() })
+ wnd.webContents.send(messages.APP_STATE_CHANGE, { stateDiff })
}
})
this.lastEmittedState = appState
- this.emit(CHANGE_EVENT, d.toJS())
+ this.emit(CHANGE_EVENT, stateDiff)
}
} else {
this.emit(CHANGE_EVENT, [])
@@ -157,9 +187,6 @@ function handleChangeSettingAction (state, settingKey, settingValue) {
state = state.setIn(['settings', settingKey], homeArray.join('|'))
break
}
- case settings.BOOKMARKS_TOOLBAR_MODE:
- state = bookmarkToolbarState.setToolbars(state)
- break
}
return state
@@ -205,7 +232,6 @@ const handleAppAction = (action) => {
require('../../app/browser/reducers/updatesReducer'),
require('../../app/browser/reducers/aboutNewTabReducer'),
require('../../app/browser/reducers/braverySettingsReducer'),
- require('../../app/browser/reducers/bookmarkToolbarReducer'),
require('../../app/browser/reducers/siteSettingsReducer'),
require('../../app/browser/reducers/pageDataReducer'),
ledgerReducer,
@@ -220,6 +246,10 @@ const handleAppAction = (action) => {
return
}
+ if (shouldDebugStoreActions) {
+ console.log('action:', action.actionType)
+ }
+
let immutableAction = Immutable.Map()
// exclude big chucks that have regular JS in it
if (
@@ -241,7 +271,9 @@ const handleAppAction = (action) => {
// TODO(bridiver) - these should be refactored into reducers
appState = filtering.init(appState, action, appStore)
appState = basicAuth.init(appState, action, appStore)
- appState = webtorrent.init(appState, action, appStore)
+ if (extensionState.isWebTorrentEnabled(appState)) {
+ appState = webtorrent.init(appState, action, appStore)
+ }
appState = profiles.init(appState, action, appStore)
appState = require('../../app/sync').init(appState, action, appStore)
calculateTopSites(true, true)
@@ -309,41 +341,48 @@ const handleAppAction = (action) => {
break
}
case appConstants.APP_SHOW_NOTIFICATION:
- let notifications = appState.get('notifications')
- notifications = notifications.filterNot((notification) => {
- let message = notification.get('message')
- // action.detail is a regular mutable object only when running tests
- return action.detail.get
- ? message === action.detail.get('message')
- : message === action.detail['message']
- })
-
- // Insert notification next to those with the same style, or at the end
- let insertIndex = notifications.size
- const style = action.detail.get
- ? action.detail.get('options').get('style')
- : action.detail['options']['style']
- if (style) {
- const styleIndex = notifications.findLastIndex((notification) => {
- return notification.get('options').get('style') === style
+ {
+ let notifications = appState.get('notifications', Immutable.List()) || Immutable.List()
+ notifications = notifications.filterNot((notification) => {
+ let message = notification.get('message')
+ // action.detail is a regular mutable object only when running tests
+ return action.detail.get
+ ? message === action.detail.get('message')
+ : message === action.detail['message']
})
- if (styleIndex > -1) {
- insertIndex = styleIndex
- } else {
- // Insert after the last notification with a style
- insertIndex = notifications.findLastIndex((notification) => {
- return typeof notification.get('options').get('style') === 'string'
- }) + 1
+
+ // Insert notification next to those with the same style, or at the end
+ let insertIndex = notifications.size
+ const style = action.detail
+ ? action.detail.get
+ ? action.detail.get('options').get('style')
+ : action.detail['options']['style']
+ : undefined
+ if (style) {
+ const styleIndex = notifications.findLastIndex((notification) => {
+ return notification.get('options').get('style') === style
+ })
+ if (styleIndex > -1) {
+ insertIndex = styleIndex
+ } else {
+ // Insert after the last notification with a style
+ insertIndex = notifications.findLastIndex((notification) => {
+ return typeof notification.get('options').get('style') === 'string'
+ }) + 1
+ }
}
+ notifications = notifications.insert(insertIndex, Immutable.fromJS(action.detail))
+ appState = appState.set('notifications', notifications)
+ break
}
- notifications = notifications.insert(insertIndex, Immutable.fromJS(action.detail))
- appState = appState.set('notifications', notifications)
- break
case appConstants.APP_HIDE_NOTIFICATION:
- appState = appState.set('notifications', appState.get('notifications').filterNot((notification) => {
- return notification.get('message') === action.message
- }))
- break
+ {
+ const notifications = appState.get('notifications', Immutable.List()) || Immutable.List()
+ appState = appState.set('notifications', notifications.filterNot((notification) => {
+ return notification.get('message') === action.message
+ }))
+ break
+ }
case appConstants.APP_TAB_CLOSE_REQUESTED:
const tabValue = tabState.getByTabId(appState, immutableAction.get('tabId'))
if (!tabValue) {
@@ -355,7 +394,8 @@ const handleAppAction = (action) => {
const tabsInOrigin = tabState.getTabs(appState).find((tabValue) =>
urlUtil.getOrigin(tabValue.get('url')) === origin && tabValue.get('tabId') !== immutableAction.get('tabId'))
if (!tabsInOrigin) {
- appState = appState.set('notifications', appState.get('notifications').filterNot((notification) => {
+ const notifications = appState.get('notifications', Immutable.List()) || Immutable.List()
+ appState = appState.set('notifications', notifications.filterNot((notification) => {
return notification.get('frameOrigin') === origin
}))
}
diff --git a/js/stores/windowStore.js b/js/stores/windowStore.js
index c539d1a33f9..aa5315a56c0 100644
--- a/js/stores/windowStore.js
+++ b/js/stores/windowStore.js
@@ -2,11 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* global performance */
-
const appDispatcher = require('../dispatcher/appDispatcher')
const EventEmitter = require('events').EventEmitter
const appActions = require('../actions/appActions')
+const webviewActions = require('../actions/webviewActions')
const appConstants = require('../constants/appConstants')
const windowConstants = require('../constants/windowConstants')
const config = require('../constants/config')
@@ -18,15 +17,16 @@ const messages = require('../constants/messages')
const debounce = require('../lib/debounce')
const getSetting = require('../settings').getSetting
const UrlUtil = require('../lib/urlutil')
+const color = require('../lib/color')
const {l10nErrorText} = require('../../app/common/lib/httpUtil')
const { makeImmutable } = require('../../app/common/state/immutableUtil')
const {aboutUrls, getTargetAboutUrl, newFrameUrl} = require('../lib/appUrlUtil')
const assert = require('assert')
const contextMenuState = require('../../app/common/state/contextMenuState')
const appStoreRenderer = require('./appStoreRenderer')
-const windowActions = require('../actions/windowActions')
const bookmarkFoldersState = require('../../app/common/state/bookmarkFoldersState')
const bookmarksState = require('../../app/common/state/bookmarksState')
+const tabState = require('../../app/common/state/tabState')
const bookmarkUtil = require('../../app/common/lib/bookmarkUtil')
let windowState = Immutable.fromJS({
@@ -46,11 +46,8 @@ let lastEmittedState
const CHANGE_EVENT = 'change'
-const focusWebview = (framePath) => {
- windowState = windowState.mergeIn(framePath, {
- activeShortcut: 'focus-webview',
- activeShortcutDetails: null
- })
+const focusWebview = () => {
+ webviewActions.setWebviewFocused()
}
let currentKey = 0
@@ -112,12 +109,24 @@ const newFrame = (state, frameOpts) => {
if (frameOpts === undefined) {
frameOpts = {}
}
+ // setup debug logging
+ const shouldLogDebug = getSetting(settings.DEBUG_VERBOSE_TAB_INFO)
+ // normalize input
frameOpts = frameOpts.toJS ? frameOpts.toJS() : frameOpts
-
// handle tabs.create properties
- let insertionIndex = frameOpts.index !== undefined
- ? frameOpts.index
- : 0
+ if (shouldLogDebug) {
+ console.debug('newFrame', frameOpts)
+ }
+ // Ensure valid index
+ let insertionIndex = frameOpts.index
+ const highestFrameIndex = (state.get('frames') || Immutable.List()).count()
+ const insertionIndexIsInvalid = (insertionIndex == null || insertionIndex < 0 || insertionIndex > highestFrameIndex)
+ if (insertionIndexIsInvalid) {
+ if (shouldLogDebug) {
+ console.debug(`newFrame: invalid insertionIndex of ${insertionIndex} so using max index of ${highestFrameIndex}`)
+ }
+ frameOpts.index = insertionIndex = highestFrameIndex
+ }
if (frameOpts.partition) {
frameOpts.isPrivate = frameStateUtil.isPrivatePartition(frameOpts.partition)
@@ -126,7 +135,7 @@ const newFrame = (state, frameOpts) => {
}
}
frameOpts.partitionNumber = frameOpts.partitionNumber || 0
-
+ const isPinned = frameOpts.isPinned
const active = frameOpts.active
delete frameOpts.active
let openInForeground = active
@@ -162,7 +171,7 @@ const newFrame = (state, frameOpts) => {
nextKey, frameOpts.partitionNumber, openInForeground, insertionIndex))
state = frameStateUtil.updateFramesInternalIndex(state, insertionIndex)
- if (openInForeground) {
+ if (openInForeground && !isPinned) {
const tabId = frameOpts.tabId
const frame = frameStateUtil.getFrameByTabId(state, tabId)
state = frameStateUtil.updateTabPageIndex(state, tabId)
@@ -174,37 +183,31 @@ const newFrame = (state, frameOpts) => {
return state
}
-const frameTabIdChanged = (state, action) => {
+const frameTabReplaced = (state, action) => {
action = makeImmutable(action)
const oldTabId = action.get('oldTabId')
- const newTabId = action.get('newTabId')
+ const newTabValue = action.get('newTabValue')
+ const newTabId = newTabValue.get('tabId')
if (newTabId == null || oldTabId === newTabId) {
+ console.error('Invalid action arguments for frameTabReplaced')
return state
}
-
let newFrameProps = new Immutable.Map()
newFrameProps = newFrameProps.set('tabId', newTabId)
- const index = frameStateUtil.getFrameIndex(state, action.getIn(['frameProps', 'key']))
+ newFrameProps = newFrameProps.set('guestInstanceId', newTabValue.get('guestInstanceId'))
+ newFrameProps = newFrameProps.set('isPlaceholder', newTabValue.get('isPlaceholder'))
+ const frame = frameStateUtil.getFrameByTabId(state, oldTabId)
+ if (!frame) {
+ console.error(`Could not find frame with tabId ${oldTabId} in order to replace with new tabId ${newTabId}`)
+ return state
+ }
+ const index = frameStateUtil.getFrameIndex(state, frame.get('key'))
state = state.mergeIn(['frames', index], newFrameProps)
state = frameStateUtil.deleteTabInternalIndex(state, oldTabId)
state = frameStateUtil.updateFramesInternalIndex(state, index)
return state
}
-const frameGuestInstanceIdChanged = (state, action) => {
- action = makeImmutable(action)
- const oldGuestInstanceId = action.get('oldGuestInstanceId')
- const newGuestInstanceId = action.get('newGuestInstanceId')
-
- if (oldGuestInstanceId === newGuestInstanceId) {
- return state
- }
-
- return state.mergeIn(['frames', frameStateUtil.getFrameIndex(state, action.getIn(['frameProps', 'key']))], {
- guestInstanceId: newGuestInstanceId
- })
-}
-
function handleChangeSettingAction (state, settingKey, settingValue) {
switch (settingKey) {
case settings.TABS_PER_PAGE:
@@ -251,7 +254,11 @@ const immediatelyEmittedActions = [
// Register callback to handle all updates
const doAction = (action) => {
- // console.log(action.actionType, action, windowState.toJS())
+ let t0
+ if (windowState.get('debugStoreActions')) {
+ t0 = window.performance.now()
+ console.log(`%caction-start %c${action.actionType}`, 'color: #aaa', 'font-weight: bold', action)
+ }
windowState = applyReducers(windowState, action, makeImmutable(action))
switch (action.actionType) {
case windowConstants.WINDOW_SET_STATE:
@@ -259,15 +266,12 @@ const doAction = (action) => {
currentKey = frameStateUtil.getFrames(windowState).reduce((previousVal, frame) => Math.max(previousVal, frame.get('key')), 0)
const activeFrame = frameStateUtil.getActiveFrame(windowState)
if (activeFrame && activeFrame.get('location') !== 'about:newtab') {
- focusWebview(frameStateUtil.activeFrameStatePath(windowState))
+ focusWebview()
}
// We should not emit here because the Window already know about the change on startup.
return
- case windowConstants.WINDOW_FRAME_TAB_ID_CHANGED:
- windowState = frameTabIdChanged(windowState, action)
- break
- case windowConstants.WINDOW_FRAME_GUEST_INSTANCE_ID_CHANGED:
- windowState = frameGuestInstanceIdChanged(windowState, action)
+ case appConstants.APP_TAB_REPLACED:
+ windowState = frameTabReplaced(windowState, action)
break
case windowConstants.WINDOW_SET_FRAME_ERROR:
const frameKey = action.frameProps.get('key')
@@ -309,16 +313,24 @@ const doAction = (action) => {
runInsecureContent: false
})
// Update loading UI
- windowState = windowState.mergeIn(statePath('frames'), {
+ const isNewTabUrl = action.location === getTargetAboutUrl('about:newtab')
+ const frameUpdatedData = {
loading: true,
provisionalLocation: action.location,
startLoadTime: new Date().getTime(),
endLoadTime: null
- })
+ }
+ // Optimization to prevent flash of tab color
+ // when creating new tabs.
+ if (isNewTabUrl) {
+ frameUpdatedData.themeColor = '#222222'
+ frameUpdatedData.computedThemeColor = undefined
+ }
+ windowState = windowState.mergeIn(statePath('frames'), frameUpdatedData)
// For about:newtab we want to have the urlbar focused, not the new frame.
// Otherwise we want to focus the new tab when it is a new frame in the foreground.
- if (action.location !== getTargetAboutUrl('about:newtab')) {
- focusWebview(statePath)
+ if (!isNewTabUrl) {
+ focusWebview()
}
break
}
@@ -349,8 +361,10 @@ const doAction = (action) => {
if (!action.location) {
windowState = windowState.set('closedFrames', new Immutable.List())
} else {
+ const closedFrames = windowState.get('closedFrames', Immutable.List()) || Immutable.List()
windowState = windowState.set('closedFrames',
- windowState.get('closedFrames').filterNot((frame) => frame.get('location') === action.location))
+ closedFrames.filterNot((frame) => frame.get('location') === action.location)
+ )
}
break
case windowConstants.WINDOW_SET_PREVIEW_TAB_PAGE_INDEX:
@@ -361,7 +375,7 @@ const doAction = (action) => {
windowState = windowState.setIn(['ui', 'tabs', 'tabPageIndex'], action.index)
windowState = windowState.deleteIn(['ui', 'tabs', 'previewTabPageIndex'])
} else {
- windowState = frameStateUtil.updateTabPageIndex(windowState, action.frameProps.get('tabId'))
+ windowState = frameStateUtil.updateTabPageIndex(windowState, action.tabId)
}
break
case windowConstants.WINDOW_SET_TAB_HOVER_STATE:
@@ -390,20 +404,16 @@ const doAction = (action) => {
{
const frameKey = action.frameProps.get('key')
if (action.themeColor !== undefined) {
- windowState = windowState.setIn(frameStateUtil.frameStatePath(windowState, frameKey).concat(['themeColor']), action.themeColor)
+ // remove alpha channel
+ const solidColor = color.removeAlphaChannelForBackground(action.themeColor, 255, 255, 255)
+ windowState = windowState.setIn(frameStateUtil.frameStatePath(windowState, frameKey).concat(['themeColor']), solidColor)
}
if (action.computedThemeColor !== undefined) {
- windowState = windowState.setIn(frameStateUtil.frameStatePath(windowState, frameKey).concat(['computedThemeColor']), action.computedThemeColor)
+ const solidColor = color.removeAlphaChannelForBackground(action.computedThemeColor, 255, 255, 255)
+ windowState = windowState.setIn(frameStateUtil.frameStatePath(windowState, frameKey).concat(['computedThemeColor']), solidColor)
}
break
}
- case windowConstants.WINDOW_FRAME_SHORTCUT_CHANGED:
- const framePath = action.frameProps ? ['frames', frameStateUtil.getFrameIndex(windowState, action.frameProps.get('key'))] : frameStateUtil.activeFrameStatePath(windowState)
- windowState = windowState.mergeIn(framePath, {
- activeShortcut: action.activeShortcut,
- activeShortcutDetails: action.activeShortcutDetails
- })
- break
case windowConstants.WINDOW_SET_FIND_DETAIL:
{
const frameIndex = frameStateUtil.getFrameIndex(windowState, action.frameKey)
@@ -473,21 +483,28 @@ const doAction = (action) => {
windowState = windowState.delete('bookmarkFolderDetail')
break
case windowConstants.WINDOW_AUTOFILL_SELECTION_CLICKED:
+ windowState = contextMenuState.setContextMenu(windowState)
ipc.send('autofill-selection-clicked', action.tabId, action.value, action.frontEndId, action.index)
- windowState = windowState.delete('contextMenuDetail')
break
case windowConstants.WINDOW_AUTOFILL_POPUP_HIDDEN:
- if (!action.detail &&
- windowState.getIn(['contextMenuDetail', 'type']) === 'autofill' &&
- windowState.getIn(['contextMenuDetail', 'tabId']) === action.tabId) {
- windowState = windowState.delete('contextMenuDetail')
- if (action.notify) {
- ipc.send('autofill-popup-hidden', action.tabId)
+ {
+ const contextMenuDetail = contextMenuState.getContextMenu(windowState)
+ if (!action.detail &&
+ contextMenuDetail.get('type') === 'autofill' &&
+ contextMenuDetail.get('tabId') === action.tabId) {
+ windowState = contextMenuState.setContextMenu(windowState)
+ if (action.notify) {
+ ipc.send('autofill-popup-hidden', action.tabId)
+ }
}
+ break
}
- break
case windowConstants.WINDOW_SET_CONTEXT_MENU_DETAIL:
- windowState = contextMenuState.setContextMenu(windowState, action.detail)
+ if (action.contextMenuDetail) {
+ windowState = windowState.set('contextMenuDetail', action.contextMenuDetail)
+ } else {
+ windowState = windowState.delete('contextMenuDetail')
+ }
break
case windowConstants.WINDOW_SET_POPUP_WINDOW_DETAIL:
if (!action.detail) {
@@ -511,9 +528,6 @@ const doAction = (action) => {
case windowConstants.WINDOW_SET_FAVICON:
windowState = windowState.setIn(['frames', frameStateUtil.getFrameIndex(windowState, action.frameProps.get('key')), 'icon'], action.favicon)
break
- case windowConstants.WINDOW_SET_LAST_ZOOM_PERCENTAGE:
- windowState = windowState.setIn(['frames', frameStateUtil.getFrameIndex(windowState, action.frameProps.get('key')), 'lastZoomPercentage'], action.percentage)
- break
case windowConstants.WINDOW_SET_MOUSE_IN_TITLEBAR:
windowState = windowState.setIn(['ui', 'mouseInTitlebar'], action.mouseInTitlebar)
break
@@ -716,7 +730,7 @@ const doAction = (action) => {
case windowConstants.WINDOW_TAB_MOUSE_LEAVE:
windowState = windowState.deleteIn(['ui', 'tabs', 'fixTabWidth'])
break
- case appConstants.APP_NEW_WEB_CONTENTS_ADDED:
+ case windowConstants.WINDOW_NEW_FRAME:
if (!action.frameOpts) {
break
}
@@ -728,7 +742,34 @@ const doAction = (action) => {
action.frameOpts.tabId = tabValue.get('tabId')
action.frameOpts.icon = action.frameOpts.icon || tabValue.get('favIconUrl')
}
+
+ // Update some properties from latest tab state as frame object has been in transit
+ // and may have missed some events.
+ // TODO: These properties should be read directly from tabState by components because
+ // of it's permanency, instead of keeping frame and tab synchronized.
+ if (action.frameOpts.tabId) {
+ const tab = tabState.getByTabId(appStoreRenderer.state, action.frameOpts.tabId)
+ if (tab) {
+ // handle tabStripWindowId changed whilst tab was being moved (avoiding non-displaying tab)
+ const existingTabStripWindowId = tab.get('tabStripWindowId')
+ action.frameOpts.tabStripWindowId = existingTabStripWindowId
+ }
+ }
+
windowState = newFrame(windowState, action.frameOpts)
+ setImmediate(() => {
+ // Inform subscribers that we now have a frame
+ // representation of a tab.
+ // Note that this is only required since we have some
+ // code that should be performed in state reducers
+ // but is performed in event handlers and requires up-to-date
+ // knowledge of frames in the state.
+ const tabId = action.frameOpts.tabId
+ if (tabId != null) {
+ const frame = frameStateUtil.getFrameByTabId(windowState, tabId)
+ windowStore.emit(`new-frame-${tabId}`, frame)
+ }
+ })
break
case appConstants.APP_CHANGE_SETTING:
windowState = handleChangeSettingAction(windowState, action.key, action.value)
@@ -739,34 +780,18 @@ const doAction = (action) => {
case windowConstants.WINDOW_FRAME_MOUSE_LEAVE:
windowState = windowState.setIn(['ui', 'mouseInFrame'], false)
break
- case windowConstants.WINDOW_ON_CERT_ERROR:
- {
- const frame = frameStateUtil.getFrameByTabId(windowState, action.tabId) || Immutable.Map()
- if (frame.get('location') === action.url ||
- frame.get('provisionalLocation') === action.url) {
- windowActions.setFrameError(frame, {
- url: action.url,
- error: action.error
- })
- appActions.loadURLRequested(action.tabId, 'about:certerror')
- }
- break
- }
- case windowConstants.WINDOW_ON_WINDOW_UPDATE:
case appConstants.APP_WINDOW_READY:
- {
- const oldInfo = windowState.get('windowInfo', Immutable.Map())
- let windowValue = makeImmutable(action.windowValue)
-
- if (windowValue.get('focused')) {
- windowValue = windowValue.set('focusTime', performance.timing.navigationStart + performance.now())
- }
- windowState = windowState.set('windowInfo', oldInfo.merge(windowValue))
- break
- }
case appConstants.APP_WINDOW_UPDATED:
case appConstants.APP_WINDOW_RESIZED:
- windowState = windowState.set('windowInfo', action.windowValue)
+ let windowValue = makeImmutable(action.windowValue)
+ const oldInfo = windowState.get('windowInfo', Immutable.Map())
+ // detect if window is newly focused
+ if (windowValue.get('focused') && !oldInfo.get('focused')) {
+ // record time of focus so we can make sure the window
+ // z-index is restored on app-restart
+ windowValue = windowValue.set('focusTime', new Date().getTime())
+ }
+ windowState = windowState.set('windowInfo', oldInfo.merge(windowValue))
break
case windowConstants.WINDOW_TAB_MOVE_INCREMENTAL_REQUESTED:
const sourceFrame = frameStateUtil.getActiveFrame(windowState)
@@ -789,7 +814,9 @@ const doAction = (action) => {
default:
break
}
-
+ if (windowState.get('debugStoreActions')) {
+ console.log(`%caction-end %dms, activeFrameKey: %d, frames:`, 'color: #aaa', window.performance.now() - t0, windowState.get('activeFrameKey'), windowState.get('frames', Immutable.List()).toJS())
+ }
// Some events must be emitted right away, such as bound countrols
if (immediatelyEmittedActions.includes(action.actionType)) {
windowStore.emitChanges()
@@ -833,36 +860,6 @@ ipc.on(messages.SHORTCUT_OPEN_CLEAR_BROWSING_DATA_PANEL, (e) => {
})
})
-const frameShortcuts = ['stop', 'reload', 'zoom-in', 'zoom-out', 'zoom-reset', 'toggle-dev-tools', 'clean-reload', 'view-source', 'mute', 'save', 'print', 'show-findbar', 'find-next', 'find-prev']
-frameShortcuts.forEach((shortcut) => {
- // Listen for actions on the active frame
- ipc.on(`shortcut-active-frame-${shortcut}`, (e, args) => {
- if (shortcut === 'toggle-dev-tools') {
- appActions.toggleDevTools(frameStateUtil.getActiveFrameTabId(windowState))
- } else {
- const framePath = frameStateUtil.activeFrameStatePath(windowState)
- if (framePath) {
- windowState = windowState.mergeIn(framePath, {
- activeShortcut: shortcut,
- activeShortcutDetails: args
- })
- emitChanges()
- }
- }
- })
- // Listen for actions on frame N
- if (['reload', 'mute'].includes(shortcut)) {
- ipc.on(`shortcut-frame-${shortcut}`, (e, i, args) => {
- const path = ['frames', frameStateUtil.getFrameIndex(windowState, i)]
- windowState = windowState.mergeIn(path, {
- activeShortcut: shortcut,
- activeShortcutDetails: args
- })
- emitChanges()
- })
- }
-})
-
appDispatcher.registerLocalCallback(doAction)
module.exports = windowStore
diff --git a/js/webtorrent/entry.js b/js/webtorrent/entry.js
index 8846ccb7011..f96ae22e804 100644
--- a/js/webtorrent/entry.js
+++ b/js/webtorrent/entry.js
@@ -27,6 +27,9 @@ const store = {
errorMessage: null
}
+// Hostname of the webtorrent server
+const webtorrentServerHostname = 'localhost'
+
let client, server
init()
@@ -135,7 +138,9 @@ function initTorrent (torrent) {
server = torrent.createServer({
// Only allow requests from this origin ('chrome-extension://...) so websites
// cannot violate same-origin policy by reading contents of active torrents.
- origin: window.location.origin
+ origin: window.location.origin,
+ // Use hostname option to mitigate DNS rebinding (#12616)
+ hostname: webtorrentServerHostname
})
server.listen(onServerListening)
@@ -148,7 +153,7 @@ function initTorrent (torrent) {
}
function onServerListening () {
- store.serverUrl = 'http://localhost:' + server.address().port
+ store.serverUrl = `http://${webtorrentServerHostname}:${server.address().port}`
update()
}
diff --git a/less/about/bookmarks.less b/less/about/bookmarks.less
index d4b3181fa1f..16c1f74eedb 100644
--- a/less/about/bookmarks.less
+++ b/less/about/bookmarks.less
@@ -24,9 +24,7 @@
.folderView {
/* TODO: once refactoring to Aphrodite, make
it more flexible with relative units */
- max-width: 410px;
- min-width: 220px;
- flex-grow: 1;
+ width: 410px;
.columnHeader {
background: linear-gradient(to bottom, @lightGray, @veryLightGray);
diff --git a/less/about/error.less b/less/about/error.less
index 26f063f036e..63c276500bc 100644
--- a/less/about/error.less
+++ b/less/about/error.less
@@ -61,7 +61,7 @@ body {
}
.certAttrText {
- color: @chromeSecondary;
+ color: @chromeText;
display: inline;
}
}
diff --git a/less/about/preferences.less b/less/about/preferences.less
index 750332ba4d4..2444e891a4f 100644
--- a/less/about/preferences.less
+++ b/less/about/preferences.less
@@ -52,6 +52,7 @@ body {
display: flex;
height: 100%;
margin-left: @sideBarWidth;
+ outline: none;
a {
text-decoration: none;
diff --git a/less/button.less b/less/button.less
index bb1fe78153f..23c995fd4b1 100644
--- a/less/button.less
+++ b/less/button.less
@@ -34,7 +34,7 @@ span.buttonSeparator {
border-radius: @borderRadius;
margin: 0 3px;
text-align: center;
- transition: .1s opacity, .1s background;
+ transition: .12s opacity ease, .12s background ease;
user-select: none;
user-select: none;
@@ -82,7 +82,8 @@ span.buttonSeparator {
&.primaryButton {
background: linear-gradient(@braveLightOrange, @braveOrange);
- border: 2px solid transparent;
+ border-left: 2px solid @braveLightOrange;
+ border-right: 2px solid @braveOrange;
border-top: 2px solid @braveLightOrange;
border-bottom: 2px solid @braveOrange;
box-shadow: @buttonShadow;
diff --git a/less/navigationBar.less b/less/navigationBar.less
index 5645906bdcd..863be5a9961 100644
--- a/less/navigationBar.less
+++ b/less/navigationBar.less
@@ -574,8 +574,6 @@
}
}
-@urlbarFormHeight: 25px;
-
.urlbarForm {
position: relative; // PR #6485
width: 0; // Fixes #4298
@@ -585,9 +583,8 @@
padding: 0 10px 0 3px;
display: flex;
flex-grow: 1;
- min-width: 0%; // allow the navigator to shrink
- margin-left: 1px;
-
+ min-width: 30px; // allow the navigator to shrink
+
*:not(legend) {
z-index: @zindexUrlbarNotLegend;
}
@@ -619,8 +616,7 @@
color: @chromeText;
// #4922
- // TODO: replace this value with a CSS variable to add a dark UI.
- background: #fff;
+ background: @chromeControlsBackground2;
}
@media (max-width: @breakpointNarrowViewport) {
@@ -825,7 +821,7 @@
justify-content: center;
height: @urlbarFormHeight;
min-height: @urlbarFormHeight;
- margin: 0 5px;
+ margin-right: 5px;
max-width: 40%;
.urlbarIcon {
@@ -835,14 +831,14 @@
background-position: center;
position: relative;
bottom: -1px;
- margin-left: 3px;
+ padding: 5px 0px 5px 5px;
// about:newtab
&.fa-search {
position: relative;
bottom: 0;
- // 50% of #5a5a5a
- color: rgba(90, 90, 90, 0.5);
+ // 50% of rgb(90, 90, 98)
+ color: rgba(90, 90, 98, 0.5);
}
&.fa-lock,
@@ -863,8 +859,10 @@
.evCert {
font-size: 12px;
- color: forestgreen;
- padding: 5px;
+ font-weight: 500;
+ color: @siteEVColor;
+ padding-left: 5px;
+ padding-right: 5px;
border-right: 1px solid #ccc;
overflow: hidden;
text-overflow: ellipsis;
diff --git a/less/variables.less b/less/variables.less
index 9c3e1747aab..905258d3395 100644
--- a/less/variables.less
+++ b/less/variables.less
@@ -45,13 +45,14 @@
@siteEVColor: green;
@loadTimeColor: @highlightBlue;
@activeTabDefaultColor: @chromePrimary;
-@buttonColor: #5a5a5a;
+@buttonColor: rgb(90, 90, 98);
@braveOrange: rgb(255, 85, 0);
@braveLightOrange: #FF7A1D;
@braveMediumOrange: rgb(232, 72, 0);
@braveDarkOrange: #D44600;
@dragSpacing: 50px;
@urlBarOutline: #bbb;
+@urlbarFormHeight: 25px;
@navbarHeight: 36px;
@downloadsBarHeight: 60px;
diff --git a/less/window.less b/less/window.less
index 12ec648d38a..4c63a2f259f 100644
--- a/less/window.less
+++ b/less/window.less
@@ -40,7 +40,7 @@ html,
}
.top {
- background: linear-gradient(to bottom, #eaeaea, #f2f2f4);
+ background: linear-gradient(to top, rgb(233, 233, 234) 0%, rgb(233, 233, 234) 29px, rgb(246,246,247) 100%);
&.allowDragging {
-webkit-app-region: drag;
}
@@ -50,13 +50,32 @@ html,
display: flex;
flex-direction: row;
flex-grow: 1;
- box-shadow: 0 -1px 0 #bbb;
+ box-shadow: 0 -1px 0 rgb(187, 187, 191);
width: 100%;
+ position: relative;
- .tabContainer {
- flex-grow: 1;
- position: relative;
+ &:after {
+ position: absolute;
+ content: ' ';
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ background: linear-gradient(to top, rgb(28, 27, 27) 0%, rgba(255, 255, 255, .3) 60%);
+ display: block;
+ opacity: 0;
+ transition: opacity .4s ease-in; // TODO: get from theme.tab
+ pointer-events: none;
+ will-change: opacity;
+ z-index: 1100;
+ }
+ &.hasFramePreview::after {
+ transition-timing-function: ease-out; // TODO: get from theme.tab
+ transition-duration: .2s; // TODO: get from theme.tab
+ opacity: 1;
}
+
+
}
.frameWrapper {
@@ -69,16 +88,7 @@ html,
// Needed to be able to click and drag to select content in pages.
user-select: none;
- // default frame background
- // TODO: use theme.frame.defaultBackground
- --frame-bg: #fff;
- // custom frame background(s)
- &.isDefaultNewTabLocation {
- // matches tab dashboard background
- // will also show when about:newtab === about:blank or is Private Tab
- // TODO: use theme.frame.newTabBackground
- --frame-bg: #222;
- }
+
// Webviews can cause flickers w/ Chrome v49 if left visible
// in the background. This also has a major benefit for background
// tabs that have video and animations in them.
@@ -91,17 +101,26 @@ html,
// Note that this value can be as large as we want, it does not
// need to match the timeout specified in the frame's element
// (in renderer main.js). However, there is no reason to set it higher than that.
- transition: visibility 0s linear 150ms;
- // 1000
- z-index: @zindexWindow;
+ --visibility-delay: .15s;
+ --frame-zIndex-delay: 0s;
+ transition: visibility 0s linear var(--visibility-delay), z-index 0s linear var(--frame-zIndex-delay);
+ // active frame z-index
+ z-index: 1000;
+
+ .hasFramePreview &.isActive {
+ // Move to below preview frame, but do so as part of 'preview' entry animation
+ // so that it is clear which frame is being previewed and which is active.
+ z-index: 993;
+ --frame-zIndex-delay: .2s;
+ }
+
&:not(.isActive) {
- // 900
- z-index: @zindexWindowNotActive;
+ // non-active always lower than active
+ z-index: 990;
}
&.isPreview {
background: #222;
- // 1100
- z-index: @zindexWindowIsPreview;
+ z-index: 995;
}
// show frame when active or preview
&.isActive,
@@ -111,7 +130,7 @@ html,
&.isExiting {
visibility: visible;
// show instantly
- transition-delay: 0s;
+ --visibility-delay: 0s;
}
// hide frame whilst it's figuring out which location to be
// note: that isEntering is timed-out at a value set in renderer main.js
@@ -119,7 +138,8 @@ html,
// has an actual location
&.isEntering.isBlankLocation {
visibility: hidden;
- transition-delay: 0s;
+ // hide instantly (at first)
+ --visibility-delay: 0s;
}
webview {
@@ -133,12 +153,6 @@ html,
.webviewContainer {
height: 100%;
width: 100%;
- &.isPreview {
- will-change: opacity;
- opacity: 0.5;
- animation: tabFadeIn 0.75s ease-in-out;
- animation-fill-mode: forwards;
- }
}
}
@@ -149,16 +163,17 @@ html,
border-style: solid;
border-width: 1px 1px 0 0;
border-top-right-radius: @borderRadius;
+ max-width: 40%;
+ position: absolute;
bottom: 0;
- color: @chromeText;
- font-size: @defaultFontSize;
left: 0;
- max-width: 40%;
- overflow-x: hidden;
padding: 0.2em 0.5em;
- position: absolute;
+ overflow-x: hidden;
+ color: @chromeText;
+ font-size: @defaultFontSize;
text-overflow: ellipsis;
white-space: nowrap;
+ z-index: 30;
&.right {
left: auto;
@@ -169,23 +184,6 @@ html,
}
}
-body.fullScreen .frameWrapper.isActive {
- z-index: @zindexWindowFullScreen;
-}
-
-/* The fullscreen notice is shown above the fullscreen element */
-body.fullScreen .banner {
- position: absolute;
- z-index: @zindexWindowFullScreenBanner;
- top: 0;
- opacity: 1;
- transition: opacity 2s ease-in-out;
-}
-
-body.fullScreen .banner.fade {
- opacity: 0;
-}
-
[draggable] {
user-select: none;
}
diff --git a/package-lock.json b/package-lock.json
index a61d521a508..76481837791 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,25 +1,24 @@
{
"name": "brave",
- "version": "0.22.0",
+ "version": "0.24.0",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
+ "7zip-bin": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-3.0.0.tgz",
+ "integrity": "sha512-CYsciSeLZvl+hlJiDBBEh987fyqvFFFJG3nZi8QbNYgmgxNOzf+kyYuAYIR48CTc/X6SX5d5KtTgvkUlj9jLQA==",
+ "dev": true
+ },
"@ambassify/backoff-strategies": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/@ambassify/backoff-strategies/-/backoff-strategies-1.0.0.tgz",
"integrity": "sha1-6salmVHxSXdAY2wGRi2QbXKfQ6U="
},
"@types/node": {
- "version": "6.0.88",
- "resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.88.tgz",
- "integrity": "sha512-bYDPZTX0/s1aihdjLuAgogUAT5M+TpoWChEMea2p0yOcfn5bu3k6cJb9cp6nw268XeSNIGGr+4+/8V5K6BGzLQ=="
- },
- "7zip-bin-mac": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/7zip-bin-mac/-/7zip-bin-mac-1.0.1.tgz",
- "integrity": "sha1-Pmh3i78JJq3GgVlCcHRQXUdVXAI=",
- "dev": true,
- "optional": true
+ "version": "10.1.2",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-10.1.2.tgz",
+ "integrity": "sha512-bjk1RIeZBCe/WukrFToIVegOf91Pebr8cXYBwLBIsfiGWVQ+ifwWsT59H3RxrWzWrzd1l/Amk1/ioY5Fq3/bpA=="
},
"abab": {
"version": "1.0.4",
@@ -27,25 +26,26 @@
"integrity": "sha1-X6rZwsB/YN12dw9xzwJbYqY8/U4="
},
"abbrev": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
- "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8="
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q=="
},
"abstract-leveldown": {
- "version": "2.6.3",
- "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-2.6.3.tgz",
- "integrity": "sha512-2++wDf/DYqkPR3o5tbfdhF96EfMApo1GpPfzOsR/ZYXdkSmELlvOOEAl9iKkRsktMPHdGjO4rtkBpf2I7TiTeA==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-4.0.3.tgz",
+ "integrity": "sha512-qsIHFQy0u17JqSY+3ZUT+ykqxYY17yOfvAsLkFkw8kSQqi05d1jyj0bCuSX6sjYlXuY9cKpgUt5EudQdP4aXyA==",
"dev": true,
"requires": {
- "xtend": "4.0.1"
+ "xtend": "~4.0.0"
}
},
"accepts": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
- "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.5.tgz",
+ "integrity": "sha1-63d99gEXI6OxTopywIBcjoZ0a9I=",
+ "dev": true,
"requires": {
- "mime-types": "2.1.17",
+ "mime-types": "~2.1.18",
"negotiator": "0.6.1"
}
},
@@ -60,7 +60,7 @@
"integrity": "sha1-x1K9IQvvZ5UBtsbLf8hPj0cVjMQ=",
"dev": true,
"requires": {
- "acorn": "4.0.13"
+ "acorn": "^4.0.3"
},
"dependencies": {
"acorn": {
@@ -76,7 +76,7 @@
"resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-3.1.0.tgz",
"integrity": "sha1-/YJw9x+7SZawBPqIDuXUZXOnMb8=",
"requires": {
- "acorn": "4.0.13"
+ "acorn": "^4.0.4"
},
"dependencies": {
"acorn": {
@@ -91,45 +91,38 @@
"resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
"integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
"requires": {
- "acorn": "3.2.0"
+ "acorn": "^3.0.4"
}
},
"addr-to-ip-port": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/addr-to-ip-port/-/addr-to-ip-port-1.4.2.tgz",
- "integrity": "sha1-fkb/Hya3qfXjP9g51XrvYwO0xpI="
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/addr-to-ip-port/-/addr-to-ip-port-1.4.3.tgz",
+ "integrity": "sha512-+KHTG8KSAFdKYmLNZp3VnKj94AZ94gDdu2ipAwxNuMmN9vpf5hdsQgk1hNXFqQOXfd+BMHokyDa1GwDAlGAtGQ=="
},
"agent-base": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz",
- "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=",
+ "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": {
- "extend": "3.0.0",
- "semver": "5.0.3"
- },
- "dependencies": {
- "semver": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
- "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no="
- }
+ "es6-promisify": "^5.0.0"
}
},
"ajv": {
- "version": "5.2.3",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.2.3.tgz",
- "integrity": "sha1-wG9Zh3jETGsWGrr+NGa4GtGBTtI=",
+ "version": "5.5.2",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
+ "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
"requires": {
- "co": "4.6.0",
- "fast-deep-equal": "1.0.0",
- "json-schema-traverse": "0.3.1",
- "json-stable-stringify": "1.0.1"
+ "co": "^4.6.0",
+ "fast-deep-equal": "^1.0.0",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.3.0"
}
},
"ajv-keywords": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.0.tgz",
- "integrity": "sha1-opbhf3v658HOT34N5T0pyzIWLfA="
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-2.1.1.tgz",
+ "integrity": "sha1-YXmX/F9gV2iUxDX5QNgZ4TW4B2I="
},
"align-text": {
"version": "0.1.4",
@@ -137,11 +130,28 @@
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
"dev": true,
"requires": {
- "kind-of": "3.2.2",
- "longest": "1.0.1",
- "repeat-string": "1.6.1"
+ "kind-of": "^3.0.2",
+ "longest": "^1.0.1",
+ "repeat-string": "^1.5.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
}
},
+ "alphanum-sort": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz",
+ "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=",
+ "dev": true
+ },
"amdefine": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
@@ -154,7 +164,7 @@
"integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=",
"dev": true,
"requires": {
- "string-width": "2.1.1"
+ "string-width": "^2.0.0"
},
"dependencies": {
"ansi-regex": {
@@ -175,8 +185,8 @@
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
@@ -185,15 +195,24 @@
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
- "ansi-regex": "3.0.0"
+ "ansi-regex": "^3.0.0"
}
}
}
},
"ansi-escapes": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
- "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.1.0.tgz",
+ "integrity": "sha512-UgAb8H9D41AQnu/PbWlCofQVcnV4Gs2bBJi9eZPxfU/hgglFh3SMDMENRIqdr7H6XFnXdoknctFByVsCOotTVw=="
+ },
+ "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"
+ }
},
"ansi-html": {
"version": "0.0.7",
@@ -211,25 +230,20 @@
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
},
- "ansicolors": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/ansicolors/-/ansicolors-0.2.1.tgz",
- "integrity": "sha1-vgiVmQl7dKXJxKhKDNvNtivYeu8=",
+ "ansi-wrap": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-wrap/-/ansi-wrap-0.1.0.tgz",
+ "integrity": "sha1-qCJQ3bABXponyoLoLqYDu/pF768=",
"dev": true
},
- "any-promise": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
- "integrity": "sha1-q8av7tzqUugJzcA3au0845Y10X8="
- },
"anymatch": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-1.3.2.tgz",
- "integrity": "sha512-0XNayC8lTHQ2OI8aljNCN3sSx6hsr/1+rlcDAotXJR7C1oZZHCNsfpbKwMjRA3Uqb5tF1Rae2oloTr4xpq+WjA==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz",
+ "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==",
"dev": true,
"requires": {
- "micromatch": "2.3.11",
- "normalize-path": "2.1.1"
+ "micromatch": "^3.1.4",
+ "normalize-path": "^2.1.1"
}
},
"aphrodite": {
@@ -237,8 +251,8 @@
"resolved": "https://registry.npmjs.org/aphrodite/-/aphrodite-1.1.0.tgz",
"integrity": "sha1-HaNq+5QBrfE0g+Kap8rljuB2dgU=",
"requires": {
- "asap": "2.0.6",
- "inline-style-prefixer": "2.0.5"
+ "asap": "^2.0.3",
+ "inline-style-prefixer": "^2.0.0"
}
},
"append-transform": {
@@ -247,7 +261,7 @@
"integrity": "sha1-126/jKlNJ24keja61EpLdKthGZE=",
"dev": true,
"requires": {
- "default-require-extensions": "1.0.0"
+ "default-require-extensions": "^1.0.0"
}
},
"aproba": {
@@ -261,47 +275,15 @@
"integrity": "sha1-TyGU1tj5nfP1MeaIHxTxXVX6ryI=",
"dev": true,
"requires": {
- "archiver-utils": "1.3.0",
- "async": "2.5.0",
- "buffer-crc32": "0.2.13",
- "glob": "7.1.2",
- "lodash": "4.17.4",
- "readable-stream": "2.3.3",
- "tar-stream": "1.5.4",
- "walkdir": "0.0.11",
- "zip-stream": "1.2.0"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "archiver-utils": "^1.3.0",
+ "async": "^2.0.0",
+ "buffer-crc32": "^0.2.1",
+ "glob": "^7.0.0",
+ "lodash": "^4.8.0",
+ "readable-stream": "^2.0.0",
+ "tar-stream": "^1.5.0",
+ "walkdir": "^0.0.11",
+ "zip-stream": "^1.1.0"
}
},
"archiver-utils": {
@@ -310,44 +292,12 @@
"integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
"dev": true,
"requires": {
- "glob": "7.1.2",
- "graceful-fs": "4.1.11",
- "lazystream": "1.0.0",
- "lodash": "4.17.4",
- "normalize-path": "2.1.1",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "glob": "^7.0.0",
+ "graceful-fs": "^4.1.0",
+ "lazystream": "^1.0.0",
+ "lodash": "^4.8.0",
+ "normalize-path": "^2.0.0",
+ "readable-stream": "^2.0.0"
}
},
"archy": {
@@ -361,63 +311,30 @@
"resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.4.tgz",
"integrity": "sha1-u13KOCu5TwXhUZQ3PRb9O6HKEQ0=",
"requires": {
- "delegates": "1.0.0",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
}
},
"argparse": {
- "version": "0.1.16",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-0.1.16.tgz",
- "integrity": "sha1-z9AeD7uj1srtBJ+9dY1A9lGW9Xw=",
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
"requires": {
- "underscore": "1.7.0",
- "underscore.string": "2.4.0"
+ "sprintf-js": "~1.0.2"
},
"dependencies": {
- "underscore": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.7.0.tgz",
- "integrity": "sha1-a7rwh3UA02vjTsqlhODbn+8DUgk="
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
}
}
},
"arr-diff": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
- "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
- "dev": true,
- "requires": {
- "arr-flatten": "1.1.0"
- }
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
},
"arr-flatten": {
"version": "1.1.0",
@@ -425,6 +342,12 @@
"integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
"dev": true
},
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
"array-differ": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/array-differ/-/array-differ-1.0.0.tgz",
@@ -449,14 +372,25 @@
"dev": true
},
"array-flatten": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
- "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz",
+ "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=",
+ "dev": true
+ },
+ "array-includes": {
+ "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"
+ }
},
"array-slice": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.0.0.tgz",
- "integrity": "sha1-5zA08A3MH0CHYAj9IP6ud71LfC8=",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==",
"dev": true
},
"array-union": {
@@ -464,7 +398,7 @@
"resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
"integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
"requires": {
- "array-uniq": "1.0.3"
+ "array-uniq": "^1.0.1"
}
},
"array-uniq": {
@@ -473,9 +407,9 @@
"integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
},
"array-unique": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
- "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
"dev": true
},
"array.prototype.find": {
@@ -484,8 +418,8 @@
"integrity": "sha1-VWpcU2LAhkgyPdrrnenRS8GGTJA=",
"dev": true,
"requires": {
- "define-properties": "1.1.2",
- "es-abstract": "1.8.2"
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.7.0"
}
},
"arrify": {
@@ -499,17 +433,17 @@
"integrity": "sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY="
},
"asar": {
- "version": "0.13.0",
- "resolved": "https://registry.npmjs.org/asar/-/asar-0.13.0.tgz",
- "integrity": "sha1-3zPdnQG/+EJGTQ2fCVdA1KYq+xQ=",
- "requires": {
- "chromium-pickle-js": "0.2.0",
- "commander": "2.11.0",
- "cuint": "0.2.2",
- "glob": "6.0.4",
- "minimatch": "3.0.4",
- "mkdirp": "0.5.1",
- "mksnapshot": "0.3.1",
+ "version": "0.13.1",
+ "resolved": "https://registry.npmjs.org/asar/-/asar-0.13.1.tgz",
+ "integrity": "sha512-HJnZadTbDVDhBDv3tMyDov3ZnwMYYmz80/+a7S6cFPvulUyRz55UG5hOyHeWSP1iZud6vjFq8GOYM6xxtxJECQ==",
+ "requires": {
+ "chromium-pickle-js": "^0.2.0",
+ "commander": "^2.9.0",
+ "cuint": "^0.2.1",
+ "glob": "^6.0.4",
+ "minimatch": "^3.0.3",
+ "mkdirp": "^0.5.0",
+ "mksnapshot": "^0.3.0",
"tmp": "0.0.28"
},
"dependencies": {
@@ -518,11 +452,19 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
"integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
"requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "tmp": {
+ "version": "0.0.28",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
+ "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
+ "requires": {
+ "os-tmpdir": "~1.0.1"
}
}
}
@@ -533,55 +475,8 @@
"integrity": "sha512-6UDOmyl4RUo8i/0Sem/UKFJ70XZrXLCDQcILTbjTjAKZrSA3JbXVnWRFi2ZFEbeZxQ2LVCc3CWHnDlqj2AyVXg==",
"dev": true,
"requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra-p": "4.5.0"
- },
- "dependencies": {
- "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
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.0.0"
- }
- },
- "jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
- }
+ "bluebird-lst": "^1.0.5",
+ "fs-extra-p": "^4.5.0"
}
},
"asn1": {
@@ -590,20 +485,21 @@
"integrity": "sha1-2sh4dxPJlmhJ/IGAd36+nB3fO4Y="
},
"asn1.js": {
- "version": "4.9.1",
- "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.9.1.tgz",
- "integrity": "sha1-SLokC0WpKA6UdImQull9IWYX/UA=",
+ "version": "4.10.1",
+ "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz",
+ "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==",
"dev": true,
"requires": {
- "bn.js": "4.11.8",
- "inherits": "2.0.3",
- "minimalistic-assert": "1.0.0"
+ "bn.js": "^4.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
}
},
"assert": {
- "version": "0.4.9",
- "resolved": "https://registry.npmjs.org/assert/-/assert-0.4.9.tgz",
- "integrity": "sha1-Rfr/Glj3GFCBGIc96tlAyLUduTk=",
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
+ "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
+ "dev": true,
"requires": {
"util": "0.10.3"
}
@@ -614,22 +510,23 @@
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
},
"assertion-error": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz",
- "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw=",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
"dev": true
},
- "ast-types": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.10.1.tgz",
- "integrity": "sha512-UY7+9DPzlJ9VM8eY0b2TUZcZvF+1pO0hzMtAyjBYKhOmnvRlqYNYnWdtsMj0V16CGaMlpL0G1jnLbLo4AyotuQ=="
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
},
"async": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/async/-/async-2.5.0.tgz",
- "integrity": "sha512-e+lJAJeNWuPCNyxZKOBdaJGyLGHugXVQtrAwtuAe2vhxTYxFTKE73p8JuTmdH0qdQZtDvI4dhJwjZc5zsfIsYw==",
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.1.tgz",
+ "integrity": "sha512-fNEiL2+AZt6AlAw/29Cr0UDe4sRAHCpEHh54WMz+Bb7QfNcFw4h3loofyJpLeQs4Yx7yuqu/2dLgM5hKOs6HlQ==",
"requires": {
- "lodash": "4.17.4"
+ "lodash": "^4.17.10"
}
},
"async-each": {
@@ -655,9 +552,9 @@
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
},
"atob": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/atob/-/atob-1.1.3.tgz",
- "integrity": "sha1-lfE2KbEsOlGl0hWr3OKqnzL4B3M=",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.1.tgz",
+ "integrity": "sha1-ri1acpR38onWDdf5amMUoi3Wwio=",
"dev": true
},
"author-regex": {
@@ -666,16 +563,85 @@
"integrity": "sha1-0IiFvmubv5Q5/gh8dihyRfCoFFA=",
"optional": true
},
+ "autoprefixer": {
+ "version": "6.7.7",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-6.7.7.tgz",
+ "integrity": "sha1-Hb0cg1ZY41zj+ZhAmdsAWFx4IBQ=",
+ "dev": true,
+ "requires": {
+ "browserslist": "^1.7.6",
+ "caniuse-db": "^1.0.30000634",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "postcss": "^5.2.16",
+ "postcss-value-parser": "^3.2.3"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "^1.0.30000639",
+ "electron-to-chromium": "^1.2.7"
+ }
+ }
+ }
+ },
"autoprefixer-core": {
"version": "5.2.1",
"resolved": "https://registry.npmjs.org/autoprefixer-core/-/autoprefixer-core-5.2.1.tgz",
"integrity": "sha1-5kDEFK5Bmq4hwa1DyOoPPbgqVm0=",
"dev": true,
"requires": {
- "browserslist": "0.4.0",
- "caniuse-db": "1.0.30000738",
- "num2fraction": "1.2.2",
- "postcss": "4.1.16"
+ "browserslist": "~0.4.0",
+ "caniuse-db": "^1.0.30000214",
+ "num2fraction": "^1.1.0",
+ "postcss": "~4.1.12"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-0.4.0.tgz",
+ "integrity": "sha1-O9SrkZncG5FQ1NbbpNnTqrvIbdQ=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "^1.0.30000153"
+ }
+ },
+ "es6-promise": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
+ "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
+ "dev": true
+ },
+ "js-base64": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
+ "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-4.1.16.tgz",
+ "integrity": "sha1-TESbTIr53zyvbTf44eV10DYXWNw=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "~2.3.0",
+ "js-base64": "~2.1.8",
+ "source-map": "~0.4.2"
+ }
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ }
}
},
"aws-sign2": {
@@ -684,9 +650,9 @@
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
},
"aws4": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.6.0.tgz",
- "integrity": "sha1-g+9cqGCysy5KDe7e6MdxudtXRx4="
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.7.0.tgz",
+ "integrity": "sha512-32NDda82rhwD9/JBCCkB+MRYDp0oSvlo2IL6rQWA10PQi7tDUM3eqMSltXmY+Oyl/7N3P3qNtAlv7X0d9bI28w=="
},
"babel": {
"version": "6.23.0",
@@ -699,35 +665,56 @@
"resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
"requires": {
- "chalk": "1.1.3",
- "esutils": "2.0.2",
- "js-tokens": "3.0.2"
+ "chalk": "^1.1.3",
+ "esutils": "^2.0.2",
+ "js-tokens": "^3.0.2"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ }
}
},
"babel-core": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.0.tgz",
- "integrity": "sha1-rzL3izGm/O8RnIew/Y2XU/A6C7g=",
- "requires": {
- "babel-code-frame": "6.26.0",
- "babel-generator": "6.26.0",
- "babel-helpers": "6.24.1",
- "babel-messages": "6.23.0",
- "babel-register": "6.26.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0",
- "convert-source-map": "1.5.0",
- "debug": "2.6.9",
- "json5": "0.5.1",
- "lodash": "4.17.4",
- "minimatch": "3.0.4",
- "path-is-absolute": "1.0.1",
- "private": "0.1.7",
- "slash": "1.0.0",
- "source-map": "0.5.7"
+ "version": "6.26.3",
+ "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz",
+ "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==",
+ "requires": {
+ "babel-code-frame": "^6.26.0",
+ "babel-generator": "^6.26.0",
+ "babel-helpers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-register": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "convert-source-map": "^1.5.1",
+ "debug": "^2.6.9",
+ "json5": "^0.5.1",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.4",
+ "path-is-absolute": "^1.0.1",
+ "private": "^0.1.8",
+ "slash": "^1.0.0",
+ "source-map": "^0.5.7"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
}
},
"babel-eslint": {
@@ -736,25 +723,32 @@
"integrity": "sha1-B5Qi63O6gR48oIZc6Hrykyf4xS8=",
"dev": true,
"requires": {
- "babel-code-frame": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0"
+ "babel-code-frame": "^6.22.0",
+ "babel-traverse": "^6.23.1",
+ "babel-types": "^6.23.0",
+ "babylon": "^6.16.1"
}
},
"babel-generator": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.0.tgz",
- "integrity": "sha1-rBriAHC3n248odMmlhMFN3TyDcU=",
- "requires": {
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "detect-indent": "4.0.0",
- "jsesc": "1.3.0",
- "lodash": "4.17.4",
- "source-map": "0.5.7",
- "trim-right": "1.0.1"
+ "version": "6.26.1",
+ "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz",
+ "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==",
+ "requires": {
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "detect-indent": "^4.0.0",
+ "jsesc": "^1.3.0",
+ "lodash": "^4.17.4",
+ "source-map": "^0.5.7",
+ "trim-right": "^1.0.1"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
}
},
"babel-helper-builder-binary-assignment-operator-visitor": {
@@ -763,9 +757,9 @@
"integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=",
"dev": true,
"requires": {
- "babel-helper-explode-assignable-expression": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-explode-assignable-expression": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-builder-react-jsx": {
@@ -774,9 +768,9 @@
"integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "esutils": "2.0.2"
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "esutils": "^2.0.2"
}
},
"babel-helper-call-delegate": {
@@ -785,10 +779,10 @@
"integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=",
"dev": true,
"requires": {
- "babel-helper-hoist-variables": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-define-map": {
@@ -797,10 +791,10 @@
"integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=",
"dev": true,
"requires": {
- "babel-helper-function-name": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "lodash": "4.17.4"
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
}
},
"babel-helper-explode-assignable-expression": {
@@ -809,9 +803,9 @@
"integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-function-name": {
@@ -820,11 +814,11 @@
"integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=",
"dev": true,
"requires": {
- "babel-helper-get-function-arity": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-get-function-arity": {
@@ -833,8 +827,8 @@
"integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-hoist-variables": {
@@ -843,8 +837,8 @@
"integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-optimise-call-expression": {
@@ -853,8 +847,8 @@
"integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-regex": {
@@ -863,9 +857,9 @@
"integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "lodash": "4.17.4"
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
}
},
"babel-helper-remap-async-to-generator": {
@@ -874,11 +868,11 @@
"integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=",
"dev": true,
"requires": {
- "babel-helper-function-name": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
}
},
"babel-helper-replace-supers": {
@@ -887,12 +881,12 @@
"integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=",
"dev": true,
"requires": {
- "babel-helper-optimise-call-expression": "6.24.1",
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
}
},
"babel-helpers": {
@@ -900,18 +894,18 @@
"resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz",
"integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=",
"requires": {
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
}
},
"babel-loader": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.2.tgz",
- "integrity": "sha512-jRwlFbINAeyDStqK6Dd5YuY0k5YuzQUvlz2ZamuXrXmxav3pNqe9vfJ402+2G+OmlJSXxCOpB6Uz0INM7RQe2A==",
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.4.tgz",
+ "integrity": "sha512-/hbyEvPzBJuGpk9o80R0ZyTej6heEOr59GoEUtn8qFKbnx4cJm9FWES6J/iv644sYgrtVw9JJQkjaLW/bqb5gw==",
"requires": {
- "find-cache-dir": "1.0.0",
- "loader-utils": "1.1.0",
- "mkdirp": "0.5.1"
+ "find-cache-dir": "^1.0.0",
+ "loader-utils": "^1.0.2",
+ "mkdirp": "^0.5.1"
}
},
"babel-messages": {
@@ -919,7 +913,7 @@
"resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz",
"integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=",
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-check-es2015-constants": {
@@ -928,7 +922,7 @@
"integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-syntax-async-functions": {
@@ -979,9 +973,9 @@
"integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=",
"dev": true,
"requires": {
- "babel-helper-remap-async-to-generator": "6.24.1",
- "babel-plugin-syntax-async-functions": "6.13.0",
- "babel-runtime": "6.26.0"
+ "babel-helper-remap-async-to-generator": "^6.24.1",
+ "babel-plugin-syntax-async-functions": "^6.8.0",
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-class-properties": {
@@ -990,10 +984,10 @@
"integrity": "sha1-anl2PqYdM9NvN7YRqp3vgagbRqw=",
"dev": true,
"requires": {
- "babel-helper-function-name": "6.24.1",
- "babel-plugin-syntax-class-properties": "6.13.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
+ "babel-helper-function-name": "^6.24.1",
+ "babel-plugin-syntax-class-properties": "^6.8.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
}
},
"babel-plugin-transform-es2015-arrow-functions": {
@@ -1002,7 +996,7 @@
"integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-block-scoped-functions": {
@@ -1011,7 +1005,7 @@
"integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-block-scoping": {
@@ -1020,11 +1014,11 @@
"integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "lodash": "4.17.4"
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "lodash": "^4.17.4"
}
},
"babel-plugin-transform-es2015-classes": {
@@ -1033,15 +1027,15 @@
"integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=",
"dev": true,
"requires": {
- "babel-helper-define-map": "6.26.0",
- "babel-helper-function-name": "6.24.1",
- "babel-helper-optimise-call-expression": "6.24.1",
- "babel-helper-replace-supers": "6.24.1",
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-define-map": "^6.24.1",
+ "babel-helper-function-name": "^6.24.1",
+ "babel-helper-optimise-call-expression": "^6.24.1",
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
}
},
"babel-plugin-transform-es2015-computed-properties": {
@@ -1050,8 +1044,8 @@
"integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
}
},
"babel-plugin-transform-es2015-destructuring": {
@@ -1060,7 +1054,7 @@
"integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-duplicate-keys": {
@@ -1069,8 +1063,8 @@
"integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-plugin-transform-es2015-for-of": {
@@ -1079,7 +1073,7 @@
"integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-function-name": {
@@ -1088,9 +1082,9 @@
"integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=",
"dev": true,
"requires": {
- "babel-helper-function-name": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-function-name": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-plugin-transform-es2015-literals": {
@@ -1099,7 +1093,7 @@
"integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-modules-amd": {
@@ -1108,21 +1102,21 @@
"integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=",
"dev": true,
"requires": {
- "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
}
},
"babel-plugin-transform-es2015-modules-commonjs": {
- "version": "6.26.0",
- "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.0.tgz",
- "integrity": "sha1-DYOUApt9xqvhqX7xgeAHWN0uXYo=",
+ "version": "6.26.2",
+ "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz",
+ "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==",
"dev": true,
"requires": {
- "babel-plugin-transform-strict-mode": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-plugin-transform-strict-mode": "^6.24.1",
+ "babel-runtime": "^6.26.0",
+ "babel-template": "^6.26.0",
+ "babel-types": "^6.26.0"
}
},
"babel-plugin-transform-es2015-modules-systemjs": {
@@ -1131,9 +1125,9 @@
"integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=",
"dev": true,
"requires": {
- "babel-helper-hoist-variables": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
+ "babel-helper-hoist-variables": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
}
},
"babel-plugin-transform-es2015-modules-umd": {
@@ -1142,9 +1136,9 @@
"integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=",
"dev": true,
"requires": {
- "babel-plugin-transform-es2015-modules-amd": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0"
+ "babel-plugin-transform-es2015-modules-amd": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1"
}
},
"babel-plugin-transform-es2015-object-super": {
@@ -1153,8 +1147,8 @@
"integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=",
"dev": true,
"requires": {
- "babel-helper-replace-supers": "6.24.1",
- "babel-runtime": "6.26.0"
+ "babel-helper-replace-supers": "^6.24.1",
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-parameters": {
@@ -1163,12 +1157,12 @@
"integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=",
"dev": true,
"requires": {
- "babel-helper-call-delegate": "6.24.1",
- "babel-helper-get-function-arity": "6.24.1",
- "babel-runtime": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-call-delegate": "^6.24.1",
+ "babel-helper-get-function-arity": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-template": "^6.24.1",
+ "babel-traverse": "^6.24.1",
+ "babel-types": "^6.24.1"
}
},
"babel-plugin-transform-es2015-shorthand-properties": {
@@ -1177,8 +1171,8 @@
"integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-plugin-transform-es2015-spread": {
@@ -1187,7 +1181,7 @@
"integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-sticky-regex": {
@@ -1196,9 +1190,9 @@
"integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=",
"dev": true,
"requires": {
- "babel-helper-regex": "6.26.0",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-plugin-transform-es2015-template-literals": {
@@ -1207,7 +1201,7 @@
"integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-typeof-symbol": {
@@ -1216,7 +1210,7 @@
"integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-es2015-unicode-regex": {
@@ -1225,9 +1219,9 @@
"integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=",
"dev": true,
"requires": {
- "babel-helper-regex": "6.26.0",
- "babel-runtime": "6.26.0",
- "regexpu-core": "2.0.0"
+ "babel-helper-regex": "^6.24.1",
+ "babel-runtime": "^6.22.0",
+ "regexpu-core": "^2.0.0"
}
},
"babel-plugin-transform-exponentiation-operator": {
@@ -1236,9 +1230,9 @@
"integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=",
"dev": true,
"requires": {
- "babel-helper-builder-binary-assignment-operator-visitor": "6.24.1",
- "babel-plugin-syntax-exponentiation-operator": "6.13.0",
- "babel-runtime": "6.26.0"
+ "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1",
+ "babel-plugin-syntax-exponentiation-operator": "^6.8.0",
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-flow-strip-types": {
@@ -1247,8 +1241,8 @@
"integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=",
"dev": true,
"requires": {
- "babel-plugin-syntax-flow": "6.18.0",
- "babel-runtime": "6.26.0"
+ "babel-plugin-syntax-flow": "^6.18.0",
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-react-constant-elements": {
@@ -1257,7 +1251,7 @@
"integrity": "sha1-LxGb9NLN1F65uqrldAU8YE9hR90=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-react-display-name": {
@@ -1266,7 +1260,7 @@
"integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-react-inline-elements": {
@@ -1275,7 +1269,7 @@
"integrity": "sha1-ZochGjK0mlLyLFc6K1UEol7xfFM=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0"
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-react-jsx": {
@@ -1284,9 +1278,9 @@
"integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=",
"dev": true,
"requires": {
- "babel-helper-builder-react-jsx": "6.26.0",
- "babel-plugin-syntax-jsx": "6.18.0",
- "babel-runtime": "6.26.0"
+ "babel-helper-builder-react-jsx": "^6.24.1",
+ "babel-plugin-syntax-jsx": "^6.8.0",
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-react-jsx-self": {
@@ -1295,8 +1289,8 @@
"integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=",
"dev": true,
"requires": {
- "babel-plugin-syntax-jsx": "6.18.0",
- "babel-runtime": "6.26.0"
+ "babel-plugin-syntax-jsx": "^6.8.0",
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-react-jsx-source": {
@@ -1305,8 +1299,8 @@
"integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=",
"dev": true,
"requires": {
- "babel-plugin-syntax-jsx": "6.18.0",
- "babel-runtime": "6.26.0"
+ "babel-plugin-syntax-jsx": "^6.8.0",
+ "babel-runtime": "^6.22.0"
}
},
"babel-plugin-transform-regenerator": {
@@ -1315,7 +1309,7 @@
"integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=",
"dev": true,
"requires": {
- "regenerator-transform": "0.10.1"
+ "regenerator-transform": "^0.10.0"
}
},
"babel-plugin-transform-strict-mode": {
@@ -1324,8 +1318,8 @@
"integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0"
+ "babel-runtime": "^6.22.0",
+ "babel-types": "^6.24.1"
}
},
"babel-polyfill": {
@@ -1334,9 +1328,9 @@
"integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "core-js": "2.5.1",
- "regenerator-runtime": "0.10.5"
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "regenerator-runtime": "^0.10.5"
},
"dependencies": {
"regenerator-runtime": {
@@ -1348,53 +1342,41 @@
}
},
"babel-preset-env": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.6.0.tgz",
- "integrity": "sha512-OVgtQRuOZKckrILgMA5rvctvFZPv72Gua9Rt006AiPoB0DJKGN07UmaQA+qRrYgK71MVct8fFhT0EyNWYorVew==",
- "dev": true,
- "requires": {
- "babel-plugin-check-es2015-constants": "6.22.0",
- "babel-plugin-syntax-trailing-function-commas": "6.22.0",
- "babel-plugin-transform-async-to-generator": "6.24.1",
- "babel-plugin-transform-es2015-arrow-functions": "6.22.0",
- "babel-plugin-transform-es2015-block-scoped-functions": "6.22.0",
- "babel-plugin-transform-es2015-block-scoping": "6.26.0",
- "babel-plugin-transform-es2015-classes": "6.24.1",
- "babel-plugin-transform-es2015-computed-properties": "6.24.1",
- "babel-plugin-transform-es2015-destructuring": "6.23.0",
- "babel-plugin-transform-es2015-duplicate-keys": "6.24.1",
- "babel-plugin-transform-es2015-for-of": "6.23.0",
- "babel-plugin-transform-es2015-function-name": "6.24.1",
- "babel-plugin-transform-es2015-literals": "6.22.0",
- "babel-plugin-transform-es2015-modules-amd": "6.24.1",
- "babel-plugin-transform-es2015-modules-commonjs": "6.26.0",
- "babel-plugin-transform-es2015-modules-systemjs": "6.24.1",
- "babel-plugin-transform-es2015-modules-umd": "6.24.1",
- "babel-plugin-transform-es2015-object-super": "6.24.1",
- "babel-plugin-transform-es2015-parameters": "6.24.1",
- "babel-plugin-transform-es2015-shorthand-properties": "6.24.1",
- "babel-plugin-transform-es2015-spread": "6.22.0",
- "babel-plugin-transform-es2015-sticky-regex": "6.24.1",
- "babel-plugin-transform-es2015-template-literals": "6.22.0",
- "babel-plugin-transform-es2015-typeof-symbol": "6.23.0",
- "babel-plugin-transform-es2015-unicode-regex": "6.24.1",
- "babel-plugin-transform-exponentiation-operator": "6.24.1",
- "babel-plugin-transform-regenerator": "6.26.0",
- "browserslist": "2.4.0",
- "invariant": "2.2.2",
- "semver": "5.4.1"
- },
- "dependencies": {
- "browserslist": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-2.4.0.tgz",
- "integrity": "sha512-aM2Gt4x9bVlCUteADBS6JP0F+2tMWKM1jQzUulVROtdFWFIcIVvY76AJbr7GDqy0eDhn+PcnpzzivGxY4qiaKQ==",
- "dev": true,
- "requires": {
- "caniuse-lite": "1.0.30000738",
- "electron-to-chromium": "1.3.22"
- }
- }
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz",
+ "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==",
+ "dev": true,
+ "requires": {
+ "babel-plugin-check-es2015-constants": "^6.22.0",
+ "babel-plugin-syntax-trailing-function-commas": "^6.22.0",
+ "babel-plugin-transform-async-to-generator": "^6.22.0",
+ "babel-plugin-transform-es2015-arrow-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0",
+ "babel-plugin-transform-es2015-block-scoping": "^6.23.0",
+ "babel-plugin-transform-es2015-classes": "^6.23.0",
+ "babel-plugin-transform-es2015-computed-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-destructuring": "^6.23.0",
+ "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0",
+ "babel-plugin-transform-es2015-for-of": "^6.23.0",
+ "babel-plugin-transform-es2015-function-name": "^6.22.0",
+ "babel-plugin-transform-es2015-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-amd": "^6.22.0",
+ "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0",
+ "babel-plugin-transform-es2015-modules-umd": "^6.23.0",
+ "babel-plugin-transform-es2015-object-super": "^6.22.0",
+ "babel-plugin-transform-es2015-parameters": "^6.23.0",
+ "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0",
+ "babel-plugin-transform-es2015-spread": "^6.22.0",
+ "babel-plugin-transform-es2015-sticky-regex": "^6.22.0",
+ "babel-plugin-transform-es2015-template-literals": "^6.22.0",
+ "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0",
+ "babel-plugin-transform-es2015-unicode-regex": "^6.22.0",
+ "babel-plugin-transform-exponentiation-operator": "^6.22.0",
+ "babel-plugin-transform-regenerator": "^6.22.0",
+ "browserslist": "^3.2.6",
+ "invariant": "^2.2.2",
+ "semver": "^5.3.0"
}
},
"babel-preset-flow": {
@@ -1403,7 +1385,7 @@
"integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=",
"dev": true,
"requires": {
- "babel-plugin-transform-flow-strip-types": "6.22.0"
+ "babel-plugin-transform-flow-strip-types": "^6.22.0"
}
},
"babel-preset-react": {
@@ -1412,12 +1394,12 @@
"integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=",
"dev": true,
"requires": {
- "babel-plugin-syntax-jsx": "6.18.0",
- "babel-plugin-transform-react-display-name": "6.25.0",
- "babel-plugin-transform-react-jsx": "6.24.1",
- "babel-plugin-transform-react-jsx-self": "6.22.0",
- "babel-plugin-transform-react-jsx-source": "6.22.0",
- "babel-preset-flow": "6.23.0"
+ "babel-plugin-syntax-jsx": "^6.3.13",
+ "babel-plugin-transform-react-display-name": "^6.23.0",
+ "babel-plugin-transform-react-jsx": "^6.24.1",
+ "babel-plugin-transform-react-jsx-self": "^6.22.0",
+ "babel-plugin-transform-react-jsx-source": "^6.22.0",
+ "babel-preset-flow": "^6.23.0"
}
},
"babel-register": {
@@ -1425,13 +1407,13 @@
"resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz",
"integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=",
"requires": {
- "babel-core": "6.26.0",
- "babel-runtime": "6.26.0",
- "core-js": "2.5.1",
- "home-or-tmp": "2.0.0",
- "lodash": "4.17.4",
- "mkdirp": "0.5.1",
- "source-map-support": "0.4.18"
+ "babel-core": "^6.26.0",
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "home-or-tmp": "^2.0.0",
+ "lodash": "^4.17.4",
+ "mkdirp": "^0.5.1",
+ "source-map-support": "^0.4.15"
}
},
"babel-runtime": {
@@ -1439,8 +1421,8 @@
"resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
"integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
"requires": {
- "core-js": "2.5.1",
- "regenerator-runtime": "0.11.0"
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
}
},
"babel-template": {
@@ -1448,11 +1430,11 @@
"resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz",
"integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=",
"requires": {
- "babel-runtime": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0",
- "lodash": "4.17.4"
+ "babel-runtime": "^6.26.0",
+ "babel-traverse": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "lodash": "^4.17.4"
}
},
"babel-traverse": {
@@ -1460,15 +1442,22 @@
"resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz",
"integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=",
"requires": {
- "babel-code-frame": "6.26.0",
- "babel-messages": "6.23.0",
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0",
- "debug": "2.6.9",
- "globals": "9.18.0",
- "invariant": "2.2.2",
- "lodash": "4.17.4"
+ "babel-code-frame": "^6.26.0",
+ "babel-messages": "^6.23.0",
+ "babel-runtime": "^6.26.0",
+ "babel-types": "^6.26.0",
+ "babylon": "^6.18.0",
+ "debug": "^2.6.8",
+ "globals": "^9.18.0",
+ "invariant": "^2.2.2",
+ "lodash": "^4.17.4"
+ },
+ "dependencies": {
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
+ }
}
},
"babel-types": {
@@ -1476,10 +1465,10 @@
"resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz",
"integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=",
"requires": {
- "babel-runtime": "6.26.0",
- "esutils": "2.0.2",
- "lodash": "4.17.4",
- "to-fast-properties": "1.0.3"
+ "babel-runtime": "^6.26.0",
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.4",
+ "to-fast-properties": "^1.0.3"
}
},
"babylon": {
@@ -1492,96 +1481,132 @@
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
},
- "base-x": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/base-x/-/base-x-3.0.2.tgz",
- "integrity": "sha1-v4c4YbdRQnm3lp80CSnquHwR0TA=",
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
}
},
"base64-js": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.1.tgz",
- "integrity": "sha512-dwVUVIXsBZXwTuwnXI9RK8sBmgq09NDHzyR9SAph9eqk76gKK2JSQmZARC2zRC81JC2QTtxD0ARU5qTS25gIGw==",
+ "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
},
- "basic-auth": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.0.tgz",
- "integrity": "sha1-AV2z81PgLlY3d1X5YnQuiYHnu7o=",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"bat-balance": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/bat-balance/-/bat-balance-1.0.4.tgz",
- "integrity": "sha512-f1zFTfSB4wz0zGOJeVInYEPCWqhH6fMjla78N3AMsoAGnNAcbFq/C97Es0NJte6nJEz0lDycmPwn2KgiQl6WUw==",
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/bat-balance/-/bat-balance-1.0.7.tgz",
+ "integrity": "sha512-ezbo6BbHpeCj9Hw/qh7q8Z05bUBt48Ii70Jr/3vrOOEOvCDxBTpXHvQVVeISRtGWgorb7oyJOLa5C3HuFJOZHw==",
"requires": {
"@ambassify/backoff-strategies": "1.0.0",
"data-expression": "1.0.0",
- "joi": "11.4.0",
+ "joi": "^13.1.2",
"underscore": "1.8.3"
},
"dependencies": {
"joi": {
- "version": "11.4.0",
- "resolved": "https://registry.npmjs.org/joi/-/joi-11.4.0.tgz",
- "integrity": "sha512-O7Uw+w/zEWgbL6OcHbyACKSj0PkQeUgmehdoXVSxt92QFCq4+1390Rwh5moI2K/OgC7D8RHRZqHZxT2husMJHA==",
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-13.3.0.tgz",
+ "integrity": "sha512-iF6jEYVfBIoYXztYymia1JfuoVbxBNuOcwdbsdoGin9/jjhBLhonKmfTQOvePss8r8v4tU4JOcNmYPHZzKEFag==",
"requires": {
- "hoek": "4.2.0",
- "isemail": "3.0.0",
- "topo": "2.0.2"
+ "hoek": "5.x.x",
+ "isemail": "3.x.x",
+ "topo": "3.x.x"
}
}
}
},
"bat-client": {
- "version": "2.0.7",
- "resolved": "https://registry.npmjs.org/bat-client/-/bat-client-2.0.7.tgz",
- "integrity": "sha512-qfpjXsdrUeYkIt/jYgc98ks2/hpOY6/XG90vhdL1KdBqPIFFPz0RnuhgmSPV+iBeD58U7DAYKWgrdQm36uF9yA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/bat-client/-/bat-client-3.0.0.tgz",
+ "integrity": "sha512-SbMpO/5/hJvS38s2uMWltQkBnUI+viR0o3D8zl5U5RH3xRFQOJU6fE008KMHeX/olgsjzwQxy0QntrFBv5qL+g==",
"requires": {
"@ambassify/backoff-strategies": "1.0.0",
- "bat-balance": "1.0.4",
- "bat-publisher": "2.0.3",
- "bitgo": "4.15.0",
- "brave-crypto": "0.0.1",
+ "bat-balance": "^1.0.7",
+ "bat-publisher": "^2.0.16",
+ "brave-crypto": "^0.1.0",
"http-request-signature": "0.0.2",
- "joi": "11.4.0",
+ "joi": "^13.1.2",
"json-stable-stringify": "1.0.1",
- "niceware": "1.0.4",
- "node-anonize2-relic-emscripten": "0.3.3",
+ "node-anonize2-relic-emscripten": "^0.3.3",
"random-lib": "2.1.0",
"underscore": "1.8.3",
"uuid": "3.1.0"
},
"dependencies": {
"joi": {
- "version": "11.4.0",
- "resolved": "https://registry.npmjs.org/joi/-/joi-11.4.0.tgz",
- "integrity": "sha512-O7Uw+w/zEWgbL6OcHbyACKSj0PkQeUgmehdoXVSxt92QFCq4+1390Rwh5moI2K/OgC7D8RHRZqHZxT2husMJHA==",
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-13.3.0.tgz",
+ "integrity": "sha512-iF6jEYVfBIoYXztYymia1JfuoVbxBNuOcwdbsdoGin9/jjhBLhonKmfTQOvePss8r8v4tU4JOcNmYPHZzKEFag==",
"requires": {
- "hoek": "4.2.0",
- "isemail": "3.0.0",
- "topo": "2.0.2"
+ "hoek": "5.x.x",
+ "isemail": "3.x.x",
+ "topo": "3.x.x"
}
}
}
},
"bat-publisher": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/bat-publisher/-/bat-publisher-2.0.3.tgz",
- "integrity": "sha512-Iu+AZ2yackBHPhxRPhJYfMlwL/YhSq5zaaNjaLM8tqDe1KhFZnA1nkXeW+N7MaodVd4KQcHWWqPFkMUgD7BzAg==",
+ "version": "2.0.16",
+ "resolved": "https://registry.npmjs.org/bat-publisher/-/bat-publisher-2.0.16.tgz",
+ "integrity": "sha512-PzGSL0GqVM8I50NGDNUlkSQk1L1//reBK72uL5vxp7EZsSQHwlvkMP/wANLX8qyNNCLomWg1FCb4jQTf/3bW9w==",
"requires": {
"@ambassify/backoff-strategies": "1.0.0",
- "async": "2.5.0",
+ "async": "^2.5.0",
"data-expression": "1.0.0",
- "glob": "7.1.2",
+ "glob": "^7.1.2",
"jimp": "0.2.28",
- "joi": "11.4.0",
+ "joi": "^13.1.2",
"jsdom": "11.2.0",
- "metascraper": "1.0.7",
"node-cache": "4.1.1",
"parse-cache-control": "1.0.1",
"random-lib": "2.1.0",
@@ -1591,13 +1616,13 @@
},
"dependencies": {
"joi": {
- "version": "11.4.0",
- "resolved": "https://registry.npmjs.org/joi/-/joi-11.4.0.tgz",
- "integrity": "sha512-O7Uw+w/zEWgbL6OcHbyACKSj0PkQeUgmehdoXVSxt92QFCq4+1390Rwh5moI2K/OgC7D8RHRZqHZxT2husMJHA==",
+ "version": "13.3.0",
+ "resolved": "https://registry.npmjs.org/joi/-/joi-13.3.0.tgz",
+ "integrity": "sha512-iF6jEYVfBIoYXztYymia1JfuoVbxBNuOcwdbsdoGin9/jjhBLhonKmfTQOvePss8r8v4tU4JOcNmYPHZzKEFag==",
"requires": {
- "hoek": "4.2.0",
- "isemail": "3.0.0",
- "topo": "2.0.2"
+ "hoek": "5.x.x",
+ "isemail": "3.x.x",
+ "topo": "3.x.x"
}
},
"punycode": {
@@ -1610,16 +1635,7 @@
"resolved": "https://registry.npmjs.org/tldjs/-/tldjs-2.2.0.tgz",
"integrity": "sha512-5b5t+HKprfccAFRAsH/fzDR4O+UgO6vStvbaJo10jvMcUavlwxR3Jrn2WmXfjG3k22T7b4pqqfput38nr1RpJQ==",
"requires": {
- "punycode": "1.4.1"
- }
- },
- "underscore.string": {
- "version": "3.3.4",
- "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz",
- "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=",
- "requires": {
- "sprintf-js": "1.1.1",
- "util-deprecate": "1.0.2"
+ "punycode": "^1.4.1"
}
}
}
@@ -1636,14 +1652,9 @@
"integrity": "sha1-Y7xdy2EzG5K8Bf1SiVPDNGKgb40=",
"optional": true,
"requires": {
- "tweetnacl": "0.14.5"
+ "tweetnacl": "^0.14.3"
}
},
- "bech32": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/bech32/-/bech32-0.0.3.tgz",
- "integrity": "sha512-O+K1w8P/aAOLcYwwQ4sbiPYZ51ZIW95lnS4/6nE8Aib/z+OOddQIIPdu2qi94qGDp4HhYy/wJotttXKkak1lXg=="
- },
"beeper": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/beeper/-/beeper-1.1.1.tgz",
@@ -1651,11 +1662,11 @@
"dev": true
},
"bencode": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/bencode/-/bencode-1.0.0.tgz",
- "integrity": "sha512-N+VOSP5MkoX+xgnp6Y056iCY5TmCZg9rgPNPQe0bIiXchxYFP4vs/Tf0dTdQ+qQhP7HM2gvfFq+sUVjQsGy5Zw==",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/bencode/-/bencode-2.0.0.tgz",
+ "integrity": "sha512-wr2HwwrUpfB5c68zmAudOltC7rZ1G0+lQOcnuEcfIM3AWAVnB3rHI3nlgd/2CWTfQ3w3zagKt89zni/M+VLZ8g==",
"requires": {
- "safe-buffer": "5.1.1"
+ "safe-buffer": "^5.1.1"
}
},
"big.js": {
@@ -1663,528 +1674,178 @@
"resolved": "https://registry.npmjs.org/big.js/-/big.js-3.2.0.tgz",
"integrity": "sha512-+hN/Zh2D08Mx65pZ/4g5bsmNiZUuChDiQfTUQ7qJr4/kuopCr88xZsAXv6mBoZEsUI4OuGHlX59qE94K2mMW8Q=="
},
- "bigi": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.0.tgz",
- "integrity": "sha1-kKwa6sClMSFkY721j0LB4FyEB6w="
- },
"bignumber.js": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.0.4.tgz",
- "integrity": "sha512-LDXpJKVzEx2/OqNbG9mXBNvHuiRL4PzHCGfnANHMJ+fv68Ads3exDVJeGDJws+AoNEuca93bU3q+S0woeUaCdg=="
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
+ "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA=="
},
"binary": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz",
"integrity": "sha1-n2BVO8XOjDOG87VTz/R0Yq3sqnk=",
"requires": {
- "buffers": "0.1.1",
- "chainsaw": "0.1.0"
+ "buffers": "~0.1.1",
+ "chainsaw": "~0.1.0"
}
},
"binary-extensions": {
- "version": "1.10.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.10.0.tgz",
- "integrity": "sha1-muuabF6IY4qtFx4Wf1kAq+JINdA=",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.11.0.tgz",
+ "integrity": "sha1-RqoXUftqL5PuXmibsQh9SxTGwgU=",
"dev": true
},
"binary-search": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/binary-search/-/binary-search-1.3.2.tgz",
- "integrity": "sha1-iMm3vStyIdNS2njsiH9a8lSeTeI="
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/binary-search/-/binary-search-1.3.3.tgz",
+ "integrity": "sha512-T/jKp3vw1JI+6KQgsyT5R6CcRhMtxlHojeKrA5gX5WG50BQaoujRfoJJKMkuokNuZ0w2S+1wHufEWzw6Qhj30Q=="
},
"bindings": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/bindings/-/bindings-1.3.0.tgz",
"integrity": "sha512-DpLh5EzMR2kzvX1KIlVC0VkC3iZtHKTgdtZ0a3pglBZdaQFjt5S9g9xd1lE+YvXyfd6mtCeRnrUfOLYiTMlNSw=="
},
- "bip66": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/bip66/-/bip66-1.1.5.tgz",
- "integrity": "sha1-AfqHSHhcpwlV1QESF9GzE5lpyiI=",
+ "bip39": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/bip39/-/bip39-2.5.0.tgz",
+ "integrity": "sha512-xwIx/8JKoT2+IPJpFEfXoWdYwP7UVAoUxxLNfGCfVowaJE7yg1Y5B1BVPqlUNsBq5/nGwmFkwRJ8xDW4sX8OdA==",
"requires": {
- "safe-buffer": "5.1.1"
+ "create-hash": "^1.1.0",
+ "pbkdf2": "^3.0.9",
+ "randombytes": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "unorm": "^1.3.3"
}
},
- "bitcoin-ops": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.4.0.tgz",
- "integrity": "sha512-hSbFP1t/hRCdTWXoSUarhwySo8g1UqIjopXNaJAf+Gi6rTzWmPEKG1khXbNIPeHLskonR1Lq09KPyu37l+7zGQ=="
- },
- "bitcoinjs-message": {
+ "bitfield": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/bitcoinjs-message/-/bitcoinjs-message-2.0.0.tgz",
- "integrity": "sha512-H5pJC7/eSqVjREiEOZ4jifX+7zXYP3Y28GIOIqg9hrgE7Vj8Eva9+HnVqnxwA1rJPOwZKuw0vo6k0UxgVc6q1A==",
- "requires": {
- "bs58check": "2.1.0",
- "buffer-equals": "1.0.4",
- "create-hash": "1.1.3",
- "secp256k1": "3.2.5",
- "varuint-bitcoin": "1.0.4"
- },
- "dependencies": {
- "bs58": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
- "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
- "requires": {
- "base-x": "3.0.2"
- }
- },
- "bs58check": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.0.tgz",
- "integrity": "sha512-FWT30tP+89OiXjWLHlAElxdPrbYo05T8XSmgKhh2GHq1JCBFUG0fujt5n7dadkEL3l4DFdfEi5KG5RcXW7UDEA==",
- "requires": {
- "bs58": "4.0.1",
- "create-hash": "1.1.3"
- }
- }
- }
+ "resolved": "https://registry.npmjs.org/bitfield/-/bitfield-2.0.0.tgz",
+ "integrity": "sha512-4xM4DYejOHQ/qWBfeqBXNA4mJ12PwcOibFYnH1kYh5U9BHciCqEJBqGNVnMJXUhm8mflujNRLSv7IiVQxovgjw=="
},
- "bitfield": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/bitfield/-/bitfield-1.1.2.tgz",
- "integrity": "sha1-pUd/AOM/Knbtwgmq8mvwk5SjeM8="
- },
- "bitgo": {
- "version": "4.15.0",
- "resolved": "https://registry.npmjs.org/bitgo/-/bitgo-4.15.0.tgz",
- "integrity": "sha512-3jd2FxpcciMNbetX+Ryj5nkwl8wb+bFYYlMXj7MuYv+1n+DuXtTl9Jy4e24w96pYNJIfvfqIFkRxGoQZ0EQ6ow==",
- "requires": {
- "argparse": "0.1.16",
- "assert": "0.4.9",
- "big.js": "3.1.3",
- "bigi": "1.4.0",
- "bignumber.js": "4.0.4",
- "bitcoinjs-lib": "git+https://github.com/dabura667/bitcoinjs-lib.git#92c602567bd62dd1b41b717cc7d977c015104f1c",
- "bitcoinjs-message": "2.0.0",
- "bluebird": "3.5.0",
- "body-parser": "1.18.2",
- "bs58": "2.0.1",
- "bs58check": "1.0.4",
- "create-hmac": "1.1.6",
- "ecurve": "1.0.6",
- "eol": "0.5.0",
- "ethereumjs-abi": "0.6.4",
- "ethereumjs-util": "4.4.1",
- "express": "4.16.2",
- "http-proxy": "1.11.1",
- "lodash": "4.13.1",
- "minimist": "0.2.0",
- "moment": "2.18.1",
- "morgan": "1.9.0",
- "prova-lib": "0.2.9",
- "ripple-lib": "0.17.9",
- "sanitize-html": "1.13.0",
- "secp256k1": "3.2.5",
- "secrets.js-grempe": "1.1.0",
- "superagent": "3.5.2",
- "superagent-proxy": "1.0.2",
- "underscore.string": "2.4.0"
+ "bittorrent-dht": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-8.3.0.tgz",
+ "integrity": "sha512-dw6yS30Xxe7ltoHwB7lnu77dhgTvsLunxHEn7DrL3TRuyu0dEBzo77bjwqqx7suLFOk7cprhqk3aTmzkG3Ynrg==",
+ "requires": {
+ "bencode": "^2.0.0",
+ "buffer-equals": "^1.0.3",
+ "debug": "^3.1.0",
+ "inherits": "^2.0.1",
+ "k-bucket": "^4.0.0",
+ "k-rpc": "^5.0.0",
+ "last-one-wins": "^1.0.4",
+ "lru": "^3.1.0",
+ "randombytes": "^2.0.5",
+ "record-cache": "^1.0.2",
+ "safe-buffer": "^5.0.1",
+ "simple-sha1": "^2.1.0"
},
"dependencies": {
- "big.js": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/big.js/-/big.js-3.1.3.tgz",
- "integrity": "sha1-TK2iGTZS6zyp7I5VyQFWacmAaXg="
- },
- "bitcoinjs-lib": {
- "version": "git+https://github.com/dabura667/bitcoinjs-lib.git#92c602567bd62dd1b41b717cc7d977c015104f1c",
- "requires": {
- "bech32": "0.0.3",
- "bigi": "1.4.0",
- "bip66": "1.1.5",
- "bitcoin-ops": "1.4.0",
- "bs58check": "2.1.0",
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
- "ecurve": "1.0.6",
- "merkle-lib": "2.0.10",
- "pushdata-bitcoin": "1.0.1",
- "randombytes": "2.0.5",
- "safe-buffer": "5.1.1",
- "typeforce": "1.11.5",
- "varuint-bitcoin": "1.0.4",
- "wif": "2.0.6"
- },
- "dependencies": {
- "bs58": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
- "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
- "requires": {
- "base-x": "3.0.2"
- }
- },
- "bs58check": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.1.0.tgz",
- "integrity": "sha512-FWT30tP+89OiXjWLHlAElxdPrbYo05T8XSmgKhh2GHq1JCBFUG0fujt5n7dadkEL3l4DFdfEi5KG5RcXW7UDEA==",
- "requires": {
- "bs58": "4.0.1",
- "create-hash": "1.1.3"
- }
- }
- }
- },
- "express": {
- "version": "4.16.2",
- "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
- "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
- "requires": {
- "accepts": "1.3.4",
- "array-flatten": "1.1.1",
- "body-parser": "1.18.2",
- "content-disposition": "0.5.2",
- "content-type": "1.0.4",
- "cookie": "0.3.1",
- "cookie-signature": "1.0.6",
- "debug": "2.6.9",
- "depd": "1.1.1",
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "etag": "1.8.1",
- "finalhandler": "1.1.0",
- "fresh": "0.5.2",
- "merge-descriptors": "1.0.1",
- "methods": "1.1.2",
- "on-finished": "2.3.0",
- "parseurl": "1.3.2",
- "path-to-regexp": "0.1.7",
- "proxy-addr": "2.0.2",
- "qs": "6.5.1",
- "range-parser": "1.2.0",
- "safe-buffer": "5.1.1",
- "send": "0.16.1",
- "serve-static": "1.13.1",
- "setprototypeof": "1.1.0",
- "statuses": "1.3.1",
- "type-is": "1.6.15",
- "utils-merge": "1.0.1",
- "vary": "1.1.2"
- }
- },
- "finalhandler": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
- "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
- "requires": {
- "debug": "2.6.9",
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "on-finished": "2.3.0",
- "parseurl": "1.3.2",
- "statuses": "1.3.1",
- "unpipe": "1.0.0"
- }
- },
- "form-data": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
- "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
- "requires": {
- "asynckit": "0.4.0",
- "combined-stream": "1.0.5",
- "mime-types": "2.1.17"
- }
- },
- "formidable": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.1.1.tgz",
- "integrity": "sha1-lriIb3w8NQi5Mta9cMTTqI818ak="
- },
- "ipaddr.js": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
- "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "lodash": {
- "version": "4.13.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.13.1.tgz",
- "integrity": "sha1-g+SxCRP0hJbU0W/sSlYK8u50S2g="
- },
- "mime": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
- "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
- },
- "minimist": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.2.0.tgz",
- "integrity": "sha1-Tf/lJdriuGTGbC4jxicdev3s784="
- },
- "proxy-addr": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
- "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
- "requires": {
- "forwarded": "0.1.2",
- "ipaddr.js": "1.5.2"
- }
- },
- "qs": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
- "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "send": {
- "version": "0.16.1",
- "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
- "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
- "requires": {
- "debug": "2.6.9",
- "depd": "1.1.1",
- "destroy": "1.0.4",
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "etag": "1.8.1",
- "fresh": "0.5.2",
- "http-errors": "1.6.2",
- "mime": "1.4.1",
- "ms": "2.0.0",
- "on-finished": "2.3.0",
- "range-parser": "1.2.0",
- "statuses": "1.3.1"
- }
- },
- "serve-static": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
- "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
- "requires": {
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "parseurl": "1.3.2",
- "send": "0.16.1"
- }
- },
- "setprototypeof": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
- "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
- "superagent": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/superagent/-/superagent-3.5.2.tgz",
- "integrity": "sha1-M2GjlxVnUEw1EGOr6q4PqiPb8/g=",
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
- "component-emitter": "1.2.1",
- "cookiejar": "2.0.6",
- "debug": "2.6.9",
- "extend": "3.0.0",
- "form-data": "2.3.1",
- "formidable": "1.1.1",
- "methods": "1.1.2",
- "mime": "1.4.1",
- "qs": "6.5.1",
- "readable-stream": "2.3.3"
+ "ms": "2.0.0"
}
- },
- "utils-merge": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
- "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
}
}
},
- "bittorrent-dht": {
- "version": "7.6.0",
- "resolved": "https://registry.npmjs.org/bittorrent-dht/-/bittorrent-dht-7.6.0.tgz",
- "integrity": "sha512-KinBmIQo4wL742f+4QjMjRHrW6GzDLUeeO+JK5dcGWyOeSKhkPQ7wditN/h0hK88wYjatIAYOC1fEU/WUI3ecw==",
- "requires": {
- "bencode": "1.0.0",
- "buffer-equals": "1.0.4",
- "debug": "2.6.9",
- "inherits": "2.0.3",
- "k-bucket": "3.3.0",
- "k-rpc": "4.1.0",
- "lru": "3.1.0",
- "safe-buffer": "5.1.1"
- }
- },
"bittorrent-peerid": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/bittorrent-peerid/-/bittorrent-peerid-1.2.0.tgz",
"integrity": "sha1-n2dWEvDmr8bvNFDfulH/cjir83E="
},
"bittorrent-protocol": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/bittorrent-protocol/-/bittorrent-protocol-2.2.3.tgz",
- "integrity": "sha512-nMPIjGGuQS9InlqYfXUZrxaivlftJLbSLQI1WQYBG1od1FnIf1iU2mN4tJctPvqw95jZ6qfAHig6dPIeKCXhrg==",
- "requires": {
- "bencode": "1.0.0",
- "bitfield": "1.1.2",
- "debug": "2.6.9",
- "inherits": "2.0.3",
- "randombytes": "2.0.5",
- "readable-stream": "2.3.3",
- "safe-buffer": "5.1.1",
- "speedometer": "1.0.0",
- "unordered-array-remove": "1.0.2",
- "xtend": "4.0.1"
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/bittorrent-protocol/-/bittorrent-protocol-2.4.1.tgz",
+ "integrity": "sha512-NaW3bx6Ga0W8kx4DxDLeWoco7O7rDKPk1KmCDmDjL+zWeLvd0eUguNhDIBd/j/XDILDIoEIOaTaSW4vASczRNw==",
+ "requires": {
+ "bencode": "^2.0.0",
+ "bitfield": "^2.0.0",
+ "debug": "^3.1.0",
+ "inherits": "^2.0.1",
+ "randombytes": "^2.0.5",
+ "readable-stream": "^2.3.2",
+ "safe-buffer": "^5.1.1",
+ "speedometer": "^1.0.0",
+ "unordered-array-remove": "^1.0.2",
+ "xtend": "^4.0.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
- "safe-buffer": "5.1.1"
+ "ms": "2.0.0"
}
}
}
},
"bittorrent-tracker": {
- "version": "9.2.3",
- "resolved": "https://registry.npmjs.org/bittorrent-tracker/-/bittorrent-tracker-9.2.3.tgz",
- "integrity": "sha512-KW7nE/Lwxlpy6BmEEufvwXXsAnq7961xsoE8qL2PWrwKqKjEWLIX/T3REdq6o+RQT0YYdmy7NnqVRs/w+2LUjg==",
- "requires": {
- "bencode": "1.0.0",
- "bittorrent-peerid": "1.2.0",
- "bn.js": "4.11.8",
- "bufferutil": "3.0.2",
- "compact2string": "1.4.0",
- "debug": "2.6.9",
- "inherits": "2.0.3",
- "ip": "1.1.5",
- "lru": "3.1.0",
- "minimist": "1.2.0",
- "once": "1.4.0",
- "random-iterate": "1.0.1",
- "randombytes": "2.0.5",
- "run-parallel": "1.1.6",
- "run-series": "1.1.4",
- "safe-buffer": "5.1.1",
- "simple-get": "2.7.0",
- "simple-peer": "8.1.1",
- "simple-websocket": "5.0.2",
- "string2compact": "1.2.2",
- "uniq": "1.0.1",
- "unordered-array-remove": "1.0.2",
- "ws": "3.2.0",
- "xtend": "4.0.1"
+ "version": "9.9.1",
+ "resolved": "https://registry.npmjs.org/bittorrent-tracker/-/bittorrent-tracker-9.9.1.tgz",
+ "integrity": "sha512-PdCrhMP0ajbutZEcw5FLd/pTvcxr7m5NTXEck3t1qS+UMcC9+pie2Zd59TSFefia2ipDlstOhVAUTOlaoZLlDQ==",
+ "requires": {
+ "bencode": "^2.0.0",
+ "bittorrent-peerid": "^1.0.2",
+ "bn.js": "^4.4.0",
+ "bufferutil": "^3.0.0",
+ "compact2string": "^1.2.0",
+ "debug": "^3.1.0",
+ "inherits": "^2.0.1",
+ "ip": "^1.0.1",
+ "lru": "^3.0.0",
+ "minimist": "^1.1.1",
+ "once": "^1.3.0",
+ "random-iterate": "^1.0.1",
+ "randombytes": "^2.0.3",
+ "run-parallel": "^1.1.2",
+ "run-series": "^1.0.2",
+ "safe-buffer": "^5.0.0",
+ "simple-get": "^3.0.0",
+ "simple-peer": "^9.0.0",
+ "simple-websocket": "^7.0.1",
+ "string2compact": "^1.1.1",
+ "uniq": "^1.0.1",
+ "unordered-array-remove": "^1.0.2",
+ "ws": "^5.0.0",
+ "xtend": "^4.0.0"
},
"dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- },
- "simple-get": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
- "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
- "decompress-response": "3.3.0",
- "once": "1.4.0",
- "simple-concat": "1.0.0"
+ "ms": "2.0.0"
}
},
- "ultron": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.0.tgz",
- "integrity": "sha1-sHoualQagV/Go0zNRTO67DB8qGQ="
- },
- "ws": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ws/-/ws-3.2.0.tgz",
- "integrity": "sha512-hTS3mkXm/j85jTQOIcwVz3yK3up9xHgPtgEhDBOH3G18LDOZmSAG1omJeXejLKJakx+okv8vS1sopgs7rw0kVw==",
+ "simple-get": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.2.tgz",
+ "integrity": "sha512-dU3TBVIGkP5Hzw6o74hJx+VzTBTX2rqIiLfugs0HdmdVQCQp76XGg2jlBCqfRJfW/n6/mUKTi+s3rnzX7SgbBA==",
"requires": {
- "async-limiter": "1.0.0",
- "safe-buffer": "5.1.1",
- "ultron": "1.1.0"
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
}
}
}
},
"bl": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.1.tgz",
- "integrity": "sha1-ysMo977kVzDUBLaSID/LWQ4XLV4=",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
+ "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
"requires": {
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
}
},
"blob-to-buffer": {
- "version": "1.2.6",
- "resolved": "https://registry.npmjs.org/blob-to-buffer/-/blob-to-buffer-1.2.6.tgz",
- "integrity": "sha1-CJrCZMaGtz6tbFOaSEqAA7+7IDM="
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/blob-to-buffer/-/blob-to-buffer-1.2.7.tgz",
+ "integrity": "sha512-IxU6RVzH4cekdAiLbsUIC3fd11fA1c+FoD/+7PTTGejYe3Q8Y++TcR8tXt+1CYG4veMzGI2uMeIismNgqIMq9w=="
},
"block-stream": {
"version": "0.0.9",
@@ -2192,7 +1853,7 @@
"integrity": "sha1-E+v+d4oDIFz+A3UUgeu0szAMEmo=",
"dev": true,
"requires": {
- "inherits": "2.0.3"
+ "inherits": "~2.0.0"
}
},
"block-stream2": {
@@ -2200,56 +1861,38 @@
"resolved": "https://registry.npmjs.org/block-stream2/-/block-stream2-1.1.0.tgz",
"integrity": "sha1-xzjjqRupd+u14f70MeE8oR2GOeI=",
"requires": {
- "defined": "1.0.0",
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "defined": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.4"
}
},
"bloodhound-js": {
"version": "github:brave/bloodhound#03555132b049adcb5a09138aa911acc3b4d3af7c",
+ "from": "github:brave/bloodhound",
"requires": {
- "babel-core": "6.26.0",
- "babel-loader": "7.1.2",
- "es6-promise": "3.3.1",
- "immutable": "3.8.1",
- "object-assign": "4.1.1",
- "storage2": "0.1.0",
- "superagent": "1.8.5"
+ "babel-core": "^6.26.0",
+ "babel-loader": "^7.1.2",
+ "es6-promise": "^3.0.2",
+ "immutable": "^3.8.1",
+ "object-assign": "^4.0.1",
+ "storage2": "^0.1.0",
+ "superagent": "^1.2.0"
}
},
"bluebird": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
- "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw="
+ "version": "3.5.1",
+ "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
+ "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
+ "dev": true
+ },
+ "bluebird-lst": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
+ "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.1"
+ }
},
"bmp-js": {
"version": "0.0.3",
@@ -2265,28 +1908,25 @@
"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",
+ "content-type": "~1.0.4",
"debug": "2.6.9",
- "depd": "1.1.1",
- "http-errors": "1.6.2",
+ "depd": "~1.1.1",
+ "http-errors": "~1.6.2",
"iconv-lite": "0.4.19",
- "on-finished": "2.3.0",
+ "on-finished": "~2.3.0",
"qs": "6.5.1",
"raw-body": "2.3.2",
- "type-is": "1.6.15"
+ "type-is": "~1.6.15"
},
"dependencies": {
- "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=="
- },
"qs": {
"version": "6.5.1",
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
- "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+ "dev": true
}
}
},
@@ -2296,53 +1936,55 @@
"integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=",
"dev": true,
"requires": {
- "array-flatten": "2.1.1",
- "deep-equal": "1.0.1",
- "dns-equal": "1.0.0",
- "dns-txt": "2.0.2",
- "multicast-dns": "6.1.1",
- "multicast-dns-service-types": "1.1.0"
- },
- "dependencies": {
- "array-flatten": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.1.tgz",
- "integrity": "sha1-Qmu52oQJDBg42BLIFQryCoMx4pY=",
- "dev": true
- }
+ "array-flatten": "^2.1.0",
+ "deep-equal": "^1.0.1",
+ "dns-equal": "^1.0.0",
+ "dns-txt": "^2.0.2",
+ "multicast-dns": "^6.0.1",
+ "multicast-dns-service-types": "^1.1.0"
}
},
"boolbase": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
- "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24="
+ "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=",
+ "dev": true
},
"boom": {
- "version": "4.3.1",
- "resolved": "https://registry.npmjs.org/boom/-/boom-4.3.1.tgz",
- "integrity": "sha1-T4owBctKfjiJ90kDD9JbluAdLjE=",
+ "version": "2.10.1",
+ "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
+ "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
+ "dev": true,
"requires": {
- "hoek": "4.2.0"
- }
- },
- "bowser": {
- "version": "1.7.3",
- "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.7.3.tgz",
- "integrity": "sha1-UEvbQxGMqNucu63yj9YPJlr5bk8="
+ "hoek": "2.x.x"
+ },
+ "dependencies": {
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ }
+ }
+ },
+ "bowser": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/bowser/-/bowser-1.9.3.tgz",
+ "integrity": "sha512-/gp96UlcFw5DbV2KQPCqTqi0Mb9gZRyDAHiDsGEH+4B/KOQjeoE5lM1PxlVX8DQDvfEfitmC1rW2Oy8fk/XBDg=="
},
"boxen": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.2.1.tgz",
- "integrity": "sha1-DxHn/jRO25OXl3/BPt5/ZNlWSB0=",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz",
+ "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==",
"dev": true,
"requires": {
- "ansi-align": "2.0.0",
- "camelcase": "4.1.0",
- "chalk": "2.1.0",
- "cli-boxes": "1.0.0",
- "string-width": "2.1.1",
- "term-size": "1.2.0",
- "widest-line": "1.0.0"
+ "ansi-align": "^2.0.0",
+ "camelcase": "^4.0.0",
+ "chalk": "^2.0.1",
+ "cli-boxes": "^1.0.0",
+ "string-width": "^2.0.0",
+ "term-size": "^1.2.0",
+ "widest-line": "^2.0.0"
},
"dependencies": {
"ansi-regex": {
@@ -2351,41 +1993,12 @@
"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"
- }
- },
"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.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.4.0"
- }
- },
- "color-convert": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
- "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
"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",
@@ -2398,8 +2011,8 @@
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
@@ -2408,46 +2021,57 @@
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
- "ansi-regex": "3.0.0"
- }
- },
- "supports-color": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
- "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
- "dev": true,
- "requires": {
- "has-flag": "2.0.0"
+ "ansi-regex": "^3.0.0"
}
}
}
},
"brace-expansion": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
"requires": {
- "balanced-match": "1.0.0",
+ "balanced-match": "^1.0.0",
"concat-map": "0.0.1"
}
},
"braces": {
- "version": "1.8.5",
- "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
- "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
- "dev": true,
- "requires": {
- "expand-range": "1.8.2",
- "preserve": "0.2.0",
- "repeat-element": "1.1.2"
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
}
},
"brave-crypto": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/brave-crypto/-/brave-crypto-0.0.1.tgz",
- "integrity": "sha512-gsm2eb4npxQh8WpnnIsUoxRVEPyFdRo5NZsU0ebrd7r3Ava+N/NkGqD2ZpdHA6m3mkIhbBaoJG4gHXLREc8liw==",
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/brave-crypto/-/brave-crypto-0.1.0.tgz",
+ "integrity": "sha512-wwkTQGt0upph8EaB4tUeSUyMlbI07VxgC/8zMoGDz9ucdZgdz2Pk3g1ReCfJpSJYuPMPPG7oSfOXyIOGhD7oIA==",
"requires": {
- "tweetnacl": "1.0.0"
+ "bip39": "^2.5.0",
+ "niceware": "^1.0.5",
+ "tweetnacl": "^1.0.0"
},
"dependencies": {
"tweetnacl": {
@@ -2460,41 +2084,43 @@
"brorand": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz",
- "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8="
+ "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=",
+ "dev": true
},
"browserify-aes": {
- "version": "1.0.8",
- "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.0.8.tgz",
- "integrity": "sha512-WYCMOT/PtGTlpOKFht0YJFYcPy6pLCR98CtWfzK13zoynLlBMvAdEMSRGmgnJCw2M2j/5qxBkinZQFobieM8dQ==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz",
+ "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==",
+ "dev": true,
"requires": {
- "buffer-xor": "1.0.3",
- "cipher-base": "1.0.4",
- "create-hash": "1.1.3",
- "evp_bytestokey": "1.0.3",
- "inherits": "2.0.3",
- "safe-buffer": "5.1.1"
+ "buffer-xor": "^1.0.3",
+ "cipher-base": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.3",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
}
},
"browserify-cipher": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.0.tgz",
- "integrity": "sha1-mYgkSHS/XtTijalWZtzWasj8Njo=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz",
+ "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==",
"dev": true,
"requires": {
- "browserify-aes": "1.0.8",
- "browserify-des": "1.0.0",
- "evp_bytestokey": "1.0.3"
+ "browserify-aes": "^1.0.4",
+ "browserify-des": "^1.0.0",
+ "evp_bytestokey": "^1.0.0"
}
},
"browserify-des": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.0.tgz",
- "integrity": "sha1-2qJ3cXRwki7S/hhZQRihdUOXId0=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.1.tgz",
+ "integrity": "sha512-zy0Cobe3hhgpiOM32Tj7KQ3Vl91m0njwsjzZQK1L+JDf11dzP9qIvjreVinsvXrgfjhStXwUWAEpB9D7Gwmayw==",
"dev": true,
"requires": {
- "cipher-base": "1.0.4",
- "des.js": "1.0.0",
- "inherits": "2.0.3"
+ "cipher-base": "^1.0.1",
+ "des.js": "^1.0.0",
+ "inherits": "^2.0.1"
}
},
"browserify-package-json": {
@@ -2508,17 +2134,8 @@
"integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=",
"dev": true,
"requires": {
- "bn.js": "4.11.8",
- "randombytes": "2.0.5"
- }
- },
- "browserify-sha3": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/browserify-sha3/-/browserify-sha3-0.0.1.tgz",
- "integrity": "sha1-P/NKMAbvFcD7NWflQbkaI0ASPRE=",
- "optional": true,
- "requires": {
- "js-sha3": "0.3.1"
+ "bn.js": "^4.1.0",
+ "randombytes": "^2.0.1"
}
},
"browserify-sign": {
@@ -2527,13 +2144,13 @@
"integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=",
"dev": true,
"requires": {
- "bn.js": "4.11.8",
- "browserify-rsa": "4.0.1",
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
- "elliptic": "6.4.0",
- "inherits": "2.0.3",
- "parse-asn1": "5.1.0"
+ "bn.js": "^4.1.1",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.2",
+ "elliptic": "^6.0.0",
+ "inherits": "^2.0.1",
+ "parse-asn1": "^5.0.0"
}
},
"browserify-zlib": {
@@ -2542,29 +2159,17 @@
"integrity": "sha1-uzX4pRn2AOD6a4SFJByXnQFB+y0=",
"dev": true,
"requires": {
- "pako": "0.2.9"
+ "pako": "~0.2.0"
}
},
"browserslist": {
- "version": "0.4.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-0.4.0.tgz",
- "integrity": "sha1-O9SrkZncG5FQ1NbbpNnTqrvIbdQ=",
+ "version": "3.2.8",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz",
+ "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==",
"dev": true,
"requires": {
- "caniuse-db": "1.0.30000738"
- }
- },
- "bs58": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/bs58/-/bs58-2.0.1.tgz",
- "integrity": "sha1-VZCNWPGYKrogCPob7Y+RmYopv40="
- },
- "bs58check": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-1.0.4.tgz",
- "integrity": "sha1-lBgKuQgh/iUElhUfYNDrPZ8yEZg=",
- "requires": {
- "bs58": "2.0.1"
+ "caniuse-lite": "^1.0.30000844",
+ "electron-to-chromium": "^1.3.47"
}
},
"buffer": {
@@ -2573,23 +2178,24 @@
"integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=",
"dev": true,
"requires": {
- "base64-js": "1.2.1",
- "ieee754": "1.1.8",
- "isarray": "1.0.0"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- }
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4",
+ "isarray": "^1.0.0"
+ }
+ },
+ "buffer-alloc": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.1.0.tgz",
+ "integrity": "sha1-BVFNM78WVtNUDGhPZbEgLpDsowM=",
+ "requires": {
+ "buffer-alloc-unsafe": "^0.1.0",
+ "buffer-fill": "^0.1.0"
}
},
"buffer-alloc-unsafe": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.0.0.tgz",
- "integrity": "sha1-R0qojzTnvHX6MR0uZFdAnFhGw/4="
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-0.1.1.tgz",
+ "integrity": "sha1-/+H2dVHdBVc33iUzN7/oU9+rGmo="
},
"buffer-crc32": {
"version": "0.2.13",
@@ -2607,6 +2213,16 @@
"resolved": "https://registry.npmjs.org/buffer-equals/-/buffer-equals-1.0.4.tgz",
"integrity": "sha1-A1O1T9B/2VZBcGca5vZrnPENJ/U="
},
+ "buffer-fill": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-0.1.1.tgz",
+ "integrity": "sha512-YgBMBzdRLEfgxJIGu2wrvI2E03tMCFU1p7d1KhB4BOoMN0VxmTFjSyN5JtKt9z8Z9JajMHruI6SE25W96wNv7Q=="
+ },
+ "buffer-from": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.0.0.tgz",
+ "integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA=="
+ },
"buffer-indexof": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz",
@@ -2619,42 +2235,18 @@
"integrity": "sha1-APFfruOreh3aLN5tkSG//dB7ImI=",
"dev": true,
"requires": {
- "file-type": "3.9.0",
- "readable-stream": "2.3.3",
- "uuid": "2.0.3",
- "vinyl": "1.2.0"
+ "file-type": "^3.1.0",
+ "readable-stream": "^2.0.2",
+ "uuid": "^2.0.1",
+ "vinyl": "^1.0.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"uuid": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
@@ -2667,8 +2259,8 @@
"integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
"dev": true,
"requires": {
- "clone": "1.0.2",
- "clone-stats": "0.0.1",
+ "clone": "^1.0.0",
+ "clone-stats": "^0.0.1",
"replace-ext": "0.0.1"
}
}
@@ -2677,7 +2269,8 @@
"buffer-xor": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz",
- "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk="
+ "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=",
+ "dev": true
},
"buffers": {
"version": "0.1.1",
@@ -2685,111 +2278,47 @@
"integrity": "sha1-skV5w77U1tOWru5tmorn9Ugqt7s="
},
"bufferutil": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-3.0.2.tgz",
- "integrity": "sha512-CGk0C62APhIdbcKwP6Pr293Pba/u9xvrC/X4D6YQZzxhSjb+/rHFYSCorEWIxLo6HbwTuy7SEsgTmsvBCn3dKw==",
+ "version": "3.0.5",
+ "resolved": "https://registry.npmjs.org/bufferutil/-/bufferutil-3.0.5.tgz",
+ "integrity": "sha512-0fUEthLqfCkYspEuP0vmiAe+PsXslE+AlILb2rmS9I4tAdm3SmpCI69M66zQL20GQEszdbXyVN6q+cpG/yhYlg==",
"optional": true,
"requires": {
- "bindings": "1.2.1",
- "nan": "2.6.2",
- "prebuild-install": "2.2.2"
+ "bindings": "~1.3.0",
+ "nan": "~2.10.0",
+ "prebuild-install": "~4.0.0"
},
"dependencies": {
- "bindings": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
- "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=",
- "optional": true
- },
"nan": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
- "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=",
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
"optional": true
}
}
},
"builder-util": {
- "version": "4.2.2",
- "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-4.2.2.tgz",
- "integrity": "sha512-B+xyCkbhUSXfyKnEyuLgxzWaEfkyVQVTH8EFGYF+38a8HMgd7UAvXBZdxxrRL/lHZULSoA31OWuzZzliWQRnTQ==",
- "dev": true,
- "requires": {
- "7zip-bin": "2.4.1",
- "bluebird-lst": "1.0.5",
- "builder-util-runtime": "4.0.4",
- "chalk": "2.3.0",
- "debug": "3.1.0",
- "fs-extra-p": "4.5.0",
- "ini": "1.3.5",
- "is-ci": "1.1.0",
- "js-yaml": "3.10.0",
- "lazy-val": "1.0.3",
- "semver": "5.5.0",
- "source-map-support": "0.5.3",
- "stat-mode": "0.2.2",
- "temp-file": "3.1.1",
- "tunnel-agent": "0.6.0"
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-4.2.4.tgz",
+ "integrity": "sha512-4MOB8Lfox9Exxmz0DDClTWRrtxYUy8/U6JbyAph1Y4Ha8DUQKKPYqEeobNEz0ZiwbNBli08HtyjjhN+RI/JF1w==",
+ "dev": true,
+ "requires": {
+ "7zip-bin": "~3.0.0",
+ "bluebird-lst": "^1.0.5",
+ "builder-util-runtime": "^4.0.4",
+ "chalk": "^2.3.0",
+ "debug": "^3.1.0",
+ "fs-extra-p": "^4.5.0",
+ "ini": "^1.3.5",
+ "is-ci": "^1.1.0",
+ "js-yaml": "^3.10.0",
+ "lazy-val": "^1.0.3",
+ "semver": "^5.5.0",
+ "source-map-support": "^0.5.3",
+ "stat-mode": "^0.2.2",
+ "temp-file": "^3.1.1",
+ "tunnel-agent": "^0.6.0"
},
"dependencies": {
- "7zip-bin": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-2.4.1.tgz",
- "integrity": "sha512-QU3oR1dLLVrYGRkb7LU17jMCpIkWtXXW7q71ECXWXkR9vOv37VjykqpvFgs29HgSCNLZHnNKJzdG6RwAW0LwIA==",
- "dev": true,
- "requires": {
- "7zip-bin-mac": "1.0.1"
- }
- },
- "7zip-bin-linux": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/7zip-bin-linux/-/7zip-bin-linux-1.3.1.tgz",
- "integrity": "sha512-Wv1uEEeHbTiS1+ycpwUxYNuIcyohU6Y6vEqY3NquBkeqy0YhVdsNUGsj0XKSRciHR6LoJSEUuqYUexmws3zH7Q=="
- },
- "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.1"
- }
- },
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
- "dev": true
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
- "chalk": {
- "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.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.5.0"
- }
- },
- "color-convert": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -2799,79 +2328,14 @@
"ms": "2.0.0"
}
},
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.0.0"
- }
- },
- "ini": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
- "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==",
- "dev": true
- },
- "is-ci": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
- "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
- "dev": true,
- "requires": {
- "ci-info": "1.1.1"
- }
- },
- "jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
- },
- "semver": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- },
"source-map-support": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.3.tgz",
- "integrity": "sha512-eKkTgWYeBOQqFGXRfKabMFdnWepo51vWqEdoeikaEPFiJC7MCU5j2h4+6Q8npkZTeLGbSyecZvRxiSoWl3rh+w==",
- "dev": true,
- "requires": {
- "source-map": "0.6.1"
- }
- },
- "supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
+ "version": "0.5.6",
+ "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.6.tgz",
+ "integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "buffer-from": "^1.0.0",
+ "source-map": "^0.6.0"
}
}
}
@@ -2882,27 +2346,12 @@
"integrity": "sha512-WyTMyWXX7zahY0MyR8Fh8SRxH//ugUaBgsgrCT/orwTv5ud4s0htLlucNiQdDTiWdHyQFqAigTfqILED4bAXUA==",
"dev": true,
"requires": {
- "bluebird-lst": "1.0.5",
- "debug": "3.1.0",
- "fs-extra-p": "4.5.0",
- "sax": "1.2.4"
+ "bluebird-lst": "^1.0.5",
+ "debug": "^3.1.0",
+ "fs-extra-p": "^4.5.0",
+ "sax": "^1.2.4"
},
"dependencies": {
- "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
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -2911,36 +2360,6 @@
"requires": {
"ms": "2.0.0"
}
- },
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.0.0"
- }
- },
- "jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
}
}
},
@@ -2960,23 +2379,100 @@
"resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz",
"integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=",
"requires": {
- "dtrace-provider": "0.8.5",
- "moment": "2.18.1",
- "mv": "2.1.1",
- "safe-json-stringify": "1.0.4"
+ "dtrace-provider": "~0.8",
+ "moment": "^2.10.6",
+ "mv": "~2",
+ "safe-json-stringify": "~1"
+ },
+ "dependencies": {
+ "dtrace-provider": {
+ "version": "0.8.6",
+ "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.6.tgz",
+ "integrity": "sha1-QooiOv4DQl0s1tY0f99AxmkDVj0=",
+ "optional": true,
+ "requires": {
+ "nan": "^2.3.3"
+ }
+ }
}
},
"bytes": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
- "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
+ "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=",
+ "dev": true
+ },
+ "cacache": {
+ "version": "10.0.4",
+ "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.4.tgz",
+ "integrity": "sha512-Dph0MzuH+rTQzGPNT9fAnrPmMmjKfST6trxJeK7NQuHRaVw24VzPRWTmg9MpcwOVQZO0E1FBICUlFeNaKPIfHA==",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.1",
+ "chownr": "^1.0.1",
+ "glob": "^7.1.2",
+ "graceful-fs": "^4.1.11",
+ "lru-cache": "^4.1.1",
+ "mississippi": "^2.0.0",
+ "mkdirp": "^0.5.1",
+ "move-concurrently": "^1.0.1",
+ "promise-inflight": "^1.0.1",
+ "rimraf": "^2.6.2",
+ "ssri": "^5.2.4",
+ "unique-filename": "^1.1.0",
+ "y18n": "^4.0.0"
+ },
+ "dependencies": {
+ "lru-cache": {
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
+ "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.5"
+ }
+ },
+ "y18n": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+ "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+ "dev": true
+ }
+ }
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
},
"caller-path": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
"integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
"requires": {
- "callsites": "0.2.0"
+ "callsites": "^0.2.0"
}
},
"callsites": {
@@ -2985,9 +2481,9 @@
"integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo="
},
"camelcase": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
- "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo="
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
+ "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
},
"camelcase-keys": {
"version": "2.1.0",
@@ -2995,28 +2491,44 @@
"integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
"dev": true,
"requires": {
- "camelcase": "2.1.1",
- "map-obj": "1.0.1"
+ "camelcase": "^2.0.0",
+ "map-obj": "^1.0.0"
+ }
+ },
+ "caniuse-api": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-1.6.1.tgz",
+ "integrity": "sha1-tTTnxzTE+B7F++isoq0kNUuWLGw=",
+ "dev": true,
+ "requires": {
+ "browserslist": "^1.3.6",
+ "caniuse-db": "^1.0.30000529",
+ "lodash.memoize": "^4.1.2",
+ "lodash.uniq": "^4.5.0"
},
"dependencies": {
- "camelcase": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8=",
- "dev": true
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "^1.0.30000639",
+ "electron-to-chromium": "^1.2.7"
+ }
}
}
},
"caniuse-db": {
- "version": "1.0.30000738",
- "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000738.tgz",
- "integrity": "sha1-hICavEmjkOWowiSrk2nT+NAaogI=",
+ "version": "1.0.30000845",
+ "resolved": "https://registry.npmjs.org/caniuse-db/-/caniuse-db-1.0.30000845.tgz",
+ "integrity": "sha1-KWqQZKhJt2z2174TLBhSxbVfNxg=",
"dev": true
},
"caniuse-lite": {
- "version": "1.0.30000738",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000738.tgz",
- "integrity": "sha1-GCDDya25oRfjEaW9yh0lvDQojro=",
+ "version": "1.0.30000844",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000844.tgz",
+ "integrity": "sha512-UpKQE7y6dLHhlv75UyBCRiun34Q+bmxyX3zS+ve9M07YG52tRafOvop9N9d5jC+sikKuG7UMweJKJNts4FVehA==",
"dev": true
},
"capture-stack-trace": {
@@ -3025,16 +2537,6 @@
"integrity": "sha1-Sm+gc5nCa7pH8LJJa00PtAjFVQ0=",
"dev": true
},
- "cardinal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/cardinal/-/cardinal-1.0.0.tgz",
- "integrity": "sha1-UOIcGwqjdyn5N33vGWtanOyTLuk=",
- "dev": true,
- "requires": {
- "ansicolors": "0.2.1",
- "redeyed": "1.0.1"
- }
- },
"caseless": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
@@ -3046,8 +2548,8 @@
"integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
"dev": true,
"requires": {
- "align-text": "0.1.4",
- "lazy-cache": "1.0.4"
+ "align-text": "^0.1.3",
+ "lazy-cache": "^1.0.3"
}
},
"chai": {
@@ -3056,9 +2558,9 @@
"integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
"dev": true,
"requires": {
- "assertion-error": "1.0.2",
- "deep-eql": "0.1.3",
- "type-detect": "1.0.0"
+ "assertion-error": "^1.0.1",
+ "deep-eql": "^0.1.3",
+ "type-detect": "^1.0.0"
}
},
"chai-as-promised": {
@@ -3067,70 +2569,100 @@
"integrity": "sha1-CdekApCKpw39vq1T5YU/x50+8hw=",
"dev": true
},
- "chain-function": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/chain-function/-/chain-function-1.0.0.tgz",
- "integrity": "sha1-DUqzfn4Y6tC9xHuSB2QRjOWHM9w="
- },
"chainsaw": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz",
"integrity": "sha1-XqtQsor+WAdNDVgpE4iCi15fvJg=",
"requires": {
- "traverse": "0.3.9"
+ "traverse": ">=0.3.0 <0.4"
}
},
"chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz",
+ "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
"requires": {
- "ansi-styles": "2.2.1",
- "escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
+ "chardet": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I="
+ },
"cheerio": {
"version": "0.22.0",
"resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz",
"integrity": "sha1-qbqoYKP5tZWmuBsahocxIe06Jp4=",
"dev": true,
"requires": {
- "css-select": "1.2.0",
- "dom-serializer": "0.1.0",
- "entities": "1.1.1",
- "htmlparser2": "3.9.2",
- "lodash.assignin": "4.2.0",
- "lodash.bind": "4.2.1",
- "lodash.defaults": "4.2.0",
- "lodash.filter": "4.6.0",
- "lodash.flatten": "4.4.0",
- "lodash.foreach": "4.5.0",
- "lodash.map": "4.6.0",
- "lodash.merge": "4.6.0",
- "lodash.pick": "4.4.0",
- "lodash.reduce": "4.6.0",
- "lodash.reject": "4.6.0",
- "lodash.some": "4.6.0"
+ "css-select": "~1.2.0",
+ "dom-serializer": "~0.1.0",
+ "entities": "~1.1.1",
+ "htmlparser2": "^3.9.1",
+ "lodash.assignin": "^4.0.9",
+ "lodash.bind": "^4.1.4",
+ "lodash.defaults": "^4.0.1",
+ "lodash.filter": "^4.4.0",
+ "lodash.flatten": "^4.2.0",
+ "lodash.foreach": "^4.3.0",
+ "lodash.map": "^4.4.0",
+ "lodash.merge": "^4.4.0",
+ "lodash.pick": "^4.2.1",
+ "lodash.reduce": "^4.4.0",
+ "lodash.reject": "^4.4.0",
+ "lodash.some": "^4.4.0"
}
},
"chokidar": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-1.7.0.tgz",
- "integrity": "sha1-eY5ol3gVHIB2tLNg5e3SjNortGg=",
- "dev": true,
- "requires": {
- "anymatch": "1.3.2",
- "async-each": "1.0.1",
- "fsevents": "1.1.2",
- "glob-parent": "2.0.0",
- "inherits": "2.0.3",
- "is-binary-path": "1.0.1",
- "is-glob": "2.0.1",
- "path-is-absolute": "1.0.1",
- "readdirp": "2.1.0"
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.0.3.tgz",
+ "integrity": "sha512-zW8iXYZtXMx4kux/nuZVXjkLP+CyIK5Al5FHnj1OgTKGZfp4Oy6/ymtMSKFv3GD8DviEmUPmJg9eFdJ/JzudMg==",
+ "dev": true,
+ "requires": {
+ "anymatch": "^2.0.0",
+ "async-each": "^1.0.0",
+ "braces": "^2.3.0",
+ "fsevents": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "inherits": "^2.0.1",
+ "is-binary-path": "^1.0.0",
+ "is-glob": "^4.0.0",
+ "normalize-path": "^2.1.1",
+ "path-is-absolute": "^1.0.0",
+ "readdirp": "^2.0.0",
+ "upath": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.0.tgz",
+ "integrity": "sha1-lSHHaEXMJhCoUgPd8ICpWML/q8A=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ }
}
},
"chownr": {
@@ -3144,8 +2676,8 @@
"integrity": "sha512-+RixJXes45Y4XnpAegjaWtDixdS6580aUpK8pzojRHHL89qXXvv0VBEPCoDaB9j0yBS+gMbpZKj2ZSH/45HABw==",
"dev": true,
"requires": {
- "commander": "2.1.0",
- "ws": "2.0.3"
+ "commander": "2.1.x",
+ "ws": "2.0.x"
},
"dependencies": {
"commander": {
@@ -3154,19 +2686,13 @@
"integrity": "sha1-0SG7roYNmZKj1Re6lvVliOR8Z4E=",
"dev": true
},
- "ultron": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.0.tgz",
- "integrity": "sha1-sHoualQagV/Go0zNRTO67DB8qGQ=",
- "dev": true
- },
"ws": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/ws/-/ws-2.0.3.tgz",
"integrity": "sha1-Uy/UmcP319cg5UPx+AcQbPxX2cs=",
"dev": true,
"requires": {
- "ultron": "1.1.0"
+ "ultron": "~1.1.0"
}
}
}
@@ -3176,57 +2702,20 @@
"resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz",
"integrity": "sha1-BKEGZywYsIWrd02YPfo+oTjyIgU="
},
- "chrono-node": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/chrono-node/-/chrono-node-1.3.5.tgz",
- "integrity": "sha1-oklSmKMtqCvMAa2b59d++l4kQSI=",
- "requires": {
- "moment": "2.18.1"
- }
- },
"chunk-store-stream": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/chunk-store-stream/-/chunk-store-stream-2.0.2.tgz",
- "integrity": "sha1-gSwY4M2+M6KxnPAQgyGLrrYI2I0=",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/chunk-store-stream/-/chunk-store-stream-2.1.0.tgz",
+ "integrity": "sha512-mVVfkjLW3E4wgBIMBw+5es+q0ShA/67r8dvGwy31o3CUo4kJ74bxWEK2WDHCJ5rTFWFbtQe5O2ZKFJgCnsOcWA==",
"requires": {
- "block-stream2": "1.1.0",
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "block-stream2": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5"
}
},
"ci-info": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.1.tgz",
- "integrity": "sha512-vHDDF/bP9RYpTWtUhpJRhCFdvvp3iDWvEbuDbWgvjUrNGV1MXJrE0MPcwGtEled04m61iwdBLUIHZtDgzWS4ZQ==",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-1.1.3.tgz",
+ "integrity": "sha512-SK/846h/Rcy8q9Z9CAwGBLfCJ6EkjJWdpelWDufQpqVDYq2Wnnv8zlSO6AMQap02jvhVruKKpEtQOufo3pFhLg==",
"dev": true
},
"cipher-base": {
@@ -3234,8 +2723,8 @@
"resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz",
"integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==",
"requires": {
- "inherits": "2.0.3",
- "safe-buffer": "5.1.1"
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
}
},
"circular-json": {
@@ -3243,6 +2732,53 @@
"resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
"integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A=="
},
+ "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"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ }
+ }
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
"classnames": {
"version": "2.2.5",
"resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.5.tgz",
@@ -3259,61 +2795,52 @@
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
"integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
"requires": {
- "restore-cursor": "2.0.0"
+ "restore-cursor": "^2.0.0"
}
},
- "cli-table": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
- "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
+ "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.0.3"
+ "colors": "^1.1.2",
+ "lodash": "^3.10.1",
+ "string-width": "^1.0.1"
},
"dependencies": {
- "colors": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
- "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
+ "lodash": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
+ "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
"dev": true
}
}
},
- "cli-usage": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/cli-usage/-/cli-usage-0.1.4.tgz",
- "integrity": "sha1-fAHg3HBsI0s5yTODjI4gshdXduI=",
- "dev": true,
- "requires": {
- "marked": "0.3.6",
- "marked-terminal": "1.7.0"
- }
- },
"cli-width": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
"integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
},
"clipboard-copy": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-1.2.0.tgz",
- "integrity": "sha1-9qPeZaiiUvqZP8sqTgz+OqS4dp4="
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/clipboard-copy/-/clipboard-copy-1.4.2.tgz",
+ "integrity": "sha512-r4cze0NDyNhKAYKarnxIiz1cI9AcNfJl9MxenO8EBG0IW2ZeDlhw2DLQDt6K2T2580VWud4xeQVyl29BK6vCow=="
},
"cliui": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/cliui/-/cliui-3.2.0.tgz",
"integrity": "sha1-EgYBU3qRbSmUD5NNo7SNWFo5IT0=",
"requires": {
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "wrap-ansi": "2.1.0"
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
}
},
"clone": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.2.tgz",
- "integrity": "sha1-Jgt6meux7f4kdTgXX3gyQ8sZ0Uk=",
- "dev": true
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
+ "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs="
},
"clone-stats": {
"version": "0.0.1",
@@ -3332,13 +2859,22 @@
"integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
},
"co-mocha": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/co-mocha/-/co-mocha-1.2.0.tgz",
- "integrity": "sha1-2b41oqLRb0sbDoP2lzQByktmYK8=",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/co-mocha/-/co-mocha-1.2.2.tgz",
+ "integrity": "sha512-ocdJRn3sxonOqpdjSU2VwTwWzjTSoatzsTqCWiC3eGvJFNs8ZNMlZwfgYolQCdfddMz4muiZl99KIV9gKoNvxg==",
+ "dev": true,
+ "requires": {
+ "co": "^4.0.0",
+ "is-generator": "^1.0.1"
+ }
+ },
+ "coa": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/coa/-/coa-1.0.4.tgz",
+ "integrity": "sha1-qe8VNmDWqGqL3sAomlxoTSF0Mv0=",
"dev": true,
"requires": {
- "co": "4.6.0",
- "is-generator": "1.0.3"
+ "q": "^1.1.2"
}
},
"code-point-at": {
@@ -3346,21 +2882,42 @@
"resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
"integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
},
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
"color": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/color/-/color-0.10.1.tgz",
- "integrity": "sha1-wEGI34KiCd3rzOzazT7DIPGTc58=",
+ "version": "0.11.4",
+ "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
+ "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
"dev": true,
"requires": {
- "color-convert": "0.5.3",
- "color-string": "0.3.0"
+ "clone": "^1.0.2",
+ "color-convert": "^1.3.0",
+ "color-string": "^0.3.0"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+ "dev": true
+ }
}
},
"color-convert": {
- "version": "0.5.3",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
- "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=",
- "dev": true
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
+ "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
+ "requires": {
+ "color-name": "^1.1.1"
+ }
},
"color-name": {
"version": "1.1.3",
@@ -3373,40 +2930,24 @@
"integrity": "sha1-J9RvtnAlxcL6JZk7+/V55HhBuZE=",
"dev": true,
"requires": {
- "color-name": "1.1.3"
+ "color-name": "^1.0.0"
}
},
+ "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==",
+ "dev": true
+ },
"colormin": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/colormin/-/colormin-1.1.2.tgz",
"integrity": "sha1-6i90IKcrlogaOKrlnsEkpvcpgTM=",
"dev": true,
"requires": {
- "color": "0.11.4",
+ "color": "^0.11.0",
"css-color-names": "0.0.4",
- "has": "1.0.1"
- },
- "dependencies": {
- "color": {
- "version": "0.11.4",
- "resolved": "https://registry.npmjs.org/color/-/color-0.11.4.tgz",
- "integrity": "sha1-bXtcdPtl6EHNSHkq0e1eB7kE12Q=",
- "dev": true,
- "requires": {
- "clone": "1.0.2",
- "color-convert": "1.9.0",
- "color-string": "0.3.0"
- }
- },
- "color-convert": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
- "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- }
+ "has": "^1.0.1"
}
},
"colors": {
@@ -3416,17 +2957,17 @@
"dev": true
},
"combined-stream": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.5.tgz",
- "integrity": "sha1-k4NwpXtKUd6ix3wV1cX9+JUWQAk=",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.6.tgz",
+ "integrity": "sha1-cj599ugBrFYTETp+RFqbactjKBg=",
"requires": {
- "delayed-stream": "1.0.0"
+ "delayed-stream": "~1.0.0"
}
},
"commander": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
- "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ=="
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+ "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag=="
},
"commondir": {
"version": "1.0.1",
@@ -3438,7 +2979,7 @@
"resolved": "https://registry.npmjs.org/compact2string/-/compact2string-1.4.0.tgz",
"integrity": "sha1-qZzZbqAAUlaEsmloOuIiLW7qe0k=",
"requires": {
- "ipaddr.js": "1.4.0"
+ "ipaddr.js": ">= 0.1.5"
}
},
"compare-version": {
@@ -3448,9 +2989,9 @@
"dev": true
},
"compare-versions": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.1.0.tgz",
- "integrity": "sha512-4hAxDSBypT/yp2ySFD346So6Ragw5xmBn/e/agIGl3bZr6DLUqnoRZPusxKrXdYRZpgexO9daejmIenlq/wrIQ=="
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.2.1.tgz",
+ "integrity": "sha512-2y2nHcopMG/NAyk6vWXlLs86XeM9sik4jmx1tKIgzMi9/RQ2eo758RGpxQO3ErihHmg0RlQITPqgz73y6s7quA=="
},
"component-emitter": {
"version": "1.2.1",
@@ -3458,87 +2999,46 @@
"integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
},
"compress-commons": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.0.tgz",
- "integrity": "sha1-WFhwku8g03y1i68AARLJJ4/3O58=",
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/compress-commons/-/compress-commons-1.2.2.tgz",
+ "integrity": "sha1-UkqfEJA/OoEzibAiXSfEi7dRiQ8=",
"dev": true,
"requires": {
- "buffer-crc32": "0.2.13",
- "crc32-stream": "2.0.0",
- "normalize-path": "2.1.1",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "buffer-crc32": "^0.2.1",
+ "crc32-stream": "^2.0.0",
+ "normalize-path": "^2.0.0",
+ "readable-stream": "^2.0.0"
}
},
"compressible": {
- "version": "2.0.11",
- "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.11.tgz",
- "integrity": "sha1-FnGKdd4oPtjmBAQWJaIGRYZ5fYo=",
+ "version": "2.0.13",
+ "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.13.tgz",
+ "integrity": "sha1-DRAgq5JLL9tNYnmHXH1tq6a6p6k=",
"dev": true,
"requires": {
- "mime-db": "1.30.0"
+ "mime-db": ">= 1.33.0 < 2"
}
},
"compression": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.0.tgz",
- "integrity": "sha1-AwyfGY8WQ6BX13anOOki2kNzAS0=",
+ "version": "1.7.2",
+ "resolved": "http://registry.npmjs.org/compression/-/compression-1.7.2.tgz",
+ "integrity": "sha1-qv+81qr4VLROuygDU9WtFlH1mmk=",
"dev": true,
"requires": {
- "accepts": "1.3.4",
- "bytes": "2.5.0",
- "compressible": "2.0.11",
- "debug": "2.6.8",
- "on-headers": "1.0.1",
+ "accepts": "~1.3.4",
+ "bytes": "3.0.0",
+ "compressible": "~2.0.13",
+ "debug": "2.6.9",
+ "on-headers": "~1.0.1",
"safe-buffer": "5.1.1",
- "vary": "1.1.2"
+ "vary": "~1.1.2"
},
"dependencies": {
- "bytes": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/bytes/-/bytes-2.5.0.tgz",
- "integrity": "sha1-TJQj6i0lLCcMQbK97+/5u2tiwGo=",
+ "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
- },
- "debug": {
- "version": "2.6.8",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
- "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
}
}
},
@@ -3548,62 +3048,34 @@
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
},
"concat-stream": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
- "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
"requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3",
- "typedarray": "0.0.6"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
}
},
"configstore": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.1.tgz",
- "integrity": "sha512-5oNkD/L++l0O6xGXxb1EWS7SivtjfGQlRyxJsYgE0Z495/L81e2h4/d3r969hoPXuFItzNOKMtsXgYG4c7dYvw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/configstore/-/configstore-3.1.2.tgz",
+ "integrity": "sha512-vtv5HtGjcYUgFrXc6Kx747B83MRRVS5R1VTEQoXvuP+kMI+if6uywV0nDGoiydJRy4yk7h9od5Og0kxx4zUXmw==",
"dev": true,
"requires": {
- "dot-prop": "4.2.0",
- "graceful-fs": "4.1.11",
- "make-dir": "1.0.0",
- "unique-string": "1.0.0",
- "write-file-atomic": "2.3.0",
- "xdg-basedir": "3.0.0"
+ "dot-prop": "^4.1.0",
+ "graceful-fs": "^4.1.2",
+ "make-dir": "^1.0.0",
+ "unique-string": "^1.0.0",
+ "write-file-atomic": "^2.0.0",
+ "xdg-basedir": "^3.0.0"
}
},
"connect-history-api-fallback": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz",
- "integrity": "sha1-5R0X+PDvDbkKZP20feMFFVbp8Wk=",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz",
+ "integrity": "sha1-sGhzk0vF40T+9hGhlqb6rgruAVo=",
"dev": true
},
"console-browserify": {
@@ -3612,7 +3084,7 @@
"integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
"dev": true,
"requires": {
- "date-now": "0.1.4"
+ "date-now": "^0.1.4"
}
},
"console-control-strings": {
@@ -3635,32 +3107,36 @@
"content-disposition": {
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
- "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
+ "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=",
+ "dev": true
},
"content-type": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
- "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
+ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==",
+ "dev": true
},
"content-type-parser": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.1.tgz",
- "integrity": "sha1-w+VpiMU8ZRJ/tG1AMqOpACRv3JQ="
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/content-type-parser/-/content-type-parser-1.0.2.tgz",
+ "integrity": "sha512-lM4l4CnMEwOLHAHr/P6MEZwZFPJFtAAKgL6pogbXmVZggIqXhdB6RbBtPOTsw2FcXwYhehRGERJmRrjOiIB8pQ=="
},
"convert-source-map": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.0.tgz",
- "integrity": "sha1-ms1whRxtXf3ZPZKC5e35SgP/RrU="
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.5.1.tgz",
+ "integrity": "sha1-uCeAl7m8IpNl3lxiz1/K7YtVmeU="
},
"cookie": {
"version": "0.3.1",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
- "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s=",
+ "dev": true
},
"cookie-signature": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
- "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=",
+ "dev": true
},
"cookiejar": {
"version": "2.0.6",
@@ -3673,18 +3149,35 @@
"integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==",
"dev": true,
"requires": {
- "aproba": "1.2.0",
- "fs-write-stream-atomic": "1.0.10",
- "iferr": "0.1.5",
- "mkdirp": "0.5.1",
- "rimraf": "2.6.2",
- "run-queue": "1.0.3"
+ "aproba": "^1.1.1",
+ "fs-write-stream-atomic": "^1.0.8",
+ "iferr": "^0.1.5",
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.5.4",
+ "run-queue": "^1.0.0"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.5"
+ }
+ }
}
},
+ "copy-descriptor": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
+ "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=",
+ "dev": true
+ },
"core-js": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.1.tgz",
- "integrity": "sha1-rmh03GaTd4m4B1T/VCjfZoGcpQs="
+ "version": "2.5.6",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.5.6.tgz",
+ "integrity": "sha512-lQUVfQi0aLix2xpyjrrJEvfuYCqPc/HwmTKsC/VNf8q0zsjX7SQZtp4+oRONN5Tsur9GDETPjj+Ub2iDiGZfSQ=="
},
"core-util-is": {
"version": "1.0.2",
@@ -3703,50 +3196,18 @@
"integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
"dev": true,
"requires": {
- "crc": "3.5.0",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "crc": "^3.4.4",
+ "readable-stream": "^2.0.0"
}
},
"create-ecdh": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.0.tgz",
- "integrity": "sha1-iIxyNZbN92EvZJgjPuvXo1MBc30=",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz",
+ "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==",
"dev": true,
"requires": {
- "bn.js": "4.11.8",
- "elliptic": "6.4.0"
+ "bn.js": "^4.1.0",
+ "elliptic": "^6.0.0"
}
},
"create-error-class": {
@@ -3755,101 +3216,63 @@
"integrity": "sha1-Br56vvlHo/FKMP1hBnHUAbyot7Y=",
"dev": true,
"requires": {
- "capture-stack-trace": "1.0.0"
+ "capture-stack-trace": "^1.0.0"
}
},
"create-hash": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.1.3.tgz",
- "integrity": "sha1-YGBCrIuSYnUPSDyt2rD1gZFy2P0=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz",
+ "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==",
"requires": {
- "cipher-base": "1.0.4",
- "inherits": "2.0.3",
- "ripemd160": "2.0.1",
- "sha.js": "2.4.9"
+ "cipher-base": "^1.0.1",
+ "inherits": "^2.0.1",
+ "md5.js": "^1.3.4",
+ "ripemd160": "^2.0.1",
+ "sha.js": "^2.4.0"
}
},
"create-hmac": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.6.tgz",
- "integrity": "sha1-rLniIaThe9sHbpBlfEK5PjcmzwY=",
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz",
+ "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==",
"requires": {
- "cipher-base": "1.0.4",
- "create-hash": "1.1.3",
- "inherits": "2.0.3",
- "ripemd160": "2.0.1",
- "safe-buffer": "5.1.1",
- "sha.js": "2.4.9"
+ "cipher-base": "^1.0.3",
+ "create-hash": "^1.1.0",
+ "inherits": "^2.0.1",
+ "ripemd160": "^2.0.0",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
}
},
"create-react-class": {
- "version": "15.6.2",
- "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.2.tgz",
- "integrity": "sha1-zx7RXxKq1/FO9fLf4F5sQvke8Co=",
+ "version": "15.6.3",
+ "resolved": "https://registry.npmjs.org/create-react-class/-/create-react-class-15.6.3.tgz",
+ "integrity": "sha512-M+/3Q6E6DLO6Yx3OwrWjwHBnvfXXYA7W+dFjt/ZDBemHO1DDZhsalX/NUtnTYclN6GfnBDRh4qRHjcDHmlJBJg==",
"requires": {
- "fbjs": "0.8.16",
- "loose-envify": "1.3.1",
- "object-assign": "4.1.1"
+ "fbjs": "^0.8.9",
+ "loose-envify": "^1.3.1",
+ "object-assign": "^4.1.1"
}
},
"create-torrent": {
- "version": "3.29.2",
- "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-3.29.2.tgz",
- "integrity": "sha512-UG4yQZ9XiXXHAJdb0HI4If+GQg3PMRIpYoFYvMbgrL4vgjOpcPs7qQPBWqnxWul/gGGVdBk/n0Oa6XLV6xGONA==",
- "requires": {
- "bencode": "1.0.0",
- "block-stream2": "1.1.0",
- "filestream": "4.1.3",
- "flatten": "1.0.2",
- "is-file": "1.0.0",
- "junk": "2.1.0",
- "minimist": "1.2.0",
- "multistream": "2.1.0",
- "once": "1.4.0",
- "piece-length": "1.0.0",
- "readable-stream": "2.3.3",
- "run-parallel": "1.1.6",
- "simple-sha1": "2.1.0",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "flatten": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
- "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I="
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "version": "3.31.0",
+ "resolved": "https://registry.npmjs.org/create-torrent/-/create-torrent-3.31.0.tgz",
+ "integrity": "sha512-0Dq9cAL2HrGxBTuA0hvcxoVUtKxoRfOJJ0liZEd19x7uta8/mqSvcnjPEAzUOaV9k85Deby3agFth/3NV4ihbA==",
+ "requires": {
+ "bencode": "^2.0.0",
+ "block-stream2": "^1.0.0",
+ "filestream": "^4.0.0",
+ "flatten": "^1.0.2",
+ "is-file": "^1.0.0",
+ "junk": "^2.1.0",
+ "minimist": "^1.1.0",
+ "multistream": "^2.0.2",
+ "once": "^1.3.0",
+ "piece-length": "^1.0.0",
+ "readable-stream": "^2.0.5",
+ "run-parallel": "^1.0.0",
+ "simple-sha1": "^2.0.0",
+ "xtend": "^4.0.1"
}
},
"cross-env": {
@@ -3858,8 +3281,8 @@
"integrity": "sha1-ngWF8neGTtQhznVvgamA/w1piro=",
"dev": true,
"requires": {
- "cross-spawn": "5.1.0",
- "is-windows": "1.0.1"
+ "cross-spawn": "^5.1.0",
+ "is-windows": "^1.0.0"
}
},
"cross-spawn": {
@@ -3867,56 +3290,48 @@
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
"integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
"requires": {
- "lru-cache": "4.1.1",
- "shebang-command": "1.2.0",
- "which": "1.3.0"
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
},
"dependencies": {
"lru-cache": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
- "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
+ "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
"requires": {
- "pseudomap": "1.0.2",
- "yallist": "2.1.2"
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
}
}
}
},
"cryptiles": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-3.1.2.tgz",
- "integrity": "sha1-qJ+7Ig9c4l7FboxKqKT9e1sNKf4=",
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
+ "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "dev": true,
"requires": {
- "boom": "5.2.0"
- },
- "dependencies": {
- "boom": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/boom/-/boom-5.2.0.tgz",
- "integrity": "sha512-Z5BTk6ZRe4tXXQlkqftmsAUANpXmuwlsF5Oov8ThoMbQRzdGTA1ngYRW160GexgOgjsFOKJz0LYhoNi+2AMBUw==",
- "requires": {
- "hoek": "4.2.0"
- }
- }
+ "boom": "2.x.x"
}
},
"crypto-browserify": {
- "version": "3.11.1",
- "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.11.1.tgz",
- "integrity": "sha512-Na7ZlwCOqoaW5RwUK1WpXws2kv8mNhWdTlzob0UXulk6G9BDbyiJaGTYBIX61Ozn9l1EPPJpICZb4DaOpT9NlQ==",
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz",
+ "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==",
"dev": true,
"requires": {
- "browserify-cipher": "1.0.0",
- "browserify-sign": "4.0.4",
- "create-ecdh": "4.0.0",
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
- "diffie-hellman": "5.0.2",
- "inherits": "2.0.3",
- "pbkdf2": "3.0.14",
- "public-encrypt": "4.0.0",
- "randombytes": "2.0.5"
+ "browserify-cipher": "^1.0.0",
+ "browserify-sign": "^4.0.0",
+ "create-ecdh": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "create-hmac": "^1.1.0",
+ "diffie-hellman": "^5.0.0",
+ "inherits": "^2.0.1",
+ "pbkdf2": "^3.0.3",
+ "public-encrypt": "^4.0.0",
+ "randombytes": "^2.0.0",
+ "randomfill": "^1.0.3"
}
},
"crypto-random-string": {
@@ -3926,15 +3341,15 @@
"dev": true
},
"css": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/css/-/css-2.2.1.tgz",
- "integrity": "sha1-c6TIHehdtmTU7mdPfUcIXjstVdw=",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.3.tgz",
+ "integrity": "sha512-0W171WccAjQGGTKLhw4m2nnl0zPHUlTO/I8td4XzJgIB8Hg3ZZx71qT4G4eX8OVsSiaAKiUMy73E3nsbPlg2DQ==",
"dev": true,
"requires": {
- "inherits": "2.0.3",
- "source-map": "0.1.43",
- "source-map-resolve": "0.3.1",
- "urix": "0.1.0"
+ "inherits": "^2.0.1",
+ "source-map": "^0.1.38",
+ "source-map-resolve": "^0.5.1",
+ "urix": "^0.1.0"
},
"dependencies": {
"source-map": {
@@ -3943,7 +3358,7 @@
"integrity": "sha1-wkvBRspRfBRx9drL4lcbK3+eM0Y=",
"dev": true,
"requires": {
- "amdefine": "1.0.1"
+ "amdefine": ">=0.0.4"
}
}
}
@@ -3961,252 +3376,25 @@
"dev": true
},
"css-loader": {
- "version": "0.28.7",
- "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.28.7.tgz",
- "integrity": "sha512-GxMpax8a/VgcfRrVy0gXD6yLd5ePYbXX/5zGgTVYp4wXtJklS8Z2VaUArJgc//f6/Dzil7BaJObdSv8eKKCPgg==",
- "dev": true,
- "requires": {
- "babel-code-frame": "6.26.0",
- "css-selector-tokenizer": "0.7.0",
- "cssnano": "2.6.1",
- "icss-utils": "2.1.0",
- "loader-utils": "1.1.0",
- "lodash.camelcase": "4.3.0",
- "object-assign": "4.1.1",
- "postcss": "5.2.17",
- "postcss-modules-extract-imports": "1.1.0",
- "postcss-modules-local-by-default": "1.2.0",
- "postcss-modules-scope": "1.1.0",
- "postcss-modules-values": "1.3.0",
- "postcss-value-parser": "3.3.0",
- "source-list-map": "2.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
- "dev": true,
- "requires": {
- "color-convert": "1.9.0"
- }
- },
- "color-convert": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
- "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "css-selector-tokenizer": {
- "version": "0.7.0",
- "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.0.tgz",
- "integrity": "sha1-5piEdK6MlTR3v15+/s/OzNnPTIY=",
- "dev": true,
- "requires": {
- "cssesc": "0.1.0",
- "fastparse": "1.1.1",
- "regexpu-core": "1.0.0"
- }
- },
- "has-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
- "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
- "dev": true
- },
- "postcss": {
- "version": "5.2.17",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.17.tgz",
- "integrity": "sha1-z09Ze4ZNZcikkrLqvp1wbIecOIs=",
- "dev": true,
- "requires": {
- "chalk": "1.1.3",
- "js-base64": "2.1.9",
- "source-map": "0.5.7",
- "supports-color": "3.2.3"
- }
- },
- "postcss-modules-extract-imports": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.1.0.tgz",
- "integrity": "sha1-thTJcgvmgW6u41+zpfqh26agXds=",
- "dev": true,
- "requires": {
- "postcss": "6.0.12"
- },
- "dependencies": {
- "chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.4.0"
- }
- },
- "has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
- "dev": true
- },
- "postcss": {
- "version": "6.0.12",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
- "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
- "dev": true,
- "requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.4.0"
- }
- },
- "supports-color": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
- "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
- "dev": true,
- "requires": {
- "has-flag": "2.0.0"
- }
- }
- }
- },
- "postcss-modules-local-by-default": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz",
- "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=",
- "dev": true,
- "requires": {
- "css-selector-tokenizer": "0.7.0",
- "postcss": "6.0.12"
- },
- "dependencies": {
- "chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.4.0"
- }
- },
- "has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
- "dev": true
- },
- "postcss": {
- "version": "6.0.12",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
- "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
- "dev": true,
- "requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.4.0"
- }
- },
- "supports-color": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
- "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
- "dev": true,
- "requires": {
- "has-flag": "2.0.0"
- }
- }
- }
- },
- "postcss-modules-scope": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz",
- "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=",
- "dev": true,
- "requires": {
- "css-selector-tokenizer": "0.7.0",
- "postcss": "6.0.12"
- },
- "dependencies": {
- "chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.4.0"
- }
- },
- "has-flag": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
- "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
- "dev": true
- },
- "postcss": {
- "version": "6.0.12",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
- "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
- "dev": true,
- "requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.4.0"
- }
- },
- "supports-color": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.4.0.tgz",
- "integrity": "sha512-rKC3+DyXWgK0ZLKwmRsrkyHVZAjNkfzeehuFWdGGcqGDTZFH73+RH6S/RDAAxl9GusSjZSUWYLmT9N5pzXFOXQ==",
- "dev": true,
- "requires": {
- "has-flag": "2.0.0"
- }
- }
- }
- },
- "postcss-value-parser": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
- "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
- "dev": true
- },
- "regexpu-core": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
- "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
- "dev": true,
- "requires": {
- "regenerate": "1.3.3",
- "regjsgen": "0.2.0",
- "regjsparser": "0.1.5"
- }
- },
- "source-list-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
- "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
- "dev": true
- },
- "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"
- }
- }
+ "version": "0.28.11",
+ "resolved": "https://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",
+ "cssnano": "^3.10.0",
+ "icss-utils": "^2.1.0",
+ "loader-utils": "^1.0.2",
+ "lodash.camelcase": "^4.3.0",
+ "object-assign": "^4.1.1",
+ "postcss": "^5.0.6",
+ "postcss-modules-extract-imports": "^1.2.0",
+ "postcss-modules-local-by-default": "^1.2.0",
+ "postcss-modules-scope": "^1.1.0",
+ "postcss-modules-values": "^1.3.0",
+ "postcss-value-parser": "^3.3.0",
+ "source-list-map": "^2.0.0"
}
},
"css-parse": {
@@ -4215,39 +3403,43 @@
"integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=",
"dev": true,
"requires": {
- "css": "2.2.1"
+ "css": "^2.0.0"
}
},
"css-select": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz",
"integrity": "sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=",
+ "dev": true,
"requires": {
- "boolbase": "1.0.0",
- "css-what": "2.1.0",
+ "boolbase": "~1.0.0",
+ "css-what": "2.1",
"domutils": "1.5.1",
- "nth-check": "1.0.1"
- },
- "dependencies": {
- "domutils": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
- "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
- "requires": {
- "dom-serializer": "0.1.0",
- "domelementtype": "1.3.0"
- }
- }
+ "nth-check": "~1.0.1"
}
},
"css-selector-tokenizer": {
- "version": "0.5.4",
- "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.5.4.tgz",
- "integrity": "sha1-E5uv00o1/QwUKEhwSeBpnm9qLCE=",
+ "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"
+ "cssesc": "^0.1.0",
+ "fastparse": "^1.1.1",
+ "regexpu-core": "^1.0.0"
+ },
+ "dependencies": {
+ "regexpu-core": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
+ "integrity": "sha1-hqdj9Y7k18L2sQLkdkBQ3n7ZDGs=",
+ "dev": true,
+ "requires": {
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
+ }
+ }
}
},
"css-value": {
@@ -4259,7 +3451,8 @@
"css-what": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.0.tgz",
- "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0="
+ "integrity": "sha1-lGfQMsOM+u+58teVASUwYvh/ob0=",
+ "dev": true
},
"cssesc": {
"version": "0.1.0",
@@ -4268,53 +3461,59 @@
"dev": true
},
"cssnano": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-2.6.1.tgz",
- "integrity": "sha1-f7NyEsz/RNPpNuAmxvZ14xR9gCQ=",
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-3.10.0.tgz",
+ "integrity": "sha1-Tzj2zqK5sX+gFJDyPx3GjqZcHDg=",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "^6.3.1",
+ "decamelize": "^1.1.2",
+ "defined": "^1.0.0",
+ "has": "^1.0.1",
+ "object-assign": "^4.0.1",
+ "postcss": "^5.0.14",
+ "postcss-calc": "^5.2.0",
+ "postcss-colormin": "^2.1.8",
+ "postcss-convert-values": "^2.3.4",
+ "postcss-discard-comments": "^2.0.4",
+ "postcss-discard-duplicates": "^2.0.1",
+ "postcss-discard-empty": "^2.0.1",
+ "postcss-discard-overridden": "^0.1.1",
+ "postcss-discard-unused": "^2.2.1",
+ "postcss-filter-plugins": "^2.0.0",
+ "postcss-merge-idents": "^2.1.5",
+ "postcss-merge-longhand": "^2.0.1",
+ "postcss-merge-rules": "^2.0.3",
+ "postcss-minify-font-values": "^1.0.2",
+ "postcss-minify-gradients": "^1.0.1",
+ "postcss-minify-params": "^1.0.4",
+ "postcss-minify-selectors": "^2.0.4",
+ "postcss-normalize-charset": "^1.1.0",
+ "postcss-normalize-url": "^3.0.7",
+ "postcss-ordered-values": "^2.1.0",
+ "postcss-reduce-idents": "^2.2.2",
+ "postcss-reduce-initial": "^1.0.0",
+ "postcss-reduce-transforms": "^1.0.3",
+ "postcss-svgo": "^2.1.1",
+ "postcss-unique-selectors": "^2.0.2",
+ "postcss-value-parser": "^3.2.3",
+ "postcss-zindex": "^2.0.1"
+ }
+ },
+ "csso": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/csso/-/csso-2.3.2.tgz",
+ "integrity": "sha1-3dUsWHAz9J6Utx/FVWnyUuj/X4U=",
"dev": true,
"requires": {
- "autoprefixer-core": "5.2.1",
- "balanced-match": "0.2.1",
- "css-list": "0.1.3",
- "decamelize": "1.2.0",
- "defined": "1.0.0",
- "indexes-of": "1.0.1",
- "minimist": "1.2.0",
- "postcss": "4.1.16",
- "postcss-calc": "4.1.0",
- "postcss-colormin": "1.2.7",
- "postcss-convert-values": "1.3.1",
- "postcss-discard-comments": "1.2.1",
- "postcss-discard-duplicates": "1.2.1",
- "postcss-discard-empty": "1.1.2",
- "postcss-discard-unused": "1.0.3",
- "postcss-filter-plugins": "1.0.1",
- "postcss-font-family": "1.2.1",
- "postcss-merge-idents": "1.0.2",
- "postcss-merge-longhand": "1.0.2",
- "postcss-merge-rules": "1.3.6",
- "postcss-minify-font-weight": "1.0.1",
- "postcss-minify-selectors": "1.5.0",
- "postcss-normalize-url": "2.1.3",
- "postcss-ordered-values": "1.1.1",
- "postcss-reduce-idents": "1.0.3",
- "postcss-single-charset": "0.3.0",
- "postcss-unique-selectors": "1.0.1",
- "postcss-zindex": "1.1.3",
- "read-file-stdin": "0.2.1",
- "write-file-stdout": "0.0.2"
+ "clap": "^1.0.9",
+ "source-map": "^0.5.3"
},
"dependencies": {
- "balanced-match": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.1.tgz",
- "integrity": "sha1-e8ZYtL7WHu5CStdPdfXD4sTfPMc=",
- "dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
"dev": true
}
}
@@ -4329,7 +3528,7 @@
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-0.2.37.tgz",
"integrity": "sha1-VBCXI0yyUTyDzu06zdwn/yeYfVQ=",
"requires": {
- "cssom": "0.3.2"
+ "cssom": "0.3.x"
}
},
"cuint": {
@@ -4343,9 +3542,15 @@
"integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
"dev": true,
"requires": {
- "array-find-index": "1.0.2"
+ "array-find-index": "^1.0.1"
}
},
+ "cvss": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/cvss/-/cvss-1.0.3.tgz",
+ "integrity": "sha512-1FfNhEFVfeC+fgZpEr6oCOOTXifJicZS+Lq/mmUKI4Om+2O8zYspc/uhw51He+CTM5givI1dqIw5JUqyi1BWtA==",
+ "dev": true
+ },
"cyclist": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz",
@@ -4358,7 +3563,7 @@
"integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
"dev": true,
"requires": {
- "es5-ext": "0.10.30"
+ "es5-ext": "^0.10.9"
}
},
"dashdash": {
@@ -4366,7 +3571,7 @@
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
"requires": {
- "assert-plus": "1.0.0"
+ "assert-plus": "^1.0.0"
}
},
"data-expression": {
@@ -4374,43 +3579,12 @@
"resolved": "https://registry.npmjs.org/data-expression/-/data-expression-1.0.0.tgz",
"integrity": "sha1-ghanI56QbF8qN7txpv9MEDyA4lY=",
"requires": {
- "extend": "2.0.1",
- "ndjson": "1.5.0",
- "through2": "0.6.5",
- "yargs": "3.32.0"
- },
- "dependencies": {
- "camelcase": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-2.1.1.tgz",
- "integrity": "sha1-fB0W1nmhu+WcoCys7PsBHiAfWh8="
- },
- "extend": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz",
- "integrity": "sha1-HugBBonnOV/5RIJByYZSvHWagmA="
- },
- "yargs": {
- "version": "3.32.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
- "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
- "requires": {
- "camelcase": "2.1.1",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "os-locale": "1.4.0",
- "string-width": "1.0.2",
- "window-size": "0.1.4",
- "y18n": "3.2.1"
- }
- }
+ "extend": "^2.0.0",
+ "ndjson": "^1.3.0",
+ "through2": "^0.6.3",
+ "yargs": "^3.5.4"
}
},
- "data-uri-to-buffer": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-1.2.0.tgz",
- "integrity": "sha512-vKQ9DTQPN1FLYiiEEOQ6IBGFqvjCa5rSK3cWMy/Nespm5d/x3dGFT9UBZnkLxCwua/IXBi2TYnwTEpsOvhC4UQ=="
- },
"date-fns": {
"version": "1.29.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.29.0.tgz",
@@ -4447,8 +3621,8 @@
"resolved": "https://registry.npmjs.org/debugnyan/-/debugnyan-2.0.1.tgz",
"integrity": "sha1-06WmasMRt26IFAXHjO/lfHiFml8=",
"requires": {
- "bunyan": "1.8.12",
- "debug": "2.6.9"
+ "bunyan": "^1.8.1",
+ "debug": "^2.2.0"
}
},
"decamelize": {
@@ -4456,10 +3630,11 @@
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
},
- "decimal.js": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-5.0.8.tgz",
- "integrity": "sha1-tIw/t9c6LU1JQOCzjxzSHbWzZ84="
+ "decode-uri-component": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
+ "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
+ "dev": true
},
"decompress": {
"version": "3.0.0",
@@ -4467,155 +3642,201 @@
"integrity": "sha1-rx3VDQbjv8QyRh033hGzjA2ZG+0=",
"dev": true,
"requires": {
- "buffer-to-vinyl": "1.1.0",
- "concat-stream": "1.6.0",
- "decompress-tar": "3.1.0",
- "decompress-tarbz2": "3.1.0",
- "decompress-targz": "3.1.0",
- "decompress-unzip": "3.4.0",
- "stream-combiner2": "1.1.1",
- "vinyl-assign": "1.2.1",
- "vinyl-fs": "2.4.4"
+ "buffer-to-vinyl": "^1.0.0",
+ "concat-stream": "^1.4.6",
+ "decompress-tar": "^3.0.0",
+ "decompress-tarbz2": "^3.0.0",
+ "decompress-targz": "^3.0.0",
+ "decompress-unzip": "^3.0.0",
+ "stream-combiner2": "^1.1.1",
+ "vinyl-assign": "^1.0.1",
+ "vinyl-fs": "^2.2.0"
},
"dependencies": {
- "glob": {
- "version": "5.0.15",
- "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
- "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
"dev": true,
"requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
+ "arr-flatten": "^1.0.1"
}
},
- "glob-parent": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
- "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
+ "dev": true
+ },
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
"dev": true,
"requires": {
- "is-glob": "3.1.0",
- "path-dirname": "1.0.2"
+ "expand-range": "^1.8.1",
+ "preserve": "^0.2.0",
+ "repeat-element": "^1.1.2"
}
},
- "glob-stream": {
- "version": "5.3.5",
- "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz",
- "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=",
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
"dev": true,
"requires": {
- "extend": "3.0.0",
- "glob": "5.0.15",
- "glob-parent": "3.1.0",
- "micromatch": "2.3.11",
- "ordered-read-streams": "0.3.0",
- "through2": "0.6.5",
- "to-absolute-glob": "0.1.1",
- "unique-stream": "2.2.1"
- },
- "dependencies": {
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "dev": true
- },
- "readable-stream": {
- "version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "0.0.1",
- "string_decoder": "0.10.31"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "dev": true
- },
- "through2": {
+ "is-posix-bracket": "^0.1.0"
+ }
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "5.0.15",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
+ "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
+ "dev": true,
+ "requires": {
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-stream": {
+ "version": "5.3.5",
+ "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-5.3.5.tgz",
+ "integrity": "sha1-pVZlqajM3EGRWofHAeMtTgFvrSI=",
+ "dev": true,
+ "requires": {
+ "extend": "^3.0.0",
+ "glob": "^5.0.3",
+ "glob-parent": "^3.0.0",
+ "micromatch": "^2.3.7",
+ "ordered-read-streams": "^0.3.0",
+ "through2": "^0.6.0",
+ "to-absolute-glob": "^0.1.1",
+ "unique-stream": "^2.0.2"
+ },
+ "dependencies": {
+ "readable-stream": {
+ "version": "1.0.34",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
+ "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "through2": {
"version": "0.6.5",
"resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
"integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
"dev": true,
"requires": {
- "readable-stream": "1.0.34",
- "xtend": "4.0.1"
+ "readable-stream": ">=1.0.33-1 <1.1.0-0",
+ "xtend": ">=4.0.0 <4.1.0-0"
}
}
}
},
"is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"dev": true
},
"is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
"dev": true,
"requires": {
- "is-extglob": "2.1.1"
+ "is-extglob": "^1.0.0"
}
},
"isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
"dev": true
},
- "ordered-read-streams": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz",
- "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=",
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
"dev": true,
"requires": {
- "is-stream": "1.1.0",
- "readable-stream": "2.3.3"
+ "is-buffer": "^1.1.5"
}
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
"dev": true,
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
+ "arr-diff": "^2.0.0",
+ "array-unique": "^0.2.1",
+ "braces": "^1.8.2",
+ "expand-brackets": "^0.1.4",
+ "extglob": "^0.3.1",
+ "filename-regex": "^2.0.0",
+ "is-extglob": "^1.0.0",
+ "is-glob": "^2.0.1",
+ "kind-of": "^3.0.2",
+ "normalize-path": "^2.0.1",
+ "object.omit": "^2.0.0",
+ "parse-glob": "^3.0.4",
+ "regex-cache": "^0.4.2"
}
},
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "ordered-read-streams": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-0.3.0.tgz",
+ "integrity": "sha1-cTfmmzKYuzQiR6G77jiByA4v14s=",
"dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "is-stream": "^1.0.1",
+ "readable-stream": "^2.0.1"
}
},
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
+ },
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
}
},
"unique-stream": {
@@ -4624,8 +3845,8 @@
"integrity": "sha1-WqADz76Uxf+GbE59ZouxxNuts2k=",
"dev": true,
"requires": {
- "json-stable-stringify": "1.0.1",
- "through2-filter": "2.0.0"
+ "json-stable-stringify": "^1.0.0",
+ "through2-filter": "^2.0.0"
}
},
"vinyl": {
@@ -4634,8 +3855,8 @@
"integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
"dev": true,
"requires": {
- "clone": "1.0.2",
- "clone-stats": "0.0.1",
+ "clone": "^1.0.0",
+ "clone-stats": "^0.0.1",
"replace-ext": "0.0.1"
}
},
@@ -4645,23 +3866,23 @@
"integrity": "sha1-vm/zJwy1Xf19MGNkDegfJddTIjk=",
"dev": true,
"requires": {
- "duplexify": "3.5.1",
- "glob-stream": "5.3.5",
- "graceful-fs": "4.1.11",
+ "duplexify": "^3.2.0",
+ "glob-stream": "^5.3.2",
+ "graceful-fs": "^4.0.0",
"gulp-sourcemaps": "1.6.0",
- "is-valid-glob": "0.3.0",
- "lazystream": "1.0.0",
- "lodash.isequal": "4.5.0",
- "merge-stream": "1.0.1",
- "mkdirp": "0.5.1",
- "object-assign": "4.1.1",
- "readable-stream": "2.3.3",
- "strip-bom": "2.0.0",
- "strip-bom-stream": "1.0.0",
- "through2": "2.0.3",
- "through2-filter": "2.0.0",
- "vali-date": "1.0.0",
- "vinyl": "1.2.0"
+ "is-valid-glob": "^0.3.0",
+ "lazystream": "^1.0.0",
+ "lodash.isequal": "^4.0.0",
+ "merge-stream": "^1.0.0",
+ "mkdirp": "^0.5.0",
+ "object-assign": "^4.0.0",
+ "readable-stream": "^2.0.4",
+ "strip-bom": "^2.0.0",
+ "strip-bom-stream": "^1.0.0",
+ "through2": "^2.0.0",
+ "through2-filter": "^2.0.0",
+ "vali-date": "^1.0.0",
+ "vinyl": "^1.0.0"
}
}
}
@@ -4671,7 +3892,7 @@
"resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz",
"integrity": "sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M=",
"requires": {
- "mimic-response": "1.0.0"
+ "mimic-response": "^1.0.0"
}
},
"decompress-tar": {
@@ -4680,12 +3901,12 @@
"integrity": "sha1-IXx4n5uURQ76rcXF5TeXj8MzxGY=",
"dev": true,
"requires": {
- "is-tar": "1.0.0",
- "object-assign": "2.1.1",
- "strip-dirs": "1.1.1",
- "tar-stream": "1.5.4",
- "through2": "0.6.5",
- "vinyl": "0.4.6"
+ "is-tar": "^1.0.0",
+ "object-assign": "^2.0.0",
+ "strip-dirs": "^1.0.0",
+ "tar-stream": "^1.1.1",
+ "through2": "^0.6.1",
+ "vinyl": "^0.4.3"
},
"dependencies": {
"clone": {
@@ -4706,8 +3927,8 @@
"integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
"dev": true,
"requires": {
- "clone": "0.2.0",
- "clone-stats": "0.0.1"
+ "clone": "^0.2.0",
+ "clone-stats": "^0.0.1"
}
}
}
@@ -4718,13 +3939,13 @@
"integrity": "sha1-iyOTVoE1X58YnYclag+L3ZbZZm0=",
"dev": true,
"requires": {
- "is-bzip2": "1.0.0",
- "object-assign": "2.1.1",
- "seek-bzip": "1.0.5",
- "strip-dirs": "1.1.1",
- "tar-stream": "1.5.4",
- "through2": "0.6.5",
- "vinyl": "0.4.6"
+ "is-bzip2": "^1.0.0",
+ "object-assign": "^2.0.0",
+ "seek-bzip": "^1.0.3",
+ "strip-dirs": "^1.0.0",
+ "tar-stream": "^1.1.1",
+ "through2": "^0.6.1",
+ "vinyl": "^0.4.3"
},
"dependencies": {
"clone": {
@@ -4745,8 +3966,8 @@
"integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
"dev": true,
"requires": {
- "clone": "0.2.0",
- "clone-stats": "0.0.1"
+ "clone": "^0.2.0",
+ "clone-stats": "^0.0.1"
}
}
}
@@ -4757,12 +3978,12 @@
"integrity": "sha1-ssE9+YFmJomRtxXWRH9kLpaW9aA=",
"dev": true,
"requires": {
- "is-gzip": "1.0.0",
- "object-assign": "2.1.1",
- "strip-dirs": "1.1.1",
- "tar-stream": "1.5.4",
- "through2": "0.6.5",
- "vinyl": "0.4.6"
+ "is-gzip": "^1.0.0",
+ "object-assign": "^2.0.0",
+ "strip-dirs": "^1.0.0",
+ "tar-stream": "^1.1.1",
+ "through2": "^0.6.1",
+ "vinyl": "^0.4.3"
},
"dependencies": {
"clone": {
@@ -4783,8 +4004,8 @@
"integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
"dev": true,
"requires": {
- "clone": "0.2.0",
- "clone-stats": "0.0.1"
+ "clone": "^0.2.0",
+ "clone-stats": "^0.0.1"
}
}
}
@@ -4795,53 +4016,29 @@
"integrity": "sha1-YUdbQVIGa74/7hL51inRX+ZHjus=",
"dev": true,
"requires": {
- "is-zip": "1.0.0",
- "read-all-stream": "3.1.0",
- "stat-mode": "0.2.2",
- "strip-dirs": "1.1.1",
- "through2": "2.0.3",
- "vinyl": "1.2.0",
- "yauzl": "2.4.1"
+ "is-zip": "^1.0.0",
+ "read-all-stream": "^3.0.0",
+ "stat-mode": "^0.2.0",
+ "strip-dirs": "^1.0.0",
+ "through2": "^2.0.0",
+ "vinyl": "^1.0.0",
+ "yauzl": "^2.2.1"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
}
},
"vinyl": {
@@ -4850,8 +4047,8 @@
"integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
"dev": true,
"requires": {
- "clone": "1.0.2",
- "clone-stats": "0.0.1",
+ "clone": "^1.0.0",
+ "clone-stats": "^0.0.1",
"replace-ext": "0.0.1"
}
}
@@ -4862,25 +4059,35 @@
"resolved": "https://registry.npmjs.org/decompress-zip/-/decompress-zip-0.3.0.tgz",
"integrity": "sha1-rjvLfjTGWHmt/nfhnDD4ZgK0vbA=",
"requires": {
- "binary": "0.3.0",
- "graceful-fs": "4.1.11",
- "mkpath": "0.1.0",
- "nopt": "3.0.6",
- "q": "1.5.0",
- "readable-stream": "1.1.14",
+ "binary": "^0.3.0",
+ "graceful-fs": "^4.1.3",
+ "mkpath": "^0.1.0",
+ "nopt": "^3.0.1",
+ "q": "^1.1.2",
+ "readable-stream": "^1.1.8",
"touch": "0.0.3"
},
"dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
"isarray": "0.0.1",
- "string_decoder": "0.10.31"
+ "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="
}
}
},
@@ -4908,9 +4115,9 @@
"dev": true
},
"deep-extend": {
- "version": "0.4.2",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.2.tgz",
- "integrity": "sha1-SLaZwn4zS/ifEIkr5DL25MfTSn8="
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.5.1.tgz",
+ "integrity": "sha512-N8vBdOa+DF7zkRrDCsaOXoCs/E2fJfx9B9MrKnnSiHNh4ws7eSys6YQE4KvT1cecKmOASYQBhbKjeuDD9lT81w=="
},
"deep-is": {
"version": "0.1.3",
@@ -4918,9 +4125,9 @@
"integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ="
},
"deepmerge": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz",
- "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ=="
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.1.0.tgz",
+ "integrity": "sha512-Q89Z26KAfA3lpPGhbF6XMfYAm3jIV3avViy6KOJ2JLzFbeWHOvPQUu5aSJIWXap3gDZC2y1eF5HXEPI2wGqgvw=="
},
"default-require-extensions": {
"version": "1.0.0",
@@ -4928,7 +4135,7 @@
"integrity": "sha1-836hXT4T/9m0N9M+GnW1+5eHTLg=",
"dev": true,
"requires": {
- "strip-bom": "2.0.0"
+ "strip-bom": "^2.0.0"
}
},
"defaults": {
@@ -4937,16 +4144,24 @@
"integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=",
"dev": true,
"requires": {
- "clone": "1.0.2"
+ "clone": "^1.0.2"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+ "dev": true
+ }
}
},
"deferred-leveldown": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-1.2.2.tgz",
- "integrity": "sha512-uukrWD2bguRtXilKt6cAWKyoXrTSMo5m7crUdLfWQmu8kIm88w3QZoUL+6nhpfKVmhHANER6Re3sKoNoZ3IKMA==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/deferred-leveldown/-/deferred-leveldown-3.0.0.tgz",
+ "integrity": "sha512-ajbXqRPMXRlcdyt0TuWqknOJkp1JgQjGB7xOl2V+ebol7/U11E9h3/nCZAtN1M7djmAJEIhypCUc1tIWxdQAuQ==",
"dev": true,
"requires": {
- "abstract-leveldown": "2.6.3"
+ "abstract-leveldown": "~4.0.0"
}
},
"define-properties": {
@@ -4955,8 +4170,8 @@
"integrity": "sha1-g6c/L+pWmJj7c3GTyPhzyvbUXJQ=",
"dev": true,
"requires": {
- "foreach": "2.0.5",
- "object-keys": "1.0.11"
+ "foreach": "^2.0.5",
+ "object-keys": "^1.0.8"
},
"dependencies": {
"object-keys": {
@@ -4967,33 +4182,64 @@
}
}
},
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "dependencies": {
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
"defined": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/defined/-/defined-1.0.0.tgz",
"integrity": "sha1-yY2bzvdWdBiOEQlpFRGZ45sfppM="
},
- "degenerator": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-1.0.4.tgz",
- "integrity": "sha1-/PSQo37OJmRk2cxDGrmMWBnO0JU=",
- "requires": {
- "ast-types": "0.10.1",
- "escodegen": "1.9.0",
- "esprima": "3.1.3"
- }
- },
"deglob": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/deglob/-/deglob-2.1.0.tgz",
"integrity": "sha1-TUSr4W7zLHebSXK9FBqAMlApoUo=",
"dev": true,
"requires": {
- "find-root": "1.1.0",
- "glob": "7.1.2",
- "ignore": "3.3.5",
- "pkg-config": "1.1.1",
- "run-parallel": "1.1.6",
- "uniq": "1.0.1"
+ "find-root": "^1.0.0",
+ "glob": "^7.0.5",
+ "ignore": "^3.0.9",
+ "pkg-config": "^1.1.0",
+ "run-parallel": "^1.1.2",
+ "uniq": "^1.0.1"
}
},
"del": {
@@ -5001,13 +4247,13 @@
"resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
"integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
"requires": {
- "globby": "5.0.0",
- "is-path-cwd": "1.0.0",
- "is-path-in-cwd": "1.0.0",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1",
- "rimraf": "2.6.2"
+ "globby": "^5.0.0",
+ "is-path-cwd": "^1.0.0",
+ "is-path-in-cwd": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "rimraf": "^2.2.8"
}
},
"delayed-stream": {
@@ -5021,9 +4267,10 @@
"integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o="
},
"depd": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
- "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=",
+ "dev": true
},
"deprecated": {
"version": "0.0.1",
@@ -5037,32 +4284,35 @@
"integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=",
"dev": true,
"requires": {
- "inherits": "2.0.3",
- "minimalistic-assert": "1.0.0"
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0"
}
},
"destroy": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
- "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=",
+ "dev": true
},
"detect-file": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-0.1.0.tgz",
- "integrity": "sha1-STXe39lIhkjgBrASlWbpOGcR6mM=",
- "dev": true,
- "requires": {
- "fs-exists-sync": "0.1.0"
- }
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=",
+ "dev": true
},
"detect-indent": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz",
"integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=",
"requires": {
- "repeating": "2.0.1"
+ "repeating": "^2.0.0"
}
},
+ "detect-libc": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
+ "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
+ },
"detect-node": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.3.tgz",
@@ -5080,8 +4330,8 @@
"resolved": "https://registry.npmjs.org/dezalgo/-/dezalgo-1.0.3.tgz",
"integrity": "sha1-f3Qt4Gb8dIvI24IFad3c5Jvw1FY=",
"requires": {
- "asap": "2.0.6",
- "wrappy": "1.0.2"
+ "asap": "^2.0.0",
+ "wrappy": "1"
}
},
"diff": {
@@ -5091,20 +4341,20 @@
"dev": true
},
"diffie-hellman": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.2.tgz",
- "integrity": "sha1-tYNXOScM/ias9jIJn97SoH8gnl4=",
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz",
+ "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==",
"dev": true,
"requires": {
- "bn.js": "4.11.8",
- "miller-rabin": "4.0.0",
- "randombytes": "2.0.5"
+ "bn.js": "^4.1.0",
+ "miller-rabin": "^4.0.0",
+ "randombytes": "^2.0.0"
}
},
"disposables": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/disposables/-/disposables-1.0.1.tgz",
- "integrity": "sha1-BkcnoltU9QK9griaot+4358bOeM="
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/disposables/-/disposables-1.0.2.tgz",
+ "integrity": "sha1-NsamdEdfVaLWkTVnpgFETkh7S24="
},
"dmg-builder": {
"version": "3.1.4",
@@ -5112,76 +4362,23 @@
"integrity": "sha512-nobhBdmpA8XmJM13rjvhLQOMUUM9HNyZjXmvFWCZPK8A8sP2rJciQDOzvJoc2ioFehR7vfLbWHNpKgYQrSPIPw==",
"dev": true,
"requires": {
- "bluebird-lst": "1.0.5",
- "builder-util": "4.2.2",
- "fs-extra-p": "4.5.0",
- "iconv-lite": "0.4.19",
- "js-yaml": "3.10.0",
- "parse-color": "1.0.0"
- },
- "dependencies": {
- "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
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.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
- },
- "jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
- }
+ "bluebird-lst": "^1.0.5",
+ "builder-util": "^4.2.2",
+ "fs-extra-p": "^4.5.0",
+ "iconv-lite": "^0.4.19",
+ "js-yaml": "^3.10.0",
+ "parse-color": "^1.0.0"
}
},
"dnd-core": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-2.5.1.tgz",
- "integrity": "sha1-F49a1lJs4C3VlQjxFVNfe/wM6U4=",
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-2.6.0.tgz",
+ "integrity": "sha1-ErrWbVh0LG5ffPKUP7aFlED4CcQ=",
"requires": {
- "asap": "2.0.6",
- "invariant": "2.2.2",
- "lodash": "4.17.4",
- "redux": "3.7.2"
+ "asap": "^2.0.6",
+ "invariant": "^2.0.0",
+ "lodash": "^4.2.0",
+ "redux": "^3.7.1"
}
},
"dns-equal": {
@@ -5191,13 +4388,13 @@
"dev": true
},
"dns-packet": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.2.2.tgz",
- "integrity": "sha512-kN+DjfGF7dJGUL7nWRktL9Z18t1rWP3aQlyZdY8XlpvU3Nc6GeFTQApftcjtWKxAZfiggZSGrCEoszNgvnpwDg==",
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz",
+ "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==",
"dev": true,
"requires": {
- "ip": "1.1.5",
- "safe-buffer": "5.1.1"
+ "ip": "^1.1.0",
+ "safe-buffer": "^5.0.1"
}
},
"dns-txt": {
@@ -5206,45 +4403,37 @@
"integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=",
"dev": true,
"requires": {
- "buffer-indexof": "1.1.1"
+ "buffer-indexof": "^1.0.0"
}
},
"doctrine": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
- "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
- "dev": true,
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz",
+ "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==",
"requires": {
- "esutils": "2.0.2",
- "isarray": "1.0.0"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- }
+ "esutils": "^2.0.2"
}
},
"dom-helpers": {
- "version": "3.2.1",
- "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.2.1.tgz",
- "integrity": "sha1-MgPgf+0he9H0JLAZc1WC/Deyglo="
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.3.1.tgz",
+ "integrity": "sha512-2Sm+JaYn74OiTM2wHvxJOo3roiq/h25Yi69Fqk269cNUwIXsCvATB6CRSFC9Am/20G2b28hGv/+7NiWydIrPvg=="
},
"dom-serializer": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.0.tgz",
"integrity": "sha1-BzxpdUbOB4DOI75KKOKT5AvDDII=",
+ "dev": true,
"requires": {
- "domelementtype": "1.1.3",
- "entities": "1.1.1"
+ "domelementtype": "~1.1.1",
+ "entities": "~1.1.1"
},
"dependencies": {
"domelementtype": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.1.3.tgz",
- "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs="
+ "integrity": "sha1-vSh3PiZCiBrsUVRJJCmcXNgiGFs=",
+ "dev": true
}
}
},
@@ -5254,31 +4443,34 @@
"integrity": "sha1-ZyIm3HTI95mtNTB9+TaroRrNYBg="
},
"domain-browser": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.1.7.tgz",
- "integrity": "sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz",
+ "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==",
"dev": true
},
"domelementtype": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.0.tgz",
- "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI="
+ "integrity": "sha1-sXrtguirWeUt2cGbF1bg/BhyBMI=",
+ "dev": true
},
"domhandler": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.1.tgz",
- "integrity": "sha1-iS5HAAqZvlW783dP/qBWHYh5wlk=",
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz",
+ "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==",
+ "dev": true,
"requires": {
- "domelementtype": "1.3.0"
+ "domelementtype": "1"
}
},
"domutils": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.6.2.tgz",
- "integrity": "sha1-GVjMC0yUJuntNn+xyOhUiRsPo/8=",
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
+ "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
+ "dev": true,
"requires": {
- "dom-serializer": "0.1.0",
- "domelementtype": "1.3.0"
+ "dom-serializer": "0",
+ "domelementtype": "1"
}
},
"dot-prop": {
@@ -5287,7 +4479,7 @@
"integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
"dev": true,
"requires": {
- "is-obj": "1.0.1"
+ "is-obj": "^1.0.0"
}
},
"dotenv": {
@@ -5297,28 +4489,16 @@
"dev": true
},
"dotenv-expand": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.0.1.tgz",
- "integrity": "sha1-aP3cFWGBTgoQlkERBX/xOM7X16g=",
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz",
+ "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=",
"dev": true
},
- "drbg.js": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/drbg.js/-/drbg.js-1.0.1.tgz",
- "integrity": "sha1-Pja2xCs3BDgjzbwzLVjzHiRFSAs=",
- "requires": {
- "browserify-aes": "1.0.8",
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6"
- }
- },
"dtrace-provider": {
- "version": "0.8.5",
- "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.5.tgz",
- "integrity": "sha1-mOu6Ihr6xG4cOf02hY2Pk2dSS5I=",
- "optional": true,
+ "version": "github:brave/node-dtrace-provider#a7cdc53514e631ce536ef7fe0d526af17e246b53",
+ "from": "github:brave/node-dtrace-provider",
"requires": {
- "nan": "2.7.0"
+ "nan": "^2.3.3"
}
},
"duplexer2": {
@@ -5327,20 +4507,32 @@
"integrity": "sha1-xhTc9n4vsUmVqRcR5aYX6KYKMds=",
"dev": true,
"requires": {
- "readable-stream": "1.1.14"
+ "readable-stream": "~1.1.9"
},
"dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true,
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
"isarray": "0.0.1",
- "string_decoder": "0.10.31"
+ "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
}
}
},
@@ -5351,47 +4543,15 @@
"dev": true
},
"duplexify": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.5.1.tgz",
- "integrity": "sha512-j5goxHTwVED1Fpe5hh3q9R93Kip0Bg2KVAt4f8CEYM3UEwYcPSvWbXaUQOzdX/HtiNomipv+gU7ASQPDbV7pGQ==",
+ "version": "3.6.0",
+ "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.6.0.tgz",
+ "integrity": "sha512-fO3Di4tBKJpYTFHAxTU00BcfWMY9w24r/x21a6rZRbsD/ToUgGxsMbiGRmB7uVAXeGKXD9MwiLZa5E97EVgIRQ==",
"dev": true,
"requires": {
- "end-of-stream": "1.4.0",
- "inherits": "2.0.3",
- "readable-stream": "2.3.3",
- "stream-shift": "1.0.0"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "end-of-stream": "^1.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0",
+ "stream-shift": "^1.0.0"
}
},
"ecc-jsbn": {
@@ -5400,48 +4560,40 @@
"integrity": "sha1-D8c6ntXw1Tw4GTOYUj735UN3dQU=",
"optional": true,
"requires": {
- "jsbn": "0.1.1"
- }
- },
- "ecurve": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/ecurve/-/ecurve-1.0.6.tgz",
- "integrity": "sha512-/BzEjNfiSuB7jIWKcS/z8FK9jNjmEWvUV2YZ4RLSmcDtP7Lq0m6FvDuSnJpBlDpGRpfRQeTLGLBI8H+kEv0r+w==",
- "requires": {
- "bigi": "1.4.0",
- "safe-buffer": "5.1.1"
+ "jsbn": "~0.1.0"
}
},
"ee-first": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
- "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=",
+ "dev": true
},
"ejs": {
- "version": "2.5.7",
- "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.7.tgz",
- "integrity": "sha1-zIcsFoiArjxxiXYv1f/ACJbJUYo=",
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.6.1.tgz",
+ "integrity": "sha512-0xy4A/twfrRCnkhfk8ErDi5DqdAsAqeGxht4xkCUrsvhhbQNs7E+4jV0CN7+NKIY0aHE72+XvqtBIXzD31ZbXQ==",
"dev": true
},
"electron-builder": {
- "version": "19.56.0",
- "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-19.56.0.tgz",
- "integrity": "sha512-3jlhgF/KuwzJRuPIa4YmZc1OrE1y2L+QEHk4W9B8Sx3ig3hK84b+yW8MfhQxwwEhYnA1q9XkzcNK5xToZPqpWQ==",
+ "version": "19.56.2",
+ "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-19.56.2.tgz",
+ "integrity": "sha512-3t6FY4Q/TPwkuL5XKSssBD0GKudWjYfMJcDIVWOE2okBfMB3LYkRj2FWG4ZxJ1FcybXLFSswQQZVbwiYpLIYxA==",
"dev": true,
"requires": {
- "bluebird-lst": "1.0.5",
- "builder-util": "4.2.2",
+ "bluebird-lst": "^1.0.5",
+ "builder-util": "4.2.4",
"builder-util-runtime": "4.0.4",
- "chalk": "2.3.0",
- "electron-builder-lib": "19.56.0",
+ "chalk": "^2.3.0",
+ "electron-builder-lib": "19.56.2",
"electron-download-tf": "4.3.4",
- "fs-extra-p": "4.5.0",
- "is-ci": "1.1.0",
- "lazy-val": "1.0.3",
+ "fs-extra-p": "^4.5.0",
+ "is-ci": "^1.1.0",
+ "lazy-val": "^1.0.3",
"read-config-file": "2.1.1",
- "sanitize-filename": "1.6.1",
- "update-notifier": "2.3.0",
- "yargs": "11.0.0"
+ "sanitize-filename": "^1.6.1",
+ "update-notifier": "^2.3.0",
+ "yargs": "^11.0.0"
},
"dependencies": {
"ansi-regex": {
@@ -5450,134 +4602,21 @@
"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==",
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
"dev": true,
"requires": {
- "color-convert": "1.9.1"
- }
- },
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
- "dev": true
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
- "camelcase": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
- "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
- "dev": true
- },
- "chalk": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
- "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
- "dev": true,
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.5.0"
- }
- },
- "cliui": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.0.0.tgz",
- "integrity": "sha512-nY3W5Gu2racvdDk//ELReY+dHjb9PlIcVDFXP72nVIhq2Gy3LuVXYwJoPVudwQnv1shtohpgkdCKT2YaKY0CKw==",
- "dev": true,
- "requires": {
- "string-width": "2.1.1",
- "strip-ansi": "4.0.0",
- "wrap-ansi": "2.1.0"
- }
- },
- "color-convert": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
- "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"
- }
- },
- "electron-download-tf": {
- "version": "4.3.4",
- "resolved": "https://registry.npmjs.org/electron-download-tf/-/electron-download-tf-4.3.4.tgz",
- "integrity": "sha512-SQYDGMLpTgty1bx3NycuDb7dNPzktVSdK2sqPZjyRocauq/uN/V4S2lcpFVLupaHhKlD8zozm9fTpm5UdohvTg==",
- "dev": true,
- "requires": {
- "debug": "3.1.0",
- "env-paths": "1.0.0",
- "fs-extra": "4.0.3",
- "minimist": "1.2.0",
- "nugget": "2.0.1",
- "path-exists": "3.0.0",
- "rc": "1.2.1",
- "semver": "5.4.1",
- "sumchecker": "2.0.2"
- }
- },
- "fs-extra": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
- "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.0.0"
- },
- "dependencies": {
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- }
- }
- },
- "is-ci": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
- "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
- "dev": true,
- "requires": {
- "ci-info": "1.1.1"
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0",
+ "wrap-ansi": "^2.0.0"
}
},
"is-fullwidth-code-point": {
@@ -5586,30 +4625,15 @@
"integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
"dev": true
},
- "jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"os-locale": {
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
"integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
"dev": true,
"requires": {
- "execa": "0.7.0",
- "lcid": "1.0.0",
- "mem": "1.1.0"
+ "execa": "^0.7.0",
+ "lcid": "^1.0.0",
+ "mem": "^1.1.0"
}
},
"string-width": {
@@ -5618,8 +4642,8 @@
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"dev": true,
"requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
@@ -5628,33 +4652,7 @@
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
- "ansi-regex": "3.0.0"
- }
- },
- "supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
- "dev": true,
- "requires": {
- "has-flag": "2.0.0"
- }
- },
- "update-notifier": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.3.0.tgz",
- "integrity": "sha1-TognpruRUUCrCTVZ1wFOPruDdFE=",
- "dev": true,
- "requires": {
- "boxen": "1.2.1",
- "chalk": "2.3.0",
- "configstore": "3.1.1",
- "import-lazy": "2.1.0",
- "is-installed-globally": "0.1.0",
- "is-npm": "1.0.0",
- "latest-version": "3.1.0",
- "semver-diff": "2.1.0",
- "xdg-basedir": "3.0.0"
+ "ansi-regex": "^3.0.0"
}
},
"which-module": {
@@ -5669,18 +4667,18 @@
"integrity": "sha512-Rjp+lMYQOWtgqojx1dEWorjCofi1YN7AoFvYV7b1gx/7dAAeuI4kN5SZiEvr0ZmsZTOpDRcCqrpI10L31tFkBw==",
"dev": true,
"requires": {
- "cliui": "4.0.0",
- "decamelize": "1.2.0",
- "find-up": "2.1.0",
- "get-caller-file": "1.0.2",
- "os-locale": "2.1.0",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "2.1.1",
- "which-module": "2.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "9.0.2"
+ "cliui": "^4.0.0",
+ "decamelize": "^1.1.1",
+ "find-up": "^2.1.0",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^2.0.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^2.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^9.0.2"
}
},
"yargs-parser": {
@@ -5689,102 +4687,44 @@
"integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
"dev": true,
"requires": {
- "camelcase": "4.1.0"
+ "camelcase": "^4.1.0"
}
}
}
},
"electron-builder-lib": {
- "version": "19.56.0",
- "resolved": "https://registry.npmjs.org/electron-builder-lib/-/electron-builder-lib-19.56.0.tgz",
- "integrity": "sha512-7uZRo/bh/o8MLS1PZQyXKua7GZ5qwJbQgvsnSanXIp/qBisaPMOyydYEcJcJDLomfStgRubbtWG82eDNKCeiLA==",
+ "version": "19.56.2",
+ "resolved": "https://registry.npmjs.org/electron-builder-lib/-/electron-builder-lib-19.56.2.tgz",
+ "integrity": "sha512-yZ1WtRqjbnT/ENVIAxqg4yJMQ/7PnokRdcym139ZvLAxv32Lt43HDVyCRvYOZPFeWKlD69aVfQLF4prXfEyROA==",
"dev": true,
"requires": {
- "7zip-bin": "2.4.1",
+ "7zip-bin": "~3.0.0",
"asar-integrity": "0.2.4",
- "async-exit-hook": "2.0.1",
- "bluebird-lst": "1.0.5",
- "builder-util": "4.2.2",
+ "async-exit-hook": "^2.0.1",
+ "bluebird-lst": "^1.0.5",
+ "builder-util": "4.2.4",
"builder-util-runtime": "4.0.4",
- "chromium-pickle-js": "0.2.0",
- "debug": "3.1.0",
+ "chromium-pickle-js": "^0.2.0",
+ "debug": "^3.1.0",
"dmg-builder": "3.1.4",
- "ejs": "2.5.7",
+ "ejs": "^2.5.7",
"electron-osx-sign": "0.4.8",
"electron-publish": "19.56.0",
- "fs-extra-p": "4.5.0",
- "hosted-git-info": "2.5.0",
- "is-ci": "1.1.0",
- "isbinaryfile": "3.0.2",
- "js-yaml": "3.10.0",
- "lazy-val": "1.0.3",
- "minimatch": "3.0.4",
- "normalize-package-data": "2.4.0",
- "plist": "2.1.0",
+ "fs-extra-p": "^4.5.0",
+ "hosted-git-info": "^2.5.0",
+ "is-ci": "^1.1.0",
+ "isbinaryfile": "^3.0.2",
+ "js-yaml": "^3.10.0",
+ "lazy-val": "^1.0.3",
+ "minimatch": "^3.0.4",
+ "normalize-package-data": "^2.4.0",
+ "plist": "^2.1.0",
"read-config-file": "2.1.1",
- "sanitize-filename": "1.6.1",
- "semver": "5.5.0",
- "temp-file": "3.1.1"
+ "sanitize-filename": "^1.6.1",
+ "semver": "^5.5.0",
+ "temp-file": "^3.1.1"
},
"dependencies": {
- "7zip-bin": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-2.4.1.tgz",
- "integrity": "sha512-QU3oR1dLLVrYGRkb7LU17jMCpIkWtXXW7q71ECXWXkR9vOv37VjykqpvFgs29HgSCNLZHnNKJzdG6RwAW0LwIA==",
- "dev": true,
- "requires": {
- "7zip-bin-mac": "1.0.1"
- }
- },
- "7zip-bin-linux": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/7zip-bin-linux/-/7zip-bin-linux-1.3.1.tgz",
- "integrity": "sha512-Wv1uEEeHbTiS1+ycpwUxYNuIcyohU6Y6vEqY3NquBkeqy0YhVdsNUGsj0XKSRciHR6LoJSEUuqYUexmws3zH7Q=="
- },
- "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.1"
- }
- },
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
- "dev": true
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
- "chalk": {
- "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.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.5.0"
- }
- },
- "color-convert": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -5793,74 +4733,73 @@
"requires": {
"ms": "2.0.0"
}
- },
- "electron-osx-sign": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.8.tgz",
- "integrity": "sha1-8Ln63e2eHlTsNfqJh3tcbDTHvEA=",
+ }
+ }
+ },
+ "electron-chromedriver": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-1.8.0.tgz",
+ "integrity": "sha512-m1f3nle5MaGp94bcDTtMZZMMOgPO54+TXoPBlTbBSUjfINR5SJ46yQXLfuE79/qsFfJKslZB1UzWURDDFIRmpQ==",
+ "dev": true,
+ "requires": {
+ "electron-download": "^4.1.0",
+ "extract-zip": "^1.6.5"
+ },
+ "dependencies": {
+ "electron-download": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.0.tgz",
+ "integrity": "sha1-v5MsdG8vh//MCdHdRy8v9rkYeEU=",
"dev": true,
"requires": {
- "bluebird": "3.5.1",
- "compare-version": "0.1.2",
- "debug": "2.6.9",
- "isbinaryfile": "3.0.2",
- "minimist": "1.2.0",
- "plist": "2.1.0"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.9",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
- "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
+ "debug": "^2.2.0",
+ "env-paths": "^1.0.0",
+ "fs-extra": "^2.0.0",
+ "minimist": "^1.2.0",
+ "nugget": "^2.0.0",
+ "path-exists": "^3.0.0",
+ "rc": "^1.1.2",
+ "semver": "^5.3.0",
+ "sumchecker": "^2.0.1"
}
- },
- "electron-publish": {
- "version": "19.56.0",
- "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-19.56.0.tgz",
- "integrity": "sha512-mJYJLaDKdxq/F1VAZwqany4LuWt9fEm2FMsKVCXdzYp1WAXhK5+J5Ng6rxc8n1BUWqYbs99tkRWp+5iyxiGcfA==",
+ }
+ }
+ },
+ "electron-download-tf": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmjs.org/electron-download-tf/-/electron-download-tf-4.3.4.tgz",
+ "integrity": "sha512-SQYDGMLpTgty1bx3NycuDb7dNPzktVSdK2sqPZjyRocauq/uN/V4S2lcpFVLupaHhKlD8zozm9fTpm5UdohvTg==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.0.0",
+ "env-paths": "^1.0.0",
+ "fs-extra": "^4.0.1",
+ "minimist": "^1.2.0",
+ "nugget": "^2.0.1",
+ "path-exists": "^3.0.0",
+ "rc": "^1.2.1",
+ "semver": "^5.4.1",
+ "sumchecker": "^2.0.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"dev": true,
"requires": {
- "bluebird-lst": "1.0.5",
- "builder-util": "4.2.2",
- "builder-util-runtime": "4.0.4",
- "chalk": "2.3.0",
- "fs-extra-p": "4.5.0",
- "mime": "2.2.0"
+ "ms": "2.0.0"
}
},
"fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.0.0"
- }
- },
- "is-ci": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
- "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
"dev": true,
"requires": {
- "ci-info": "1.1.1"
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
}
},
"jsonfile": {
@@ -5869,137 +4808,110 @@
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11"
- }
- },
- "mime": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/mime/-/mime-2.2.0.tgz",
- "integrity": "sha512-0Qz9uF1ATtl8RKJG4VRfOymh7PyEor6NbrI/61lRfuRe4vx9SNATrvAeTj2EWVRKjEQGskrzWkJBBY5NbaVHIA==",
- "dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
- "semver": {
- "version": "5.5.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
- "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
- "dev": true
- },
- "supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
- "dev": true,
- "requires": {
- "has-flag": "2.0.0"
- }
- }
- }
- },
- "electron-chromedriver": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-1.7.1.tgz",
- "integrity": "sha1-AIyXl2AHqk6xhJHuCV6U0X7kdhA=",
- "dev": true,
- "requires": {
- "electron-download": "4.1.0",
- "extract-zip": "1.6.5"
- },
- "dependencies": {
- "electron-download": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.0.tgz",
- "integrity": "sha1-v5MsdG8vh//MCdHdRy8v9rkYeEU=",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "env-paths": "1.0.0",
- "fs-extra": "2.1.2",
- "minimist": "1.2.0",
- "nugget": "2.0.1",
- "path-exists": "3.0.0",
- "rc": "1.2.1",
- "semver": "5.4.1",
- "sumchecker": "2.0.2"
+ "graceful-fs": "^4.1.6"
}
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
}
}
},
"electron-installer-debian": {
- "version": "github:brave/electron-installer-debian#5f37713f52437678e5cbf9b17500fba4ae7cb5ad",
+ "version": "0.5.2",
+ "resolved": "github:brave/electron-installer-debian#5f37713f52437678e5cbf9b17500fba4ae7cb5ad",
"optional": true,
"requires": {
- "asar": "0.13.0",
- "async": "2.5.0",
- "debug": "2.6.9",
- "fs-extra": "1.0.0",
- "get-folder-size": "1.0.1",
- "glob": "7.1.2",
- "lodash": "4.17.4",
- "temp": "0.8.3",
- "word-wrap": "1.2.3",
- "yargs": "7.1.0"
+ "asar": "^0.13.0",
+ "async": "^2.0.0",
+ "debug": "^2.2.0",
+ "fs-extra": "^1.0.0",
+ "get-folder-size": "^1.0.0",
+ "glob": "^7.0.0",
+ "lodash": "^4.13.0",
+ "temp": "^0.8.3",
+ "word-wrap": "^1.1.0",
+ "yargs": "^7.0.2"
},
"dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "optional": true
+ },
"fs-extra": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-1.0.0.tgz",
"integrity": "sha1-zTzl9+fLYUWIP8rjGR6Yd/hYeVA=",
"optional": true,
"requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "2.4.0",
- "klaw": "1.3.1"
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0"
+ }
+ },
+ "yargs": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
+ "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
+ "optional": true,
+ "requires": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.0"
}
}
}
},
"electron-installer-redhat": {
- "version": "github:brave/electron-installer-redhat#442d0c83fa3cfea853d69857e6806e2bb5e8fe72",
+ "version": "0.5.0",
+ "resolved": "github:brave/electron-installer-redhat#442d0c83fa3cfea853d69857e6806e2bb5e8fe72",
"optional": true,
"requires": {
- "asar": "0.13.0",
- "async": "2.5.0",
- "debug": "2.6.9",
- "fs-extra": "2.1.2",
- "glob": "7.1.2",
- "lodash": "4.17.4",
- "parse-author": "2.0.0",
- "temp": "0.8.3",
- "word-wrap": "1.2.3",
+ "asar": "^0.13.0",
+ "async": "^2.1.5",
+ "debug": "^2.6.3",
+ "fs-extra": "^2.1.2",
+ "glob": "^7.1.1",
+ "lodash": "^4.17.4",
+ "parse-author": "^2.0.0",
+ "temp": "^0.8.3",
+ "word-wrap": "^1.2.1",
"yargs": "7.0.2"
},
"dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "optional": true
+ },
"yargs": {
"version": "7.0.2",
"resolved": "https://registry.npmjs.org/yargs/-/yargs-7.0.2.tgz",
"integrity": "sha1-EVuX3xMhgj6Lhkjolox4JSEiH2c=",
"optional": true,
"requires": {
- "camelcase": "3.0.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.2",
- "os-locale": "1.4.0",
- "read-pkg-up": "1.0.1",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "1.0.2",
- "which-module": "1.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "5.0.0"
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.0"
}
}
}
@@ -6009,21 +4921,36 @@
"resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-0.6.1.tgz",
"integrity": "sha1-xOJow4puQvQN5WGPyQbR7WCPEao="
},
+ "electron-osx-sign": {
+ "version": "0.4.8",
+ "resolved": "https://registry.npmjs.org/electron-osx-sign/-/electron-osx-sign-0.4.8.tgz",
+ "integrity": "sha1-8Ln63e2eHlTsNfqJh3tcbDTHvEA=",
+ "dev": true,
+ "requires": {
+ "bluebird": "^3.5.0",
+ "compare-version": "^0.1.2",
+ "debug": "^2.6.8",
+ "isbinaryfile": "^3.0.2",
+ "minimist": "^1.2.0",
+ "plist": "^2.1.0"
+ }
+ },
"electron-packager": {
"version": "github:brave/electron-packager#0dcbc2d5b56b058e8ee9a2ec1f43f96d94f4925e",
+ "from": "github:brave/electron-packager",
"dev": true,
"requires": {
- "asar": "0.11.0",
+ "asar": "^0.11.0",
"electron-download": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c",
- "electron-osx-sign": "0.3.2",
- "extract-zip": "1.6.5",
- "fs-extra": "0.28.0",
+ "electron-osx-sign": "^0.3.0",
+ "extract-zip": "^1.0.3",
+ "fs-extra": "^0.28.0",
"get-package-info": "0.0.2",
- "minimist": "1.2.0",
- "plist": "1.2.0",
- "rcedit": "0.5.1",
- "resolve": "1.4.0",
- "run-series": "1.1.4"
+ "minimist": "^1.1.1",
+ "plist": "^1.1.0",
+ "rcedit": "^0.5.0",
+ "resolve": "^1.1.6",
+ "run-series": "^1.1.1"
},
"dependencies": {
"asar": {
@@ -6032,13 +4959,13 @@
"integrity": "sha1-uSbnksMV+MBIxDNx4yWwnJenZGQ=",
"dev": true,
"requires": {
- "chromium-pickle-js": "0.1.0",
- "commander": "2.11.0",
- "cuint": "0.2.2",
- "glob": "6.0.4",
- "minimatch": "3.0.4",
- "mkdirp": "0.5.1",
- "mksnapshot": "0.3.1"
+ "chromium-pickle-js": "^0.1.0",
+ "commander": "^2.9.0",
+ "cuint": "^0.2.1",
+ "glob": "^6.0.4",
+ "minimatch": "^3.0.0",
+ "mkdirp": "^0.5.0",
+ "mksnapshot": "^0.3.0"
}
},
"base64-js": {
@@ -6055,16 +4982,17 @@
},
"electron-download": {
"version": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c",
+ "from": "github:brave/electron-download",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "home-path": "1.0.5",
- "minimist": "1.2.0",
- "mkdirp": "0.5.1",
- "mv": "2.1.1",
- "nugget": "1.6.2",
- "path-exists": "1.0.0",
- "rc": "1.2.1"
+ "debug": "^2.2.0",
+ "home-path": "^1.0.1",
+ "minimist": "^1.2.0",
+ "mkdirp": "^0.5.0",
+ "mv": "^2.0.3",
+ "nugget": "^1.5.1",
+ "path-exists": "^1.0.0",
+ "rc": "^1.1.2"
}
},
"electron-osx-sign": {
@@ -6073,9 +5001,9 @@
"integrity": "sha1-iPp9brrbXZx5NouWSRoNjEYwFG4=",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "minimist": "1.2.0",
- "run-series": "1.1.4"
+ "debug": "^2.2.0",
+ "minimist": "^1.1.1",
+ "run-series": "^1.1.1"
}
},
"fs-extra": {
@@ -6084,11 +5012,11 @@
"integrity": "sha1-mhwHCOqMUWkperBv2MuRT1ZHsnI=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "2.4.0",
- "klaw": "1.3.1",
- "path-is-absolute": "1.0.1",
- "rimraf": "2.6.2"
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
}
},
"glob": {
@@ -6097,11 +5025,11 @@
"integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
"dev": true,
"requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
}
},
"lodash": {
@@ -6110,24 +5038,18 @@
"integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y=",
"dev": true
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"nugget": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz",
"integrity": "sha1-iMpuA7pXBqmRc/XaCQJZPWvK4Qc=",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "minimist": "1.2.0",
- "pretty-bytes": "1.0.4",
- "progress-stream": "1.2.0",
- "request": "2.82.0",
- "single-line-log": "0.4.1",
+ "debug": "^2.1.3",
+ "minimist": "^1.1.0",
+ "pretty-bytes": "^1.0.2",
+ "progress-stream": "^1.1.0",
+ "request": "^2.45.0",
+ "single-line-log": "^0.4.1",
"throttleit": "0.0.2"
}
},
@@ -6146,7 +5068,7 @@
"base64-js": "0.0.8",
"util-deprecate": "1.0.2",
"xmlbuilder": "4.0.0",
- "xmldom": "0.1.27"
+ "xmldom": "0.1.x"
}
},
"single-line-log": {
@@ -6167,51 +5089,47 @@
"integrity": "sha1-mLj2UcowqmJANvEn0RzGbce5B6M=",
"dev": true,
"requires": {
- "lodash": "3.10.1"
+ "lodash": "^3.5.0"
}
}
}
},
"electron-prebuilt": {
"version": "github:brave/electron-prebuilt#e65e72f4bc7a8e7de160667f3eb3c2b22e3e395e",
+ "from": "github:brave/electron-prebuilt",
"dev": true,
"requires": {
"electron-download": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c",
- "extract-zip": "1.6.5"
+ "extract-zip": "^1.0.3"
},
"dependencies": {
"electron-download": {
"version": "github:brave/electron-download#409b65caff14edeef1daa36a7445ba6334658d7c",
+ "from": "github:brave/electron-download",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "home-path": "1.0.5",
- "minimist": "1.2.0",
- "mkdirp": "0.5.1",
- "mv": "2.1.1",
- "nugget": "1.6.2",
- "path-exists": "1.0.0",
- "rc": "1.2.1"
+ "debug": "^2.2.0",
+ "home-path": "^1.0.1",
+ "minimist": "^1.2.0",
+ "mkdirp": "^0.5.0",
+ "mv": "^2.0.3",
+ "nugget": "^1.5.1",
+ "path-exists": "^1.0.0",
+ "rc": "^1.1.2"
}
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"nugget": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/nugget/-/nugget-1.6.2.tgz",
"integrity": "sha1-iMpuA7pXBqmRc/XaCQJZPWvK4Qc=",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "minimist": "1.2.0",
- "pretty-bytes": "1.0.4",
- "progress-stream": "1.2.0",
- "request": "2.82.0",
- "single-line-log": "0.4.1",
+ "debug": "^2.1.3",
+ "minimist": "^1.1.0",
+ "pretty-bytes": "^1.0.2",
+ "progress-stream": "^1.1.0",
+ "request": "^2.45.0",
+ "single-line-log": "^0.4.1",
"throttleit": "0.0.2"
}
},
@@ -6235,30 +5153,54 @@
}
}
},
+ "electron-publish": {
+ "version": "19.56.0",
+ "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-19.56.0.tgz",
+ "integrity": "sha512-mJYJLaDKdxq/F1VAZwqany4LuWt9fEm2FMsKVCXdzYp1WAXhK5+J5Ng6rxc8n1BUWqYbs99tkRWp+5iyxiGcfA==",
+ "dev": true,
+ "requires": {
+ "bluebird-lst": "^1.0.5",
+ "builder-util": "^4.2.2",
+ "builder-util-runtime": "^4.0.4",
+ "chalk": "^2.3.0",
+ "fs-extra-p": "^4.5.0",
+ "mime": "^2.2.0"
+ },
+ "dependencies": {
+ "mime": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+ "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg==",
+ "dev": true
+ }
+ }
+ },
"electron-squirrel-startup": {
"version": "github:brave/electron-squirrel-startup#88d78fee0079d7bfce7e5238658e54e2e75550ef",
+ "from": "github:brave/electron-squirrel-startup",
"requires": {
- "debug": "2.6.9"
+ "debug": "^2.2.0"
}
},
"electron-to-chromium": {
- "version": "1.3.22",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.22.tgz",
- "integrity": "sha1-QyLVLBUUBuPq73StAmdog+hBZBg=",
+ "version": "1.3.47",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.47.tgz",
+ "integrity": "sha1-dk6IfKkQTQGgrI6r7n38DizhQQQ=",
"dev": true
},
"elliptic": {
"version": "6.4.0",
"resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.4.0.tgz",
"integrity": "sha1-ysmvh2LIWDYYcAPI3+GT5eLq5d8=",
+ "dev": true,
"requires": {
- "bn.js": "4.11.8",
- "brorand": "1.1.0",
- "hash.js": "1.1.3",
- "hmac-drbg": "1.0.1",
- "inherits": "2.0.3",
- "minimalistic-assert": "1.0.0",
- "minimalistic-crypto-utils": "1.0.1"
+ "bn.js": "^4.4.0",
+ "brorand": "^1.0.1",
+ "hash.js": "^1.0.0",
+ "hmac-drbg": "^1.0.0",
+ "inherits": "^2.0.1",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.0"
}
},
"emoji-regex": {
@@ -6278,24 +5220,37 @@
"dev": true
},
"encodeurl": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.1.tgz",
- "integrity": "sha1-eePVhlU0aQn+bw9Fpd5oEDspTSA="
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=",
+ "dev": true
},
"encoding": {
"version": "0.1.12",
"resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.12.tgz",
"integrity": "sha1-U4tm8+5izRq1HsMjgp0flIDHS+s=",
"requires": {
- "iconv-lite": "0.4.15"
+ "iconv-lite": "~0.4.13"
}
},
- "end-of-stream": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.0.tgz",
- "integrity": "sha1-epDYM+/abPpurA9JSduw+tOmMgY=",
+ "encoding-down": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/encoding-down/-/encoding-down-4.0.1.tgz",
+ "integrity": "sha512-AlSE+ugBIpLL0i9if2SlnOZ4oWj/XvBb8tw2Ie/pFB73vdYs5O/6plRyqIgjbZbz8onaL20AAuMP87LWbP56IQ==",
+ "dev": true,
+ "requires": {
+ "abstract-leveldown": "^4.0.0",
+ "level-codec": "^8.0.0",
+ "level-errors": "^1.0.4",
+ "xtend": "^4.0.1"
+ }
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
"requires": {
- "once": "1.4.0"
+ "once": "^1.4.0"
}
},
"enhanced-resolve": {
@@ -6304,16 +5259,17 @@
"integrity": "sha1-BCHjOf1xQZs9oT0Smzl5BAIwR24=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "memory-fs": "0.4.1",
- "object-assign": "4.1.1",
- "tapable": "0.2.8"
+ "graceful-fs": "^4.1.2",
+ "memory-fs": "^0.4.0",
+ "object-assign": "^4.0.1",
+ "tapable": "^0.2.7"
}
},
"entities": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/entities/-/entities-1.1.1.tgz",
- "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA="
+ "integrity": "sha1-blwtClYhtdra7O+AuQ7ftc13cvA=",
+ "dev": true
},
"env-paths": {
"version": "1.0.0",
@@ -6327,30 +5283,25 @@
"integrity": "sha1-B9XOaRJBJA+4F78sSxjW5TAkDfY=",
"dev": true,
"requires": {
- "cheerio": "0.22.0",
- "function.prototype.name": "1.0.3",
- "is-subset": "0.1.1",
- "lodash": "4.17.4",
- "object-is": "1.0.1",
- "object.assign": "4.0.4",
- "object.entries": "1.0.4",
- "object.values": "1.0.4",
- "prop-types": "15.6.0",
- "uuid": "3.1.0"
+ "cheerio": "^0.22.0",
+ "function.prototype.name": "^1.0.0",
+ "is-subset": "^0.1.1",
+ "lodash": "^4.17.4",
+ "object-is": "^1.0.1",
+ "object.assign": "^4.0.4",
+ "object.entries": "^1.0.4",
+ "object.values": "^1.0.4",
+ "prop-types": "^15.5.10",
+ "uuid": "^3.0.1"
}
},
- "eol": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/eol/-/eol-0.5.0.tgz",
- "integrity": "sha1-dUTuHJzvysYEEoarrB5/Xls28Qw="
- },
"errno": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.4.tgz",
- "integrity": "sha1-uJbiOp5ei6M4cfyZar02NfyaHH0=",
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz",
+ "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==",
"dev": true,
"requires": {
- "prr": "0.0.0"
+ "prr": "~1.0.1"
}
},
"error-ex": {
@@ -6358,20 +5309,20 @@
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.1.tgz",
"integrity": "sha1-+FWobOYa3E6GIcPNoh56dhLDqNw=",
"requires": {
- "is-arrayish": "0.2.1"
+ "is-arrayish": "^0.2.1"
}
},
"es-abstract": {
- "version": "1.8.2",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.8.2.tgz",
- "integrity": "sha512-dvhwFL3yjQxNNsOWx6exMlaDrRHCRGMQlnx5lsXDCZ/J7G/frgIIl94zhZSp/galVAYp7VzPi1OrAHta89/yGQ==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.11.0.tgz",
+ "integrity": "sha512-ZnQrE/lXTTQ39ulXZ+J1DTFazV9qBy61x2bY071B+qGco8Z8q1QddsLdt/EF8Ai9hcWH72dWS0kFqXLxOxqslA==",
"dev": true,
"requires": {
- "es-to-primitive": "1.1.1",
- "function-bind": "1.1.1",
- "has": "1.0.1",
- "is-callable": "1.1.3",
- "is-regex": "1.0.4"
+ "es-to-primitive": "^1.1.1",
+ "function-bind": "^1.1.1",
+ "has": "^1.0.1",
+ "is-callable": "^1.1.3",
+ "is-regex": "^1.0.4"
}
},
"es-to-primitive": {
@@ -6380,30 +5331,31 @@
"integrity": "sha1-RTVSSKiJeQNLZ5Lhm7gfK3l13Q0=",
"dev": true,
"requires": {
- "is-callable": "1.1.3",
- "is-date-object": "1.0.1",
- "is-symbol": "1.0.1"
+ "is-callable": "^1.1.1",
+ "is-date-object": "^1.0.1",
+ "is-symbol": "^1.0.1"
}
},
"es5-ext": {
- "version": "0.10.30",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz",
- "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=",
+ "version": "0.10.42",
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.42.tgz",
+ "integrity": "sha512-AJxO1rmPe1bDEfSR6TJ/FgMFYuTBhR5R57KW58iCkYACMyFbrkqVyzXSurYoScDGvgyMpk7uRF/lPUPPTmsRSA==",
"dev": true,
"requires": {
- "es6-iterator": "2.0.1",
- "es6-symbol": "3.1.1"
+ "es6-iterator": "~2.0.3",
+ "es6-symbol": "~3.1.1",
+ "next-tick": "1"
}
},
"es6-iterator": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
- "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
+ "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=",
"dev": true,
"requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-symbol": "3.1.1"
+ "d": "1",
+ "es5-ext": "^0.10.35",
+ "es6-symbol": "^3.1.1"
}
},
"es6-map": {
@@ -6412,12 +5364,12 @@
"integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
"dev": true,
"requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-iterator": "2.0.1",
- "es6-set": "0.1.5",
- "es6-symbol": "3.1.1",
- "event-emitter": "0.3.5"
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
+ "es6-set": "~0.1.5",
+ "es6-symbol": "~3.1.1",
+ "event-emitter": "~0.3.5"
}
},
"es6-promise": {
@@ -6429,14 +5381,16 @@
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+ "dev": true,
"requires": {
- "es6-promise": "4.1.1"
+ "es6-promise": "^4.0.3"
},
"dependencies": {
"es6-promise": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.1.1.tgz",
- "integrity": "sha512-OaU1hHjgJf+b0NzsxCg7NdIYERD6Hy/PEmFLTjw+b65scuisG3Kt4QoTvJ66BBkPZ581gr0kpoVzKnxniM8nng=="
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.4.tgz",
+ "integrity": "sha512-/NdNZVJg+uZgtm9eS3O6lrOLYmQag2DjdEXuPaHlZ6RuVqgqaVZfgYCepEIKsLqwdQArOPtC3XzRLqGGfT8KQQ==",
+ "dev": true
}
}
},
@@ -6446,11 +5400,11 @@
"integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
"dev": true,
"requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-iterator": "2.0.1",
+ "d": "1",
+ "es5-ext": "~0.10.14",
+ "es6-iterator": "~2.0.1",
"es6-symbol": "3.1.1",
- "event-emitter": "0.3.5"
+ "event-emitter": "~0.3.5"
}
},
"es6-symbol": {
@@ -6459,8 +5413,8 @@
"integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
"dev": true,
"requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30"
+ "d": "1",
+ "es5-ext": "~0.10.14"
}
},
"es6-weak-map": {
@@ -6469,21 +5423,17 @@
"integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
"dev": true,
"requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-iterator": "2.0.1",
- "es6-symbol": "3.1.1"
+ "d": "1",
+ "es5-ext": "^0.10.14",
+ "es6-iterator": "^2.0.1",
+ "es6-symbol": "^3.1.1"
}
},
"escape-html": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
- "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
- },
- "escape-regexp-component": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/escape-regexp-component/-/escape-regexp-component-1.0.2.tgz",
- "integrity": "sha1-nGO20LJf8qiMOtvRjFthrMO5+qI="
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=",
+ "dev": true
},
"escape-string-regexp": {
"version": "1.0.5",
@@ -6491,15 +5441,15 @@
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
},
"escodegen": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.0.tgz",
- "integrity": "sha512-v0MYvNQ32bzwoG2OSFzWAkuahDQHK92JBN0pTAALJ4RIxEZe766QJPDR8Hqy7XNUy5K3fnVL76OqYAdc4TZEIw==",
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.9.1.tgz",
+ "integrity": "sha512-6hTjO1NAWkHnDk3OqQ4YrCuwwmGHL9S3nPlzBOUG/R44rda3wLNrfvQ5fkSGjyhHFKM7ALPKcKGrwvCLe0lC7Q==",
"requires": {
- "esprima": "3.1.3",
- "estraverse": "4.2.0",
- "esutils": "2.0.2",
- "optionator": "0.8.2",
- "source-map": "0.5.7"
+ "esprima": "^3.1.3",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
}
},
"escope": {
@@ -6508,103 +5458,62 @@
"integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
"dev": true,
"requires": {
- "es6-map": "0.1.5",
- "es6-weak-map": "2.0.2",
- "esrecurse": "4.2.0",
- "estraverse": "4.2.0"
+ "es6-map": "^0.1.3",
+ "es6-weak-map": "^2.0.1",
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
}
},
"eslint": {
- "version": "4.12.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.12.1.tgz",
- "integrity": "sha512-28hOYej+NZ/R5H1yMvyKa1+bPlu+fnsIAQffK6hxXgvmXnImos2bA5XfCn5dYv2k2mrKj+/U/Z4L5ICWxC7TQw==",
- "requires": {
- "ajv": "5.5.1",
- "babel-code-frame": "6.26.0",
- "chalk": "2.3.0",
- "concat-stream": "1.6.0",
- "cross-spawn": "5.1.0",
- "debug": "3.1.0",
- "doctrine": "2.0.2",
- "eslint-scope": "3.7.1",
- "espree": "3.5.2",
- "esquery": "1.0.0",
- "estraverse": "4.2.0",
- "esutils": "2.0.2",
- "file-entry-cache": "2.0.0",
- "functional-red-black-tree": "1.0.1",
- "glob": "7.1.2",
- "globals": "11.0.1",
- "ignore": "3.3.5",
- "imurmurhash": "0.1.4",
- "inquirer": "3.0.6",
- "is-resolvable": "1.0.0",
- "js-yaml": "3.10.0",
- "json-stable-stringify-without-jsonify": "1.0.1",
- "levn": "0.3.0",
- "lodash": "4.17.4",
- "minimatch": "3.0.4",
- "mkdirp": "0.5.1",
- "natural-compare": "1.4.0",
- "optionator": "0.8.2",
- "path-is-inside": "1.0.2",
- "pluralize": "7.0.0",
- "progress": "2.0.0",
- "require-uncached": "1.0.3",
- "semver": "5.4.1",
- "strip-ansi": "4.0.0",
- "strip-json-comments": "2.0.1",
+ "version": "4.19.1",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-4.19.1.tgz",
+ "integrity": "sha512-bT3/1x1EbZB7phzYu7vCr1v3ONuzDtX8WjuM9c0iYxe+cq+pwcKEoQjl7zd3RpC6YOLgnSy3cTN58M2jcoPDIQ==",
+ "requires": {
+ "ajv": "^5.3.0",
+ "babel-code-frame": "^6.22.0",
+ "chalk": "^2.1.0",
+ "concat-stream": "^1.6.0",
+ "cross-spawn": "^5.1.0",
+ "debug": "^3.1.0",
+ "doctrine": "^2.1.0",
+ "eslint-scope": "^3.7.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "espree": "^3.5.4",
+ "esquery": "^1.0.0",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^2.0.0",
+ "functional-red-black-tree": "^1.0.1",
+ "glob": "^7.1.2",
+ "globals": "^11.0.1",
+ "ignore": "^3.3.3",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^3.0.6",
+ "is-resolvable": "^1.0.0",
+ "js-yaml": "^3.9.1",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.4",
+ "minimatch": "^3.0.2",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.2",
+ "pluralize": "^7.0.0",
+ "progress": "^2.0.0",
+ "regexpp": "^1.0.1",
+ "require-uncached": "^1.0.3",
+ "semver": "^5.3.0",
+ "strip-ansi": "^4.0.0",
+ "strip-json-comments": "~2.0.1",
"table": "4.0.2",
- "text-table": "0.2.0"
+ "text-table": "~0.2.0"
},
"dependencies": {
- "acorn": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz",
- "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w=="
- },
- "ajv": {
- "version": "5.5.1",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.1.tgz",
- "integrity": "sha1-s4u4h22ehr7plJVqBOch6IskjrI=",
- "requires": {
- "co": "4.6.0",
- "fast-deep-equal": "1.0.0",
- "fast-json-stable-stringify": "2.0.0",
- "json-schema-traverse": "0.3.1"
- }
- },
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
"integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
- "ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
- "requires": {
- "color-convert": "1.9.1"
- }
- },
- "chalk": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.3.0.tgz",
- "integrity": "sha512-Az5zJR2CBujap2rqXGaJKaPHyJ0IrUimvYNX+ncCy8PJP4ltOGTrHUIo097ZaL2zMeKYpiCdqDvS6zdrTFok3Q==",
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.5.0"
- }
- },
- "color-convert": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.1.tgz",
- "integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
- "requires": {
- "color-name": "1.1.3"
- }
- },
"debug": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
@@ -6613,110 +5522,47 @@
"ms": "2.0.0"
}
},
- "doctrine": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.2.tgz",
- "integrity": "sha512-y0tm5Pq6ywp3qSTZ1vPgVdAnbDEoeoc5wlOHXoY1c4Wug/a7JvqHIl7BTvwodaHmejWkK/9dSb3sCYfyo/om8A==",
- "requires": {
- "esutils": "2.0.2"
- }
- },
- "espree": {
- "version": "3.5.2",
- "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.2.tgz",
- "integrity": "sha512-sadKeYwaR/aJ3stC2CdvgXu1T16TdYN+qwCpcWbMnGJ8s0zNWemzrvb2GbD4OhmJ/fwpJjudThAlLobGbWZbCQ==",
- "requires": {
- "acorn": "5.2.1",
- "acorn-jsx": "3.0.1"
- }
- },
- "globals": {
- "version": "11.0.1",
- "resolved": "https://registry.npmjs.org/globals/-/globals-11.0.1.tgz",
- "integrity": "sha1-Eqh7sBDlFUOWrMU14eQ/x1Ow5eg="
- },
- "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="
- },
- "pluralize": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
- "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow=="
- },
- "progress": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
- "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8="
- },
- "slice-ansi": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
- "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
- "requires": {
- "is-fullwidth-code-point": "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==",
- "requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
- }
- },
"strip-ansi": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"requires": {
- "ansi-regex": "3.0.0"
- }
- },
- "supports-color": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-4.5.0.tgz",
- "integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
- "requires": {
- "has-flag": "2.0.0"
- }
- },
- "table": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
- "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
- "requires": {
- "ajv": "5.5.1",
- "ajv-keywords": "2.1.0",
- "chalk": "2.3.0",
- "lodash": "4.17.4",
- "slice-ansi": "1.0.0",
- "string-width": "2.1.1"
+ "ansi-regex": "^3.0.0"
}
}
}
},
+ "eslint-config-standard": {
+ "version": "10.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz",
+ "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=",
+ "dev": true
+ },
+ "eslint-config-standard-jsx": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz",
+ "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==",
+ "dev": true
+ },
"eslint-import-resolver-node": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.2.3.tgz",
"integrity": "sha1-Wt2BBujJKNssuiMrzZ76hG49oWw=",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "object-assign": "4.1.1",
- "resolve": "1.4.0"
+ "debug": "^2.2.0",
+ "object-assign": "^4.0.1",
+ "resolve": "^1.1.6"
}
},
"eslint-module-utils": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz",
- "integrity": "sha512-jDI/X5l/6D1rRD/3T43q8Qgbls2nq5km5KSqiwlyUbGo5+04fXhMKdCPhjwbqAa6HXWaMxj8Q4hQDIh7IadJQw==",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.2.0.tgz",
+ "integrity": "sha1-snA2LNiLGkitMIl2zn+lTphBF0Y=",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "pkg-dir": "1.0.0"
+ "debug": "^2.6.8",
+ "pkg-dir": "^1.0.0"
},
"dependencies": {
"find-up": {
@@ -6725,8 +5571,8 @@
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
"dev": true,
"requires": {
- "path-exists": "2.1.0",
- "pinkie-promise": "2.0.1"
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
}
},
"path-exists": {
@@ -6735,7 +5581,7 @@
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
"dev": true,
"requires": {
- "pinkie-promise": "2.0.1"
+ "pinkie-promise": "^2.0.0"
}
},
"pkg-dir": {
@@ -6744,18 +5590,18 @@
"integrity": "sha1-ektQio1bstYp1EcFb/TpyTFM89Q=",
"dev": true,
"requires": {
- "find-up": "1.1.2"
+ "find-up": "^1.0.0"
}
}
}
},
"eslint-plugin-flowtype": {
- "version": "2.40.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.40.1.tgz",
- "integrity": "sha512-0EBDPR3/iguDQin7nb5WMT1ZWYB95eNllY+oiFZjvLa1oqE0BGO6ZSFnMdNE9HEkajB6Cw850PRIBbp+O+EzYQ==",
+ "version": "2.46.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-flowtype/-/eslint-plugin-flowtype-2.46.3.tgz",
+ "integrity": "sha512-VpnNeC4E6t2E2NCw8Oveda91p8CPEaujZURC1KhHe4lBRZJla3o0DVvZu1QGXQZO1ZJ4vUmy3TCp95PqGvIZgQ==",
"dev": true,
"requires": {
- "lodash": "4.17.4"
+ "lodash": "^4.15.0"
}
},
"eslint-plugin-import": {
@@ -6764,16 +5610,28 @@
"integrity": "sha1-crowb60wXWfEgWNIpGmaQimsi04=",
"dev": true,
"requires": {
- "builtin-modules": "1.1.1",
- "contains-path": "0.1.0",
- "debug": "2.6.9",
+ "builtin-modules": "^1.1.1",
+ "contains-path": "^0.1.0",
+ "debug": "^2.2.0",
"doctrine": "1.5.0",
- "eslint-import-resolver-node": "0.2.3",
- "eslint-module-utils": "2.1.1",
- "has": "1.0.1",
- "lodash.cond": "4.5.2",
- "minimatch": "3.0.4",
- "pkg-up": "1.0.0"
+ "eslint-import-resolver-node": "^0.2.0",
+ "eslint-module-utils": "^2.0.0",
+ "has": "^1.0.1",
+ "lodash.cond": "^4.3.0",
+ "minimatch": "^3.0.3",
+ "pkg-up": "^1.0.0"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ }
}
},
"eslint-plugin-node": {
@@ -6782,10 +5640,10 @@
"integrity": "sha512-vIUQPuwbVYdz/CYnlTLsJrRy7iXHQjdEe5wz0XhhdTym3IInM/zZLlPf9nZ2mThsH0QcsieCOWs2vOeCy/22LQ==",
"dev": true,
"requires": {
- "ignore": "3.3.5",
- "minimatch": "3.0.4",
- "object-assign": "4.1.1",
- "resolve": "1.4.0",
+ "ignore": "^3.0.11",
+ "minimatch": "^3.0.2",
+ "object-assign": "^4.0.1",
+ "resolve": "^1.1.7",
"semver": "5.3.0"
},
"dependencies": {
@@ -6797,30 +5655,70 @@
}
}
},
+ "eslint-plugin-promise": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz",
+ "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=",
+ "dev": true
+ },
+ "eslint-plugin-react": {
+ "version": "6.10.3",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz",
+ "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=",
+ "dev": true,
+ "requires": {
+ "array.prototype.find": "^2.0.1",
+ "doctrine": "^1.2.2",
+ "has": "^1.0.1",
+ "jsx-ast-utils": "^1.3.4",
+ "object.assign": "^4.0.4"
+ },
+ "dependencies": {
+ "doctrine": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
+ "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "isarray": "^1.0.0"
+ }
+ }
+ }
+ },
+ "eslint-plugin-standard": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz",
+ "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=",
+ "dev": true
+ },
"eslint-scope": {
"version": "3.7.1",
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-3.7.1.tgz",
"integrity": "sha1-PWPD7f2gLgbgGkUq2IyqzHzctug=",
"requires": {
- "esrecurse": "4.2.0",
- "estraverse": "4.2.0"
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
}
},
+ "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=="
+ },
"espree": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.1.tgz",
- "integrity": "sha1-DJiLirRttTEAoZVK5LqZXd0n2H4=",
- "dev": true,
+ "version": "3.5.4",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.4.tgz",
+ "integrity": "sha512-yAcIQxtmMiB/jL32dzEp2enBeidsB7xWPLNiw3IIkpVds1P+h7qF9YwJq1yUNzp2OKXgAprs4F61ih66UsoD1A==",
"requires": {
- "acorn": "5.1.2",
- "acorn-jsx": "3.0.1"
+ "acorn": "^5.5.0",
+ "acorn-jsx": "^3.0.0"
},
"dependencies": {
"acorn": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.2.tgz",
- "integrity": "sha512-o96FZLJBPY1lvTuJylGA9Bk3t/GKPPJG8H0ydQQl01crzwJgspa4AEIq/pVTXigmK0PHVQhiAtn8WMBLL9D2WA==",
- "dev": true
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
+ "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ=="
}
}
},
@@ -6830,20 +5728,19 @@
"integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM="
},
"esquery": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.0.tgz",
- "integrity": "sha1-z7qLV9f7qT8XKYqKAGoEzaE9gPo=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
"requires": {
- "estraverse": "4.2.0"
+ "estraverse": "^4.0.0"
}
},
"esrecurse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
- "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
"requires": {
- "estraverse": "4.2.0",
- "object-assign": "4.1.1"
+ "estraverse": "^4.1.0"
}
},
"estraverse": {
@@ -6859,30 +5756,8 @@
"etag": {
"version": "1.8.1",
"resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
- "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
- },
- "ethereumjs-abi": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/ethereumjs-abi/-/ethereumjs-abi-0.6.4.tgz",
- "integrity": "sha1-m6G7BWSS0AwnJ59uzNTVgnWRLBo=",
- "optional": true,
- "requires": {
- "bn.js": "4.11.8",
- "ethereumjs-util": "4.4.1"
- }
- },
- "ethereumjs-util": {
- "version": "4.4.1",
- "resolved": "https://registry.npmjs.org/ethereumjs-util/-/ethereumjs-util-4.4.1.tgz",
- "integrity": "sha1-Yxa/vIoByHZ6eGIJKO1570JMP5I=",
- "optional": true,
- "requires": {
- "bn.js": "4.11.8",
- "create-hash": "1.1.3",
- "keccakjs": "0.2.1",
- "rlp": "2.0.0",
- "secp256k1": "3.2.5"
- }
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=",
+ "dev": true
},
"event-emitter": {
"version": "0.3.5",
@@ -6890,14 +5765,15 @@
"integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
"dev": true,
"requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30"
+ "d": "1",
+ "es5-ext": "~0.10.14"
}
},
"eventemitter3": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-1.2.0.tgz",
- "integrity": "sha1-HIaZHYFq0eUEdQ5zh0Ik7PO+xQg="
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.0.tgz",
+ "integrity": "sha512-ivIvhpq/Y0uSjcHDcOIccjmYjGLcP09MFGE7ysAwkAvkXfpZlC985pH2/ui64DKazbTW/4kN3yqozUxlXzI6cA==",
+ "dev": true
},
"events": {
"version": "1.1.1",
@@ -6911,16 +5787,17 @@
"integrity": "sha1-Cs7ehJ7X3RzMMsgRuxG5RNTykjI=",
"dev": true,
"requires": {
- "original": "1.0.0"
+ "original": ">=0.0.5"
}
},
"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"
+ "md5.js": "^1.3.4",
+ "safe-buffer": "^5.1.1"
}
},
"execa": {
@@ -6929,13 +5806,13 @@
"integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
"dev": true,
"requires": {
- "cross-spawn": "5.1.0",
- "get-stream": "3.0.0",
- "is-stream": "1.1.0",
- "npm-run-path": "2.0.2",
- "p-finally": "1.0.0",
- "signal-exit": "3.0.2",
- "strip-eof": "1.0.0"
+ "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"
}
},
"exif-parser": {
@@ -6950,12 +5827,38 @@
"dev": true
},
"expand-brackets": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
- "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
- "dev": true,
- "requires": {
- "is-posix-bracket": "0.1.1"
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
}
},
"expand-range": {
@@ -6964,150 +5867,261 @@
"integrity": "sha1-opnv/TNf4nIeuujiV+x5ZE/IUzc=",
"dev": true,
"requires": {
- "fill-range": "2.2.3"
+ "fill-range": "^2.1.0"
+ },
+ "dependencies": {
+ "fill-range": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.4.tgz",
+ "integrity": "sha512-cnrcCbj01+j2gTG921VZPnHbjmdAf8oQV/iGeV2kZxGSyfYjjTyY79ErsK1WJWMpw6DaApEX72binqJE+/d+5Q==",
+ "dev": true,
+ "requires": {
+ "is-number": "^2.1.0",
+ "isobject": "^2.0.0",
+ "randomatic": "^3.0.0",
+ "repeat-element": "^1.1.2",
+ "repeat-string": "^1.5.2"
+ }
+ },
+ "is-number": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
+ "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ }
+ },
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
}
},
"expand-template": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.0.tgz",
- "integrity": "sha512-kkjwkMqj0h4w/sb32ERCDxCQkREMCAgS39DscDnSwDsbxnwwM1BTZySdC3Bn1lhY7vL08n9GoO/fVTynjDgRyQ=="
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-1.1.1.tgz",
+ "integrity": "sha512-cebqLtV8KOZfw0UI8TEFWxtczxxC1jvyUvx6H4fyp1K1FN7A4Q+uggVUlOsI1K8AGU0rwOGqP8nCapdrw8CYQg=="
},
"expand-tilde": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-1.2.2.tgz",
- "integrity": "sha1-C4HrqJflo9MdHD0QL48BRB5VlEk=",
+ "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": {
- "os-homedir": "1.0.2"
+ "homedir-polyfill": "^1.0.1"
}
},
"express": {
- "version": "4.15.5",
- "resolved": "https://registry.npmjs.org/express/-/express-4.15.5.tgz",
- "integrity": "sha1-ZwI1ypWYiQpa6BcLg9tyK4Qu2Sc=",
+ "version": "4.16.3",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.16.3.tgz",
+ "integrity": "sha1-avilAjUNsyRuzEvs9rWjTSL37VM=",
"dev": true,
"requires": {
- "accepts": "1.3.4",
+ "accepts": "~1.3.5",
"array-flatten": "1.1.1",
+ "body-parser": "1.18.2",
"content-disposition": "0.5.2",
- "content-type": "1.0.4",
+ "content-type": "~1.0.4",
"cookie": "0.3.1",
"cookie-signature": "1.0.6",
"debug": "2.6.9",
- "depd": "1.1.1",
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "etag": "1.8.1",
- "finalhandler": "1.0.6",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "1.1.1",
"fresh": "0.5.2",
"merge-descriptors": "1.0.1",
- "methods": "1.1.2",
- "on-finished": "2.3.0",
- "parseurl": "1.3.2",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
"path-to-regexp": "0.1.7",
- "proxy-addr": "1.1.5",
- "qs": "6.5.0",
- "range-parser": "1.2.0",
- "send": "0.15.6",
- "serve-static": "1.12.6",
- "setprototypeof": "1.0.3",
- "statuses": "1.3.1",
- "type-is": "1.6.15",
- "utils-merge": "1.0.0",
- "vary": "1.1.2"
+ "proxy-addr": "~2.0.3",
+ "qs": "6.5.1",
+ "range-parser": "~1.2.0",
+ "safe-buffer": "5.1.1",
+ "send": "0.16.2",
+ "serve-static": "1.13.2",
+ "setprototypeof": "1.1.0",
+ "statuses": "~1.4.0",
+ "type-is": "~1.6.16",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
},
"dependencies": {
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=",
+ "dev": true
+ },
"qs": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz",
- "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg==",
+ "version": "6.5.1",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
+ "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A==",
+ "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
}
}
},
"extend": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
- "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ="
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-2.0.1.tgz",
+ "integrity": "sha1-HugBBonnOV/5RIJByYZSvHWagmA="
},
"extend-shallow": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
- "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
"dev": true,
"requires": {
- "is-extendable": "0.1.1"
- }
- },
- "external-editor": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.0.5.tgz",
- "integrity": "sha512-Msjo64WT5W+NhOpQXh0nOHm+n0RfU1QUwDnKYvJ8dEJ8zlwLrqXNTv5mSUTJpepf41PDJGyhueTw2vNZW+Fr/w==",
- "requires": {
- "iconv-lite": "0.4.19",
- "jschardet": "1.5.1",
- "tmp": "0.0.33"
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
},
"dependencies": {
- "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=="
- },
- "tmp": {
- "version": "0.0.33",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
- "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "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": {
- "os-tmpdir": "1.0.2"
+ "is-plain-object": "^2.0.4"
}
}
}
},
- "extglob": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
- "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
- "dev": true,
+ "external-editor": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-2.2.0.tgz",
+ "integrity": "sha512-bSn6gvGxKt+b7+6TKEv1ZycHleA7aHhRHyAqJyp5pbUFuYYNIzpZnQDk7AsYckyWdEnTeAnay0aCy2aV6iTk9A==",
"requires": {
- "is-extglob": "1.0.0"
+ "chardet": "^0.4.0",
+ "iconv-lite": "^0.4.17",
+ "tmp": "^0.0.33"
}
},
- "extract-zip": {
- "version": "1.6.5",
- "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.5.tgz",
- "integrity": "sha1-maBnNbbqIOqbcF13ms/8yHz/BEA=",
- "dev": true,
- "requires": {
- "concat-stream": "1.6.0",
- "debug": "2.2.0",
- "mkdirp": "0.5.0",
- "yauzl": "2.4.1"
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
},
"dependencies": {
- "debug": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
- "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
"dev": true,
"requires": {
- "ms": "0.7.1"
+ "is-descriptor": "^1.0.0"
}
},
- "mkdirp": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
- "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
"dev": true,
"requires": {
- "minimist": "0.0.8"
+ "is-extendable": "^0.1.0"
}
},
- "ms": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
- "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "extract-zip": {
+ "version": "1.6.6",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.6.tgz",
+ "integrity": "sha1-EpDt6NINCHK0Kf0/NRyhKOxe+Fw=",
+ "dev": true,
+ "requires": {
+ "concat-stream": "1.6.0",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.0",
+ "yauzl": "2.4.1"
+ },
+ "dependencies": {
+ "concat-stream": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
+ "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "typedarray": "^0.0.6"
+ }
+ },
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
"dev": true
+ },
+ "mkdirp": {
+ "version": "0.5.0",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.0.tgz",
+ "integrity": "sha1-HXMHam35hs2TROFecfzAWkyavxI=",
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
}
}
},
@@ -7117,19 +6131,20 @@
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
},
"fancy-log": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.0.tgz",
- "integrity": "sha1-Rb4X0Cu5kX1gzP/UmVyZnmyMmUg=",
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/fancy-log/-/fancy-log-1.3.2.tgz",
+ "integrity": "sha1-9BEl49hPLn2JpD0G2VjI94vha+E=",
"dev": true,
"requires": {
- "chalk": "1.1.3",
- "time-stamp": "1.1.0"
+ "ansi-gray": "^0.1.1",
+ "color-support": "^1.1.3",
+ "time-stamp": "^1.0.0"
}
},
"fast-deep-equal": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz",
- "integrity": "sha1-liVqO8l1WV6zbYLpkp0GDYk0Of8="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-1.1.0.tgz",
+ "integrity": "sha1-wFNHeBfIa1HaqFPIHgWbcz0CNhQ="
},
"fast-future": {
"version": "1.0.2",
@@ -7159,7 +6174,7 @@
"integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=",
"dev": true,
"requires": {
- "websocket-driver": "0.7.0"
+ "websocket-driver": ">=0.5.1"
}
},
"fbjs": {
@@ -7167,13 +6182,13 @@
"resolved": "https://registry.npmjs.org/fbjs/-/fbjs-0.8.16.tgz",
"integrity": "sha1-XmdDL1UNxBtXK/VYR7ispk5TN9s=",
"requires": {
- "core-js": "1.2.7",
- "isomorphic-fetch": "2.2.1",
- "loose-envify": "1.3.1",
- "object-assign": "4.1.1",
- "promise": "7.3.1",
- "setimmediate": "1.0.5",
- "ua-parser-js": "0.7.14"
+ "core-js": "^1.0.0",
+ "isomorphic-fetch": "^2.1.1",
+ "loose-envify": "^1.0.0",
+ "object-assign": "^4.1.0",
+ "promise": "^7.1.1",
+ "setimmediate": "^1.0.5",
+ "ua-parser-js": "^0.7.9"
},
"dependencies": {
"core-js": {
@@ -7189,7 +6204,7 @@
"integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
"dev": true,
"requires": {
- "pend": "1.2.0"
+ "pend": "~1.2.0"
}
},
"figures": {
@@ -7197,7 +6212,7 @@
"resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
"integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
"requires": {
- "escape-string-regexp": "1.0.5"
+ "escape-string-regexp": "^1.0.5"
}
},
"file-entry-cache": {
@@ -7205,8 +6220,8 @@
"resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-2.0.0.tgz",
"integrity": "sha1-w5KZDD5oR4PYOLjISkXYoEhFg2E=",
"requires": {
- "flat-cache": "1.3.0",
- "object-assign": "4.1.1"
+ "flat-cache": "^1.2.1",
+ "object-assign": "^4.0.1"
}
},
"file-loader": {
@@ -7214,7 +6229,7 @@
"resolved": "https://registry.npmjs.org/file-loader/-/file-loader-0.11.2.tgz",
"integrity": "sha512-N+uhF3mswIFeziHQjGScJ/yHXYt3DiLBeC+9vWW+WjUBiClMSOlV1YrXQi+7KM2aA3Rn4Bybgv+uXFQbfkzpvg==",
"requires": {
- "loader-utils": "1.1.0"
+ "loader-utils": "^1.0.2"
}
},
"file-type": {
@@ -7222,11 +6237,6 @@
"resolved": "https://registry.npmjs.org/file-type/-/file-type-3.9.0.tgz",
"integrity": "sha1-JXoHg4TR24CHvESdEH1SpSZyuek="
},
- "file-uri-to-path": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz",
- "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw=="
- },
"filename-regex": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz",
@@ -7239,8 +6249,8 @@
"integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=",
"dev": true,
"requires": {
- "glob": "7.1.2",
- "minimatch": "3.0.4"
+ "glob": "^7.0.3",
+ "minimatch": "^3.0.3"
}
},
"filestream": {
@@ -7248,67 +6258,48 @@
"resolved": "https://registry.npmjs.org/filestream/-/filestream-4.1.3.tgz",
"integrity": "sha1-lI/KregiH3FfXsrdxUhi+qrMkyU=",
"requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3",
- "typedarray-to-buffer": "3.1.2",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5",
+ "typedarray-to-buffer": "^3.0.0",
+ "xtend": "^4.0.1"
}
},
"fill-range": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-2.2.3.tgz",
- "integrity": "sha1-ULd9/X5Gm8dJJHCWNpn+eoSFpyM=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
"dev": true,
"requires": {
- "is-number": "2.1.0",
- "isobject": "2.1.0",
- "randomatic": "1.1.7",
- "repeat-element": "1.1.2",
- "repeat-string": "1.6.1"
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
}
},
"finalhandler": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.0.6.tgz",
- "integrity": "sha1-AHrqM9Gk0+QgF/YkhIrVjSEvgU8=",
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.1.tgz",
+ "integrity": "sha512-Y1GUDo39ez4aHAw7MysnUD5JzYX+WaIj8I57kO3aEPT1fFRL4sr7mjei97FgnwhAyyzRYmQZaTHb2+9uZ1dPtg==",
"dev": true,
"requires": {
"debug": "2.6.9",
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "on-finished": "2.3.0",
- "parseurl": "1.3.2",
- "statuses": "1.3.1",
- "unpipe": "1.0.0"
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.2",
+ "statuses": "~1.4.0",
+ "unpipe": "~1.0.0"
}
},
"find-cache-dir": {
@@ -7316,9 +6307,9 @@
"resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz",
"integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=",
"requires": {
- "commondir": "1.0.1",
- "make-dir": "1.0.0",
- "pkg-dir": "2.0.0"
+ "commondir": "^1.0.1",
+ "make-dir": "^1.0.0",
+ "pkg-dir": "^2.0.0"
}
},
"find-index": {
@@ -7338,19 +6329,19 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
"integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
"requires": {
- "locate-path": "2.0.0"
+ "locate-path": "^2.0.0"
}
},
"findup-sync": {
- "version": "0.4.3",
- "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.4.3.tgz",
- "integrity": "sha1-QAQ5Kee8YK3wt/SCfExudaDeyhI=",
+ "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": "0.1.0",
- "is-glob": "2.0.1",
- "micromatch": "2.3.11",
- "resolve-dir": "0.1.1"
+ "detect-file": "^1.0.0",
+ "is-glob": "^3.1.0",
+ "micromatch": "^3.0.4",
+ "resolve-dir": "^1.0.1"
}
},
"fined": {
@@ -7359,22 +6350,11 @@
"integrity": "sha1-s33IRLdqL15wgeiE98CuNE8VNHY=",
"dev": true,
"requires": {
- "expand-tilde": "2.0.2",
- "is-plain-object": "2.0.4",
- "object.defaults": "1.1.0",
- "object.pick": "1.3.0",
- "parse-filepath": "1.0.1"
- },
- "dependencies": {
- "expand-tilde": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
- "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
- "dev": true,
- "requires": {
- "homedir-polyfill": "1.0.1"
- }
- }
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^2.0.3",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.2.0",
+ "parse-filepath": "^1.0.1"
}
},
"first-chunk-stream": {
@@ -7384,9 +6364,9 @@
"dev": true
},
"flagged-respawn": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-0.3.2.tgz",
- "integrity": "sha1-/xke3c1wiKZ1smEP/8l2vpuAdLU=",
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/flagged-respawn/-/flagged-respawn-1.0.0.tgz",
+ "integrity": "sha1-Tnmumy6zi/hrO7Vr8+ClaqX8q9c=",
"dev": true
},
"flat-cache": {
@@ -7394,17 +6374,16 @@
"resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.3.0.tgz",
"integrity": "sha1-0wMLMrOBVPTjt+nHCfSQ9++XxIE=",
"requires": {
- "circular-json": "0.3.3",
- "del": "2.2.2",
- "graceful-fs": "4.1.11",
- "write": "0.2.1"
+ "circular-json": "^0.3.1",
+ "del": "^2.0.2",
+ "graceful-fs": "^4.1.2",
+ "write": "^0.2.1"
}
},
"flatten": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/flatten/-/flatten-0.0.1.tgz",
- "integrity": "sha1-VURAdm2goNYDmZ9DNFP2wvxqdcE=",
- "dev": true
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
+ "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I="
},
"flow-bin": {
"version": "0.53.1",
@@ -7413,43 +6392,31 @@
"dev": true
},
"flush-write-stream": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.0.2.tgz",
- "integrity": "sha1-yBuQ2HRnZvGmCaRoCZRsRd2K5Bc=",
+ "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.3",
- "readable-stream": "2.3.3"
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.4"
+ }
+ },
+ "follow-redirects": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.0.tgz",
+ "integrity": "sha512-fdrt472/9qQ6Kgjvb935ig6vJCuofpBUD14f9Vb+SLlm7xIe4Qva5gey8EKtv8lp7ahE1wilg3xL1znpVGtZIA==",
+ "dev": true,
+ "requires": {
+ "debug": "^3.1.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "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": {
- "safe-buffer": "5.1.1"
+ "ms": "2.0.0"
}
}
}
@@ -7465,749 +6432,781 @@
"integrity": "sha1-bXWEdGzGu8grRjTUkTnEe1bmEao=",
"dev": true,
"requires": {
- "css-loader": "0.17.0",
- "less-loader": "2.2.3",
- "style-loader": "0.12.4"
+ "css-loader": "~0.17.0",
+ "less-loader": "~2.2.0",
+ "style-loader": "~0.12.3"
},
"dependencies": {
+ "balanced-match": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.2.1.tgz",
+ "integrity": "sha1-e8ZYtL7WHu5CStdPdfXD4sTfPMc=",
+ "dev": true
+ },
+ "color": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/color/-/color-0.10.1.tgz",
+ "integrity": "sha1-wEGI34KiCd3rzOzazT7DIPGTc58=",
+ "dev": true,
+ "requires": {
+ "color-convert": "^0.5.3",
+ "color-string": "^0.3.0"
+ }
+ },
+ "color-convert": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+ "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=",
+ "dev": true
+ },
"css-loader": {
"version": "0.17.0",
"resolved": "https://registry.npmjs.org/css-loader/-/css-loader-0.17.0.tgz",
"integrity": "sha1-od3y34a6CPvSJ4G7Mzefw7CNpus=",
"dev": true,
"requires": {
- "css-selector-tokenizer": "0.5.4",
- "cssnano": "2.6.1",
- "loader-utils": "0.2.17",
- "postcss": "4.1.16",
+ "css-selector-tokenizer": "^0.5.1",
+ "cssnano": "^2.6.1",
+ "loader-utils": "~0.2.2",
+ "postcss": "^4.1.11",
"postcss-modules-extract-imports": "0.0.5",
"postcss-modules-local-by-default": "0.0.12",
"postcss-modules-scope": "0.0.8",
- "source-list-map": "0.1.8"
+ "source-list-map": "^0.1.4"
+ }
+ },
+ "css-selector-tokenizer": {
+ "version": "0.5.4",
+ "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.5.4.tgz",
+ "integrity": "sha1-E5uv00o1/QwUKEhwSeBpnm9qLCE=",
+ "dev": true,
+ "requires": {
+ "cssesc": "^0.1.0",
+ "fastparse": "^1.1.1"
}
},
+ "cssnano": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-2.6.1.tgz",
+ "integrity": "sha1-f7NyEsz/RNPpNuAmxvZ14xR9gCQ=",
+ "dev": true,
+ "requires": {
+ "autoprefixer-core": "^5.2.1",
+ "balanced-match": "^0.2.0",
+ "css-list": "^0.1.2",
+ "decamelize": "^1.0.0",
+ "defined": "^1.0.0",
+ "indexes-of": "^1.0.1",
+ "minimist": "^1.1.3",
+ "postcss": "^4.1.16",
+ "postcss-calc": "^4.1.0",
+ "postcss-colormin": "^1.2.5",
+ "postcss-convert-values": "^1.2.4",
+ "postcss-discard-comments": "^1.2.1",
+ "postcss-discard-duplicates": "^1.1.5",
+ "postcss-discard-empty": "^1.1.2",
+ "postcss-discard-unused": "^1.0.3",
+ "postcss-filter-plugins": "^1.0.0",
+ "postcss-font-family": "^1.2.1",
+ "postcss-merge-idents": "^1.0.1",
+ "postcss-merge-longhand": "^1.0.1",
+ "postcss-merge-rules": "^1.3.5",
+ "postcss-minify-font-weight": "^1.0.1",
+ "postcss-minify-selectors": "^1.5.0",
+ "postcss-normalize-url": "^2.1.1",
+ "postcss-ordered-values": "^1.0.1",
+ "postcss-reduce-idents": "^1.0.2",
+ "postcss-single-charset": "^0.3.0",
+ "postcss-unique-selectors": "^1.0.0",
+ "postcss-zindex": "^1.1.3",
+ "read-file-stdin": "^0.2.0",
+ "write-file-stdout": "0.0.2"
+ }
+ },
+ "es6-promise": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
+ "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
+ "dev": true
+ },
+ "flatten": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/flatten/-/flatten-0.0.1.tgz",
+ "integrity": "sha1-VURAdm2goNYDmZ9DNFP2wvxqdcE=",
+ "dev": true
+ },
+ "js-base64": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
+ "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=",
+ "dev": true
+ },
"loader-utils": {
"version": "0.2.17",
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-0.2.17.tgz",
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
"dev": true,
"requires": {
- "big.js": "3.2.0",
- "emojis-list": "2.1.0",
- "json5": "0.5.1",
- "object-assign": "4.1.1"
+ "big.js": "^3.1.3",
+ "emojis-list": "^2.0.0",
+ "json5": "^0.5.0",
+ "object-assign": "^4.0.1"
}
},
- "style-loader": {
- "version": "0.12.4",
- "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.12.4.tgz",
- "integrity": "sha1-rn0GZdxNxlPaov6Xu5CRS8HSLZs=",
+ "postcss": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-4.1.16.tgz",
+ "integrity": "sha1-TESbTIr53zyvbTf44eV10DYXWNw=",
"dev": true,
"requires": {
- "loader-utils": "0.2.17"
+ "es6-promise": "~2.3.0",
+ "js-base64": "~2.1.8",
+ "source-map": "~0.4.2"
}
- }
- }
- },
- "for-each": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz",
- "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=",
- "requires": {
- "is-function": "1.0.1"
- }
- },
- "for-in": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
- "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
- "dev": true
- },
- "for-own": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
- "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
- "dev": true,
- "requires": {
- "for-in": "1.0.2"
- }
- },
- "foreach": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
- "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
- "dev": true
- },
- "forever-agent": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
- "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
- },
- "form-data": {
- "version": "1.0.0-rc3",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz",
- "integrity": "sha1-01vGLn+8KTeuePlIqqDTjZBgdXc=",
- "requires": {
- "async": "1.5.2",
- "combined-stream": "1.0.5",
- "mime-types": "2.1.17"
- },
- "dependencies": {
- "async": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
- }
- }
- },
- "formatio": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz",
- "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=",
- "dev": true,
- "requires": {
- "samsam": "1.1.2"
- }
- },
- "formidable": {
- "version": "1.0.17",
- "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.17.tgz",
- "integrity": "sha1-71SRSQ+UM7cF+qdyScmQKa40hVk="
- },
- "forwarded": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
- "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
- },
- "fresh": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
- "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
- },
- "from2": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
- "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
- "dev": true,
- "requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "postcss-calc": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-4.1.0.tgz",
+ "integrity": "sha1-vuf/ySjHmGmZ7vF7LdiXDIk31HI=",
"dev": true,
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
+ "postcss": "^4.1.11",
+ "postcss-message-helpers": "^2.0.0",
+ "reduce-css-calc": "^1.2.0"
}
},
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "postcss-colormin": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-1.2.7.tgz",
+ "integrity": "sha1-63Pb6DgE6pGYNWsTL2+Z9GAP1lQ=",
"dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "color": "^0.10.1",
+ "colormin": "^1.0.3",
+ "postcss": "^4.1.16",
+ "reduce-function-call": "^1.0.1"
}
- }
- }
- },
- "fs-chunk-store": {
- "version": "1.6.5",
- "resolved": "https://registry.npmjs.org/fs-chunk-store/-/fs-chunk-store-1.6.5.tgz",
- "integrity": "sha1-/ELC/0x/FoirX9Qc8XwPns5MYVY=",
- "requires": {
- "mkdirp": "0.5.1",
- "random-access-file": "1.8.1",
- "randombytes": "2.0.5",
- "rimraf": "2.6.2",
- "run-parallel": "1.1.6",
- "thunky": "1.0.2"
- }
- },
- "fs-exists-sync": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/fs-exists-sync/-/fs-exists-sync-0.1.0.tgz",
- "integrity": "sha1-mC1ok6+RjnLQjeyehnP/K1qNat0=",
- "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=",
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "2.4.0"
- }
- },
- "fs-write-stream-atomic": {
- "version": "1.0.10",
- "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
- "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "iferr": "0.1.5",
- "imurmurhash": "0.1.4",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "postcss-convert-values": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-1.3.1.tgz",
+ "integrity": "sha1-I/GHxhP6d7Y3p4BblIteCJlpDkY=",
"dev": true,
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
+ "postcss": "^4.1.16",
+ "postcss-value-parser": "^1.1.0"
}
},
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "postcss-discard-comments": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-1.2.1.tgz",
+ "integrity": "sha1-hR3Ka5NUwPtjFssaEEj29eOWCtA=",
"dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "node-balanced": "0.0.14",
+ "postcss": "^4.1.16"
}
- }
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "fsevents": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.1.2.tgz",
- "integrity": "sha512-Sn44E5wQW4bTHXvQmvSHwqbuiXtduD6Rrjm2ZtUEGbyrig+nUH3t/QD4M4/ZXViY556TBpRgZkHLDx3JxPwxiw==",
- "dev": true,
- "optional": true,
- "requires": {
- "nan": "2.7.0",
- "node-pre-gyp": "0.6.36"
- },
- "dependencies": {
- "abbrev": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true,
- "optional": true
},
- "ajv": {
- "version": "4.11.8",
- "bundled": true,
+ "postcss-discard-duplicates": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-1.2.1.tgz",
+ "integrity": "sha1-SbsztNNHcQWwDQSDlfc6KQK8miU=",
"dev": true,
- "optional": true,
"requires": {
- "co": "4.6.0",
- "json-stable-stringify": "1.0.1"
+ "postcss": "^4.1.16"
}
},
- "ansi-regex": {
- "version": "2.1.1",
- "bundled": true,
- "dev": true
- },
- "aproba": {
- "version": "1.1.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "are-we-there-yet": {
- "version": "1.1.4",
- "bundled": true,
+ "postcss-discard-empty": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-1.1.2.tgz",
+ "integrity": "sha1-KsVayPy4HCMEPmMQaTT9Y0cNXA0=",
"dev": true,
- "optional": true,
"requires": {
- "delegates": "1.0.0",
- "readable-stream": "2.2.9"
+ "postcss": "^4.1.13"
}
},
- "asn1": {
- "version": "0.2.3",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "assert-plus": {
- "version": "0.2.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "asynckit": {
- "version": "0.4.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "aws-sign2": {
- "version": "0.6.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "aws4": {
- "version": "1.6.0",
- "bundled": true,
+ "postcss-discard-unused": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-1.0.3.tgz",
+ "integrity": "sha1-Xsy5v6xGXqa+VjQpepx3gczQmIY=",
"dev": true,
- "optional": true
- },
- "balanced-match": {
- "version": "0.4.2",
- "bundled": true,
- "dev": true
+ "requires": {
+ "flatten": "0.0.1",
+ "postcss": "^4.1.16",
+ "uniqs": "^2.0.0"
+ }
},
- "bcrypt-pbkdf": {
+ "postcss-filter-plugins": {
"version": "1.0.1",
- "bundled": true,
+ "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-1.0.1.tgz",
+ "integrity": "sha1-J/gnnV76t6o8FwmIE5hrS50dUOI=",
"dev": true,
- "optional": true,
"requires": {
- "tweetnacl": "0.14.5"
+ "postcss": "^4.1.11",
+ "uniqid": "^1.0.0"
}
},
- "block-stream": {
- "version": "0.0.9",
- "bundled": true,
+ "postcss-merge-idents": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-1.0.2.tgz",
+ "integrity": "sha1-qToNrXj2UugjfZrew0LkHSwd01s=",
"dev": true,
"requires": {
- "inherits": "2.0.3"
+ "css-list": "^0.1.0",
+ "postcss": "^4.1.9"
}
},
- "boom": {
- "version": "2.10.1",
- "bundled": true,
+ "postcss-merge-longhand": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-1.0.2.tgz",
+ "integrity": "sha1-QxcgZfz4We4RztMUH1ZkFMZzBX4=",
"dev": true,
"requires": {
- "hoek": "2.16.3"
+ "postcss": "^4.1.16"
}
},
- "brace-expansion": {
- "version": "1.1.7",
- "bundled": true,
+ "postcss-merge-rules": {
+ "version": "1.3.6",
+ "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-1.3.6.tgz",
+ "integrity": "sha1-sUrRf31AEqMYut032r1ZuT8TUy8=",
"dev": true,
"requires": {
- "balanced-match": "0.4.2",
- "concat-map": "0.0.1"
+ "postcss": "^4.1.16"
}
},
- "buffer-shims": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "caseless": {
- "version": "0.12.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "co": {
- "version": "4.6.0",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "code-point-at": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true
- },
- "combined-stream": {
- "version": "1.0.5",
- "bundled": true,
+ "postcss-minify-selectors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-1.5.0.tgz",
+ "integrity": "sha1-5ZxWxtSVXaFXz30iv4Bptur1Jic=",
"dev": true,
"requires": {
- "delayed-stream": "1.0.0"
+ "javascript-natural-sort": "^0.7.1",
+ "normalize-selector": "^0.2.0",
+ "postcss": "^4.1.16",
+ "postcss-selector-parser": "^1.1.2",
+ "uniqs": "^2.0.0"
}
},
- "concat-map": {
- "version": "0.0.1",
- "bundled": true,
- "dev": true
- },
- "console-control-strings": {
- "version": "1.1.0",
- "bundled": true,
- "dev": true
- },
- "core-util-is": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true
- },
- "cryptiles": {
- "version": "2.0.5",
- "bundled": true,
+ "postcss-modules-extract-imports": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-0.0.5.tgz",
+ "integrity": "sha1-zMy0Cz3SmFmZOEodumDGLJYKbaA=",
"dev": true,
- "optional": true,
"requires": {
- "boom": "2.10.1"
+ "postcss": "^4.1.11"
}
},
- "dashdash": {
- "version": "1.14.1",
- "bundled": true,
+ "postcss-modules-local-by-default": {
+ "version": "0.0.12",
+ "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-0.0.12.tgz",
+ "integrity": "sha1-qTQxpLHQt6QCHiOPwn1ejkSSgsI=",
"dev": true,
- "optional": true,
"requires": {
- "assert-plus": "1.0.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- }
+ "css-selector-tokenizer": "^0.5.1",
+ "postcss": "^4.1.5"
}
},
- "debug": {
- "version": "2.6.8",
- "bundled": true,
+ "postcss-modules-scope": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-0.0.8.tgz",
+ "integrity": "sha1-gck1+/KJJyOIyLoulqEcohugmgQ=",
"dev": true,
- "optional": true,
"requires": {
- "ms": "2.0.0"
+ "css-selector-tokenizer": "^0.5.0",
+ "postcss": "^4.1.11"
}
},
- "deep-extend": {
- "version": "0.4.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "delayed-stream": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true
- },
- "delegates": {
- "version": "1.0.0",
- "bundled": true,
+ "postcss-normalize-url": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-2.1.3.tgz",
+ "integrity": "sha1-8StfShFDyV6gJfx/jgBQkFmPNgI=",
"dev": true,
- "optional": true
+ "requires": {
+ "is-absolute-url": "^2.0.0",
+ "normalize-url": "^1.3.0",
+ "object-assign": "^4.0.1",
+ "postcss": "^4.1.16",
+ "postcss-value-parser": "^1.4.2"
+ }
},
- "ecc-jsbn": {
- "version": "0.1.1",
- "bundled": true,
+ "postcss-ordered-values": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-1.1.1.tgz",
+ "integrity": "sha1-nu1PrS55Kr/D0EAs93O6+G/ne4E=",
"dev": true,
- "optional": true,
"requires": {
- "jsbn": "0.1.1"
+ "postcss": "^4.1.16",
+ "postcss-value-parser": "^1.1.0"
}
},
- "extend": {
- "version": "3.0.1",
- "bundled": true,
+ "postcss-reduce-idents": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-1.0.3.tgz",
+ "integrity": "sha1-p58bJIXiPZs8x6gfXsY6XCvewg0=",
"dev": true,
- "optional": true
- },
- "extsprintf": {
- "version": "1.0.2",
- "bundled": true,
- "dev": true
+ "requires": {
+ "postcss": "^4.1.2",
+ "reduce-function-call": "^1.0.1"
+ }
},
- "forever-agent": {
- "version": "0.6.1",
- "bundled": true,
+ "postcss-selector-parser": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-1.3.3.tgz",
+ "integrity": "sha1-0u4Z33pk+O8hwacchvfUg1yIwoE=",
"dev": true,
- "optional": true
+ "requires": {
+ "flatten": "^1.0.2",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ },
+ "dependencies": {
+ "flatten": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
+ "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
+ "dev": true
+ }
+ }
},
- "form-data": {
- "version": "2.1.4",
- "bundled": true,
+ "postcss-unique-selectors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-1.0.1.tgz",
+ "integrity": "sha1-SBfnTHtPmZzgTI5mRRoZaRT12zw=",
"dev": true,
- "optional": true,
"requires": {
- "asynckit": "0.4.0",
- "combined-stream": "1.0.5",
- "mime-types": "2.1.15"
+ "javascript-natural-sort": "^0.7.1",
+ "postcss": "^4.1.10",
+ "uniqs": "^2.0.0"
}
},
- "fs.realpath": {
- "version": "1.0.0",
- "bundled": true,
+ "postcss-value-parser": {
+ "version": "1.4.2",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-1.4.2.tgz",
+ "integrity": "sha1-GGVjPhNwH4pyHng02tGFyxRKrQw=",
"dev": true
},
- "fstream": {
- "version": "1.0.11",
- "bundled": true,
+ "postcss-zindex": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-1.1.3.tgz",
+ "integrity": "sha1-SVZKtJ092hcGf42sHIM11/LQDOE=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "inherits": "2.0.3",
- "mkdirp": "0.5.1",
- "rimraf": "2.6.1"
+ "postcss": "^4.1.2"
}
},
- "fstream-ignore": {
- "version": "1.0.5",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "fstream": "1.0.11",
- "inherits": "2.0.3",
- "minimatch": "3.0.4"
- }
+ "source-list-map": {
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz",
+ "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=",
+ "dev": true
},
- "gauge": {
- "version": "2.7.4",
- "bundled": true,
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
- "optional": true,
"requires": {
- "aproba": "1.1.1",
- "console-control-strings": "1.1.0",
- "has-unicode": "2.0.1",
- "object-assign": "4.1.1",
- "signal-exit": "3.0.2",
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "wide-align": "1.1.2"
+ "amdefine": ">=0.0.4"
}
},
- "getpass": {
- "version": "0.1.7",
- "bundled": true,
+ "style-loader": {
+ "version": "0.12.4",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.12.4.tgz",
+ "integrity": "sha1-rn0GZdxNxlPaov6Xu5CRS8HSLZs=",
"dev": true,
- "optional": true,
"requires": {
- "assert-plus": "1.0.0"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- }
+ "loader-utils": "^0.2.7"
}
},
- "glob": {
- "version": "7.1.2",
- "bundled": true,
+ "uniqid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-1.0.0.tgz",
+ "integrity": "sha1-JYJSTgdASESkLelPviv1SeG3RVU=",
+ "dev": true
+ }
+ }
+ },
+ "for-each": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.2.tgz",
+ "integrity": "sha1-LEBFC5NI6X8oEyJZO6lnBLmr1NQ=",
+ "requires": {
+ "is-function": "~1.0.0"
+ }
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "for-own": {
+ "version": "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"
+ }
+ },
+ "foreach": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/foreach/-/foreach-2.0.5.tgz",
+ "integrity": "sha1-C+4AUBiusmDQo6865ljdATbsG5k=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.2.tgz",
+ "integrity": "sha1-SXBJi+YEwgwAXU9cI67NIda0kJk=",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "formatio": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/formatio/-/formatio-1.1.1.tgz",
+ "integrity": "sha1-XtPM1jZVEJc4NGXZlhmRAOhhYek=",
+ "dev": true,
+ "requires": {
+ "samsam": "~1.1"
+ }
+ },
+ "formidable": {
+ "version": "1.0.16",
+ "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.0.16.tgz",
+ "integrity": "sha1-SRbP38TL7QILJXpqlQWpqzjCzQ4="
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=",
+ "dev": true
+ },
+ "fragment-cache": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz",
+ "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=",
+ "dev": true,
+ "requires": {
+ "map-cache": "^0.2.2"
+ }
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=",
+ "dev": true
+ },
+ "from2": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz",
+ "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.0"
+ }
+ },
+ "fs-chunk-store": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/fs-chunk-store/-/fs-chunk-store-1.7.0.tgz",
+ "integrity": "sha512-KhjJmZAs2eqfhCb6PdPx4RcZtheGTz86tpTC5JTvqBn/xda+Nb+0C7dCyjOSN7T76H6a56LvH0SVXQMchLXDRw==",
+ "requires": {
+ "mkdirp": "^0.5.1",
+ "random-access-file": "^2.0.1",
+ "randombytes": "^2.0.3",
+ "rimraf": "^2.4.2",
+ "run-parallel": "^1.1.2",
+ "thunky": "^1.0.1"
+ }
+ },
+ "fs-constants": {
+ "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=="
+ },
+ "fs-extra": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-2.1.2.tgz",
+ "integrity": "sha1-BGxwFjzvmq1GsOSn+kZ/si1x3jU=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0"
+ }
+ },
+ "fs-extra-p": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.6.0.tgz",
+ "integrity": "sha512-nSVqB5UfWZQdU6pzBwcFh+7lJpBynnTsVtNJTBhAnAppUQRut0W7WeM271iS0TqQ9FoCqDXqyL0+h+h8DQUCpg==",
+ "dev": true,
+ "requires": {
+ "bluebird-lst": "^1.0.5",
+ "fs-extra": "^6.0.0"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-6.0.1.tgz",
+ "integrity": "sha512-GnyIkKhhzXZUWFCaJzvyDLEEgDkPfb4/TPvJCJVuS8MWZgoSsErf++QpiAlDnKFcqhRlm+tIOcencCjyJE6ZCA==",
"dev": true,
"requires": {
- "fs.realpath": "1.0.0",
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
}
},
- "graceful-fs": {
- "version": "4.1.11",
- "bundled": true,
- "dev": true
- },
- "har-schema": {
- "version": "1.0.5",
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ }
+ }
+ },
+ "fs-write-stream-atomic": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz",
+ "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "iferr": "^0.1.5",
+ "imurmurhash": "^0.1.4",
+ "readable-stream": "1 || 2"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
+ },
+ "fsevents": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.4.tgz",
+ "integrity": "sha512-z8H8/diyk76B7q5wg+Ud0+CqzcAF3mBBI/bA5ne5zrRUUIvNkJY//D3BqyH571KuAC4Nr7Rw7CjWX4r0y9DvNg==",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "nan": "^2.9.2",
+ "node-pre-gyp": "^0.10.0"
+ },
+ "dependencies": {
+ "abbrev": {
+ "version": "1.1.1",
"bundled": true,
"dev": true,
"optional": true
},
- "har-validator": {
- "version": "4.2.1",
+ "ansi-regex": {
+ "version": "2.1.1",
"bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "ajv": "4.11.8",
- "har-schema": "1.0.5"
- }
+ "dev": true
},
- "has-unicode": {
- "version": "2.0.1",
+ "aproba": {
+ "version": "1.2.0",
"bundled": true,
"dev": true,
"optional": true
},
- "hawk": {
- "version": "3.1.3",
+ "are-we-there-yet": {
+ "version": "1.1.4",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "boom": "2.10.1",
- "cryptiles": "2.0.5",
- "hoek": "2.16.3",
- "sntp": "1.0.9"
+ "delegates": "^1.0.0",
+ "readable-stream": "^2.0.6"
}
},
- "hoek": {
- "version": "2.16.3",
+ "balanced-match": {
+ "version": "1.0.0",
"bundled": true,
"dev": true
},
- "http-signature": {
- "version": "1.1.1",
+ "brace-expansion": {
+ "version": "1.1.11",
"bundled": true,
"dev": true,
- "optional": true,
"requires": {
- "assert-plus": "0.2.0",
- "jsprim": "1.4.0",
- "sshpk": "1.13.0"
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
}
},
- "inflight": {
- "version": "1.0.6",
+ "chownr": {
+ "version": "1.0.1",
"bundled": true,
"dev": true,
- "requires": {
- "once": "1.4.0",
- "wrappy": "1.0.2"
- }
+ "optional": true
},
- "inherits": {
- "version": "2.0.3",
+ "code-point-at": {
+ "version": "1.1.0",
"bundled": true,
"dev": true
},
- "ini": {
- "version": "1.3.4",
+ "concat-map": {
+ "version": "0.0.1",
+ "bundled": true,
+ "dev": true
+ },
+ "console-control-strings": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
"bundled": true,
"dev": true,
"optional": true
},
- "is-fullwidth-code-point": {
- "version": "1.0.0",
+ "debug": {
+ "version": "2.6.9",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
- "number-is-nan": "1.0.1"
+ "ms": "2.0.0"
}
},
- "is-typedarray": {
- "version": "1.0.0",
+ "deep-extend": {
+ "version": "0.5.1",
"bundled": true,
"dev": true,
"optional": true
},
- "isarray": {
+ "delegates": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
- "isstream": {
- "version": "0.1.2",
+ "detect-libc": {
+ "version": "1.0.3",
"bundled": true,
"dev": true,
"optional": true
},
- "jodid25519": {
- "version": "1.0.2",
+ "fs-minipass": {
+ "version": "1.2.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "jsbn": "0.1.1"
+ "minipass": "^2.2.1"
}
},
- "jsbn": {
- "version": "0.1.1",
+ "fs.realpath": {
+ "version": "1.0.0",
"bundled": true,
"dev": true,
"optional": true
},
- "json-schema": {
- "version": "0.2.3",
+ "gauge": {
+ "version": "2.7.4",
"bundled": true,
"dev": true,
- "optional": true
+ "optional": true,
+ "requires": {
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
+ }
},
- "json-stable-stringify": {
- "version": "1.0.1",
+ "glob": {
+ "version": "7.1.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "jsonify": "0.0.0"
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
}
},
- "json-stringify-safe": {
- "version": "5.0.1",
+ "has-unicode": {
+ "version": "2.0.1",
"bundled": true,
"dev": true,
"optional": true
},
- "jsonify": {
- "version": "0.0.0",
+ "iconv-lite": {
+ "version": "0.4.21",
"bundled": true,
"dev": true,
- "optional": true
+ "optional": true,
+ "requires": {
+ "safer-buffer": "^2.1.0"
+ }
},
- "jsprim": {
- "version": "1.4.0",
+ "ignore-walk": {
+ "version": "3.0.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "assert-plus": "1.0.0",
- "extsprintf": "1.0.2",
- "json-schema": "0.2.3",
- "verror": "1.3.6"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- }
+ "minimatch": "^3.0.4"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
}
},
- "mime-db": {
- "version": "1.27.0",
+ "inherits": {
+ "version": "2.0.3",
"bundled": true,
"dev": true
},
- "mime-types": {
- "version": "2.1.15",
+ "ini": {
+ "version": "1.3.5",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
"bundled": true,
"dev": true,
"requires": {
- "mime-db": "1.27.0"
+ "number-is-nan": "^1.0.0"
}
},
+ "isarray": {
+ "version": "1.0.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
"minimatch": {
"version": "3.0.4",
"bundled": true,
"dev": true,
"requires": {
- "brace-expansion": "1.1.7"
+ "brace-expansion": "^1.1.7"
}
},
"minimist": {
@@ -8215,35 +7214,72 @@
"bundled": true,
"dev": true
},
- "mkdirp": {
- "version": "0.5.1",
+ "minipass": {
+ "version": "2.2.4",
"bundled": true,
"dev": true,
"requires": {
- "minimist": "0.0.8"
+ "safe-buffer": "^5.1.1",
+ "yallist": "^3.0.0"
}
},
- "ms": {
- "version": "2.0.0",
+ "minizlib": {
+ "version": "1.1.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "minipass": "^2.2.1"
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "bundled": true,
+ "dev": true,
+ "requires": {
+ "minimist": "0.0.8"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
"bundled": true,
"dev": true,
"optional": true
},
+ "nan": {
+ "version": "2.10.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.10.0.tgz",
+ "integrity": "sha512-bAdJv7fBLhWC+/Bls0Oza+mvTaNQtP+1RyhhhvD95pgUJz6XM5IzgmxOkItJ9tkoCiplvAnXI1tNmmUD/eScyA==",
+ "dev": true,
+ "optional": true
+ },
+ "needle": {
+ "version": "2.2.0",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "debug": "^2.1.2",
+ "iconv-lite": "^0.4.4",
+ "sax": "^1.2.4"
+ }
+ },
"node-pre-gyp": {
- "version": "0.6.36",
+ "version": "0.10.0",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "mkdirp": "0.5.1",
- "nopt": "4.0.1",
- "npmlog": "4.1.0",
- "rc": "1.2.1",
- "request": "2.81.0",
- "rimraf": "2.6.1",
- "semver": "5.3.0",
- "tar": "2.2.1",
- "tar-pack": "3.4.0"
+ "detect-libc": "^1.0.2",
+ "mkdirp": "^0.5.1",
+ "needle": "^2.2.0",
+ "nopt": "^4.0.1",
+ "npm-packlist": "^1.1.6",
+ "npmlog": "^4.0.2",
+ "rc": "^1.1.7",
+ "rimraf": "^2.6.1",
+ "semver": "^5.3.0",
+ "tar": "^4"
}
},
"nopt": {
@@ -8252,20 +7288,36 @@
"dev": true,
"optional": true,
"requires": {
- "abbrev": "1.1.0",
- "osenv": "0.1.4"
+ "abbrev": "1",
+ "osenv": "^0.1.4"
+ }
+ },
+ "npm-bundled": {
+ "version": "1.0.3",
+ "bundled": true,
+ "dev": true,
+ "optional": true
+ },
+ "npm-packlist": {
+ "version": "1.1.10",
+ "bundled": true,
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ignore-walk": "^3.0.1",
+ "npm-bundled": "^1.0.1"
}
},
"npmlog": {
- "version": "4.1.0",
+ "version": "4.1.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "are-we-there-yet": "1.1.4",
- "console-control-strings": "1.1.0",
- "gauge": "2.7.4",
- "set-blocking": "2.0.0"
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
}
},
"number-is-nan": {
@@ -8273,12 +7325,6 @@
"bundled": true,
"dev": true
},
- "oauth-sign": {
- "version": "0.8.2",
- "bundled": true,
- "dev": true,
- "optional": true
- },
"object-assign": {
"version": "4.1.1",
"bundled": true,
@@ -8290,7 +7336,7 @@
"bundled": true,
"dev": true,
"requires": {
- "wrappy": "1.0.2"
+ "wrappy": "1"
}
},
"os-homedir": {
@@ -8306,53 +7352,37 @@
"optional": true
},
"osenv": {
- "version": "0.1.4",
+ "version": "0.1.5",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "os-homedir": "1.0.2",
- "os-tmpdir": "1.0.2"
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
}
},
"path-is-absolute": {
"version": "1.0.1",
"bundled": true,
- "dev": true
- },
- "performance-now": {
- "version": "0.2.0",
- "bundled": true,
"dev": true,
"optional": true
},
"process-nextick-args": {
- "version": "1.0.7",
- "bundled": true,
- "dev": true
- },
- "punycode": {
- "version": "1.4.1",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "qs": {
- "version": "6.4.0",
+ "version": "2.0.0",
"bundled": true,
"dev": true,
"optional": true
},
"rc": {
- "version": "1.2.1",
+ "version": "1.2.7",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "deep-extend": "0.4.2",
- "ini": "1.3.4",
- "minimist": "1.2.0",
- "strip-json-comments": "2.0.1"
+ "deep-extend": "^0.5.1",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
},
"dependencies": {
"minimist": {
@@ -8364,144 +7394,89 @@
}
},
"readable-stream": {
- "version": "2.2.9",
- "bundled": true,
- "dev": true,
- "requires": {
- "buffer-shims": "1.0.0",
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "string_decoder": "1.0.1",
- "util-deprecate": "1.0.2"
- }
- },
- "request": {
- "version": "2.81.0",
+ "version": "2.3.6",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "aws-sign2": "0.6.0",
- "aws4": "1.6.0",
- "caseless": "0.12.0",
- "combined-stream": "1.0.5",
- "extend": "3.0.1",
- "forever-agent": "0.6.1",
- "form-data": "2.1.4",
- "har-validator": "4.2.1",
- "hawk": "3.1.3",
- "http-signature": "1.1.1",
- "is-typedarray": "1.0.0",
- "isstream": "0.1.2",
- "json-stringify-safe": "5.0.1",
- "mime-types": "2.1.15",
- "oauth-sign": "0.8.2",
- "performance-now": "0.2.0",
- "qs": "6.4.0",
- "safe-buffer": "5.0.1",
- "stringstream": "0.0.5",
- "tough-cookie": "2.3.2",
- "tunnel-agent": "0.6.0",
- "uuid": "3.0.1"
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
}
},
"rimraf": {
- "version": "2.6.1",
+ "version": "2.6.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
- "glob": "7.1.2"
+ "glob": "^7.0.5"
}
},
"safe-buffer": {
- "version": "5.0.1",
+ "version": "5.1.1",
"bundled": true,
"dev": true
},
- "semver": {
- "version": "5.3.0",
+ "safer-buffer": {
+ "version": "2.1.2",
"bundled": true,
"dev": true,
"optional": true
},
- "set-blocking": {
- "version": "2.0.0",
+ "sax": {
+ "version": "1.2.4",
"bundled": true,
"dev": true,
"optional": true
},
- "signal-exit": {
- "version": "3.0.2",
+ "semver": {
+ "version": "5.5.0",
"bundled": true,
"dev": true,
"optional": true
},
- "sntp": {
- "version": "1.0.9",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "hoek": "2.16.3"
- }
- },
- "sshpk": {
- "version": "1.13.0",
+ "set-blocking": {
+ "version": "2.0.0",
"bundled": true,
"dev": true,
- "optional": true,
- "requires": {
- "asn1": "0.2.3",
- "assert-plus": "1.0.0",
- "bcrypt-pbkdf": "1.0.1",
- "dashdash": "1.14.1",
- "ecc-jsbn": "0.1.1",
- "getpass": "0.1.7",
- "jodid25519": "1.0.2",
- "jsbn": "0.1.1",
- "tweetnacl": "0.14.5"
- },
- "dependencies": {
- "assert-plus": {
- "version": "1.0.0",
- "bundled": true,
- "dev": true,
- "optional": true
- }
- }
+ "optional": true
},
- "string_decoder": {
- "version": "1.0.1",
+ "signal-exit": {
+ "version": "3.0.2",
"bundled": true,
"dev": true,
- "requires": {
- "safe-buffer": "5.0.1"
- }
+ "optional": true
},
"string-width": {
"version": "1.0.2",
"bundled": true,
"dev": true,
"requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
- "strip-ansi": "3.0.1"
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
}
},
- "stringstream": {
- "version": "0.0.5",
+ "string_decoder": {
+ "version": "1.1.1",
"bundled": true,
"dev": true,
- "optional": true
+ "optional": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
},
"strip-ansi": {
"version": "3.0.1",
"bundled": true,
"dev": true,
"requires": {
- "ansi-regex": "2.1.1"
+ "ansi-regex": "^2.0.0"
}
},
"strip-json-comments": {
@@ -8511,94 +7486,44 @@
"optional": true
},
"tar": {
- "version": "2.2.1",
- "bundled": true,
- "dev": true,
- "requires": {
- "block-stream": "0.0.9",
- "fstream": "1.0.11",
- "inherits": "2.0.3"
- }
- },
- "tar-pack": {
- "version": "3.4.0",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "debug": "2.6.8",
- "fstream": "1.0.11",
- "fstream-ignore": "1.0.5",
- "once": "1.4.0",
- "readable-stream": "2.2.9",
- "rimraf": "2.6.1",
- "tar": "2.2.1",
- "uid-number": "0.0.6"
- }
- },
- "tough-cookie": {
- "version": "2.3.2",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "punycode": "1.4.1"
- }
- },
- "tunnel-agent": {
- "version": "0.6.0",
+ "version": "4.4.1",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "safe-buffer": "5.0.1"
+ "chownr": "^1.0.1",
+ "fs-minipass": "^1.2.5",
+ "minipass": "^2.2.4",
+ "minizlib": "^1.1.0",
+ "mkdirp": "^0.5.0",
+ "safe-buffer": "^5.1.1",
+ "yallist": "^3.0.2"
}
},
- "tweetnacl": {
- "version": "0.14.5",
- "bundled": true,
- "dev": true,
- "optional": true
- },
- "uid-number": {
- "version": "0.0.6",
- "bundled": true,
- "dev": true,
- "optional": true
- },
"util-deprecate": {
"version": "1.0.2",
"bundled": true,
- "dev": true
- },
- "uuid": {
- "version": "3.0.1",
- "bundled": true,
"dev": true,
"optional": true
},
- "verror": {
- "version": "1.3.6",
- "bundled": true,
- "dev": true,
- "optional": true,
- "requires": {
- "extsprintf": "1.0.2"
- }
- },
"wide-align": {
"version": "1.1.2",
"bundled": true,
"dev": true,
"optional": true,
"requires": {
- "string-width": "1.0.2"
+ "string-width": "^1.0.2"
}
},
"wrappy": {
"version": "1.0.2",
"bundled": true,
"dev": true
+ },
+ "yallist": {
+ "version": "3.0.2",
+ "bundled": true,
+ "dev": true
}
}
},
@@ -8608,32 +7533,10 @@
"integrity": "sha1-XB+x8RdHcRTwYyoOtLcbPLD9MXE=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "inherits": "2.0.3",
- "mkdirp": "0.5.1",
- "rimraf": "2.6.2"
- }
- },
- "ftp": {
- "version": "0.3.10",
- "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz",
- "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=",
- "requires": {
- "readable-stream": "1.1.14",
- "xregexp": "2.0.0"
- },
- "dependencies": {
- "readable-stream": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "0.0.1",
- "string_decoder": "0.10.31"
- }
- }
+ "graceful-fs": "^4.1.2",
+ "inherits": "~2.0.0",
+ "mkdirp": ">=0.5 0",
+ "rimraf": "2"
}
},
"function-bind": {
@@ -8643,14 +7546,14 @@
"dev": true
},
"function.prototype.name": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.0.3.tgz",
- "integrity": "sha512-5EblxZUdioXi2JiMZ9FUbwYj40eQ9MFHyzFLBSPdlRl3SO8l7SLWuAnQ/at/1Wi4hjJwME/C5WpF2ZfAc8nGNw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.0.tgz",
+ "integrity": "sha512-Bs0VRrTz4ghD8pTmbJQD1mZ8A/mN0ur/jGz+A6FBxPDUPkm1tNfF6bhTYPA7i7aF4lZJVr+OXTNNrnnIl58Wfg==",
"dev": true,
"requires": {
- "define-properties": "1.1.2",
- "function-bind": "1.1.1",
- "is-callable": "1.1.3"
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "is-callable": "^1.1.3"
}
},
"functional-red-black-tree": {
@@ -8659,9 +7562,9 @@
"integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc="
},
"gar": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.2.tgz",
- "integrity": "sha512-Zn3tdQgiXQlVHiASU/cXzpo+EOC1qE/tOPdge6SjgJC39MxHFlESOHN38a9htTszCQy8rMWiPzoypL8sNv0ifg==",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/gar/-/gar-1.0.3.tgz",
+ "integrity": "sha512-zDpwk/l3HbhjVAvdxNUTJFzgXiNy0a7EmE/50XT38o1z+7NJbFhp+8CDsv1Qgy2adBAwUVYlMpIX2fZUbmlUJw==",
"optional": true
},
"gather-stream": {
@@ -8675,14 +7578,14 @@
"resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
"integrity": "sha1-LANAXHU4w51+s3sxcCLjJfsBi/c=",
"requires": {
- "aproba": "1.2.0",
- "console-control-strings": "1.1.0",
- "has-unicode": "2.0.1",
- "object-assign": "4.1.1",
- "signal-exit": "3.0.2",
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "wide-align": "1.1.2"
+ "aproba": "^1.0.3",
+ "console-control-strings": "^1.0.0",
+ "has-unicode": "^2.0.0",
+ "object-assign": "^4.1.0",
+ "signal-exit": "^3.0.0",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wide-align": "^1.1.0"
}
},
"gaze": {
@@ -8691,7 +7594,7 @@
"integrity": "sha1-QLcJU30k0dRXZ9takIaJ3+aaxE8=",
"dev": true,
"requires": {
- "globule": "0.1.0"
+ "globule": "~0.1.0"
}
},
"generate-function": {
@@ -8706,7 +7609,7 @@
"integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
"dev": true,
"requires": {
- "is-property": "1.0.2"
+ "is-property": "^1.0.0"
}
},
"get-browser-rtc": {
@@ -8725,8 +7628,8 @@
"integrity": "sha1-gC+kIIQ03nEgUYKxWrfxNSCI5YA=",
"optional": true,
"requires": {
- "async": "1.5.2",
- "gar": "1.0.2"
+ "async": "^1.4.2",
+ "gar": "^1.0.2"
},
"dependencies": {
"async": {
@@ -8743,15 +7646,15 @@
"integrity": "sha1-csOPvuLnZyhCSgDcFOJN0aKMI5E=",
"dev": true,
"requires": {
- "bluebird": "3.5.0",
- "lodash.get": "4.4.2",
- "resolve": "1.4.0"
+ "bluebird": "^3.1.1",
+ "lodash.get": "^4.0.0",
+ "resolve": "^1.1.6"
}
},
"get-stdin": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
- "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g="
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g=="
},
"get-stream": {
"version": "3.0.0",
@@ -8759,60 +7662,24 @@
"integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
"dev": true
},
- "get-uri": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-2.0.1.tgz",
- "integrity": "sha512-7aelVrYqCLuVjq2kEKRTH8fXPTC0xKTkM+G7UlFkEwCXY3sFbSxvY375JoFowOAYbkaU47SrBvOefUlLZZ+6QA==",
- "requires": {
- "data-uri-to-buffer": "1.2.0",
- "debug": "2.6.9",
- "extend": "3.0.0",
- "file-uri-to-path": "1.0.0",
- "ftp": "0.3.10",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
- }
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
},
"getpass": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
"requires": {
- "assert-plus": "1.0.0"
+ "assert-plus": "^1.0.0"
}
},
"git-rev-sync": {
- "version": "1.9.1",
- "resolved": "https://registry.npmjs.org/git-rev-sync/-/git-rev-sync-1.9.1.tgz",
- "integrity": "sha1-oMLj3TkqvPa3aWLif8dfsyI0Sc4=",
+ "version": "1.12.0",
+ "resolved": "https://registry.npmjs.org/git-rev-sync/-/git-rev-sync-1.12.0.tgz",
+ "integrity": "sha1-RGhAbH5sO6TPRYeZnhrbKNnRr1U=",
"dev": true,
"requires": {
"escape-string-regexp": "1.0.5",
@@ -8830,12 +7697,12 @@
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
"requires": {
- "fs.realpath": "1.0.0",
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
}
},
"glob-base": {
@@ -8844,17 +7711,44 @@
"integrity": "sha1-27Fk9iIbHAscz4Kuoyi0l98Oo8Q=",
"dev": true,
"requires": {
- "glob-parent": "2.0.0",
- "is-glob": "2.0.1"
+ "glob-parent": "^2.0.0",
+ "is-glob": "^2.0.0"
+ },
+ "dependencies": {
+ "glob-parent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
+ "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^2.0.0"
+ }
+ },
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^1.0.0"
+ }
+ }
}
},
"glob-parent": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz",
- "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=",
+ "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": "2.0.1"
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
}
},
"glob-stream": {
@@ -8863,12 +7757,12 @@
"integrity": "sha1-kXCl8St5Awb9/lmPMT+PeVT9FDs=",
"dev": true,
"requires": {
- "glob": "4.5.3",
- "glob2base": "0.0.12",
- "minimatch": "2.0.10",
- "ordered-read-streams": "0.1.0",
- "through2": "0.6.5",
- "unique-stream": "1.0.0"
+ "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": {
"glob": {
@@ -8877,10 +7771,10 @@
"integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=",
"dev": true,
"requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "2.0.10",
- "once": "1.4.0"
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^2.0.1",
+ "once": "^1.3.0"
}
},
"minimatch": {
@@ -8889,7 +7783,7 @@
"integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
"dev": true,
"requires": {
- "brace-expansion": "1.1.8"
+ "brace-expansion": "^1.0.0"
}
}
}
@@ -8900,7 +7794,7 @@
"integrity": "sha1-uVtKjfdLOcgymLDAXJeLTZo7cQs=",
"dev": true,
"requires": {
- "gaze": "0.5.2"
+ "gaze": "^0.5.1"
}
},
"glob2base": {
@@ -8909,7 +7803,7 @@
"integrity": "sha1-nUGbPijxLoOjYhZKJ3BVkiycDVY=",
"dev": true,
"requires": {
- "find-index": "0.1.1"
+ "find-index": "^0.1.1"
}
},
"global": {
@@ -8917,15 +7811,8 @@
"resolved": "https://registry.npmjs.org/global/-/global-4.3.2.tgz",
"integrity": "sha1-52mJJopsdMOJCLEwWxD8DjlOnQ8=",
"requires": {
- "min-document": "2.19.0",
- "process": "0.5.2"
- },
- "dependencies": {
- "process": {
- "version": "0.5.2",
- "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
- "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
- }
+ "min-document": "^2.19.0",
+ "process": "~0.5.1"
}
},
"global-dirs": {
@@ -8934,63 +7821,49 @@
"integrity": "sha1-sxnA3UYH81PzvpzKTHL8FIxJ9EU=",
"dev": true,
"requires": {
- "ini": "1.3.4"
+ "ini": "^1.3.4"
}
},
"global-modules": {
- "version": "0.2.3",
- "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-0.2.3.tgz",
- "integrity": "sha1-6lo77ULG1s6ZWk+KEmm12uIjgo0=",
+ "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": "0.1.5",
- "is-windows": "0.2.0"
- },
- "dependencies": {
- "is-windows": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
- "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
- "dev": true
- }
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
}
},
"global-prefix": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-0.1.5.tgz",
- "integrity": "sha1-jTvGuNo8qBEqFg2NSW/wRiv+948=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=",
"dev": true,
"requires": {
- "homedir-polyfill": "1.0.1",
- "ini": "1.3.4",
- "is-windows": "0.2.0",
- "which": "1.3.0"
- },
- "dependencies": {
- "is-windows": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
- "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
- "dev": true
- }
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
}
},
"globals": {
- "version": "9.18.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
- "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
+ "version": "11.5.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.5.0.tgz",
+ "integrity": "sha512-hYyf+kI8dm3nORsiiXUQigOU62hDLfJ9G01uyGMxhc6BKsircrUhC4uJPQPUSuq2GrTmiiEt7ewxlMdBewfmKQ=="
},
"globby": {
"version": "5.0.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
"integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
"requires": {
- "array-union": "1.0.2",
- "arrify": "1.0.1",
- "glob": "7.1.2",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1"
+ "array-union": "^1.0.1",
+ "arrify": "^1.0.0",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
}
},
"globule": {
@@ -8999,9 +7872,9 @@
"integrity": "sha1-2cjt3h2nnRJaFRt5UzuXhnY0auU=",
"dev": true,
"requires": {
- "glob": "3.1.21",
- "lodash": "1.0.2",
- "minimatch": "0.2.14"
+ "glob": "~3.1.21",
+ "lodash": "~1.0.1",
+ "minimatch": "~0.2.11"
},
"dependencies": {
"glob": {
@@ -9010,9 +7883,9 @@
"integrity": "sha1-0p4KBV3qUTj00H7UDomC6DwgZs0=",
"dev": true,
"requires": {
- "graceful-fs": "1.2.3",
- "inherits": "1.0.2",
- "minimatch": "0.2.14"
+ "graceful-fs": "~1.2.0",
+ "inherits": "1",
+ "minimatch": "~0.2.11"
}
},
"graceful-fs": {
@@ -9045,19 +7918,19 @@
"integrity": "sha1-x054BXT2PG+aCQ6Q775u9TpqdWo=",
"dev": true,
"requires": {
- "lru-cache": "2.7.3",
- "sigmund": "1.0.1"
+ "lru-cache": "2",
+ "sigmund": "~1.0.0"
}
}
}
},
"glogg": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.0.tgz",
- "integrity": "sha1-f+DxmfV6yQbPUS/urY+Q7kooT8U=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/glogg/-/glogg-1.0.1.tgz",
+ "integrity": "sha512-ynYqXLoluBKf9XGR1gA59yEJisIL7YHEH4xr3ZziHB5/yl4qWfaK8Js9jGe6gBGCSCKVqiyO30WnRZADvemUNw==",
"dev": true,
"requires": {
- "sparkles": "1.0.0"
+ "sparkles": "^1.0.0"
}
},
"got": {
@@ -9066,25 +7939,17 @@
"integrity": "sha1-JAzQV4WpoY5WHcG0S0HHY+8ejbA=",
"dev": true,
"requires": {
- "create-error-class": "3.0.2",
- "duplexer3": "0.1.4",
- "get-stream": "3.0.0",
- "is-redirect": "1.0.0",
- "is-retry-allowed": "1.1.0",
- "is-stream": "1.1.0",
- "lowercase-keys": "1.0.0",
- "safe-buffer": "5.1.1",
- "timed-out": "4.0.1",
- "unzip-response": "2.0.1",
- "url-parse-lax": "1.0.0"
- },
- "dependencies": {
- "unzip-response": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
- "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
- "dev": true
- }
+ "create-error-class": "^3.0.0",
+ "duplexer3": "^0.1.4",
+ "get-stream": "^3.0.0",
+ "is-redirect": "^1.0.0",
+ "is-retry-allowed": "^1.0.0",
+ "is-stream": "^1.0.0",
+ "lowercase-keys": "^1.0.0",
+ "safe-buffer": "^5.0.1",
+ "timed-out": "^4.0.0",
+ "unzip-response": "^2.0.1",
+ "url-parse-lax": "^1.0.0"
}
},
"graceful-fs": {
@@ -9116,26 +7981,33 @@
"integrity": "sha1-VxzkWSjdQK9lFPxAEYZgFsE4RbQ=",
"dev": true,
"requires": {
- "archy": "1.0.0",
- "chalk": "1.1.3",
- "deprecated": "0.0.1",
- "gulp-util": "3.0.8",
- "interpret": "1.0.4",
- "liftoff": "2.3.0",
- "minimist": "1.2.0",
- "orchestrator": "0.3.8",
- "pretty-hrtime": "1.0.3",
- "semver": "4.3.6",
- "tildify": "1.2.0",
- "v8flags": "2.1.1",
- "vinyl-fs": "0.3.14"
+ "archy": "^1.0.0",
+ "chalk": "^1.0.0",
+ "deprecated": "^0.0.1",
+ "gulp-util": "^3.0.0",
+ "interpret": "^1.0.0",
+ "liftoff": "^2.1.0",
+ "minimist": "^1.1.0",
+ "orchestrator": "^0.3.0",
+ "pretty-hrtime": "^1.0.0",
+ "semver": "^4.1.0",
+ "tildify": "^1.0.0",
+ "v8flags": "^2.0.2",
+ "vinyl-fs": "^0.3.0"
},
"dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
},
"semver": {
"version": "4.3.6",
@@ -9151,51 +8023,27 @@
"integrity": "sha1-uG/zSdgBzrVuHZ59x7vLS33uYAw=",
"dev": true,
"requires": {
- "convert-source-map": "1.5.0",
- "graceful-fs": "4.1.11",
- "strip-bom": "2.0.0",
- "through2": "2.0.3",
- "vinyl": "1.2.0"
+ "convert-source-map": "^1.1.1",
+ "graceful-fs": "^4.1.2",
+ "strip-bom": "^2.0.0",
+ "through2": "^2.0.0",
+ "vinyl": "^1.0.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
"dev": true
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
}
},
"vinyl": {
@@ -9204,8 +8052,8 @@
"integrity": "sha1-XIgDbPVl5d8FVYv8kR+GVt8hiIQ=",
"dev": true,
"requires": {
- "clone": "1.0.2",
- "clone-stats": "0.0.1",
+ "clone": "^1.0.0",
+ "clone-stats": "^0.0.1",
"replace-ext": "0.0.1"
}
}
@@ -9217,37 +8065,38 @@
"integrity": "sha1-AFTh50RQLifATBh8PsxQXdVLu08=",
"dev": true,
"requires": {
- "array-differ": "1.0.0",
- "array-uniq": "1.0.3",
- "beeper": "1.1.1",
- "chalk": "1.1.3",
- "dateformat": "2.2.0",
- "fancy-log": "1.3.0",
- "gulplog": "1.0.0",
- "has-gulplog": "0.1.0",
- "lodash._reescape": "3.0.0",
- "lodash._reevaluate": "3.0.0",
- "lodash._reinterpolate": "3.0.0",
- "lodash.template": "3.6.2",
- "minimist": "1.2.0",
- "multipipe": "0.1.2",
- "object-assign": "3.0.0",
+ "array-differ": "^1.0.0",
+ "array-uniq": "^1.0.2",
+ "beeper": "^1.0.0",
+ "chalk": "^1.0.0",
+ "dateformat": "^2.0.0",
+ "fancy-log": "^1.1.0",
+ "gulplog": "^1.0.0",
+ "has-gulplog": "^0.1.0",
+ "lodash._reescape": "^3.0.0",
+ "lodash._reevaluate": "^3.0.0",
+ "lodash._reinterpolate": "^3.0.0",
+ "lodash.template": "^3.0.0",
+ "minimist": "^1.1.0",
+ "multipipe": "^0.1.2",
+ "object-assign": "^3.0.0",
"replace-ext": "0.0.1",
- "through2": "2.0.3",
- "vinyl": "0.5.3"
+ "through2": "^2.0.0",
+ "vinyl": "^0.5.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
},
"object-assign": {
"version": "3.0.0",
@@ -9255,38 +8104,14 @@
"integrity": "sha1-m+3VygiXlJvKR+f/QIBi1Un1h/I=",
"dev": true
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
}
}
}
@@ -9297,7 +8122,7 @@
"integrity": "sha1-4oxNRdBey77YGDY86PnFkmIp/+U=",
"dev": true,
"requires": {
- "glogg": "1.0.0"
+ "glogg": "^1.0.0"
}
},
"handle-thing": {
@@ -9307,15 +8132,15 @@
"dev": true
},
"handlebars": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
- "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=",
+ "version": "4.0.11",
+ "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.11.tgz",
+ "integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
"dev": true,
"requires": {
- "async": "1.5.2",
- "optimist": "0.6.1",
- "source-map": "0.4.4",
- "uglify-js": "2.8.29"
+ "async": "^1.4.0",
+ "optimist": "^0.6.1",
+ "source-map": "^0.4.4",
+ "uglify-js": "^2.6"
},
"dependencies": {
"async": {
@@ -9330,7 +8155,7 @@
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
"dev": true,
"requires": {
- "amdefine": "1.0.1"
+ "amdefine": ">=0.0.4"
}
}
}
@@ -9345,8 +8170,8 @@
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.0.3.tgz",
"integrity": "sha1-ukAsJmGU8VlW7xXg/PJCmT9qff0=",
"requires": {
- "ajv": "5.2.3",
- "har-schema": "2.0.0"
+ "ajv": "^5.1.0",
+ "har-schema": "^2.0.0"
}
},
"has": {
@@ -9355,7 +8180,7 @@
"integrity": "sha1-hGFzP1OLCDfJNh45qauelwTcLyg=",
"dev": true,
"requires": {
- "function-bind": "1.1.1"
+ "function-bind": "^1.0.2"
}
},
"has-ansi": {
@@ -9363,13 +8188,13 @@
"resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
"requires": {
- "ansi-regex": "2.1.1"
+ "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="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0="
},
"has-gulplog": {
"version": "0.1.0",
@@ -9377,75 +8202,125 @@
"integrity": "sha1-ZBTIKRNpfaUVkDl9r7EvIpZ4Ec4=",
"dev": true,
"requires": {
- "sparkles": "1.0.0"
+ "sparkles": "^1.0.0"
}
},
+ "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-unicode": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz",
"integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk="
},
+ "has-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz",
+ "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.6",
+ "has-values": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "has-values": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz",
+ "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "kind-of": "^4.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
+ "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
"hash-base": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-2.0.2.tgz",
- "integrity": "sha1-ZuodhW206KVHDK32/OI65SRO8uE=",
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
+ "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
"requires": {
- "inherits": "2.0.3"
+ "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,
"requires": {
- "inherits": "2.0.3",
- "minimalistic-assert": "1.0.0"
+ "inherits": "^2.0.3",
+ "minimalistic-assert": "^1.0.0"
}
},
"hawk": {
- "version": "6.0.2",
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-6.0.2.tgz",
- "integrity": "sha512-miowhl2+U7Qle4vdLqDdPt9m09K6yZhkLDTWGoUiUzrQCn+mHHSmfJgAyGaLRZbPmTqfFFjRV1QWCW0VWUJBbQ==",
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
+ "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
+ "dev": true,
"requires": {
- "boom": "4.3.1",
- "cryptiles": "3.1.2",
- "hoek": "4.2.0",
- "sntp": "2.0.2"
+ "boom": "2.x.x",
+ "cryptiles": "2.x.x",
+ "hoek": "2.x.x",
+ "sntp": "1.x.x"
+ },
+ "dependencies": {
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
+ "dev": true
+ }
}
},
"hmac-drbg": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz",
"integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=",
+ "dev": true,
"requires": {
- "hash.js": "1.1.3",
- "minimalistic-assert": "1.0.0",
- "minimalistic-crypto-utils": "1.0.1"
+ "hash.js": "^1.0.3",
+ "minimalistic-assert": "^1.0.0",
+ "minimalistic-crypto-utils": "^1.0.1"
}
},
"hoek": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-4.2.0.tgz",
- "integrity": "sha512-v0XCLxICi9nPfYrS9RL8HbYnXi9obYAeLbSP00BmnZwCK9+Ih9WOjoZ8YoHCoav2csqn4FOz4Orldsy2dmDwmQ=="
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-5.0.3.tgz",
+ "integrity": "sha512-Bmr56pxML1c9kU+NS51SMFkiVQAb+9uFfXwyqR2tn4w2FPvmPt65eZ9aCcEfRXd9G74HkZnILC6p967pED4aiw=="
},
"hoist-non-react-statics": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.3.1.tgz",
- "integrity": "sha1-ND24TGAYxlB3iJgkATWhQg7iLOA="
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-2.5.0.tgz",
+ "integrity": "sha512-6Bl6XsDT1ntE0lHbIhr4Kp2PGcleGZ66qu5Jqk8lc0Xc/IeG6gVLmwUGs/K0Us+L8VWoKgj0uWdPMataOsm31w=="
},
"home-or-tmp": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz",
"integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=",
"requires": {
- "os-homedir": "1.0.2",
- "os-tmpdir": "1.0.2"
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.1"
}
},
"home-path": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.5.tgz",
- "integrity": "sha1-eIspgVsS1Tus9XVkhHbm+QQdEz8=",
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/home-path/-/home-path-1.0.6.tgz",
+ "integrity": "sha512-wo+yjrdAtoXt43Vy92a+0IPCYViiyLAHyp0QVS4xL/tfvVz5sXIW1ubLZk3nhVkD92fQpUMKX+fzMjr5F489vw==",
"dev": true
},
"homedir-polyfill": {
@@ -9454,13 +8329,13 @@
"integrity": "sha1-TCu8inWJmP7r9e1oWA921GdotLw=",
"dev": true,
"requires": {
- "parse-passwd": "1.0.0"
+ "parse-passwd": "^1.0.0"
}
},
"hosted-git-info": {
- "version": "2.5.0",
- "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.5.0.tgz",
- "integrity": "sha512-pNgbURSuab90KbTqvRPsseaTxOJCZBD0a7t+haSN33piP9cCM4l0CqdzAif2hUqm716UovKB2ROmiabGAKVXyg=="
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.6.0.tgz",
+ "integrity": "sha512-lIbgIIQA3lz5XaB6vxakj6sDHADJiZadYEJB+FgA+C4nubM1NwcuvUr9EJPmnH1skZqpqUzWborWo8EIUi0Sdw=="
},
"hpack.js": {
"version": "2.1.6",
@@ -9468,50 +8343,24 @@
"integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=",
"dev": true,
"requires": {
- "inherits": "2.0.3",
- "obuf": "1.1.1",
- "readable-stream": "2.3.3",
- "wbuf": "1.7.2"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "inherits": "^2.0.1",
+ "obuf": "^1.0.0",
+ "readable-stream": "^2.0.1",
+ "wbuf": "^1.1.0"
}
},
+ "html-comment-regex": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.1.tgz",
+ "integrity": "sha1-ZouTd26q5V696POtRkswekljYl4=",
+ "dev": true
+ },
"html-encoding-sniffer": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.1.tgz",
- "integrity": "sha1-eb96eF6klf5mFl5zQVPzY/9UN9o=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+ "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
"requires": {
- "whatwg-encoding": "1.0.1"
+ "whatwg-encoding": "^1.0.1"
}
},
"html-entities": {
@@ -9524,42 +8373,14 @@
"version": "3.9.2",
"resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.9.2.tgz",
"integrity": "sha1-G9+HrMoPP55T+k/M6w9LTLsAszg=",
+ "dev": true,
"requires": {
- "domelementtype": "1.3.0",
- "domhandler": "2.4.1",
- "domutils": "1.6.2",
- "entities": "1.1.1",
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "domelementtype": "^1.3.0",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.2"
}
},
"http-deceiver": {
@@ -9569,39 +8390,32 @@
"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=",
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz",
+ "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=",
+ "dev": true,
"requires": {
- "depd": "1.1.1",
+ "depd": "~1.1.2",
"inherits": "2.0.3",
- "setprototypeof": "1.0.3",
- "statuses": "1.3.1"
+ "setprototypeof": "1.1.0",
+ "statuses": ">= 1.4.0 < 2"
}
},
"http-parser-js": {
- "version": "0.4.8",
- "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.8.tgz",
- "integrity": "sha512-jmHp99g6/fLx0pRNJqzsQgjsclCHAY7NhIeA3/U+bsGNvgbvUCQFQY9m5AYpqpAxY/2VcikfbKpjQozSTiz0jA==",
+ "version": "0.4.13",
+ "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.4.13.tgz",
+ "integrity": "sha1-O9bW/ebjFyyTNMOzO2wZPYD+ETc=",
"dev": true
},
"http-proxy": {
- "version": "1.11.1",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.11.1.tgz",
- "integrity": "sha1-cd9VdX6ALVjqgQ3yJEAZ3aBa6F0=",
- "requires": {
- "eventemitter3": "1.2.0",
- "requires-port": "0.0.1"
- }
- },
- "http-proxy-agent": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-1.0.0.tgz",
- "integrity": "sha1-zBzjjkU7+YSg93AtLdWcc9CBKEo=",
+ "version": "1.17.0",
+ "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.17.0.tgz",
+ "integrity": "sha512-Taqn+3nNvYRfJ3bGvKfBSRwy1v6eePlm3oc/aWVxZp57DQr5Eq3xhKJi7Z4hZpS8PC3H4qI+Yly5EmFacGuA/g==",
+ "dev": true,
"requires": {
- "agent-base": "2.1.1",
- "debug": "2.6.9",
- "extend": "3.0.0"
+ "eventemitter3": "^3.0.0",
+ "follow-redirects": "^1.0.0",
+ "requires-port": "^1.0.0"
}
},
"http-proxy-middleware": {
@@ -9610,42 +8424,102 @@
"integrity": "sha1-ZC6ISIUdZvCdTxJJEoRtuutBuDM=",
"dev": true,
"requires": {
- "http-proxy": "1.16.2",
- "is-glob": "3.1.0",
- "lodash": "4.17.4",
- "micromatch": "2.3.11"
+ "http-proxy": "^1.16.2",
+ "is-glob": "^3.1.0",
+ "lodash": "^4.17.2",
+ "micromatch": "^2.3.11"
},
"dependencies": {
- "http-proxy": {
- "version": "1.16.2",
- "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.16.2.tgz",
- "integrity": "sha1-Bt/ykpUr9k2+hHH6nfcwZtTzd0I=",
+ "arr-diff": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-2.0.0.tgz",
+ "integrity": "sha1-jzuCf5Vai9ZpaX5KQlasPOrjVs8=",
"dev": true,
"requires": {
- "eventemitter3": "1.2.0",
- "requires-port": "1.0.0"
+ "arr-flatten": "^1.0.1"
}
},
- "is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "array-unique": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.2.1.tgz",
+ "integrity": "sha1-odl8yvy8JiXMcPrc6zalDFiwGlM=",
"dev": true
},
- "is-glob": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
- "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "braces": {
+ "version": "1.8.5",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-1.8.5.tgz",
+ "integrity": "sha1-uneWLhLf+WnWt2cR6RS3N4V79qc=",
+ "dev": true,
+ "requires": {
+ "expand-range": "^1.8.1",
+ "preserve": "^0.2.0",
+ "repeat-element": "^1.1.2"
+ }
+ },
+ "expand-brackets": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-0.1.5.tgz",
+ "integrity": "sha1-3wcoTjQqgHzXM6xa9yQR5YHRF3s=",
+ "dev": true,
+ "requires": {
+ "is-posix-bracket": "^0.1.0"
+ }
+ },
+ "extglob": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-0.3.2.tgz",
+ "integrity": "sha1-Lhj/PS9JqydlzskCPwEdqo2DSaE=",
"dev": true,
"requires": {
- "is-extglob": "2.1.1"
+ "is-extglob": "^1.0.0"
}
},
- "requires-port": {
+ "is-extglob": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
"dev": true
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ },
+ "micromatch": {
+ "version": "2.3.11",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
+ "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^2.0.0",
+ "array-unique": "^0.2.1",
+ "braces": "^1.8.2",
+ "expand-brackets": "^0.1.4",
+ "extglob": "^0.3.1",
+ "filename-regex": "^2.0.0",
+ "is-extglob": "^1.0.0",
+ "is-glob": "^2.0.1",
+ "kind-of": "^3.0.2",
+ "normalize-path": "^2.0.1",
+ "object.omit": "^2.0.0",
+ "parse-glob": "^3.0.4",
+ "regex-cache": "^0.4.2"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^1.0.0"
+ }
+ }
+ }
}
}
},
@@ -9654,12 +8528,12 @@
"resolved": "https://registry.npmjs.org/http-request-signature/-/http-request-signature-0.0.2.tgz",
"integrity": "sha512-lyI0DUMqj211+xKIZX6cSSKNJTV30Q6IvWEb23S7Z3zt47P2p5AyYaaLGsFlBMGCOJAi8mxWMloFcM3RsiGNyg==",
"requires": {
- "debugnyan": "2.0.1",
- "eslint": "4.12.1",
- "lodash": "4.17.4",
- "standard-http-error": "2.0.1",
- "validator.js": "2.0.3",
- "validator.js-asserts": "3.1.0"
+ "debugnyan": "^2.0.1",
+ "eslint": "^4.6.1",
+ "lodash": "^4.17.4",
+ "standard-http-error": "^2.0.0",
+ "validator.js": "^2.0.3",
+ "validator.js-asserts": "^3.1.0"
}
},
"http-signature": {
@@ -9667,9 +8541,9 @@
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
"requires": {
- "assert-plus": "1.0.0",
- "jsprim": "1.4.1",
- "sshpk": "1.13.1"
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
}
},
"https-browserify": {
@@ -9679,13 +8553,24 @@
"dev": true
},
"https-proxy-agent": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
- "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
+ "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": "2.1.1",
- "debug": "2.6.9",
- "extend": "3.0.0"
+ "agent-base": "^4.1.0",
+ "debug": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ }
}
},
"hyphenate-style-name": {
@@ -9694,9 +8579,9 @@
"integrity": "sha1-MRYKNpMK2vH8BMYHT360FGXU7Es="
},
"iconv-lite": {
- "version": "0.4.15",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.15.tgz",
- "integrity": "sha1-/iZaIYrGpXz+hUkn6dBMGYJe3es="
+ "version": "0.4.19",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
+ "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
},
"icss-replace-symbols": {
"version": "1.1.0",
@@ -9710,64 +8595,35 @@
"integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=",
"dev": true,
"requires": {
- "postcss": "6.0.12"
+ "postcss": "^6.0.1"
},
"dependencies": {
- "ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
- "dev": true,
- "requires": {
- "color-convert": "1.9.0"
- }
- },
- "chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.4.0"
- }
- },
- "color-convert": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
- "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
"postcss": {
- "version": "6.0.12",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
- "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
"dev": true,
"requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.4.0"
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.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==",
+ "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": "2.0.0"
+ "has-flag": "^3.0.0"
}
}
}
},
"ieee754": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.8.tgz",
- "integrity": "sha1-vjPUCsEO8ZJnAfbwii2G+/0a0+Q=",
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.11.tgz",
+ "integrity": "sha512-VhDzCKN7K8ufStx/CLj5/PDTMgph+qwN5Pkd5i0sGnVwk56zJ0lkT8Qzi1xqWLS0Wp29DgDtNeS7v8/wMoZeHg==",
"dev": true
},
"iferr": {
@@ -9777,9 +8633,9 @@
"dev": true
},
"ignore": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
- "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw=="
+ "version": "3.3.8",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.8.tgz",
+ "integrity": "sha512-pUh+xUQQhQzevjRHHFqqcTy0/dP/kS9I8HSrUydhihjuD09W6ldVWFtIrwhXdUJHis3i2rZNqEHpZH/cbinFbg=="
},
"image-size": {
"version": "0.5.5",
@@ -9794,22 +8650,23 @@
"integrity": "sha1-Ds2tDFRjMmcte1tRGya7GM5W5z8="
},
"immutable": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.1.tgz",
- "integrity": "sha1-IAgH8Rqw9ycQ6khVQt4IgHX2jNI="
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.8.2.tgz",
+ "integrity": "sha1-wkOZUUVbs5kT2vKBN28VMOEErfM="
},
"immutablediff": {
"version": "0.4.4",
"resolved": "https://registry.npmjs.org/immutablediff/-/immutablediff-0.4.4.tgz",
"integrity": "sha1-oBDmlI9wD+EkNkM/NsbirYaXKrE=",
"requires": {
- "immutable": "3.8.1"
+ "immutable": "^3.2.1"
}
},
"immutablepatch": {
"version": "github:brave/immutable-js-patch#84e400e5419defd1f15928c3af8dbcd96364cbc1",
+ "from": "github:brave/immutable-js-patch",
"requires": {
- "immutable": "3.8.1"
+ "immutable": "^3.2.1"
}
},
"import-lazy": {
@@ -9818,6 +8675,16 @@
"integrity": "sha1-BWmOPUXIjo1+nZLLBYTnfwlvPkM=",
"dev": true
},
+ "import-local": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/import-local/-/import-local-1.0.0.tgz",
+ "integrity": "sha512-vAaZHieK9qjGo58agRBg+bhHX3hoTZU/Oa3GESWLz7t1U62fk63aHuDJJEteXoDeTCcPmUT+z38gkHPZkkmpmQ==",
+ "dev": true,
+ "requires": {
+ "pkg-dir": "^2.0.0",
+ "resolve-cwd": "^2.0.0"
+ }
+ },
"imurmurhash": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
@@ -9829,7 +8696,7 @@
"integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
"dev": true,
"requires": {
- "repeating": "2.0.1"
+ "repeating": "^2.0.0"
}
},
"indexes-of": {
@@ -9849,8 +8716,8 @@
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
"requires": {
- "once": "1.4.0",
- "wrappy": "1.0.2"
+ "once": "^1.3.0",
+ "wrappy": "1"
}
},
"inherits": {
@@ -9859,37 +8726,38 @@
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
},
"ini": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
- "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4="
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
},
"inline-style-prefixer": {
"version": "2.0.5",
"resolved": "https://registry.npmjs.org/inline-style-prefixer/-/inline-style-prefixer-2.0.5.tgz",
"integrity": "sha1-wVPH6I/YT+9cYC6VqBaLJ3BnH+c=",
"requires": {
- "bowser": "1.7.3",
- "hyphenate-style-name": "1.0.2"
+ "bowser": "^1.0.0",
+ "hyphenate-style-name": "^1.0.1"
}
},
"inquirer": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz",
- "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=",
- "requires": {
- "ansi-escapes": "1.4.0",
- "chalk": "1.1.3",
- "cli-cursor": "2.1.0",
- "cli-width": "2.2.0",
- "external-editor": "2.0.5",
- "figures": "2.0.0",
- "lodash": "4.17.4",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+ "requires": {
+ "ansi-escapes": "^3.0.0",
+ "chalk": "^2.0.0",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^2.0.4",
+ "figures": "^2.0.0",
+ "lodash": "^4.3.0",
"mute-stream": "0.0.7",
- "run-async": "2.3.0",
- "rx": "4.1.0",
- "string-width": "2.1.1",
- "strip-ansi": "3.0.1",
- "through": "2.3.8"
+ "run-async": "^2.2.0",
+ "rx-lite": "^4.0.8",
+ "rx-lite-aggregates": "^4.0.8",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^4.0.0",
+ "through": "^2.3.6"
},
"dependencies": {
"ansi-regex": {
@@ -9907,21 +8775,19 @@
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
"requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
- },
- "dependencies": {
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "requires": {
- "ansi-regex": "3.0.0"
- }
- }
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
}
- }
- }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
},
"internal-ip": {
"version": "1.2.0",
@@ -9929,21 +8795,21 @@
"integrity": "sha1-rp+/k7mEh4eF1QqN4bNWlWBYz1w=",
"dev": true,
"requires": {
- "meow": "3.7.0"
+ "meow": "^3.3.0"
}
},
"interpret": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.0.4.tgz",
- "integrity": "sha1-ggzdWIuGj/sZGoCVBtbJyPISsbA=",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.1.0.tgz",
+ "integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
"dev": true
},
"invariant": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.2.tgz",
- "integrity": "sha1-nh9WrArNtr8wMwbzOL47IErmA2A=",
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz",
+ "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==",
"requires": {
- "loose-envify": "1.3.1"
+ "loose-envify": "^1.0.0"
}
},
"invert-kv": {
@@ -9966,30 +8832,22 @@
"resolved": "https://registry.npmjs.org/ip-set/-/ip-set-1.0.1.tgz",
"integrity": "sha1-Yztm0L1sjQ3paNBTJjyRINO2cn4=",
"requires": {
- "ip": "1.1.5"
+ "ip": "^1.1.3"
}
},
"ipaddr.js": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.4.0.tgz",
- "integrity": "sha1-KWrKh4qCGBbluF0KKFqZvP9FgvA="
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.7.0.tgz",
+ "integrity": "sha1-IgbtM0r8MuAf7T7oOLayUhBoudI="
},
"is-absolute": {
- "version": "0.2.6",
- "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-0.2.6.tgz",
- "integrity": "sha1-IN5p89uULvLYe5wto28XIjWxtes=",
+ "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": "0.2.1",
- "is-windows": "0.2.0"
- },
- "dependencies": {
- "is-windows": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-0.2.0.tgz",
- "integrity": "sha1-3hqm1j6indJIc3tp8f+LgALSEIw=",
- "dev": true
- }
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
}
},
"is-absolute-url": {
@@ -9998,6 +8856,26 @@
"integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=",
"dev": true
},
+ "is-accessor-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz",
+ "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
"is-arrayish": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
@@ -10014,13 +8892,13 @@
"integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=",
"dev": true,
"requires": {
- "binary-extensions": "1.10.0"
+ "binary-extensions": "^1.0.0"
}
},
"is-buffer": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
- "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=",
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
"dev": true
},
"is-builtin-module": {
@@ -10028,7 +8906,7 @@
"resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-1.0.0.tgz",
"integrity": "sha1-VAVy0096wxGfj3bDDLwbHgN6/74=",
"requires": {
- "builtin-modules": "1.1.1"
+ "builtin-modules": "^1.0.0"
}
},
"is-bzip2": {
@@ -10043,12 +8921,60 @@
"integrity": "sha1-hut1OSgF3cM69xySoO7fdO52BLI=",
"dev": true
},
+ "is-ci": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-1.1.0.tgz",
+ "integrity": "sha512-c7TnwxLePuqIlxHgr7xtxzycJPegNHFuIrBkwbf8hc58//+Op1CqFkyS+xnIMkwn9UsJIwc174BIjkyBmSpjKg==",
+ "dev": true,
+ "requires": {
+ "ci-info": "^1.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz",
+ "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
"is-date-object": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz",
"integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=",
"dev": true
},
+ "is-descriptor": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz",
+ "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^0.1.6",
+ "is-data-descriptor": "^0.1.4",
+ "kind-of": "^5.0.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz",
+ "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==",
+ "dev": true
+ }
+ }
+ },
"is-dotfile": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/is-dotfile/-/is-dotfile-1.0.3.tgz",
@@ -10061,7 +8987,7 @@
"integrity": "sha1-IjgJj8Ih3gvPpdnqxMRdY4qhxTQ=",
"dev": true,
"requires": {
- "is-primitive": "2.0.0"
+ "is-primitive": "^2.0.0"
}
},
"is-extendable": {
@@ -10071,9 +8997,9 @@
"dev": true
},
"is-extglob": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
- "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
"dev": true
},
"is-file": {
@@ -10086,7 +9012,7 @@
"resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
"integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
"requires": {
- "number-is-nan": "1.0.1"
+ "number-is-nan": "^1.0.0"
}
},
"is-fullwidth-code-point": {
@@ -10094,7 +9020,7 @@
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
"integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
"requires": {
- "number-is-nan": "1.0.1"
+ "number-is-nan": "^1.0.0"
}
},
"is-function": {
@@ -10109,12 +9035,12 @@
"dev": true
},
"is-glob": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
- "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "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": "1.0.0"
+ "is-extglob": "^2.1.0"
}
},
"is-gzip": {
@@ -10129,25 +9055,27 @@
"integrity": "sha1-Df2Y9akRFxbdU13aZJL2e/PSWoA=",
"dev": true,
"requires": {
- "global-dirs": "0.1.1",
- "is-path-inside": "1.0.0"
+ "global-dirs": "^0.1.0",
+ "is-path-inside": "^1.0.0"
}
},
- "is-isodate": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/is-isodate/-/is-isodate-0.0.1.tgz",
- "integrity": "sha1-T+LpN9UPO6aMe2mwIYAItiSqUDY="
+ "is-my-ip-valid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-my-ip-valid/-/is-my-ip-valid-1.0.0.tgz",
+ "integrity": "sha512-gmh/eWXROncUzRnIa1Ubrt5b8ep/MGSnfAUI3aRp+sqTCs1tv1Isl8d8F6JmkN3dXKc3ehZMrtiPN9eL03NuaQ==",
+ "dev": true
},
"is-my-json-valid": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
- "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
+ "version": "2.17.2",
+ "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.17.2.tgz",
+ "integrity": "sha512-IBhBslgngMQN8DDSppmgDv7RNrlFotuuDsKcrCP3+HbFaVivIBU7u9oiiErw8sH4ynx3+gOGQ3q2otkgiSi6kg==",
"dev": true,
"requires": {
- "generate-function": "2.0.0",
- "generate-object-property": "1.2.0",
- "jsonpointer": "4.0.1",
- "xtend": "4.0.1"
+ "generate-function": "^2.0.0",
+ "generate-object-property": "^1.1.0",
+ "is-my-ip-valid": "^1.0.0",
+ "jsonpointer": "^4.0.0",
+ "xtend": "^4.0.0"
}
},
"is-natural-number": {
@@ -10163,12 +9091,23 @@
"dev": true
},
"is-number": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-2.1.0.tgz",
- "integrity": "sha1-Afy7s5NGOlSPL0ZszhbezknbkI8=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
"dev": true,
"requires": {
- "kind-of": "3.2.2"
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
}
},
"is-obj": {
@@ -10177,25 +9116,42 @@
"integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
"dev": true
},
+ "is-odd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-odd/-/is-odd-2.0.0.tgz",
+ "integrity": "sha512-OTiixgpZAT1M4NHgS5IguFp/Vz2VI3U7Goh4/HA1adtwyLtSBrxYlcSYkhpAE07s4fKEcjrFxyvtQBND4vFQyQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^4.0.0"
+ },
+ "dependencies": {
+ "is-number": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true
+ }
+ }
+ },
"is-path-cwd": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-1.0.0.tgz",
"integrity": "sha1-0iXsIxMuie3Tj9p2dHLmLmXxEG0="
},
"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=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-1.0.1.tgz",
+ "integrity": "sha512-FjV1RTW48E7CWM7eE/J2NJvAEEVektecDBVBE5Hh3nM1Jd0kvhHtX68Pr3xsDf857xt3Y4AkwVULK1Vku62aaQ==",
"requires": {
- "is-path-inside": "1.0.0"
+ "is-path-inside": "^1.0.0"
}
},
"is-path-inside": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
- "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.1.tgz",
+ "integrity": "sha1-jvW33lBDej/cprToZe96pVy0gDY=",
"requires": {
- "path-is-inside": "1.0.2"
+ "path-is-inside": "^1.0.1"
}
},
"is-plain-obj": {
@@ -10210,15 +9166,7 @@
"integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
"dev": true,
"requires": {
- "isobject": "3.0.1"
- },
- "dependencies": {
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- }
+ "isobject": "^3.0.1"
}
},
"is-posix-bracket": {
@@ -10256,25 +9204,22 @@
"integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=",
"dev": true,
"requires": {
- "has": "1.0.1"
+ "has": "^1.0.1"
}
},
"is-relative": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.2.1.tgz",
- "integrity": "sha1-0n9MfVFtF1+2ENuEu+7yPDvJeqU=",
+ "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": "0.1.2"
+ "is-unc-path": "^1.0.0"
}
},
"is-resolvable": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
- "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
- "requires": {
- "tryit": "1.0.3"
- }
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz",
+ "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg=="
},
"is-retry-allowed": {
"version": "1.1.0",
@@ -10293,6 +9238,15 @@
"integrity": "sha1-ilkRfZMt4d4A8kX83TnOQ/HpOaY=",
"dev": true
},
+ "is-svg": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-2.1.0.tgz",
+ "integrity": "sha1-z2EJDaDZ77yrhyLeum8DIgjbsOk=",
+ "dev": true,
+ "requires": {
+ "html-comment-regex": "^1.1.0"
+ }
+ },
"is-symbol": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.1.tgz",
@@ -10311,19 +9265,14 @@
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
},
"is-unc-path": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-0.1.2.tgz",
- "integrity": "sha1-arBTpyVzwQJQ/0FqOBTDUXivObk=",
+ "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"
+ "unc-path-regex": "^0.1.2"
}
},
- "is-url": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.2.tgz",
- "integrity": "sha1-SYkFpZO/R8wtnn9zg3K792lsfyY="
- },
"is-utf8": {
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
@@ -10336,9 +9285,15 @@
"dev": true
},
"is-windows": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.1.tgz",
- "integrity": "sha1-MQ23D3QtJZoWo2kgK1GvhCMzENk=",
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-wsl": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz",
+ "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=",
"dev": true
},
"is-zip": {
@@ -10348,9 +9303,9 @@
"dev": true
},
"isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
},
"isbinaryfile": {
"version": "3.0.2",
@@ -10359,11 +9314,11 @@
"dev": true
},
"isemail": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.0.0.tgz",
- "integrity": "sha512-rz0ng/c+fX+zACpLgDB8fnUQ845WSU06f4hlhk4K8TJxmR6f5hyvitu9a9JdMD7aq/P4E0XdG1uaab2OiXgHlA==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/isemail/-/isemail-3.1.2.tgz",
+ "integrity": "sha512-zfRhJn9rFSGhzU5tGZqepRSAj3+g6oTOHxMGGriWNJZzyLPUK8H7VHpqKntegnW8KLyGA9zwuNaCoopl40LTpg==",
"requires": {
- "punycode": "2.1.0"
+ "punycode": "2.x.x"
}
},
"isexe": {
@@ -10372,29 +9327,18 @@
"integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA="
},
"isobject": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
- "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
- "dev": true,
- "requires": {
- "isarray": "1.0.0"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- }
- }
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
},
"isomorphic-fetch": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz",
"integrity": "sha1-YRrhrPFPXoH3KVB0coGf6XM1WKk=",
"requires": {
- "node-fetch": "1.7.3",
- "whatwg-fetch": "2.0.3"
+ "node-fetch": "^1.0.1",
+ "whatwg-fetch": ">=0.10.0"
}
},
"isstream": {
@@ -10408,14 +9352,14 @@
"integrity": "sha1-eBeVZWAYohdMX2DzZ+5dNhy1e3c=",
"dev": true,
"requires": {
- "abbrev": "1.0.9",
- "async": "1.5.2",
- "istanbul-api": "1.1.14",
- "js-yaml": "3.10.0",
- "mkdirp": "0.5.1",
- "nopt": "3.0.6",
- "which": "1.3.0",
- "wordwrap": "1.0.0"
+ "abbrev": "1.0.x",
+ "async": "1.x",
+ "istanbul-api": "^1.1.0-alpha",
+ "js-yaml": "3.x",
+ "mkdirp": "0.5.x",
+ "nopt": "3.x",
+ "which": "^1.1.1",
+ "wordwrap": "^1.0.0"
},
"dependencies": {
"abbrev": {
@@ -10433,64 +9377,65 @@
}
},
"istanbul-api": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.1.14.tgz",
- "integrity": "sha1-JbxXAffGgMD//5E95G42GaOm5oA=",
- "dev": true,
- "requires": {
- "async": "2.5.0",
- "fileset": "2.0.3",
- "istanbul-lib-coverage": "1.1.1",
- "istanbul-lib-hook": "1.0.7",
- "istanbul-lib-instrument": "1.8.0",
- "istanbul-lib-report": "1.1.1",
- "istanbul-lib-source-maps": "1.2.1",
- "istanbul-reports": "1.1.2",
- "js-yaml": "3.10.0",
- "mkdirp": "0.5.1",
- "once": "1.4.0"
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/istanbul-api/-/istanbul-api-1.3.1.tgz",
+ "integrity": "sha512-duj6AlLcsWNwUpfyfHt0nWIeRiZpuShnP40YTxOGQgtaN8fd6JYSxsvxUphTDy8V5MfDXo4s/xVCIIvVCO808g==",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.4",
+ "compare-versions": "^3.1.0",
+ "fileset": "^2.0.2",
+ "istanbul-lib-coverage": "^1.2.0",
+ "istanbul-lib-hook": "^1.2.0",
+ "istanbul-lib-instrument": "^1.10.1",
+ "istanbul-lib-report": "^1.1.4",
+ "istanbul-lib-source-maps": "^1.2.4",
+ "istanbul-reports": "^1.3.0",
+ "js-yaml": "^3.7.0",
+ "mkdirp": "^0.5.1",
+ "once": "^1.4.0"
}
},
"istanbul-lib-coverage": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.1.1.tgz",
- "integrity": "sha512-0+1vDkmzxqJIn5rcoEqapSB4DmPxE31EtI2dF2aCkV5esN9EWHxZ0dwgDClivMXJqE7zaYQxq30hj5L0nlTN5Q==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.0.tgz",
+ "integrity": "sha512-GvgM/uXRwm+gLlvkWHTjDAvwynZkL9ns15calTrmhGgowlwJBbWMYzWbKqE2DT6JDP1AFXKa+Zi0EkqNCUqY0A==",
"dev": true
},
"istanbul-lib-hook": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.0.7.tgz",
- "integrity": "sha512-3U2HB9y1ZV9UmFlE12Fx+nPtFqIymzrqCksrXujm3NVbAZIJg/RfYgO1XiIa0mbmxTjWpVEVlkIZJ25xVIAfkQ==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-1.2.0.tgz",
+ "integrity": "sha512-p3En6/oGkFQV55Up8ZPC2oLxvgSxD8CzA0yBrhRZSh3pfv3OFj9aSGVC0yoerAi/O4u7jUVnOGVX1eVFM+0tmQ==",
"dev": true,
"requires": {
- "append-transform": "0.4.0"
+ "append-transform": "^0.4.0"
}
},
"istanbul-lib-instrument": {
- "version": "1.8.0",
- "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.8.0.tgz",
- "integrity": "sha1-ZvbJQhzJ7EcE928tsIS6kHiitTI=",
+ "version": "1.10.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.1.tgz",
+ "integrity": "sha512-1dYuzkOCbuR5GRJqySuZdsmsNKPL3PTuyPevQfoCXJePT9C8y1ga75neU+Tuy9+yS3G/dgx8wgOmp2KLpgdoeQ==",
"dev": true,
"requires": {
- "babel-generator": "6.26.0",
- "babel-template": "6.26.0",
- "babel-traverse": "6.26.0",
- "babel-types": "6.26.0",
- "babylon": "6.18.0",
- "istanbul-lib-coverage": "1.1.1",
- "semver": "5.4.1"
+ "babel-generator": "^6.18.0",
+ "babel-template": "^6.16.0",
+ "babel-traverse": "^6.18.0",
+ "babel-types": "^6.18.0",
+ "babylon": "^6.18.0",
+ "istanbul-lib-coverage": "^1.2.0",
+ "semver": "^5.3.0"
}
},
"istanbul-lib-report": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.1.tgz",
- "integrity": "sha512-tvF+YmCmH4thnez6JFX06ujIA19WPa9YUiwjc1uALF2cv5dmE3It8b5I8Ob7FHJ70H9Y5yF+TDkVa/mcADuw1Q==",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-1.1.4.tgz",
+ "integrity": "sha512-Azqvq5tT0U09nrncK3q82e/Zjkxa4tkFZv7E6VcqP0QCPn6oNljDPfrZEC/umNXds2t7b8sRJfs6Kmpzt8m2kA==",
"dev": true,
"requires": {
- "istanbul-lib-coverage": "1.1.1",
- "mkdirp": "0.5.1",
- "path-parse": "1.0.5",
- "supports-color": "3.2.3"
+ "istanbul-lib-coverage": "^1.2.0",
+ "mkdirp": "^0.5.1",
+ "path-parse": "^1.0.5",
+ "supports-color": "^3.1.2"
},
"dependencies": {
"has-flag": {
@@ -10505,31 +9450,57 @@
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
"dev": true,
"requires": {
- "has-flag": "1.0.0"
+ "has-flag": "^1.0.0"
}
}
}
},
"istanbul-lib-source-maps": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.1.tgz",
- "integrity": "sha512-mukVvSXCn9JQvdJl8wP/iPhqig0MRtuWuD4ZNKo6vB2Ik//AmhAKe3QnPN02dmkRe3lTudFk3rzoHhwU4hb94w==",
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.4.tgz",
+ "integrity": "sha512-UzuK0g1wyQijiaYQxj/CdNycFhAd2TLtO2obKQMTZrZ1jzEMRY3rvpASEKkaxbRR6brvdovfA03znPa/pXcejg==",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "istanbul-lib-coverage": "1.1.1",
- "mkdirp": "0.5.1",
- "rimraf": "2.6.2",
- "source-map": "0.5.7"
+ "debug": "^3.1.0",
+ "istanbul-lib-coverage": "^1.2.0",
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.6.1",
+ "source-map": "^0.5.3"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.5"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
}
},
"istanbul-reports": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.1.2.tgz",
- "integrity": "sha1-D7Lj9qqZIr085F0F2KtNXo4HvU8=",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-1.3.0.tgz",
+ "integrity": "sha512-y2Z2IMqE1gefWUaVjrBm0mSKvUkaBy9Vqz8iwr/r40Y9hBbIteH5wqHG/9DLTfJ9xUnUT2j7A3+VVJ6EaYBllA==",
"dev": true,
"requires": {
- "handlebars": "4.0.10"
+ "handlebars": "^4.0.3"
}
},
"items": {
@@ -10573,22 +9544,22 @@
"resolved": "https://registry.npmjs.org/jimp/-/jimp-0.2.28.tgz",
"integrity": "sha1-3VKak3GQ9ClXp5N9Gsw6d2KZbqI=",
"requires": {
- "bignumber.js": "2.4.0",
+ "bignumber.js": "^2.1.0",
"bmp-js": "0.0.3",
- "es6-promise": "3.3.1",
- "exif-parser": "0.1.12",
- "file-type": "3.9.0",
- "jpeg-js": "0.2.0",
- "load-bmfont": "1.3.0",
- "mime": "1.3.4",
+ "es6-promise": "^3.0.2",
+ "exif-parser": "^0.1.9",
+ "file-type": "^3.1.0",
+ "jpeg-js": "^0.2.0",
+ "load-bmfont": "^1.2.3",
+ "mime": "^1.3.4",
"mkdirp": "0.5.1",
- "pixelmatch": "4.0.2",
- "pngjs": "3.3.0",
- "read-chunk": "1.0.1",
- "request": "2.82.0",
- "stream-to-buffer": "0.1.0",
- "tinycolor2": "1.4.1",
- "url-regex": "3.2.0"
+ "pixelmatch": "^4.0.0",
+ "pngjs": "^3.0.0",
+ "read-chunk": "^1.0.1",
+ "request": "^2.65.0",
+ "stream-to-buffer": "^0.1.0",
+ "tinycolor2": "^1.1.2",
+ "url-regex": "^3.0.0"
},
"dependencies": {
"bignumber.js": {
@@ -10604,17 +9575,32 @@
"integrity": "sha512-hBF3LcqyAid+9X/pwg+eXjD2QBZI5eXnBFJYaAkH4SK3mp9QSRiiQnDYlmlz5pccMvnLcJRS4whhDOTCkmsAdQ==",
"dev": true,
"requires": {
- "hoek": "4.2.0",
- "isemail": "2.2.1",
- "items": "2.1.1",
- "topo": "2.0.2"
+ "hoek": "4.x.x",
+ "isemail": "2.x.x",
+ "items": "2.x.x",
+ "topo": "2.x.x"
},
"dependencies": {
+ "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
+ },
"isemail": {
"version": "2.2.1",
"resolved": "https://registry.npmjs.org/isemail/-/isemail-2.2.1.tgz",
"integrity": "sha1-A1PT2aYpUQgMJiwqoKQrjqjp4qY=",
"dev": true
+ },
+ "topo": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz",
+ "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=",
+ "dev": true,
+ "requires": {
+ "hoek": "4.x.x"
+ }
}
}
},
@@ -10624,48 +9610,29 @@
"integrity": "sha1-U+RI7J0mPmgyZkZ+lELSxaLvVII="
},
"js-base64": {
- "version": "2.1.9",
- "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
- "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=",
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.4.5.tgz",
+ "integrity": "sha512-aUnNwqMOXw3yvErjMPSQu6qIIzUmT1e5KcU1OZxRDU1g/am6mzBvcrmLAYwzmB59BHPrh5/tKaiF4OPhqRWESQ==",
"dev": true
},
- "js-sha3": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.3.1.tgz",
- "integrity": "sha1-hhIoAhQvCChQKg0d7h2V4lO7AkM=",
- "optional": true
- },
"js-tokens": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz",
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls="
},
"js-yaml": {
- "version": "3.10.0",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.10.0.tgz",
- "integrity": "sha512-O2v52ffjLa9VeM43J4XocZE//WT9N0IiwDa3KSHH7Tu8CtH+1qM8SIZvnsTh6v+4yFy5KUY3BHUVwjpfAWsjIA==",
+ "version": "3.11.0",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.11.0.tgz",
+ "integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
"requires": {
- "argparse": "1.0.9",
- "esprima": "4.0.0"
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
},
"dependencies": {
- "argparse": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
- "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
- "requires": {
- "sprintf-js": "1.0.3"
- }
- },
"esprima": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
"integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
}
}
},
@@ -10675,37 +9642,32 @@
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
"optional": true
},
- "jschardet": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/jschardet/-/jschardet-1.5.1.tgz",
- "integrity": "sha512-vE2hT1D0HLZCLLclfBSfkfTTedhVj0fubHpJBHKwwUWX0nSbhPAfk+SG9rTX95BYNmau8rGFfCeaT6T5OW1C2A=="
- },
"jsdom": {
"version": "11.2.0",
"resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.2.0.tgz",
"integrity": "sha512-+5wd6vJuh/Evw3wkmCuKXKibDd5RS7PYZjKaP4s2Hj5W7tvmbuFuaDN4erbH07VznTBFcK+lcsrGVnP6EugXow==",
"requires": {
- "abab": "1.0.4",
- "acorn": "4.0.13",
- "acorn-globals": "3.1.0",
- "array-equal": "1.0.0",
- "content-type-parser": "1.0.1",
- "cssom": "0.3.2",
- "cssstyle": "0.2.37",
- "escodegen": "1.9.0",
- "html-encoding-sniffer": "1.0.1",
- "nwmatcher": "1.4.2",
- "parse5": "3.0.2",
- "pn": "1.0.0",
- "request": "2.82.0",
- "request-promise-native": "1.0.5",
- "sax": "1.2.4",
- "symbol-tree": "3.2.2",
- "tough-cookie": "2.3.3",
- "webidl-conversions": "4.0.2",
- "whatwg-encoding": "1.0.1",
- "whatwg-url": "6.3.0",
- "xml-name-validator": "2.0.1"
+ "abab": "^1.0.3",
+ "acorn": "^4.0.4",
+ "acorn-globals": "^3.1.0",
+ "array-equal": "^1.0.0",
+ "content-type-parser": "^1.0.1",
+ "cssom": ">= 0.3.2 < 0.4.0",
+ "cssstyle": ">= 0.2.37 < 0.3.0",
+ "escodegen": "^1.6.1",
+ "html-encoding-sniffer": "^1.0.1",
+ "nwmatcher": "^1.4.1",
+ "parse5": "^3.0.2",
+ "pn": "^1.0.0",
+ "request": "^2.79.0",
+ "request-promise-native": "^1.0.3",
+ "sax": "^1.2.1",
+ "symbol-tree": "^3.2.1",
+ "tough-cookie": "^2.3.2",
+ "webidl-conversions": "^4.0.0",
+ "whatwg-encoding": "^1.0.1",
+ "whatwg-url": "^6.1.0",
+ "xml-name-validator": "^2.0.1"
},
"dependencies": {
"acorn": {
@@ -10732,6 +9694,12 @@
"integrity": "sha512-QLPs8Dj7lnf3e3QYS1zkCo+4ZwqOiF9d/nZnYozTISxXWCfNs9yuky5rJw4/W34s7POaNlbZmQGaB5NiXCbP4w==",
"dev": true
},
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
"json-schema": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
@@ -10747,7 +9715,7 @@
"resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
"integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
"requires": {
- "jsonify": "0.0.0"
+ "jsonify": "~0.0.0"
}
},
"json-stable-stringify-without-jsonify": {
@@ -10776,7 +9744,7 @@
"resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-2.4.0.tgz",
"integrity": "sha1-NzaitCi4e72gzIO1P6PWM6NcKug=",
"requires": {
- "graceful-fs": "4.1.11"
+ "graceful-fs": "^4.1.6"
}
},
"jsonify": {
@@ -10790,11 +9758,6 @@
"integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
"dev": true
},
- "jsonschema": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/jsonschema/-/jsonschema-1.2.0.tgz",
- "integrity": "sha512-XDJApzBauMg0TinJNP4iVcJl99PQ4JbWKK7nwzpOIkAOVveDKgh/2xm41T3x7Spu4PWMhnnQpNJmUSIUgl6sKg=="
- },
"jsprim": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
@@ -10818,60 +9781,54 @@
"integrity": "sha1-9DG0t/By3FAKXxDOf07HGTDnATQ="
},
"k-bucket": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-3.3.0.tgz",
- "integrity": "sha512-WIAQ54LfNjzt4viUIEVnXo9cr7ALS9Yocg+USLoiO89Uvbf9hz0OBtqmfzSr49kT3vbnhlzFfsJHFQ0xnp7LbA==",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/k-bucket/-/k-bucket-4.0.1.tgz",
+ "integrity": "sha512-YvDpmY3waI999h1zZoW1rJ04fZrgZ+5PAlVmvwDHT6YO/Q1AOhdel07xsKy9eAvJjQ9xZV1wz3rXKqEfaWvlcQ==",
"requires": {
- "buffer-equals": "1.0.4",
- "inherits": "2.0.3",
- "randombytes": "2.0.5"
+ "inherits": "^2.0.1",
+ "randombytes": "^2.0.3"
}
},
"k-rpc": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/k-rpc/-/k-rpc-4.1.0.tgz",
- "integrity": "sha512-Qvetvl34ZXrOWDXMMeP/WQMN3/ep3SASGxcJhUZLgQb1U7VA+/SzwxhDi9KRZWBEqrU0FUWr/yqLP44TfzSwzw==",
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/k-rpc/-/k-rpc-5.0.0.tgz",
+ "integrity": "sha512-vCH2rQdfMOS+MlUuTSuar1pS2EMrltURf9LmAR9xR6Jik0XPlMX3vEixgqMn17wKmFVCublJqSJ4hJIP7oKZ3Q==",
"requires": {
- "buffer-equals": "1.0.4",
- "k-bucket": "3.3.0",
- "k-rpc-socket": "1.7.1",
- "safe-buffer": "5.1.1"
+ "buffer-equals": "^1.0.3",
+ "k-bucket": "^4.0.0",
+ "k-rpc-socket": "^1.7.2",
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.1"
}
},
"k-rpc-socket": {
- "version": "1.7.1",
- "resolved": "https://registry.npmjs.org/k-rpc-socket/-/k-rpc-socket-1.7.1.tgz",
- "integrity": "sha512-FmHDmrT6sIs2MM/uMYW0Jmjd01wk2NxzPd6+9iH7onvutqhWXZ8PoZ9p/mVS58SQILC7jKZacC72V5QNkvAXew==",
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/k-rpc-socket/-/k-rpc-socket-1.8.0.tgz",
+ "integrity": "sha512-f/9TynsO8YYjZ6JjNNtSSH7CJcIHcio1buy3zqByGxb/GX8AWLdL6FZEWTrN8V3/J7W4/E0ZTQQ+Jt2rVq7ELg==",
"requires": {
- "bencode": "1.0.0",
- "safe-buffer": "5.1.1"
+ "bencode": "^2.0.0",
+ "buffer-equals": "^1.0.4",
+ "safe-buffer": "^5.1.1"
}
},
- "keccakjs": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/keccakjs/-/keccakjs-0.2.1.tgz",
- "integrity": "sha1-HWM6+QfvMFu/ny+mFtVsRFYd+k0=",
- "optional": true,
- "requires": {
- "browserify-sha3": "0.0.1",
- "sha3": "1.2.0"
- }
+ "killable": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.0.tgz",
+ "integrity": "sha1-2ouEvUfeU5WHj5XWTQLyRJ/gXms=",
+ "dev": true
},
"kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "1.1.5"
- }
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
},
"klaw": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/klaw/-/klaw-1.3.1.tgz",
"integrity": "sha1-QIhDO0azsbolnXh4XY6W9zugJDk=",
"requires": {
- "graceful-fs": "4.1.11"
+ "graceful-fs": "^4.1.9"
}
},
"l20n": {
@@ -10879,13 +9836,18 @@
"resolved": "https://registry.npmjs.org/l20n/-/l20n-3.5.1.tgz",
"integrity": "sha1-0m6C1BFKGVajSwDCObEqQ7QLCKM="
},
+ "last-one-wins": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/last-one-wins/-/last-one-wins-1.0.4.tgz",
+ "integrity": "sha1-wb/Qy8tGeQ7JFWuNGu6Py4bNoio="
+ },
"latest-version": {
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/latest-version/-/latest-version-3.1.0.tgz",
"integrity": "sha1-ogU4P+oyKzO1rjsYq+4NwvNW7hU=",
"dev": true,
"requires": {
- "package-json": "4.0.1"
+ "package-json": "^4.0.0"
}
},
"lazy-cache": {
@@ -10906,39 +9868,7 @@
"integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "readable-stream": "^2.0.5"
}
},
"lcid": {
@@ -10946,23 +9876,151 @@
"resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
"integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
"requires": {
- "invert-kv": "1.0.0"
+ "invert-kv": "^1.0.0"
}
},
"less": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/less/-/less-2.7.2.tgz",
- "integrity": "sha1-No1sxz4fsDmBGDKAkYdDxdz5s98=",
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/less/-/less-2.7.3.tgz",
+ "integrity": "sha512-KPdIJKWcEAb02TuJtaLrhue0krtRLoRoo7x6BNJIBelO00t/CCdJQUnHW5V34OnHMWzIktSalJxRO+FvytQlCQ==",
"dev": true,
"requires": {
- "errno": "0.1.4",
- "graceful-fs": "4.1.11",
- "image-size": "0.5.5",
- "mime": "1.3.4",
- "mkdirp": "0.5.1",
- "promise": "7.3.1",
- "request": "2.82.0",
- "source-map": "0.5.7"
+ "errno": "^0.1.1",
+ "graceful-fs": "^4.1.2",
+ "image-size": "~0.5.0",
+ "mime": "^1.2.11",
+ "mkdirp": "^0.5.0",
+ "promise": "^7.1.1",
+ "request": "2.81.0",
+ "source-map": "^0.5.3"
+ },
+ "dependencies": {
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
+ }
+ },
+ "assert-plus": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
+ "integrity": "sha1-104bh+ev/A24qttwIfP+SBAasjQ=",
+ "dev": true,
+ "optional": true
+ },
+ "aws-sign2": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.6.0.tgz",
+ "integrity": "sha1-FDQt0428yU0OW4fXY81jYSwOeU8=",
+ "dev": true,
+ "optional": true
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true,
+ "optional": true
+ },
+ "form-data": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
+ "integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.5",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "har-schema": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-1.0.5.tgz",
+ "integrity": "sha1-0mMTX0MwfALGAq/I/pWXDAFRNp4=",
+ "dev": true,
+ "optional": true
+ },
+ "har-validator": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-4.2.1.tgz",
+ "integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "ajv": "^4.9.1",
+ "har-schema": "^1.0.5"
+ }
+ },
+ "http-signature": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
+ "integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "assert-plus": "^0.2.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "performance-now": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
+ "integrity": "sha1-M+8wxcd9TqIcWlOGnZG1bY8lVeU=",
+ "dev": true,
+ "optional": true
+ },
+ "qs": {
+ "version": "6.4.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.4.0.tgz",
+ "integrity": "sha1-E+JtKK1rD/qpExLNO/cI7TUecjM=",
+ "dev": true,
+ "optional": true
+ },
+ "request": {
+ "version": "2.81.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.81.0.tgz",
+ "integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
+ "dev": true,
+ "optional": true,
+ "requires": {
+ "aws-sign2": "~0.6.0",
+ "aws4": "^1.2.1",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.0",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.1.1",
+ "har-validator": "~4.2.1",
+ "hawk": "~3.1.3",
+ "http-signature": "~1.1.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.7",
+ "oauth-sign": "~0.8.1",
+ "performance-now": "^0.2.0",
+ "qs": "~6.4.0",
+ "safe-buffer": "^5.0.1",
+ "stringstream": "~0.0.4",
+ "tough-cookie": "~2.3.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.0.0"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true,
+ "optional": true
+ }
}
},
"less-loader": {
@@ -10971,7 +10029,7 @@
"integrity": "sha1-ttj4E5yEk98J2ZKpOgBzSwj4RSg=",
"dev": true,
"requires": {
- "loader-utils": "0.2.17"
+ "loader-utils": "^0.2.5"
},
"dependencies": {
"loader-utils": {
@@ -10980,122 +10038,128 @@
"integrity": "sha1-+G5jdNQyBabmxg6RlvF8Apm/s0g=",
"dev": true,
"requires": {
- "big.js": "3.2.0",
- "emojis-list": "2.1.0",
- "json5": "0.5.1",
- "object-assign": "4.1.1"
+ "big.js": "^3.1.3",
+ "emojis-list": "^2.0.0",
+ "json5": "^0.5.0",
+ "object-assign": "^4.0.1"
}
}
}
},
"level": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/level/-/level-1.7.0.tgz",
- "integrity": "sha1-Q0ZKOounOy895WokKSgFFG2iE6E=",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/level/-/level-2.1.2.tgz",
+ "integrity": "sha512-BPcWD6a1oNSXU9b9V/rCaYfmDGhoJ7AezgZ7IKOrR5d9TXz0GRtGNFWm6rCfo3Y36w3nUeP9OefFvy13YiSoYQ==",
"dev": true,
"requires": {
- "level-packager": "1.2.1",
- "leveldown": "1.7.2"
+ "level-packager": "^2.0.2",
+ "leveldown": "^2.1.1",
+ "opencollective": "^1.0.3"
}
},
"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": "8.0.0",
+ "resolved": "https://registry.npmjs.org/level-codec/-/level-codec-8.0.0.tgz",
+ "integrity": "sha512-gNZlo1HRHz0BWxzGCyNf7xntAs2HKOPvvRBWtXsoDvEX4vMYnSTBS6ZnxoaiX7nhxSBPpegRa8CQ/hnfGBKk3Q==",
"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": "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.4"
+ "errno": "~0.1.1"
}
},
"level-iterator-stream": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-1.3.1.tgz",
- "integrity": "sha1-5Dt4sagUPm+pek9IXrjqUwNS8u0=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/level-iterator-stream/-/level-iterator-stream-2.0.0.tgz",
+ "integrity": "sha512-TWOYw8HR5mhj6xwoVLo0yu26RPL6v28KgvhK1kY1CJf9LyL+rJXjx99zhORTYhN9ysOBIH+iaxAiqRteA+C1/g==",
"dev": true,
"requires": {
- "inherits": "2.0.3",
- "level-errors": "1.0.5",
- "readable-stream": "1.1.14",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "readable-stream": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "0.0.1",
- "string_decoder": "0.10.31"
- }
- }
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5",
+ "xtend": "^4.0.0"
}
},
"level-packager": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-1.2.1.tgz",
- "integrity": "sha1-Bn/t/Qcrf+PGvsYIDAy9SmsuEfQ=",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/level-packager/-/level-packager-2.1.1.tgz",
+ "integrity": "sha512-6l3G6dVkmdvHwOJrEA9d9hL6SSFrzwjQoLP8HsvohOgfY/8Z9LyTKNCM5Gc84wtsUWCuIHu6r+S6WrCtTWUJCw==",
"dev": true,
"requires": {
- "levelup": "1.3.9"
+ "encoding-down": "~4.0.0",
+ "levelup": "^2.0.0"
}
},
"leveldown": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-1.7.2.tgz",
- "integrity": "sha1-XjRnuyfuJGpKe429j7KxYgam64s=",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/leveldown/-/leveldown-2.1.1.tgz",
+ "integrity": "sha512-JNMCTSchq1YtQLMGePmT07UE7hIIYR4GHpZI7+nUXbM9XgNtRAwcBGhnyJyITwpTILTkUcNPBKZ9lZmTUj2E3g==",
"dev": true,
"requires": {
- "abstract-leveldown": "2.6.3",
- "bindings": "1.2.1",
- "fast-future": "1.0.2",
- "nan": "2.6.2",
- "prebuild-install": "2.2.2"
+ "abstract-leveldown": "~3.0.0",
+ "bindings": "~1.3.0",
+ "fast-future": "~1.0.2",
+ "nan": "~2.8.0",
+ "prebuild-install": "^2.1.0"
},
"dependencies": {
- "bindings": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.2.1.tgz",
- "integrity": "sha1-FK1hE4EtLTfXLme0ystLtyZQXxE=",
- "dev": true
+ "abstract-leveldown": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abstract-leveldown/-/abstract-leveldown-3.0.0.tgz",
+ "integrity": "sha512-KUWx9UWGQD12zsmLNj64/pndaz4iJh/Pj7nopgkfDG6RlCcbMZvT6+9l7dchK4idog2Is8VdC/PvNbFuFmalIQ==",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.0"
+ }
},
- "nan": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.6.2.tgz",
- "integrity": "sha1-5P805slf37WuzAjeZZb0NgWn20U=",
- "dev": true
+ "prebuild-install": {
+ "version": "2.5.3",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.5.3.tgz",
+ "integrity": "sha512-/rI36cN2g7vDQnKWN8Uzupi++KjyqS9iS+/fpwG4Ea8d0Pip0PQ5bshUNzVwt+/D2MRfhVAplYMMvWLqWrCF/g==",
+ "dev": true,
+ "requires": {
+ "detect-libc": "^1.0.3",
+ "expand-template": "^1.0.2",
+ "github-from-package": "0.0.0",
+ "minimist": "^1.2.0",
+ "mkdirp": "^0.5.1",
+ "node-abi": "^2.2.0",
+ "noop-logger": "^0.1.1",
+ "npmlog": "^4.0.1",
+ "os-homedir": "^1.0.1",
+ "pump": "^2.0.1",
+ "rc": "^1.1.6",
+ "simple-get": "^2.7.0",
+ "tar-fs": "^1.13.0",
+ "tunnel-agent": "^0.6.0",
+ "which-pm-runs": "^1.0.0"
+ }
+ },
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
"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.2",
- "level-codec": "7.0.1",
- "level-errors": "1.0.5",
- "level-iterator-stream": "1.3.1",
- "prr": "1.0.1",
- "semver": "5.4.1",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "prr": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
- "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
- "dev": true
- }
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/levelup/-/levelup-2.0.2.tgz",
+ "integrity": "sha512-us+nTLUyd/eLnclYYddOCdAVw1hnymGx/9p4Jr5ThohStsjLqMVmbYiz6/SYFZEPXNF+AKQSvh6fA2e2KZpC8w==",
+ "dev": true,
+ "requires": {
+ "deferred-leveldown": "~3.0.0",
+ "level-errors": "~1.1.0",
+ "level-iterator-stream": "~2.0.0",
+ "xtend": "~4.0.0"
}
},
"levn": {
@@ -11103,25 +10167,32 @@
"resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
"integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
"requires": {
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2"
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
}
},
"liftoff": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/liftoff/-/liftoff-2.3.0.tgz",
- "integrity": "sha1-qY8v9nGD2Lp8+soQVIvX/wVQs4U=",
- "dev": true,
- "requires": {
- "extend": "3.0.0",
- "findup-sync": "0.4.3",
- "fined": "1.1.0",
- "flagged-respawn": "0.3.2",
- "lodash.isplainobject": "4.0.6",
- "lodash.isstring": "4.0.1",
- "lodash.mapvalues": "4.6.0",
- "rechoir": "0.6.2",
- "resolve": "1.4.0"
+ "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",
+ "fined": "^1.0.1",
+ "flagged-respawn": "^1.0.0",
+ "is-plain-object": "^2.0.4",
+ "object.map": "^1.0.0",
+ "rechoir": "^0.6.2",
+ "resolve": "^1.1.7"
+ },
+ "dependencies": {
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ }
}
},
"load-bmfont": {
@@ -11130,12 +10201,12 @@
"integrity": "sha1-u358cQ3mvK/LE8s7jIHgwBMey8k=",
"requires": {
"buffer-equal": "0.0.1",
- "mime": "1.3.4",
- "parse-bmfont-ascii": "1.0.6",
- "parse-bmfont-binary": "1.0.6",
- "parse-bmfont-xml": "1.1.3",
- "xhr": "2.4.0",
- "xtend": "4.0.1"
+ "mime": "^1.3.4",
+ "parse-bmfont-ascii": "^1.0.3",
+ "parse-bmfont-binary": "^1.0.5",
+ "parse-bmfont-xml": "^1.1.0",
+ "xhr": "^2.0.1",
+ "xtend": "^4.0.0"
}
},
"load-ip-set": {
@@ -11143,23 +10214,11 @@
"resolved": "https://registry.npmjs.org/load-ip-set/-/load-ip-set-1.3.1.tgz",
"integrity": "sha1-z9BQxpFue6DKhdC1ZueFRxPrSV4=",
"requires": {
- "ip-set": "1.0.1",
- "netmask": "1.0.6",
- "once": "1.4.0",
- "simple-get": "2.7.0",
- "split": "1.0.1"
- },
- "dependencies": {
- "simple-get": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
- "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
- "requires": {
- "decompress-response": "3.3.0",
- "once": "1.4.0",
- "simple-concat": "1.0.0"
- }
- }
+ "ip-set": "^1.0.0",
+ "netmask": "^1.0.6",
+ "once": "^1.3.0",
+ "simple-get": "^2.0.0",
+ "split": "^1.0.0"
}
},
"load-json-file": {
@@ -11167,11 +10226,11 @@
"resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
"integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
"requires": {
- "graceful-fs": "4.1.11",
- "parse-json": "2.2.0",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1",
- "strip-bom": "2.0.0"
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
}
},
"loader-runner": {
@@ -11185,9 +10244,9 @@
"resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.1.0.tgz",
"integrity": "sha1-yYrvSIvM7aL/teLeZG1qdUQp9c0=",
"requires": {
- "big.js": "3.2.0",
- "emojis-list": "2.1.0",
- "json5": "0.5.1"
+ "big.js": "^3.1.3",
+ "emojis-list": "^2.0.0",
+ "json5": "^0.5.0"
}
},
"locate-path": {
@@ -11195,55 +10254,19 @@
"resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
"integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
"requires": {
- "p-locate": "2.0.0",
- "path-exists": "3.0.0"
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
}
},
"lodash": {
- "version": "4.17.4",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
+ "version": "4.17.10",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.10.tgz",
+ "integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg=="
},
"lodash-es": {
- "version": "4.17.4",
- "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.4.tgz",
- "integrity": "sha1-3MHXVS4VCgZABzupyzHXDwMpUOc="
- },
- "lodash._arraycopy": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz",
- "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE=",
- "dev": true
- },
- "lodash._arrayeach": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz",
- "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754=",
- "dev": true
- },
- "lodash._baseassign": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
- "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
- "dev": true,
- "requires": {
- "lodash._basecopy": "3.0.1",
- "lodash.keys": "3.1.2"
- }
- },
- "lodash._baseclone": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz",
- "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=",
- "dev": true,
- "requires": {
- "lodash._arraycopy": "3.0.0",
- "lodash._arrayeach": "3.0.0",
- "lodash._baseassign": "3.2.0",
- "lodash._basefor": "3.0.3",
- "lodash.isarray": "3.0.4",
- "lodash.keys": "3.1.2"
- }
+ "version": "4.17.10",
+ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.10.tgz",
+ "integrity": "sha512-iesFYPmxYYGTcmQK0sL8bX3TGHyM6b2qREaB4kamHfQyfPJP0xgoGxp19nsH16nsfquLdiyKyX3mQkfiSGV8Rg=="
},
"lodash._basecopy": {
"version": "3.0.1",
@@ -11251,12 +10274,6 @@
"integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=",
"dev": true
},
- "lodash._basefor": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz",
- "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI=",
- "dev": true
- },
"lodash._basetostring": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/lodash._basetostring/-/lodash._basetostring-3.0.1.tgz",
@@ -11269,12 +10286,6 @@
"integrity": "sha1-W3dXYoAr3j0yl1A+JjAIIP32Ybc=",
"dev": true
},
- "lodash._bindcallback": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
- "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4=",
- "dev": true
- },
"lodash._getnative": {
"version": "3.9.1",
"resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
@@ -11311,12 +10322,6 @@
"integrity": "sha1-+6HEUkwZ7ppfgTa0YJ8BfPTe1pI=",
"dev": true
},
- "lodash.assign": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/lodash.assign/-/lodash.assign-4.2.0.tgz",
- "integrity": "sha1-DZnzzNem0mHRm9rrkkUAXShYCOc=",
- "dev": true
- },
"lodash.assignin": {
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz",
@@ -11335,16 +10340,6 @@
"integrity": "sha1-soqmKIorn8ZRA1x3EfZathkDMaY=",
"dev": true
},
- "lodash.clonedeep": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz",
- "integrity": "sha1-oKHkDYKl6on/WxR7hETtY9koJ9s=",
- "dev": true,
- "requires": {
- "lodash._baseclone": "3.3.0",
- "lodash._bindcallback": "3.0.1"
- }
- },
"lodash.cond": {
"version": "4.5.2",
"resolved": "https://registry.npmjs.org/lodash.cond/-/lodash.cond-4.5.2.tgz",
@@ -11363,7 +10358,7 @@
"integrity": "sha1-mV7g3BjBtIzJLv+ucaEKq1tIdpg=",
"dev": true,
"requires": {
- "lodash._root": "3.0.1"
+ "lodash._root": "^3.0.0"
}
},
"lodash.filter": {
@@ -11408,27 +10403,15 @@
"integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=",
"dev": true
},
- "lodash.isplainobject": {
- "version": "4.0.6",
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
- "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=",
- "dev": true
- },
- "lodash.isstring": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz",
- "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=",
- "dev": true
- },
"lodash.keys": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
"integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
"dev": true,
"requires": {
- "lodash._getnative": "3.9.1",
- "lodash.isarguments": "3.1.0",
- "lodash.isarray": "3.0.4"
+ "lodash._getnative": "^3.0.0",
+ "lodash.isarguments": "^3.0.0",
+ "lodash.isarray": "^3.0.0"
}
},
"lodash.map": {
@@ -11437,16 +10420,16 @@
"integrity": "sha1-dx7Hg540c9nEzeKLGTlMNWL09tM=",
"dev": true
},
- "lodash.mapvalues": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/lodash.mapvalues/-/lodash.mapvalues-4.6.0.tgz",
- "integrity": "sha1-G6+lAF3p3W9PJmaMMMo3IwzJaJw=",
+ "lodash.memoize": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
+ "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=",
"dev": true
},
"lodash.merge": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.0.tgz",
- "integrity": "sha1-aYhLoUSsM/5plzemCG3v+t0PicU=",
+ "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==",
"dev": true
},
"lodash.pick": {
@@ -11490,15 +10473,15 @@
"integrity": "sha1-+M3sxhaaJVvpCYrosMU9N4kx0U8=",
"dev": true,
"requires": {
- "lodash._basecopy": "3.0.1",
- "lodash._basetostring": "3.0.1",
- "lodash._basevalues": "3.0.0",
- "lodash._isiterateecall": "3.0.9",
- "lodash._reinterpolate": "3.0.0",
- "lodash.escape": "3.2.0",
- "lodash.keys": "3.1.2",
- "lodash.restparam": "3.6.1",
- "lodash.templatesettings": "3.1.1"
+ "lodash._basecopy": "^3.0.0",
+ "lodash._basetostring": "^3.0.0",
+ "lodash._basevalues": "^3.0.0",
+ "lodash._isiterateecall": "^3.0.0",
+ "lodash._reinterpolate": "^3.0.0",
+ "lodash.escape": "^3.0.0",
+ "lodash.keys": "^3.0.0",
+ "lodash.restparam": "^3.0.0",
+ "lodash.templatesettings": "^3.0.0"
}
},
"lodash.templatesettings": {
@@ -11507,20 +10490,20 @@
"integrity": "sha1-+zB4RHU7Zrnxr6VOJix0UwfbqOU=",
"dev": true,
"requires": {
- "lodash._reinterpolate": "3.0.0",
- "lodash.escape": "3.2.0"
+ "lodash._reinterpolate": "^3.0.0",
+ "lodash.escape": "^3.0.0"
}
},
- "lodash.toarray": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/lodash.toarray/-/lodash.toarray-4.4.0.tgz",
- "integrity": "sha1-JMS/zWsvuji/0FlNsRedjptlZWE=",
+ "lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=",
"dev": true
},
"loglevel": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.5.0.tgz",
- "integrity": "sha512-OQ2jhWI5G2qsvO0UFNyCQWgKl/tFiwuPIXxELzACeUO2FqstN/R7mmL09+nhv6xOWVPPojQO1A90sCEoJSgBcQ==",
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.1.tgz",
+ "integrity": "sha1-4PyVEztu8nbNyIh82vJKpvFW+Po=",
"dev": true
},
"lolex": {
@@ -11540,7 +10523,7 @@
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.3.1.tgz",
"integrity": "sha1-0aitM/qc4OcT1l/dCsi3SNR4yEg=",
"requires": {
- "js-tokens": "3.0.2"
+ "js-tokens": "^3.0.0"
}
},
"loud-rejection": {
@@ -11549,14 +10532,14 @@
"integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
"dev": true,
"requires": {
- "currently-unhandled": "0.4.1",
- "signal-exit": "3.0.2"
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
}
},
"lowercase-keys": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.0.tgz",
- "integrity": "sha1-TjNms55/VFfjXxMkvfb4jQv8cwY=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz",
+ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==",
"dev": true
},
"lru": {
@@ -11564,7 +10547,7 @@
"resolved": "https://registry.npmjs.org/lru/-/lru-3.1.0.tgz",
"integrity": "sha1-6n+4VG2DczOWoTCR12z+tMBoN9U=",
"requires": {
- "inherits": "2.0.3"
+ "inherits": "^2.0.1"
}
},
"lru-cache": {
@@ -11572,36 +10555,45 @@
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-1.1.1.tgz",
"integrity": "sha1-1vJPdcKMnsEjnKIGlSaJaW7BHmI="
},
+ "macaddress": {
+ "version": "0.2.8",
+ "resolved": "https://registry.npmjs.org/macaddress/-/macaddress-0.2.8.tgz",
+ "integrity": "sha1-WQTcU3w57G2+/q6QIycTX6hRHxI=",
+ "dev": true
+ },
"magnet-uri": {
- "version": "5.1.7",
- "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-5.1.7.tgz",
- "integrity": "sha1-j4AWq3TEFfJ09PsZQ/qvfpIDDv8=",
+ "version": "5.1.8",
+ "resolved": "https://registry.npmjs.org/magnet-uri/-/magnet-uri-5.1.8.tgz",
+ "integrity": "sha512-rHCJ81C3W2MuLpb4c3JKshQtCbRZhgeKKNYy1YFBtLR3eAB0FjQ5thfCo16w/+VF9yN5tJDtDq4NHPtf9a328A==",
"requires": {
- "safe-buffer": "5.1.1",
- "thirty-two": "1.0.2",
- "uniq": "1.0.1",
- "xtend": "4.0.1"
+ "safe-buffer": "^5.0.1",
+ "thirty-two": "^1.0.1",
+ "uniq": "^1.0.1",
+ "xtend": "^4.0.0"
}
},
"make-dir": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.0.0.tgz",
- "integrity": "sha1-l6ARdR6R3YfPre9Ygy67BJNt6Xg=",
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz",
+ "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==",
"requires": {
- "pify": "2.3.0"
+ "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="
+ }
}
},
- "make-error": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.0.tgz",
- "integrity": "sha1-Uq06M5zPEM5itAQLcI/nByRLi5Y="
- },
- "make-error-cause": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/make-error-cause/-/make-error-cause-1.2.2.tgz",
- "integrity": "sha1-3wOI/NCzeBbf8KX7gQiTl3fcvJ0=",
+ "make-iterator": {
+ "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": {
- "make-error": "1.3.0"
+ "kind-of": "^6.0.2"
}
},
"map-cache": {
@@ -11616,23 +10608,13 @@
"integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=",
"dev": true
},
- "marked": {
- "version": "0.3.6",
- "resolved": "https://registry.npmjs.org/marked/-/marked-0.3.6.tgz",
- "integrity": "sha1-ssbGGPzOzk74bE/Gy4p8v1rtqNc=",
- "dev": true
- },
- "marked-terminal": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-1.7.0.tgz",
- "integrity": "sha1-yMRgiBx3LHYEtkNnAH7l938SWQQ=",
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
"dev": true,
"requires": {
- "cardinal": "1.0.0",
- "chalk": "1.1.3",
- "cli-table": "0.3.1",
- "lodash.assign": "4.2.0",
- "node-emoji": "1.8.1"
+ "object-visit": "^1.0.0"
}
},
"math-expression-evaluator": {
@@ -11641,68 +10623,35 @@
"integrity": "sha1-3oGf282E3M2PrlnGrreWFbnSZqw=",
"dev": true
},
+ "math-random": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/math-random/-/math-random-1.0.1.tgz",
+ "integrity": "sha1-izqsWIuKZuSXXjzepn97sylgH6w=",
+ "dev": true
+ },
"md5.js": {
"version": "1.3.4",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.4.tgz",
"integrity": "sha1-6b296UogpawYsENA/Fdk1bCdkB0=",
"requires": {
- "hash-base": "3.0.4",
- "inherits": "2.0.3"
- },
- "dependencies": {
- "hash-base": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz",
- "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=",
- "requires": {
- "inherits": "2.0.3",
- "safe-buffer": "5.1.1"
- }
- }
+ "hash-base": "^3.0.0",
+ "inherits": "^2.0.1"
}
},
"media-typer": {
"version": "0.3.0",
"resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
- "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=",
+ "dev": true
},
"mediasource": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/mediasource/-/mediasource-2.1.3.tgz",
- "integrity": "sha1-J6nBqsUb+266lq8tE6hNCyqOrGg=",
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/mediasource/-/mediasource-2.2.1.tgz",
+ "integrity": "sha512-WRtioPZW7FbuD4OvgrGZU3t5c0sp1F4rGJhrYp4pMIK1u8Hi5HS5aiVvQf24T2/NBg650xdWOXgx8yqTUM71lw==",
"requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3",
- "to-arraybuffer": "1.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5",
+ "to-arraybuffer": "^1.0.1"
}
},
"mem": {
@@ -11711,7 +10660,7 @@
"integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
"dev": true,
"requires": {
- "mimic-fn": "1.1.0"
+ "mimic-fn": "^1.0.0"
}
},
"memory-chunk-store": {
@@ -11725,40 +10674,8 @@
"integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=",
"dev": true,
"requires": {
- "errno": "0.1.4",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "errno": "^0.1.3",
+ "readable-stream": "^2.0.1"
}
},
"meow": {
@@ -11767,30 +10684,23 @@
"integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
"dev": true,
"requires": {
- "camelcase-keys": "2.1.0",
- "decamelize": "1.2.0",
- "loud-rejection": "1.6.0",
- "map-obj": "1.0.1",
- "minimist": "1.2.0",
- "normalize-package-data": "2.4.0",
- "object-assign": "4.1.1",
- "read-pkg-up": "1.0.1",
- "redent": "1.0.0",
- "trim-newlines": "1.0.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
+ "camelcase-keys": "^2.0.0",
+ "decamelize": "^1.1.2",
+ "loud-rejection": "^1.0.0",
+ "map-obj": "^1.0.1",
+ "minimist": "^1.1.3",
+ "normalize-package-data": "^2.3.4",
+ "object-assign": "^4.0.1",
+ "read-pkg-up": "^1.0.1",
+ "redent": "^1.0.0",
+ "trim-newlines": "^1.0.0"
}
},
"merge-descriptors": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
- "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=",
+ "dev": true
},
"merge-stream": {
"version": "1.0.1",
@@ -11798,168 +10708,7 @@
"integrity": "sha1-QEEgLVCKNCugAXQAjfDCUbjBNeE=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
- }
- },
- "merkle-lib": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/merkle-lib/-/merkle-lib-2.0.10.tgz",
- "integrity": "sha1-grjbrnXieneFOItz+ddyXQ9vMyY="
- },
- "metascraper": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/metascraper/-/metascraper-1.0.7.tgz",
- "integrity": "sha512-UPGR9eGM4u6iS3oWNS/KQoHrfINz8N33a1astWECiLz9st6e1PUc7+sGyHvQuzXDzYvc+Qu0/TrzOWUNuw+Fcg==",
- "requires": {
- "cheerio": "0.20.0",
- "chrono-node": "1.3.5",
- "is-isodate": "0.0.1",
- "is-url": "1.2.2",
- "popsicle": "6.2.2",
- "to-title-case": "1.0.0"
- },
- "dependencies": {
- "acorn": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-2.7.0.tgz",
- "integrity": "sha1-q259nYhqrKiwhbwzEreaGYQz8Oc="
- },
- "acorn-globals": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-1.0.9.tgz",
- "integrity": "sha1-VbtemGkVB7dFedBRNBMhfDgMVM8=",
- "optional": true,
- "requires": {
- "acorn": "2.7.0"
- }
- },
- "cheerio": {
- "version": "0.20.0",
- "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.20.0.tgz",
- "integrity": "sha1-XHEPK6uVZTJyhCugHG6mGzVF7DU=",
- "requires": {
- "css-select": "1.2.0",
- "dom-serializer": "0.1.0",
- "entities": "1.1.1",
- "htmlparser2": "3.8.3",
- "jsdom": "7.2.2",
- "lodash": "4.17.4"
- }
- },
- "domhandler": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
- "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
- "requires": {
- "domelementtype": "1.3.0"
- }
- },
- "domutils": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz",
- "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=",
- "requires": {
- "dom-serializer": "0.1.0",
- "domelementtype": "1.3.0"
- }
- },
- "htmlparser2": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
- "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
- "requires": {
- "domelementtype": "1.3.0",
- "domhandler": "2.3.0",
- "domutils": "1.5.1",
- "entities": "1.0.0",
- "readable-stream": "1.1.14"
- },
- "dependencies": {
- "entities": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
- "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY="
- }
- }
- },
- "jsdom": {
- "version": "7.2.2",
- "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-7.2.2.tgz",
- "integrity": "sha1-QLQCdwwr2iNGkJa+6Rq2deOx/G4=",
- "optional": true,
- "requires": {
- "abab": "1.0.4",
- "acorn": "2.7.0",
- "acorn-globals": "1.0.9",
- "cssom": "0.3.2",
- "cssstyle": "0.2.37",
- "escodegen": "1.9.0",
- "nwmatcher": "1.4.2",
- "parse5": "1.5.1",
- "request": "2.82.0",
- "sax": "1.2.4",
- "symbol-tree": "3.2.2",
- "tough-cookie": "2.3.3",
- "webidl-conversions": "2.0.1",
- "whatwg-url-compat": "0.6.5",
- "xml-name-validator": "2.0.1"
- }
- },
- "parse5": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-1.5.1.tgz",
- "integrity": "sha1-m387DeMr543CQBsXVzzK8Pb1nZQ=",
- "optional": true
- },
- "readable-stream": {
- "version": "1.1.14",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
- "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "0.0.1",
- "string_decoder": "0.10.31"
- }
- },
- "webidl-conversions": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-2.0.1.tgz",
- "integrity": "sha1-O/glj30xjHRDw28uFpQCoaZwNQY=",
- "optional": true
- }
+ "readable-stream": "^2.0.1"
}
},
"methods": {
@@ -11968,58 +10717,58 @@
"integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
},
"micromatch": {
- "version": "2.3.11",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-2.3.11.tgz",
- "integrity": "sha1-hmd8l9FyCzY0MdBNDRUpO9OMFWU=",
- "dev": true,
- "requires": {
- "arr-diff": "2.0.0",
- "array-unique": "0.2.1",
- "braces": "1.8.5",
- "expand-brackets": "0.1.5",
- "extglob": "0.3.2",
- "filename-regex": "2.0.1",
- "is-extglob": "1.0.0",
- "is-glob": "2.0.1",
- "kind-of": "3.2.2",
- "normalize-path": "2.1.1",
- "object.omit": "2.0.1",
- "parse-glob": "3.0.4",
- "regex-cache": "0.4.4"
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
}
},
"miller-rabin": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.0.tgz",
- "integrity": "sha1-SmL7HUKTPAVYOYL0xxb2+55sbT0=",
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz",
+ "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==",
"dev": true,
"requires": {
- "bn.js": "4.11.8",
- "brorand": "1.1.0"
+ "bn.js": "^4.0.0",
+ "brorand": "^1.0.1"
}
},
"mime": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
- "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
},
"mime-db": {
- "version": "1.30.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
- "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
+ "version": "1.33.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz",
+ "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ=="
},
"mime-types": {
- "version": "2.1.17",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
- "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
+ "version": "2.1.18",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz",
+ "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==",
"requires": {
- "mime-db": "1.30.0"
+ "mime-db": "~1.33.0"
}
},
"mimic-fn": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.1.0.tgz",
- "integrity": "sha1-5md4PZLonb00KBi1IwudYqZyrRg="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ=="
},
"mimic-response": {
"version": "1.0.0",
@@ -12031,78 +10780,60 @@
"resolved": "https://registry.npmjs.org/min-document/-/min-document-2.19.0.tgz",
"integrity": "sha1-e9KC4/WELtKVu3SM3Z8f+iyCRoU=",
"requires": {
- "dom-walk": "0.1.1"
+ "dom-walk": "^0.1.0"
}
},
"minimalistic-assert": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz",
- "integrity": "sha1-cCvi3aazf0g2vLP121ZkG2Sh09M="
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz",
+ "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==",
+ "dev": true
},
"minimalistic-crypto-utils": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz",
- "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo="
+ "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=",
+ "dev": true
},
"minimatch": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
"requires": {
- "brace-expansion": "1.1.8"
+ "brace-expansion": "^1.1.7"
}
},
"minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
},
"mississippi": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-1.3.0.tgz",
- "integrity": "sha1-0gFYPrEjJ+PFwWQqQEqcrPlONPU=",
- "dev": true,
- "requires": {
- "concat-stream": "1.6.0",
- "duplexify": "3.5.1",
- "end-of-stream": "1.4.0",
- "flush-write-stream": "1.0.2",
- "from2": "2.3.0",
- "parallel-transform": "1.1.0",
- "pump": "1.0.2",
- "pumpify": "1.3.5",
- "stream-each": "1.2.0",
- "through2": "2.0.3"
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-2.0.0.tgz",
+ "integrity": "sha512-zHo8v+otD1J10j/tC+VNoGK9keCuByhKovAvdn74dmxJl9+mWHnx6EMsDN4lgRoMI/eYo2nchAxniIbUPb5onw==",
+ "dev": true,
+ "requires": {
+ "concat-stream": "^1.5.0",
+ "duplexify": "^3.4.2",
+ "end-of-stream": "^1.1.0",
+ "flush-write-stream": "^1.0.0",
+ "from2": "^2.1.0",
+ "parallel-transform": "^1.1.0",
+ "pump": "^2.0.1",
+ "pumpify": "^1.3.3",
+ "stream-each": "^1.1.0",
+ "through2": "^2.0.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
"dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
}
},
"through2": {
@@ -12111,8 +10842,29 @@
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
+ }
+ }
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
}
}
}
@@ -12123,6 +10875,13 @@
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
"requires": {
"minimist": "0.0.8"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "0.0.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
+ "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
+ }
}
},
"mkpath": {
@@ -12137,7 +10896,7 @@
"requires": {
"decompress-zip": "0.3.0",
"fs-extra": "0.26.7",
- "request": "2.82.0"
+ "request": "^2.79.0"
},
"dependencies": {
"fs-extra": {
@@ -12145,11 +10904,11 @@
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.26.7.tgz",
"integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
"requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "2.4.0",
- "klaw": "1.3.1",
- "path-is-absolute": "1.0.1",
- "rimraf": "2.6.2"
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
}
}
}
@@ -12199,8 +10958,8 @@
"integrity": "sha1-Spc/Y1uRkPcV0QmH1cAP0oFevj0=",
"dev": true,
"requires": {
- "inherits": "2.0.3",
- "minimatch": "0.3.0"
+ "inherits": "2",
+ "minimatch": "0.3"
}
},
"lru-cache": {
@@ -12215,8 +10974,8 @@
"integrity": "sha1-J12O2qxPG7MyZHIInnlJyDlGmd0=",
"dev": true,
"requires": {
- "lru-cache": "2.7.3",
- "sigmund": "1.0.1"
+ "lru-cache": "2",
+ "sigmund": "~1.0.0"
}
},
"ms": {
@@ -12240,21 +10999,10 @@
"dev": true
},
"moment": {
- "version": "2.18.1",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.18.1.tgz",
- "integrity": "sha1-w2GT3Tzhwu7SrbfIAtu8d6gbHA8="
- },
- "morgan": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.9.0.tgz",
- "integrity": "sha1-0B+mxlhZt2/PMbPLU6OCGjEdgFE=",
- "requires": {
- "basic-auth": "2.0.0",
- "debug": "2.6.9",
- "depd": "1.1.1",
- "on-finished": "2.3.0",
- "on-headers": "1.0.1"
- }
+ "version": "2.22.1",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.22.1.tgz",
+ "integrity": "sha512-shJkRTSebXvsVqk56I+lkb2latjBs8I+pc2TzWc545y2iFnSjm7Wg0QMh+ZWcdSLQyGEau5jI8ocnmkyTgr9YQ==",
+ "optional": true
},
"move-concurrently": {
"version": "1.0.1",
@@ -12262,60 +11010,45 @@
"integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=",
"dev": true,
"requires": {
- "aproba": "1.2.0",
- "copy-concurrently": "1.0.5",
- "fs-write-stream-atomic": "1.0.10",
- "mkdirp": "0.5.1",
- "rimraf": "2.6.2",
- "run-queue": "1.0.3"
+ "aproba": "^1.1.1",
+ "copy-concurrently": "^1.0.0",
+ "fs-write-stream-atomic": "^1.0.8",
+ "mkdirp": "^0.5.1",
+ "rimraf": "^2.5.4",
+ "run-queue": "^1.0.3"
+ },
+ "dependencies": {
+ "rimraf": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
+ "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.0.5"
+ }
+ }
}
},
"mp4-box-encoding": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/mp4-box-encoding/-/mp4-box-encoding-1.1.2.tgz",
- "integrity": "sha1-OYUO4FulNwRgBws6KsvQdhbi2DE=",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/mp4-box-encoding/-/mp4-box-encoding-1.1.4.tgz",
+ "integrity": "sha512-p6AN8M4IBaMQLcnzynXhKXW+RTz3Cc6CE12lkyffnlvwy11IjgCmmQeeOSqVaNwXdePhYviXUbwD/1GUlHQKog==",
"requires": {
- "uint64be": "1.0.1"
+ "buffer-alloc": "^1.1.0",
+ "buffer-from": "^1.0.0",
+ "uint64be": "^1.0.1"
}
},
"mp4-stream": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/mp4-stream/-/mp4-stream-2.0.2.tgz",
- "integrity": "sha1-NBYbotm2CHM7SyJH7fN4C6LEfsU=",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/mp4-stream/-/mp4-stream-2.0.3.tgz",
+ "integrity": "sha512-5NzgI0+bGakoZEwnIYINXqB3mnewkt3Y7jcvkXsTubnCNUSdM8cpP0Vemxf6FLg0qUN8fydTgNMVAc3QU8B92g==",
"requires": {
- "inherits": "2.0.3",
- "mp4-box-encoding": "1.1.2",
- "next-event": "1.0.0",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "buffer-alloc": "^1.1.0",
+ "inherits": "^2.0.1",
+ "mp4-box-encoding": "^1.1.0",
+ "next-event": "^1.0.0",
+ "readable-stream": "^2.0.3"
}
},
"ms": {
@@ -12324,21 +11057,13 @@
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
},
"multicast-dns": {
- "version": "6.1.1",
- "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.1.1.tgz",
- "integrity": "sha1-bn3oalcIcqsXBYrepxYLvsqBTd4=",
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz",
+ "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==",
"dev": true,
"requires": {
- "dns-packet": "1.2.2",
- "thunky": "0.1.0"
- },
- "dependencies": {
- "thunky": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/thunky/-/thunky-0.1.0.tgz",
- "integrity": "sha1-vzAUaCTituZ7Dy16Ssi+smkIaE4=",
- "dev": true
- }
+ "dns-packet": "^1.3.1",
+ "thunky": "^1.0.2"
}
},
"multicast-dns-service-types": {
@@ -12361,37 +11086,8 @@
"resolved": "https://registry.npmjs.org/multistream/-/multistream-2.1.0.tgz",
"integrity": "sha1-YlwmfVxEQkrWKUeItbtNo9yzLx0=",
"requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5"
}
},
"muon-winstaller": {
@@ -12400,12 +11096,12 @@
"integrity": "sha512-Sehkir6G+TCAfQVUR1EQTzwcH5AW2lzWcnpo+fX5B4G6RvXibUGyUhsjhrrlmkulc48/8k7DX3H1yO2376v1Ow==",
"dev": true,
"requires": {
- "asar": "0.11.0",
- "bluebird": "3.5.0",
- "debug": "2.6.9",
- "fs-extra": "0.26.7",
- "lodash.template": "4.4.0",
- "temp": "0.8.3"
+ "asar": "^0.11.0",
+ "bluebird": "^3.3.4",
+ "debug": "^2.2.0",
+ "fs-extra": "^0.26.7",
+ "lodash.template": "^4.2.2",
+ "temp": "^0.8.3"
},
"dependencies": {
"asar": {
@@ -12414,13 +11110,13 @@
"integrity": "sha1-uSbnksMV+MBIxDNx4yWwnJenZGQ=",
"dev": true,
"requires": {
- "chromium-pickle-js": "0.1.0",
- "commander": "2.11.0",
- "cuint": "0.2.2",
- "glob": "6.0.4",
- "minimatch": "3.0.4",
- "mkdirp": "0.5.1",
- "mksnapshot": "0.3.1"
+ "chromium-pickle-js": "^0.1.0",
+ "commander": "^2.9.0",
+ "cuint": "^0.2.1",
+ "glob": "^6.0.4",
+ "minimatch": "^3.0.0",
+ "mkdirp": "^0.5.0",
+ "mksnapshot": "^0.3.0"
}
},
"chromium-pickle-js": {
@@ -12435,11 +11131,11 @@
"integrity": "sha1-muH92UiXeY7at20JGM9C0MMYT6k=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "2.4.0",
- "klaw": "1.3.1",
- "path-is-absolute": "1.0.1",
- "rimraf": "2.6.2"
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^2.1.0",
+ "klaw": "^1.0.0",
+ "path-is-absolute": "^1.0.0",
+ "rimraf": "^2.2.8"
}
},
"glob": {
@@ -12448,11 +11144,11 @@
"integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
"dev": true,
"requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
}
},
"lodash.template": {
@@ -12461,8 +11157,8 @@
"integrity": "sha1-5zoDhcg1VZF0bgILmWecaQ5o+6A=",
"dev": true,
"requires": {
- "lodash._reinterpolate": "3.0.0",
- "lodash.templatesettings": "4.1.0"
+ "lodash._reinterpolate": "~3.0.0",
+ "lodash.templatesettings": "^4.0.0"
}
},
"lodash.templatesettings": {
@@ -12471,7 +11167,7 @@
"integrity": "sha1-K01OlbpEDZFf8IvImeRVNmZxMxY=",
"dev": true,
"requires": {
- "lodash._reinterpolate": "3.0.0"
+ "lodash._reinterpolate": "~3.0.0"
}
}
}
@@ -12486,42 +11182,40 @@
"resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
"integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=",
"requires": {
- "mkdirp": "0.5.1",
- "ncp": "2.0.0",
- "rimraf": "2.4.5"
- },
- "dependencies": {
- "glob": {
- "version": "6.0.4",
- "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
- "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
- "requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.1"
- }
- },
- "rimraf": {
- "version": "2.4.5",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
- "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=",
- "requires": {
- "glob": "6.0.4"
- }
- }
+ "mkdirp": "~0.5.1",
+ "ncp": "~2.0.0",
+ "rimraf": "~2.4.0"
}
},
"nan": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/nan/-/nan-2.7.0.tgz",
- "integrity": "sha1-2Vv3IeyHfgjbJ27T/G63j5CDrUY="
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/nan/-/nan-2.8.0.tgz",
+ "integrity": "sha1-7XFfP+neArV6XmJS2QqWZ14fCFo="
+ },
+ "nanomatch": {
+ "version": "1.2.9",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.9.tgz",
+ "integrity": "sha512-n8R9bS8yQ6eSXaV6jHUpKzD8gLsin02w1HSFiegwrs9E098Ylhw5jdyKPaYqvHknHaSCKTPp7C8dGCQ0q9koXA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-odd": "^2.0.0",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ }
},
"natives": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.0.tgz",
- "integrity": "sha1-6f+EFBimsux6SV6TmYT3jxY+bjE=",
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/natives/-/natives-1.1.4.tgz",
+ "integrity": "sha512-Q29yeg9aFKwhLVdkTAejM/HvYG0Y1Am1+HUkFQGn5k2j8GS+v60TVmZh6nujpEAj/qql+wGUrlryO8bF+b1jEg==",
"dev": true
},
"natural-compare": {
@@ -12539,51 +11233,19 @@
"resolved": "https://registry.npmjs.org/ndjson/-/ndjson-1.5.0.tgz",
"integrity": "sha1-rmA7NrE0vOw0e0UkIrC/mNWDLsg=",
"requires": {
- "json-stringify-safe": "5.0.1",
- "minimist": "1.2.0",
- "split2": "2.2.0",
- "through2": "2.0.3"
+ "json-stringify-safe": "^5.0.1",
+ "minimist": "^1.2.0",
+ "split2": "^2.1.0",
+ "through2": "^2.0.3"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
}
}
}
@@ -12591,7 +11253,14 @@
"negotiator": {
"version": "0.6.1",
"resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
- "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
+ "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk=",
+ "dev": true
+ },
+ "neo-async": {
+ "version": "2.5.1",
+ "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.5.1.tgz",
+ "integrity": "sha512-3KL3fvuRkZ7s4IFOMfztb7zJp3QaVWnBeGoJlgB38XnCRPj/0tLzzLG5IB8NYOHbJ8g8UGrgZv44GLDk6CxTxA==",
+ "dev": true
},
"netmask": {
"version": "1.0.6",
@@ -12603,21 +11272,30 @@
"resolved": "https://registry.npmjs.org/next-event/-/next-event-1.0.0.tgz",
"integrity": "sha1-53eKzeLlWALgrRh5w5z2917aYdg="
},
+ "next-tick": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz",
+ "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=",
+ "dev": true
+ },
"niceware": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/niceware/-/niceware-1.0.4.tgz",
- "integrity": "sha1-QSLxpvrJpNGEtYsVVe5j0GGp/hk=",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/niceware/-/niceware-1.0.5.tgz",
+ "integrity": "sha512-x7PuXncaSWbgqHb6O+uLHfxYqqywTK/J8Qipih7v4ubNYu10FdrovYvPfPrGFRXnp3HaQg6spilYZ39uC4VaOQ==",
"requires": {
- "binary-search": "1.3.2",
- "randombytes": "2.0.5"
+ "binary-search": "^1.3.3",
+ "randombytes": "^2.0.6"
}
},
"node-abi": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.1.1.tgz",
- "integrity": "sha512-6oxV13poCOv7TfGvhsSz6XZWpXeKkdGVh72++cs33OfMh3KAX8lN84dCvmqSETyDXAFcUHtV7eJrgFBoOqZbNQ=="
- },
- "node-anonize2-relic-emscripten": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-2.4.1.tgz",
+ "integrity": "sha512-pUlswqpHQ7zGPI9lGjZ4XDNIEUDbHxsltfIRb7dTnYdhgHWHOcB0MLZKLoCz6UMcGzSPG5wGl1HODZVQAUsH6w==",
+ "requires": {
+ "semver": "^5.4.1"
+ }
+ },
+ "node-anonize2-relic-emscripten": {
"version": "0.3.3",
"resolved": "https://registry.npmjs.org/node-anonize2-relic-emscripten/-/node-anonize2-relic-emscripten-0.3.3.tgz",
"integrity": "sha1-d+K4parVCdf1OXjDlKoPjOVcRAE=",
@@ -12636,24 +11314,8 @@
"resolved": "https://registry.npmjs.org/node-cache/-/node-cache-4.1.1.tgz",
"integrity": "sha1-CFJGRe5AOd7cPcwd18a5eeBhnkQ=",
"requires": {
- "clone": "2.1.1",
- "lodash": "4.17.4"
- },
- "dependencies": {
- "clone": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.1.tgz",
- "integrity": "sha1-0hfR6WERjjrJpLi7oyhVU79kfNs="
- }
- }
- },
- "node-emoji": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-1.8.1.tgz",
- "integrity": "sha512-+ktMAh1Jwas+TnGodfCfjUbJKoANqPaJFN0z0iqh41eqD8dvguNzcitVSBSVK1pidz0AqGbLKcoVuVLRVZ/aVg==",
- "dev": true,
- "requires": {
- "lodash.toarray": "4.4.0"
+ "clone": "2.x",
+ "lodash": "4.x"
}
},
"node-fetch": {
@@ -12661,29 +11323,35 @@
"resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.7.3.tgz",
"integrity": "sha512-NhZ4CsKx7cYm2vSrBAr2PvFOe6sWDf0UYLRqA6svUYg7+/TSfVAu49jYC4BvQ4Sms9SZgdqGBgroqfDhJdTyKQ==",
"requires": {
- "encoding": "0.1.12",
- "is-stream": "1.1.0"
+ "encoding": "^0.1.11",
+ "is-stream": "^1.0.1"
}
},
+ "node-forge": {
+ "version": "0.7.5",
+ "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.7.5.tgz",
+ "integrity": "sha512-MmbQJ2MTESTjt3Gi/3yG1wGpIMhUfcIypUCGtTizFR9IiccFwxSpfp0vtIZlkFclEqERemxfnSdZEMR9VqqEFQ==",
+ "dev": true
+ },
"node-gyp": {
"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.11",
- "glob": "7.1.2",
- "graceful-fs": "4.1.11",
- "minimatch": "3.0.4",
- "mkdirp": "0.5.1",
- "nopt": "3.0.6",
- "npmlog": "4.1.2",
- "osenv": "0.1.4",
- "request": "2.82.0",
- "rimraf": "2.6.2",
- "semver": "5.3.0",
- "tar": "2.2.1",
- "which": "1.3.0"
+ "fstream": "^1.0.0",
+ "glob": "^7.0.3",
+ "graceful-fs": "^4.1.2",
+ "minimatch": "^3.0.2",
+ "mkdirp": "^0.5.0",
+ "nopt": "2 || 3",
+ "npmlog": "0 || 1 || 2 || 3 || 4",
+ "osenv": "0",
+ "request": "2",
+ "rimraf": "2",
+ "semver": "~5.3.0",
+ "tar": "^2.0.0",
+ "which": "1"
},
"dependencies": {
"semver": {
@@ -12700,44 +11368,35 @@
"integrity": "sha1-o6WeyXAkmFtG6Vg3lkb5bEthZkY=",
"dev": true,
"requires": {
- "assert": "1.4.1",
- "browserify-zlib": "0.1.4",
- "buffer": "4.9.1",
- "console-browserify": "1.1.0",
- "constants-browserify": "1.0.0",
- "crypto-browserify": "3.11.1",
- "domain-browser": "1.1.7",
- "events": "1.1.1",
+ "assert": "^1.1.1",
+ "browserify-zlib": "^0.1.4",
+ "buffer": "^4.3.0",
+ "console-browserify": "^1.1.0",
+ "constants-browserify": "^1.0.0",
+ "crypto-browserify": "^3.11.0",
+ "domain-browser": "^1.1.1",
+ "events": "^1.0.0",
"https-browserify": "0.0.1",
- "os-browserify": "0.2.1",
+ "os-browserify": "^0.2.0",
"path-browserify": "0.0.0",
- "process": "0.11.10",
- "punycode": "1.4.1",
- "querystring-es3": "0.2.1",
- "readable-stream": "2.3.3",
- "stream-browserify": "2.0.1",
- "stream-http": "2.7.2",
- "string_decoder": "0.10.31",
- "timers-browserify": "2.0.4",
+ "process": "^0.11.0",
+ "punycode": "^1.2.4",
+ "querystring-es3": "^0.2.0",
+ "readable-stream": "^2.0.5",
+ "stream-browserify": "^2.0.1",
+ "stream-http": "^2.3.1",
+ "string_decoder": "^0.10.25",
+ "timers-browserify": "^2.0.2",
"tty-browserify": "0.0.0",
- "url": "0.11.0",
- "util": "0.10.3",
+ "url": "^0.11.0",
+ "util": "^0.10.3",
"vm-browserify": "0.0.4"
},
"dependencies": {
- "assert": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz",
- "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=",
- "dev": true,
- "requires": {
- "util": "0.10.3"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "process": {
+ "version": "0.11.10",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
+ "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
"dev": true
},
"punycode": {
@@ -12746,55 +11405,24 @@
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
"dev": true
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- },
- "dependencies": {
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
- }
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
+ "dev": true
}
}
},
"node-notifier": {
- "version": "4.6.1",
- "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-4.6.1.tgz",
- "integrity": "sha1-BW0UJE89zBzq3+aK+c/wxUc6M/M=",
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.2.1.tgz",
+ "integrity": "sha512-MIBs+AAd6dJ2SklbbE8RUDRlIVhU8MaNLh1A9SUZDUHPiZkWLFde6UNwG41yQHZEToHgJMXqyVZ9UcS/ReOVTg==",
"dev": true,
"requires": {
- "cli-usage": "0.1.4",
- "growly": "1.3.0",
- "lodash.clonedeep": "3.0.2",
- "minimist": "1.2.0",
- "semver": "5.4.1",
- "shellwords": "0.1.1",
- "which": "1.3.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- }
+ "growly": "^1.3.0",
+ "semver": "^5.4.1",
+ "shellwords": "^0.1.1",
+ "which": "^1.3.0"
}
},
"node-static": {
@@ -12803,11 +11431,17 @@
"integrity": "sha512-bd7zO5hvCWzdglgwz9t82T4mYTEUzEG5pXnSqEzitvmEacusbhl8/VwuCbMaYR9g2PNK5191yBtAEQLJEmQh1A==",
"dev": true,
"requires": {
- "colors": "1.1.2",
- "mime": "1.3.4",
- "optimist": "0.6.1"
+ "colors": ">=0.6.0",
+ "mime": "^1.2.9",
+ "optimist": ">=0.3.4"
}
},
+ "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
+ },
"noop-logger": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/noop-logger/-/noop-logger-0.1.1.tgz",
@@ -12818,7 +11452,7 @@
"resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
"integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
"requires": {
- "abbrev": "1.1.0"
+ "abbrev": "1"
}
},
"normalize-package-data": {
@@ -12826,10 +11460,10 @@
"resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.4.0.tgz",
"integrity": "sha512-9jjUFbTPfEy3R/ad/2oNbKtW9Hgovl5O1FvFWKkKblNXoN/Oou6+9+KKohPK13Yc3/TyunyWhJp6gvRNR/PPAw==",
"requires": {
- "hosted-git-info": "2.5.0",
- "is-builtin-module": "1.0.0",
- "semver": "5.4.1",
- "validate-npm-package-license": "3.0.1"
+ "hosted-git-info": "^2.1.4",
+ "is-builtin-module": "^1.0.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
}
},
"normalize-path": {
@@ -12838,9 +11472,15 @@
"integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
"dev": true,
"requires": {
- "remove-trailing-separator": "1.1.0"
+ "remove-trailing-separator": "^1.0.1"
}
},
+ "normalize-range": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
+ "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
+ "dev": true
+ },
"normalize-selector": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz",
@@ -12853,10 +11493,10 @@
"integrity": "sha1-LMDWazHqIwNkWENuNiDYWVTGbDw=",
"dev": true,
"requires": {
- "object-assign": "4.1.1",
- "prepend-http": "1.0.4",
- "query-string": "4.3.4",
- "sort-keys": "1.1.2"
+ "object-assign": "^4.0.1",
+ "prepend-http": "^1.0.0",
+ "query-string": "^4.1.0",
+ "sort-keys": "^1.0.0"
}
},
"npm-install-package": {
@@ -12871,7 +11511,7 @@
"integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
"dev": true,
"requires": {
- "path-key": "2.0.1"
+ "path-key": "^2.0.0"
}
},
"npmlog": {
@@ -12879,2378 +11519,159 @@
"resolved": "https://registry.npmjs.org/npmlog/-/npmlog-4.1.2.tgz",
"integrity": "sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==",
"requires": {
- "are-we-there-yet": "1.1.4",
- "console-control-strings": "1.1.0",
- "gauge": "2.7.4",
- "set-blocking": "2.0.0"
+ "are-we-there-yet": "~1.1.2",
+ "console-control-strings": "~1.1.0",
+ "gauge": "~2.7.3",
+ "set-blocking": "~2.0.0"
}
},
"nsp": {
- "version": "2.8.0",
- "resolved": "https://registry.npmjs.org/nsp/-/nsp-2.8.0.tgz",
- "integrity": "sha512-Xd2O4BpocQZJJF0DCK5rhOPEPyo9L7A/UlVmT9/Hof14cVgizgDF3y6MSDwJQHD+5eNXN46hdlG528Lrao83Sw==",
- "dev": true,
- "requires": {
- "chalk": "1.1.3",
- "cli-table": "0.3.1",
- "cvss": "1.0.1",
- "https-proxy-agent": "1.0.0",
- "joi": "6.10.1",
- "nodesecurity-npm-utils": "5.0.0",
- "path-is-absolute": "1.0.0",
- "rc": "1.1.6",
- "semver": "5.1.0",
- "subcommand": "2.0.3",
- "wreck": "6.3.0"
+ "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": {
- "abbrev": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.0.tgz",
- "integrity": "sha1-0FVMIlZjbi9W58LlrRg/hZQo2B8=",
- "optional": true
- },
- "acorn": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.1.1.tgz",
- "integrity": "sha512-vOk6uEMctu0vQrvuSqFdJyqj1Q0S5VTDL79qtjo+DhRr+1mmaD+tluFSCZqhvi/JUhXSzoZN2BhtstaPEeE8cw=="
- },
- "acorn-jsx": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-3.0.1.tgz",
- "integrity": "sha1-r9+UiPsezvyDSPb7IvRk4ypYs2s=",
- "requires": {
- "acorn": "3.3.0"
- },
- "dependencies": {
- "acorn": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-3.3.0.tgz",
- "integrity": "sha1-ReN/s56No/JbruP/U2niu18iAXo="
- }
- }
- },
- "ajv": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
- "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
- "requires": {
- "co": "4.6.0",
- "json-stable-stringify": "1.0.1"
- }
- },
- "ajv-keywords": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
- "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw="
- },
- "align-text": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/align-text/-/align-text-0.1.4.tgz",
- "integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
- "requires": {
- "kind-of": "3.2.2",
- "longest": "1.0.1",
- "repeat-string": "1.6.1"
- }
- },
- "amdefine": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/amdefine/-/amdefine-1.0.1.tgz",
- "integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU="
- },
- "ansi-escapes": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
- "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4="
- },
"ansi-regex": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
- "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
- },
- "argparse": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.9.tgz",
- "integrity": "sha1-c9g7wmP4bpf4zE9rrhsOkKfSLIY=",
- "requires": {
- "sprintf-js": "1.0.3"
- }
- },
- "array-union": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
- "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
- "requires": {
- "array-uniq": "1.0.3"
- }
- },
- "array-uniq": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
- "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY="
- },
- "arrify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
- "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0="
- },
- "assertion-error": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.2.tgz",
- "integrity": "sha1-E8pRXYYgbaC6xm6DTdOX2HWBCUw="
- },
- "async": {
- "version": "1.5.2",
- "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
- "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
- },
- "balanced-match": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
- "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
- },
- "bossy": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/bossy/-/bossy-1.0.3.tgz",
- "integrity": "sha1-p9JHiuDC33X0cJi5ute9ZB7tX68=",
- "requires": {
- "hoek": "2.16.3"
- }
- },
- "brace-expansion": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
- "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
- "requires": {
- "balanced-match": "1.0.0",
- "concat-map": "0.0.1"
- }
- },
- "caller-path": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-0.1.0.tgz",
- "integrity": "sha1-lAhe9jWB7NPaqSREqP6U6CV3dR8=",
- "requires": {
- "callsites": "0.2.0"
- }
- },
- "callsites": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/callsites/-/callsites-0.2.0.tgz",
- "integrity": "sha1-r6uWJikQp/M8GaV3WCXGnzTjUMo="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
},
"camelcase": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-1.2.1.tgz",
- "integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
- "optional": true
- },
- "center-align": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/center-align/-/center-align-0.1.3.tgz",
- "integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
- "optional": true,
- "requires": {
- "align-text": "0.1.4",
- "lazy-cache": "1.0.4"
- }
- },
- "chai": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/chai/-/chai-3.5.0.tgz",
- "integrity": "sha1-TQJjewZ/6Vi9v906QOxW/vc3Mkc=",
- "requires": {
- "assertion-error": "1.0.2",
- "deep-eql": "0.1.3",
- "type-detect": "1.0.0"
- }
- },
- "chalk": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
- "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
- "requires": {
- "ansi-styles": "2.2.1",
- "escape-string-regexp": "1.0.5",
- "has-ansi": "2.0.0",
- "strip-ansi": "3.0.1",
- "supports-color": "2.0.0"
- },
- "dependencies": {
- "ansi-styles": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
- "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4="
- },
- "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="
- },
- "has-ansi": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
- "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
- "requires": {
- "ansi-regex": "2.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz",
- "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc="
- }
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "2.0.0"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.0.0.tgz",
- "integrity": "sha1-xQYbbg74qBd15Q9dZhUb9r83EQc="
- }
- }
- },
- "supports-color": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
- "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
- }
- }
- },
- "circular-json": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/circular-json/-/circular-json-0.3.3.tgz",
- "integrity": "sha512-UZK3NBx2Mca+b5LsG7bY183pHWt5Y1xts4P3Pz7ENTwGVnJOUWbRb3ocjvX7hx9tq/yTAdclXm9sZ38gNuem4A=="
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
},
- "cli-cursor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
- "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
- "requires": {
- "restore-cursor": "1.0.1"
- }
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
},
- "cli-table": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/cli-table/-/cli-table-0.3.1.tgz",
- "integrity": "sha1-9TsFJmqLGguTSz0IIebi3FkUriM=",
+ "load-json-file": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
+ "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"dev": true,
"requires": {
- "colors": "1.0.3"
- },
- "dependencies": {
- "colors": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/colors/-/colors-1.0.3.tgz",
- "integrity": "sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs=",
- "dev": true
- }
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
}
},
- "cli-width": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
- "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk="
- },
- "cliui": {
+ "os-locale": {
"version": "2.1.0",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-2.1.0.tgz",
- "integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
- "optional": true,
- "requires": {
- "center-align": "0.1.3",
- "right-align": "0.1.3",
- "wordwrap": "0.0.2"
- },
- "dependencies": {
- "wordwrap": {
- "version": "0.0.2",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.2.tgz",
- "integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
- "optional": true
- }
- }
- },
- "co": {
- "version": "4.6.0",
- "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz",
- "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ="
- },
- "code": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/code/-/code-1.5.0.tgz",
- "integrity": "sha1-1hWfvQ7p+ERRZ4CdQ7XNm8QFEDo=",
- "requires": {
- "hoek": "2.16.3"
- }
- },
- "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="
- },
- "concat-map": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
- "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
- },
- "concat-stream": {
- "version": "1.6.0",
- "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.0.tgz",
- "integrity": "sha1-CqxmL9Ur54lk1VMvaUeE5wEQrPc=",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "dev": true,
"requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3",
- "typedarray": "0.0.6"
+ "execa": "^0.7.0",
+ "lcid": "^1.0.0",
+ "mem": "^1.1.0"
}
},
- "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="
- },
- "cvss": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/cvss/-/cvss-1.0.1.tgz",
- "integrity": "sha1-XAffU2FqxW1m6PR0vtJePBRhk9s=",
- "dev": true
- },
- "d": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/d/-/d-1.0.0.tgz",
- "integrity": "sha1-dUu1v+VUUdpppYuU1F9MWwRi1Y8=",
+ "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": {
- "es5-ext": "0.10.30"
+ "pify": "^2.0.0"
}
},
- "debug": {
- "version": "2.6.8",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
- "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
+ "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": {
- "ms": "2.0.0"
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
}
},
- "decamelize": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
- "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
- "optional": true
- },
- "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",
- "integrity": "sha1-9dJgKStmDghO/0zbyfCK0yR0SLU="
- },
- "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="
- },
- "del": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/del/-/del-2.2.2.tgz",
- "integrity": "sha1-wSyYHQZ4RshLyvhiz/kw2Qf/0ag=",
- "requires": {
- "globby": "5.0.0",
- "is-path-cwd": "1.0.0",
- "is-path-in-cwd": "1.0.0",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1",
- "rimraf": "2.6.1"
- }
- },
- "diff": {
- "version": "2.2.3",
- "resolved": "https://registry.npmjs.org/diff/-/diff-2.2.3.tgz",
- "integrity": "sha1-YOr9DSjukG5Oj/ClLBIpUhAzv5k="
- },
- "doctrine": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
- "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
- "requires": {
- "esutils": "2.0.2",
- "isarray": "1.0.0"
- }
- },
- "es5-ext": {
- "version": "0.10.30",
- "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.30.tgz",
- "integrity": "sha1-cUGhaDZpfbq/qq7uQUlc4p9SyTk=",
- "requires": {
- "es6-iterator": "2.0.1",
- "es6-symbol": "3.1.1"
- }
- },
- "es6-iterator": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.1.tgz",
- "integrity": "sha1-jjGcnwRTv1ddN0lAplWSDlnKVRI=",
- "requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-symbol": "3.1.1"
- }
- },
- "es6-map": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/es6-map/-/es6-map-0.1.5.tgz",
- "integrity": "sha1-kTbgUD3MBqMBaQ8LsU/042TpSfA=",
- "requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-iterator": "2.0.1",
- "es6-set": "0.1.5",
- "es6-symbol": "3.1.1",
- "event-emitter": "0.3.5"
- }
- },
- "es6-set": {
- "version": "0.1.5",
- "resolved": "https://registry.npmjs.org/es6-set/-/es6-set-0.1.5.tgz",
- "integrity": "sha1-0rPsXU2ADO2BjbU40ol02wpzzLE=",
- "requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-iterator": "2.0.1",
- "es6-symbol": "3.1.1",
- "event-emitter": "0.3.5"
- }
- },
- "es6-symbol": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.1.tgz",
- "integrity": "sha1-vwDvT9q2uhtG7Le2KbTH7VcVzHc=",
- "requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30"
- }
- },
- "es6-weak-map": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.2.tgz",
- "integrity": "sha1-XjqzIlH/0VOKH45f+hNXdy+S2W8=",
- "requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30",
- "es6-iterator": "2.0.1",
- "es6-symbol": "3.1.1"
- }
- },
- "escape-string-regexp": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
- "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ="
- },
- "escope": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/escope/-/escope-3.6.0.tgz",
- "integrity": "sha1-4Bl16BJ4GhY6ba392AOY3GTIicM=",
- "requires": {
- "es6-map": "0.1.5",
- "es6-weak-map": "2.0.2",
- "esrecurse": "4.2.0",
- "estraverse": "4.2.0"
- }
- },
- "eslint": {
- "version": "2.13.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-2.13.1.tgz",
- "integrity": "sha1-5MyPoPAJ+4KaquI4VaKTYL4fbBE=",
- "requires": {
- "chalk": "1.1.3",
- "concat-stream": "1.6.0",
- "debug": "2.6.8",
- "doctrine": "1.5.0",
- "es6-map": "0.1.5",
- "escope": "3.6.0",
- "espree": "3.5.0",
- "estraverse": "4.2.0",
- "esutils": "2.0.2",
- "file-entry-cache": "1.3.1",
- "glob": "7.1.2",
- "globals": "9.18.0",
- "ignore": "3.3.5",
- "imurmurhash": "0.1.4",
- "inquirer": "0.12.0",
- "is-my-json-valid": "2.16.1",
- "is-resolvable": "1.0.0",
- "js-yaml": "3.9.1",
- "json-stable-stringify": "1.0.1",
- "levn": "0.3.0",
- "lodash": "4.17.4",
- "mkdirp": "0.5.1",
- "optionator": "0.8.2",
- "path-is-absolute": "1.0.0",
- "path-is-inside": "1.0.2",
- "pluralize": "1.2.1",
- "progress": "1.1.8",
- "require-uncached": "1.0.3",
- "shelljs": "0.6.1",
- "strip-json-comments": "1.0.4",
- "table": "3.8.3",
- "text-table": "0.2.0",
- "user-home": "2.0.0"
- }
- },
- "eslint-config-hapi": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/eslint-config-hapi/-/eslint-config-hapi-3.0.2.tgz",
- "integrity": "sha1-Wk+tJQeELM0phRtjrwWitbFnw2c="
- },
- "eslint-config-nodesecurity": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/eslint-config-nodesecurity/-/eslint-config-nodesecurity-1.3.1.tgz",
- "integrity": "sha1-8IAQ/DDJZPrdG0Yi5mO8Dx8P7Uk=",
- "requires": {
- "eslint-plugin-hapi": "4.0.0"
- },
- "dependencies": {
- "eslint-plugin-hapi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-hapi/-/eslint-plugin-hapi-4.0.0.tgz",
- "integrity": "sha1-RKouRfeTmlI5Kc2DK7mqEpqV6CM=",
- "requires": {
- "hapi-capitalize-modules": "1.1.6",
- "hapi-for-you": "1.0.0",
- "hapi-scope-start": "2.1.1",
- "no-arrowception": "1.0.0"
- }
- }
- }
- },
- "eslint-plugin-hapi": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-hapi/-/eslint-plugin-hapi-1.2.2.tgz",
- "integrity": "sha1-QcwGNDhxibEcAGdWM6cVZGq4lJA=",
- "requires": {
- "hapi-capitalize-modules": "1.1.6",
- "hapi-scope-start": "1.1.4",
- "no-shadow-relaxed": "1.0.1"
- },
- "dependencies": {
- "hapi-scope-start": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/hapi-scope-start/-/hapi-scope-start-1.1.4.tgz",
- "integrity": "sha1-VxC1r7dOdJYdrn6wmdjYvkp1sA4="
- }
- }
- },
- "espree": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-3.5.0.tgz",
- "integrity": "sha1-mDWGJb3QVYYeon4oZ+pyn69GPY0=",
- "requires": {
- "acorn": "5.1.1",
- "acorn-jsx": "3.0.1"
- }
- },
- "esprima": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.0.tgz",
- "integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw=="
- },
- "esrecurse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.0.tgz",
- "integrity": "sha1-+pVo2Y04I/mkHZHpAtyrnqblsWM=",
- "requires": {
- "estraverse": "4.2.0",
- "object-assign": "4.1.1"
- }
- },
- "estraverse": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
- "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM="
- },
- "estraverse-fb": {
- "version": "1.3.2",
- "resolved": "https://registry.npmjs.org/estraverse-fb/-/estraverse-fb-1.3.2.tgz",
- "integrity": "sha1-0yOky15awzHOoDNBOpJT4WQ+B8Q="
- },
- "esutils": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
- "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs="
- },
- "event-emitter": {
- "version": "0.3.5",
- "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
- "integrity": "sha1-34xp7vFkeSPHFXuc6DhAYQsCzDk=",
- "requires": {
- "d": "1.0.0",
- "es5-ext": "0.10.30"
- }
- },
- "exit": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
- "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
- "optional": true
- },
- "exit-hook": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/exit-hook/-/exit-hook-1.1.1.tgz",
- "integrity": "sha1-8FyiM7SMBdVP/wd2XfhQfpXAL/g="
- },
- "fast-levenshtein": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
- "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc="
- },
- "figures": {
- "version": "1.7.0",
- "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
- "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
- "requires": {
- "escape-string-regexp": "1.0.5",
- "object-assign": "4.1.1"
- }
- },
- "file-entry-cache": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-1.3.1.tgz",
- "integrity": "sha1-RMYepgeuS+nBQC9B9EJwy/4zT/g=",
- "requires": {
- "flat-cache": "1.2.2",
- "object-assign": "4.1.1"
- }
- },
- "flat-cache": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-1.2.2.tgz",
- "integrity": "sha1-+oZxTnLCHbiGAXYezy9VXRq8a5Y=",
- "requires": {
- "circular-json": "0.3.3",
- "del": "2.2.2",
- "graceful-fs": "4.1.11",
- "write": "0.2.1"
- }
- },
- "fs.realpath": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
- "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8="
- },
- "generate-function": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.0.0.tgz",
- "integrity": "sha1-aFj+fAlpt9TpCTM3ZHrHn2DfvnQ="
- },
- "generate-object-property": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/generate-object-property/-/generate-object-property-1.2.0.tgz",
- "integrity": "sha1-nA4cQDCM6AT0eDYYuTf6iPmdUNA=",
- "requires": {
- "is-property": "1.0.2"
- }
- },
- "get-stdin": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-3.0.2.tgz",
- "integrity": "sha1-wc7SS5A5s43thb3xYeV3E7bdSr4="
- },
- "git-validate": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/git-validate/-/git-validate-2.2.2.tgz",
- "integrity": "sha1-nMj/ABF3lXoRcmq1CNQVu4Cxi88="
- },
- "glob": {
- "version": "7.1.2",
- "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
- "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
- "requires": {
- "fs.realpath": "1.0.0",
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "3.0.4",
- "once": "1.4.0",
- "path-is-absolute": "1.0.0"
- }
- },
- "globals": {
- "version": "9.18.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
- "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ=="
- },
- "globby": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/globby/-/globby-5.0.0.tgz",
- "integrity": "sha1-69hGZ8oNuzMLmbz8aOrCvFQ3Dg0=",
- "requires": {
- "array-union": "1.0.2",
- "arrify": "1.0.1",
- "glob": "7.1.2",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1"
- }
- },
- "graceful-fs": {
- "version": "4.1.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.11.tgz",
- "integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg="
- },
- "handlebars": {
- "version": "4.0.10",
- "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.0.10.tgz",
- "integrity": "sha1-PTDHGLCaPZbyPqTMH0A8TTup/08=",
- "requires": {
- "async": "1.5.2",
- "optimist": "0.6.1",
- "source-map": "0.4.4",
- "uglify-js": "2.8.29"
- }
- },
- "hapi-capitalize-modules": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/hapi-capitalize-modules/-/hapi-capitalize-modules-1.1.6.tgz",
- "integrity": "sha1-eZEXFBXhXmqjIx5k3ac8gUZmUxg="
- },
- "hapi-for-you": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/hapi-for-you/-/hapi-for-you-1.0.0.tgz",
- "integrity": "sha1-02L77o172pwseAHiB+WlzRoLans="
- },
- "hapi-scope-start": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/hapi-scope-start/-/hapi-scope-start-2.1.1.tgz",
- "integrity": "sha1-dJWnJv5yt7yo3izcwdh82M5qtPI="
- },
- "hoek": {
- "version": "2.16.3",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0="
- },
- "https-proxy-agent": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz",
- "integrity": "sha1-NffabEjOTdv6JkiRrFk+5f+GceY=",
- "dev": true,
- "requires": {
- "agent-base": "2.0.1",
- "debug": "2.2.0",
- "extend": "3.0.0"
- },
- "dependencies": {
- "agent-base": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.0.1.tgz",
- "integrity": "sha1-vY+ehqjrIh//oHvRS+/VXfFCgV4=",
- "dev": true,
- "requires": {
- "extend": "3.0.0",
- "semver": "5.0.3"
- },
- "dependencies": {
- "semver": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz",
- "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=",
- "dev": true
- }
- }
- },
- "debug": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
- "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
- "dev": true,
- "requires": {
- "ms": "0.7.1"
- },
- "dependencies": {
- "ms": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
- "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
- "dev": true
- }
- }
- },
- "extend": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
- "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ=",
- "dev": true
- }
- }
- },
- "ignore": {
- "version": "3.3.5",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.5.tgz",
- "integrity": "sha512-JLH93mL8amZQhh/p6mfQgVBH3M6epNq3DfsXsTSuSrInVjwyYlFE1nv2AgfRCC8PoOhM0jwQ5v8s9LgbK7yGDw=="
- },
- "imurmurhash": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
- "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o="
- },
- "inflight": {
- "version": "1.0.6",
- "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
- "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
- "requires": {
- "once": "1.4.0",
- "wrappy": "1.0.2"
- }
- },
- "inherits": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
- "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
- },
- "inquirer": {
- "version": "0.12.0",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
- "integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
- "requires": {
- "ansi-escapes": "1.4.0",
- "ansi-regex": "2.1.1",
- "chalk": "1.1.3",
- "cli-cursor": "1.0.2",
- "cli-width": "2.2.0",
- "figures": "1.7.0",
- "lodash": "4.17.4",
- "readline2": "1.0.1",
- "run-async": "0.1.0",
- "rx-lite": "3.1.2",
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "through": "2.3.8"
- }
- },
- "is-buffer": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz",
- "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw="
- },
- "is-fullwidth-code-point": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
- "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
- "requires": {
- "number-is-nan": "1.0.1"
- }
- },
- "is-my-json-valid": {
- "version": "2.16.1",
- "resolved": "https://registry.npmjs.org/is-my-json-valid/-/is-my-json-valid-2.16.1.tgz",
- "integrity": "sha512-ochPsqWS1WXj8ZnMIV0vnNXooaMhp7cyL4FMSIPKTtnV0Ha/T19G2b9kkhcNsabV9bxYkze7/aLZJb/bYuFduQ==",
- "requires": {
- "generate-function": "2.0.0",
- "generate-object-property": "1.2.0",
- "jsonpointer": "4.0.1",
- "xtend": "4.0.1"
- }
- },
- "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="
- },
- "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=",
- "requires": {
- "is-path-inside": "1.0.0"
- }
- },
- "is-path-inside": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-1.0.0.tgz",
- "integrity": "sha1-/AbloWg/vaE95mev9xe7wQpI838=",
- "requires": {
- "path-is-inside": "1.0.2"
- }
- },
- "is-property": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz",
- "integrity": "sha1-V/4cTkhHTt1lsJkR8msc1Ald2oQ="
- },
- "is-resolvable": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.0.0.tgz",
- "integrity": "sha1-jfV8YeouPFAUCNEA+wE8+NbgzGI=",
- "requires": {
- "tryit": "1.0.3"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "items": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/items/-/items-1.1.1.tgz",
- "integrity": "sha1-Q1td0hvKKLPP0lu1xrJ4txUBD9k="
- },
- "joi": {
- "version": "6.10.1",
- "resolved": "https://registry.npmjs.org/joi/-/joi-6.10.1.tgz",
- "integrity": "sha1-TVDDGAeRIgAP5fFq8f+OGRe3fgY=",
- "dev": true,
- "requires": {
- "hoek": "2.16.3",
- "isemail": "1.2.0",
- "moment": "2.12.0",
- "topo": "1.1.0"
- },
- "dependencies": {
- "hoek": {
- "version": "2.16.3",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
- "dev": true
- },
- "isemail": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/isemail/-/isemail-1.2.0.tgz",
- "integrity": "sha1-vgPfjMPineTSxd9lASY/H6RZXpo=",
- "dev": true
- },
- "moment": {
- "version": "2.12.0",
- "resolved": "https://registry.npmjs.org/moment/-/moment-2.12.0.tgz",
- "integrity": "sha1-3CVg0Zg41sBzGxpq+gRnUmTTYNY=",
- "dev": true
- },
- "topo": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/topo/-/topo-1.1.0.tgz",
- "integrity": "sha1-6ddRYV0buH3IZdsYL6HKCl71NtU=",
- "dev": true,
- "requires": {
- "hoek": "2.16.3"
- }
- }
- }
- },
- "js-yaml": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.9.1.tgz",
- "integrity": "sha512-CbcG379L1e+mWBnLvHWWeLs8GyV/EMw862uLI3c+GxVyDHWZcjZinwuBd3iW2pgxgIlksW/1vNJa4to+RvDOww==",
- "requires": {
- "argparse": "1.0.9",
- "esprima": "4.0.0"
- }
- },
- "jslint": {
- "version": "0.9.8",
- "resolved": "https://registry.npmjs.org/jslint/-/jslint-0.9.8.tgz",
- "integrity": "sha1-uSyoXKhtaoKXchCO6RnshJ3EsSk=",
- "optional": true,
- "requires": {
- "exit": "0.1.2",
- "glob": "4.5.3",
- "nopt": "3.0.6",
- "readable-stream": "1.0.34"
- },
- "dependencies": {
- "glob": {
- "version": "4.5.3",
- "resolved": "https://registry.npmjs.org/glob/-/glob-4.5.3.tgz",
- "integrity": "sha1-xstz0yJsHv7wTePFbQEvAzd+4V8=",
- "optional": true,
- "requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "2.0.10",
- "once": "1.4.0"
- }
- },
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
- "optional": true
- },
- "minimatch": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
- "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
- "optional": true,
- "requires": {
- "brace-expansion": "1.1.8"
- }
- },
- "readable-stream": {
- "version": "1.0.34",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.34.tgz",
- "integrity": "sha1-Elgg40vIQtLyqq+v5MKRbuMsFXw=",
- "optional": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "0.0.1",
- "string_decoder": "0.10.31"
- }
- },
- "string_decoder": {
- "version": "0.10.31",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
- "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=",
- "optional": true
- }
- }
- },
- "json-stable-stringify": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz",
- "integrity": "sha1-mnWdOcXy/1A/1TAGRu1EX4jE+a8=",
- "requires": {
- "jsonify": "0.0.0"
- }
- },
- "json-stringify-safe": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
- "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
- },
- "jsonify": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/jsonify/-/jsonify-0.0.0.tgz",
- "integrity": "sha1-LHS27kHZPKUbe1qu6PUDYx0lKnM="
- },
- "jsonpointer": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
- "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk="
- },
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "requires": {
- "is-buffer": "1.1.5"
- }
- },
- "lab": {
- "version": "6.2.0",
- "resolved": "https://registry.npmjs.org/lab/-/lab-6.2.0.tgz",
- "integrity": "sha1-RonomYv3V1YH0nNpgmjRXMWe3Qg=",
- "requires": {
- "bossy": "1.0.3",
- "diff": "2.2.3",
- "eslint": "1.5.1",
- "eslint-config-hapi": "3.0.2",
- "eslint-plugin-hapi": "1.2.2",
- "espree": "2.2.5",
- "handlebars": "4.0.10",
- "hoek": "2.16.3",
- "items": "1.1.1",
- "jslint": "0.9.8",
- "json-stringify-safe": "5.0.1",
- "mkdirp": "0.5.1",
- "source-map-support": "0.3.3"
- },
- "dependencies": {
- "cli-width": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
- "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0="
- },
- "doctrine": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.7.2.tgz",
- "integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=",
- "requires": {
- "esutils": "1.1.6",
- "isarray": "0.0.1"
- }
- },
- "eslint": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-1.5.1.tgz",
- "integrity": "sha1-u54WHwFh1xuF3EgWO/FKhvICVis=",
- "requires": {
- "chalk": "1.1.3",
- "concat-stream": "1.6.0",
- "debug": "2.6.8",
- "doctrine": "0.7.2",
- "escape-string-regexp": "1.0.5",
- "escope": "3.6.0",
- "espree": "2.2.5",
- "estraverse": "4.2.0",
- "estraverse-fb": "1.3.2",
- "file-entry-cache": "1.3.1",
- "glob": "5.0.15",
- "globals": "8.18.0",
- "handlebars": "4.0.10",
- "inquirer": "0.9.0",
- "is-my-json-valid": "2.16.1",
- "is-resolvable": "1.0.0",
- "js-yaml": "3.9.1",
- "lodash.clonedeep": "3.0.2",
- "lodash.merge": "3.3.2",
- "lodash.omit": "3.1.0",
- "minimatch": "2.0.10",
- "mkdirp": "0.5.1",
- "object-assign": "2.1.1",
- "optionator": "0.5.0",
- "path-is-absolute": "1.0.0",
- "path-is-inside": "1.0.2",
- "shelljs": "0.3.0",
- "strip-json-comments": "1.0.4",
- "text-table": "0.2.0",
- "to-double-quotes": "1.0.2",
- "to-single-quotes": "1.0.4",
- "user-home": "1.1.1",
- "xml-escape": "1.0.0"
- }
- },
- "espree": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/espree/-/espree-2.2.5.tgz",
- "integrity": "sha1-32kbkxCIlAKuspzAZnCMVmkLhUs="
- },
- "esutils": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz",
- "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U="
- },
- "fast-levenshtein": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz",
- "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk="
- },
- "glob": {
- "version": "5.0.15",
- "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz",
- "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=",
- "requires": {
- "inflight": "1.0.6",
- "inherits": "2.0.3",
- "minimatch": "2.0.10",
- "once": "1.4.0",
- "path-is-absolute": "1.0.0"
- }
- },
- "globals": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz",
- "integrity": "sha1-k9SmK9ysOM+vr8R9awNHaMsP/LQ="
- },
- "inquirer": {
- "version": "0.9.0",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.9.0.tgz",
- "integrity": "sha1-c2bjijMeYZBJWKzlstpKml9jZ5g=",
- "requires": {
- "ansi-regex": "2.1.1",
- "chalk": "1.1.3",
- "cli-width": "1.1.1",
- "figures": "1.7.0",
- "lodash": "3.10.1",
- "readline2": "0.1.1",
- "run-async": "0.1.0",
- "rx-lite": "2.5.2",
- "strip-ansi": "3.0.1",
- "through": "2.3.8"
- }
- },
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
- },
- "levn": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz",
- "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=",
- "requires": {
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2"
- }
- },
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
- },
- "minimatch": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
- "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
- "requires": {
- "brace-expansion": "1.1.8"
- }
- },
- "mute-stream": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.4.tgz",
- "integrity": "sha1-qSGZYKbV1dBGWXruUSUsZlX3F34="
- },
- "object-assign": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
- "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo="
- },
- "optionator": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz",
- "integrity": "sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=",
- "requires": {
- "deep-is": "0.1.3",
- "fast-levenshtein": "1.0.7",
- "levn": "0.2.5",
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2",
- "wordwrap": "0.0.3"
- }
- },
- "readline2": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/readline2/-/readline2-0.1.1.tgz",
- "integrity": "sha1-mUQ7pug7gw7zBRv9fcJBqCco1Wg=",
- "requires": {
- "mute-stream": "0.0.4",
- "strip-ansi": "2.0.1"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz",
- "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0="
- },
- "strip-ansi": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz",
- "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=",
- "requires": {
- "ansi-regex": "1.1.1"
- }
- }
- }
- },
- "rx-lite": {
- "version": "2.5.2",
- "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-2.5.2.tgz",
- "integrity": "sha1-X+9C1Nbna6tRmdIXEyfbcJ5Y5jQ="
- },
- "shelljs": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
- "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E="
- },
- "user-home": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
- "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA="
- },
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
- }
- }
- },
- "lazy-cache": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/lazy-cache/-/lazy-cache-1.0.4.tgz",
- "integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
- "optional": true
- },
- "levn": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
- "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
- "requires": {
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2"
- }
- },
- "lodash": {
- "version": "4.17.4",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.4.tgz",
- "integrity": "sha1-eCA6TRwyiuHYbcpkYONptX9AVa4="
- },
- "lodash._arraycopy": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._arraycopy/-/lodash._arraycopy-3.0.0.tgz",
- "integrity": "sha1-due3wfH7klRzdIeKVi7Qaj5Q9uE="
- },
- "lodash._arrayeach": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._arrayeach/-/lodash._arrayeach-3.0.0.tgz",
- "integrity": "sha1-urFWsqkNPxu9XGU0AzSeXlkz754="
- },
- "lodash._arraymap": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._arraymap/-/lodash._arraymap-3.0.0.tgz",
- "integrity": "sha1-Go/Q9MDfS2HeoHbXF83Jfwo8PmY="
- },
- "lodash._baseassign": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz",
- "integrity": "sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=",
- "requires": {
- "lodash._basecopy": "3.0.1",
- "lodash.keys": "3.1.2"
- }
- },
- "lodash._baseclone": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/lodash._baseclone/-/lodash._baseclone-3.3.0.tgz",
- "integrity": "sha1-MDUZv2OT/n5C802LYw73eU41Qrc=",
- "requires": {
- "lodash._arraycopy": "3.0.0",
- "lodash._arrayeach": "3.0.0",
- "lodash._baseassign": "3.2.0",
- "lodash._basefor": "3.0.3",
- "lodash.isarray": "3.0.4",
- "lodash.keys": "3.1.2"
- }
- },
- "lodash._basecopy": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz",
- "integrity": "sha1-jaDmqHbPNEwK2KVIghEd08XHyjY="
- },
- "lodash._basedifference": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash._basedifference/-/lodash._basedifference-3.0.3.tgz",
- "integrity": "sha1-8sIEKWwqeOArOJCBtu3KyTPPYpw=",
- "requires": {
- "lodash._baseindexof": "3.1.0",
- "lodash._cacheindexof": "3.0.2",
- "lodash._createcache": "3.1.2"
- }
- },
- "lodash._baseflatten": {
- "version": "3.1.4",
- "resolved": "https://registry.npmjs.org/lodash._baseflatten/-/lodash._baseflatten-3.1.4.tgz",
- "integrity": "sha1-B3D/gBMa9uNPO1EXlqe6UhTmX/c=",
- "requires": {
- "lodash.isarguments": "3.1.0",
- "lodash.isarray": "3.0.4"
- }
- },
- "lodash._basefor": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/lodash._basefor/-/lodash._basefor-3.0.3.tgz",
- "integrity": "sha1-dVC06SGO8J+tJDQ7YSAhx5tMIMI="
- },
- "lodash._baseindexof": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz",
- "integrity": "sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw="
- },
- "lodash._bindcallback": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz",
- "integrity": "sha1-5THCdkTPi1epnhftlbNcdIeJOS4="
- },
- "lodash._cacheindexof": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz",
- "integrity": "sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI="
- },
- "lodash._createassigner": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/lodash._createassigner/-/lodash._createassigner-3.1.1.tgz",
- "integrity": "sha1-g4pbri/aymOsIt7o4Z+k5taXCxE=",
- "requires": {
- "lodash._bindcallback": "3.0.1",
- "lodash._isiterateecall": "3.0.9",
- "lodash.restparam": "3.6.1"
- }
- },
- "lodash._createcache": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/lodash._createcache/-/lodash._createcache-3.1.2.tgz",
- "integrity": "sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=",
- "requires": {
- "lodash._getnative": "3.9.1"
- }
- },
- "lodash._getnative": {
- "version": "3.9.1",
- "resolved": "https://registry.npmjs.org/lodash._getnative/-/lodash._getnative-3.9.1.tgz",
- "integrity": "sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U="
- },
- "lodash._isiterateecall": {
- "version": "3.0.9",
- "resolved": "https://registry.npmjs.org/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz",
- "integrity": "sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw="
- },
- "lodash._pickbyarray": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/lodash._pickbyarray/-/lodash._pickbyarray-3.0.2.tgz",
- "integrity": "sha1-H4mNlgfrVgsOFnOEt3x8bRCKpMU="
- },
- "lodash._pickbycallback": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash._pickbycallback/-/lodash._pickbycallback-3.0.0.tgz",
- "integrity": "sha1-/2G5oBens699MObFPeKK+hm4dQo=",
- "requires": {
- "lodash._basefor": "3.0.3",
- "lodash.keysin": "3.0.8"
- }
- },
- "lodash.clonedeep": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-3.0.2.tgz",
- "integrity": "sha1-oKHkDYKl6on/WxR7hETtY9koJ9s=",
- "requires": {
- "lodash._baseclone": "3.3.0",
- "lodash._bindcallback": "3.0.1"
- }
- },
- "lodash.isarguments": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz",
- "integrity": "sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo="
- },
- "lodash.isarray": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/lodash.isarray/-/lodash.isarray-3.0.4.tgz",
- "integrity": "sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U="
- },
- "lodash.isplainobject": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-3.2.0.tgz",
- "integrity": "sha1-moI4rhayAEMpYM1zRlEtASP79MU=",
- "requires": {
- "lodash._basefor": "3.0.3",
- "lodash.isarguments": "3.1.0",
- "lodash.keysin": "3.0.8"
- }
- },
- "lodash.istypedarray": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz",
- "integrity": "sha1-yaR3SYYHUB2OhJTSg7h8OSgc72I="
- },
- "lodash.keys": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-3.1.2.tgz",
- "integrity": "sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=",
- "requires": {
- "lodash._getnative": "3.9.1",
- "lodash.isarguments": "3.1.0",
- "lodash.isarray": "3.0.4"
- }
- },
- "lodash.keysin": {
- "version": "3.0.8",
- "resolved": "https://registry.npmjs.org/lodash.keysin/-/lodash.keysin-3.0.8.tgz",
- "integrity": "sha1-IsRJPrvtsUJ5YqVLRFssinZ/tH8=",
- "requires": {
- "lodash.isarguments": "3.1.0",
- "lodash.isarray": "3.0.4"
- }
- },
- "lodash.merge": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-3.3.2.tgz",
- "integrity": "sha1-DZDZPtY3sYeEN7s+IWASYNev6ZQ=",
- "requires": {
- "lodash._arraycopy": "3.0.0",
- "lodash._arrayeach": "3.0.0",
- "lodash._createassigner": "3.1.1",
- "lodash._getnative": "3.9.1",
- "lodash.isarguments": "3.1.0",
- "lodash.isarray": "3.0.4",
- "lodash.isplainobject": "3.2.0",
- "lodash.istypedarray": "3.0.6",
- "lodash.keys": "3.1.2",
- "lodash.keysin": "3.0.8",
- "lodash.toplainobject": "3.0.0"
- }
- },
- "lodash.omit": {
- "version": "3.1.0",
- "resolved": "https://registry.npmjs.org/lodash.omit/-/lodash.omit-3.1.0.tgz",
- "integrity": "sha1-iX/jguZBPZrJfGH3jtHgV6AK+fM=",
- "requires": {
- "lodash._arraymap": "3.0.0",
- "lodash._basedifference": "3.0.3",
- "lodash._baseflatten": "3.1.4",
- "lodash._bindcallback": "3.0.1",
- "lodash._pickbyarray": "3.0.2",
- "lodash._pickbycallback": "3.0.0",
- "lodash.keysin": "3.0.8",
- "lodash.restparam": "3.6.1"
- }
- },
- "lodash.restparam": {
- "version": "3.6.1",
- "resolved": "https://registry.npmjs.org/lodash.restparam/-/lodash.restparam-3.6.1.tgz",
- "integrity": "sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU="
- },
- "lodash.toplainobject": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/lodash.toplainobject/-/lodash.toplainobject-3.0.0.tgz",
- "integrity": "sha1-KHkK2ULSk9eKpmOgfs9/UsoEGY0=",
- "requires": {
- "lodash._basecopy": "3.0.1",
- "lodash.keysin": "3.0.8"
- }
- },
- "longest": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/longest/-/longest-1.0.1.tgz",
- "integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc="
- },
- "minimatch": {
- "version": "3.0.4",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
- "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
- "requires": {
- "brace-expansion": "1.1.8"
- }
- },
- "minimist": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
- "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0="
- },
- "mkdirp": {
- "version": "0.5.1",
- "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
- "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
- "requires": {
- "minimist": "0.0.8"
- }
- },
- "ms": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
- "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
- },
- "mute-stream": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.5.tgz",
- "integrity": "sha1-j7+rsKmKJT0xhDMfno3rc3L6xsA="
- },
- "no-arrowception": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/no-arrowception/-/no-arrowception-1.0.0.tgz",
- "integrity": "sha1-W/PpXrnEG1c4SoBTM9qjtzTuMno="
- },
- "no-shadow-relaxed": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/no-shadow-relaxed/-/no-shadow-relaxed-1.0.1.tgz",
- "integrity": "sha1-z2zAFAL0IwuE/TvYoVZG3d8i7fI=",
- "requires": {
- "eslint": "0.24.1"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-1.1.1.tgz",
- "integrity": "sha1-QchHGUZGN15qGl0Qw8oFTvn8mA0="
- },
- "cli-width": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-1.1.1.tgz",
- "integrity": "sha1-pNKT72frt7iNSk1CwMzwDE0eNm0="
- },
- "doctrine": {
- "version": "0.6.4",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-0.6.4.tgz",
- "integrity": "sha1-gUKEkalC7xiwSSBW7aOADu5X1h0=",
- "requires": {
- "esutils": "1.1.6",
- "isarray": "0.0.1"
- }
- },
- "eslint": {
- "version": "0.24.1",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-0.24.1.tgz",
- "integrity": "sha1-VKUICYVbllVyHG8u5Xs1HtzigQE=",
- "requires": {
- "chalk": "1.1.3",
- "concat-stream": "1.6.0",
- "debug": "2.6.8",
- "doctrine": "0.6.4",
- "escape-string-regexp": "1.0.5",
- "escope": "3.6.0",
- "espree": "2.2.5",
- "estraverse": "4.2.0",
- "estraverse-fb": "1.3.2",
- "globals": "8.18.0",
- "inquirer": "0.8.5",
- "is-my-json-valid": "2.16.1",
- "js-yaml": "3.9.1",
- "minimatch": "2.0.10",
- "mkdirp": "0.5.1",
- "object-assign": "2.1.1",
- "optionator": "0.5.0",
- "path-is-absolute": "1.0.0",
- "strip-json-comments": "1.0.4",
- "text-table": "0.2.0",
- "user-home": "1.1.1",
- "xml-escape": "1.0.0"
- }
- },
- "espree": {
- "version": "2.2.5",
- "resolved": "https://registry.npmjs.org/espree/-/espree-2.2.5.tgz",
- "integrity": "sha1-32kbkxCIlAKuspzAZnCMVmkLhUs="
- },
- "esutils": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/esutils/-/esutils-1.1.6.tgz",
- "integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U="
- },
- "fast-levenshtein": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-1.0.7.tgz",
- "integrity": "sha1-AXjc3uAjuSkFGTrwlZ6KdjnP3Lk="
- },
- "globals": {
- "version": "8.18.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-8.18.0.tgz",
- "integrity": "sha1-k9SmK9ysOM+vr8R9awNHaMsP/LQ="
- },
- "inquirer": {
- "version": "0.8.5",
- "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.8.5.tgz",
- "integrity": "sha1-29dAz2yjtzEpamPOb22WGFHzNt8=",
- "requires": {
- "ansi-regex": "1.1.1",
- "chalk": "1.1.3",
- "cli-width": "1.1.1",
- "figures": "1.7.0",
- "lodash": "3.10.1",
- "readline2": "0.1.1",
- "rx": "2.5.3",
- "through": "2.3.8"
- }
- },
- "isarray": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
- "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
- },
- "levn": {
- "version": "0.2.5",
- "resolved": "https://registry.npmjs.org/levn/-/levn-0.2.5.tgz",
- "integrity": "sha1-uo0znQykphDjo/FFucr0iAcVUFQ=",
- "requires": {
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2"
- }
- },
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
- },
- "minimatch": {
- "version": "2.0.10",
- "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-2.0.10.tgz",
- "integrity": "sha1-jQh8OcazjAAbl/ynzm0OHoCvusc=",
- "requires": {
- "brace-expansion": "1.1.8"
- }
- },
- "mute-stream": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.4.tgz",
- "integrity": "sha1-qSGZYKbV1dBGWXruUSUsZlX3F34="
- },
- "object-assign": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-2.1.1.tgz",
- "integrity": "sha1-Q8NuXVaf+OSBbE76i+AtJpZ8GKo="
- },
- "optionator": {
- "version": "0.5.0",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.5.0.tgz",
- "integrity": "sha1-t1qJlaLUF98ltuTjhi9QqohlE2g=",
- "requires": {
- "deep-is": "0.1.3",
- "fast-levenshtein": "1.0.7",
- "levn": "0.2.5",
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2",
- "wordwrap": "0.0.3"
- }
- },
- "readline2": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/readline2/-/readline2-0.1.1.tgz",
- "integrity": "sha1-mUQ7pug7gw7zBRv9fcJBqCco1Wg=",
- "requires": {
- "mute-stream": "0.0.4",
- "strip-ansi": "2.0.1"
- }
- },
- "strip-ansi": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-2.0.1.tgz",
- "integrity": "sha1-32LBqpTtLxFOHQ8h/R1QSCt5pg4=",
- "requires": {
- "ansi-regex": "1.1.1"
- }
- },
- "user-home": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/user-home/-/user-home-1.1.1.tgz",
- "integrity": "sha1-K1viOjK2Onyd640PKNSFcko98ZA="
- },
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
- }
- }
- },
- "nock": {
- "version": "7.7.3",
- "resolved": "https://registry.npmjs.org/nock/-/nock-7.7.3.tgz",
- "integrity": "sha1-0GAJgKREPt9uULXtMxRgLLfMxIk=",
- "requires": {
- "chai": "3.5.0",
- "debug": "2.6.8",
- "deep-equal": "1.0.1",
- "json-stringify-safe": "5.0.1",
- "lodash": "3.10.1",
- "mkdirp": "0.5.1",
- "propagate": "0.3.1",
- "qs": "6.5.0"
- },
- "dependencies": {
- "lodash": {
- "version": "3.10.1",
- "resolved": "https://registry.npmjs.org/lodash/-/lodash-3.10.1.tgz",
- "integrity": "sha1-W/Rejkm6QYnhfUgnid/RW9FAt7Y="
- }
- }
- },
- "nodesecurity-npm-utils": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/nodesecurity-npm-utils/-/nodesecurity-npm-utils-5.0.0.tgz",
- "integrity": "sha1-Baow3jDKjIRcQEjpT9eOXgi1Xtk=",
- "dev": true
- },
- "nopt": {
- "version": "3.0.6",
- "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
- "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
- "optional": true,
- "requires": {
- "abbrev": "1.1.0"
- }
- },
- "number-is-nan": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz",
- "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
- },
- "object-assign": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
- "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
- },
- "once": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
- "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
- "requires": {
- "wrappy": "1.0.2"
- }
- },
- "onetime": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
- "integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k="
- },
- "optimist": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
- "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
- "requires": {
- "minimist": "0.0.8",
- "wordwrap": "0.0.3"
- },
- "dependencies": {
- "wordwrap": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
- "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc="
- }
- }
- },
- "optionator": {
- "version": "0.8.2",
- "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
- "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
- "requires": {
- "deep-is": "0.1.3",
- "fast-levenshtein": "2.0.6",
- "levn": "0.3.0",
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2",
- "wordwrap": "1.0.0"
- }
- },
- "os-homedir": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz",
- "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M="
- },
- "path-is-absolute": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.0.tgz",
- "integrity": "sha1-Jj2tpmqz8vsQv3+dJN2PPlcO+RI="
- },
- "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="
- },
- "pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw="
- },
- "pinkie": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz",
- "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA="
- },
- "pinkie-promise": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
- "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
- "requires": {
- "pinkie": "2.0.4"
- }
- },
- "pluralize": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
- "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU="
- },
- "prelude-ls": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
- "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ="
- },
- "process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
- },
- "progress": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
- "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74="
- },
- "propagate": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/propagate/-/propagate-0.3.1.tgz",
- "integrity": "sha1-46hEBKfs6CDda76p9tkk4xNa4Jw="
- },
- "qs": {
- "version": "6.5.0",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.0.tgz",
- "integrity": "sha512-fjVFjW9yhqMhVGwRExCXLhJKrLlkYSaxNWdyc9rmHlrVZbk35YHH312dFd7191uQeXkI3mKLZTIbSvIeFwFemg=="
- },
- "rc": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.1.6.tgz",
- "integrity": "sha1-Q2UbdrauU7XIAvEVH6P8OwWZack=",
- "dev": true,
- "requires": {
- "deep-extend": "0.4.1",
- "ini": "1.3.4",
- "minimist": "1.2.0",
- "strip-json-comments": "1.0.4"
- },
- "dependencies": {
- "deep-extend": {
- "version": "0.4.1",
- "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.4.1.tgz",
- "integrity": "sha1-7+QRPQgIX05vlod1mBD4B0aeIlM=",
- "dev": true
- },
- "ini": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.4.tgz",
- "integrity": "sha1-BTfLedr1m1mhpRff9wbIbsA5Fi4=",
- "dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
- "strip-json-comments": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
- "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E=",
- "dev": true
- }
- }
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "readline2": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/readline2/-/readline2-1.0.1.tgz",
- "integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
- "requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
- "mute-stream": "0.0.5"
- }
- },
- "repeat-string": {
- "version": "1.6.1",
- "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
- "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc="
- },
- "require-uncached": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
- "integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
- "requires": {
- "caller-path": "0.1.0",
- "resolve-from": "1.0.1"
- }
- },
- "resolve-from": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-1.0.1.tgz",
- "integrity": "sha1-Jsv+k10a7uq7Kbw/5a6wHpPUQiY="
- },
- "restore-cursor": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
- "integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
- "requires": {
- "exit-hook": "1.1.1",
- "onetime": "1.1.0"
- }
- },
- "right-align": {
- "version": "0.1.3",
- "resolved": "https://registry.npmjs.org/right-align/-/right-align-0.1.3.tgz",
- "integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
- "optional": true,
- "requires": {
- "align-text": "0.1.4"
- }
- },
- "rimraf": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.1.tgz",
- "integrity": "sha1-wjOOxkPfeht/5cVPqG9XQopV8z0=",
- "requires": {
- "glob": "7.1.2"
- }
- },
- "run-async": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/run-async/-/run-async-0.1.0.tgz",
- "integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
- "requires": {
- "once": "1.4.0"
- }
- },
- "rx": {
- "version": "2.5.3",
- "resolved": "https://registry.npmjs.org/rx/-/rx-2.5.3.tgz",
- "integrity": "sha1-Ia3H2A8CACr1Da6X/Z2/JIdV9WY="
- },
- "rx-lite": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
- "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI="
- },
- "safe-buffer": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
- },
- "semver": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.1.0.tgz",
- "integrity": "sha1-hfLPhVBGXE3wAM99hvawVBBqueU=",
- "dev": true
- },
- "shelljs": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.6.1.tgz",
- "integrity": "sha1-7GIRvtGSBEIIj+D3Cyg3Iy7SyKg="
- },
- "shrinkydink": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/shrinkydink/-/shrinkydink-1.0.1.tgz",
- "integrity": "sha1-3IbklqHndptP4GIYm89s18TxhIY=",
- "requires": {
- "minimist": "1.2.0"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- }
- }
- },
- "slice-ansi": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
- "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU="
- },
- "source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
- "requires": {
- "amdefine": "1.0.1"
- }
- },
- "source-map-support": {
- "version": "0.3.3",
- "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.3.3.tgz",
- "integrity": "sha1-NJAJd9W6PwfHdX7nLnO7GptTdU8=",
- "requires": {
- "source-map": "0.1.32"
- },
- "dependencies": {
- "source-map": {
- "version": "0.1.32",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.1.32.tgz",
- "integrity": "sha1-yLbBZ3l7pHQKjqMyUhYv8IWRsmY=",
- "requires": {
- "amdefine": "1.0.1"
- }
- }
- }
- },
- "sprintf-js": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
- "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw="
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
- "string-width": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
- "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
- "requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
- "strip-ansi": "3.0.1"
- }
- },
- "strip-ansi": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
- "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
- "requires": {
- "ansi-regex": "2.1.1"
- }
- },
- "strip-json-comments": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-1.0.4.tgz",
- "integrity": "sha1-HhX7ysl9Pumb8tc7TGVrCCu6+5E="
- },
- "subcommand": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/subcommand/-/subcommand-2.0.3.tgz",
- "integrity": "sha1-mz/Rp1PjxEHwBBDLRBMdhlX1LDI=",
- "dev": true,
- "requires": {
- "cliclopts": "1.1.1",
- "debug": "2.2.0",
- "minimist": "1.2.0",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "cliclopts": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/cliclopts/-/cliclopts-1.1.1.tgz",
- "integrity": "sha1-aUMcfLWvcjd0sNORG0w3USQxkQ8=",
- "dev": true
- },
- "debug": {
- "version": "2.2.0",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
- "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
- "dev": true,
- "requires": {
- "ms": "0.7.1"
- },
- "dependencies": {
- "ms": {
- "version": "0.7.1",
- "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
- "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg=",
- "dev": true
- }
- }
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
- "xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
- "dev": true
- }
- }
- },
- "table": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
- "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
- "requires": {
- "ajv": "4.11.8",
- "ajv-keywords": "1.5.1",
- "chalk": "1.1.3",
- "lodash": "4.17.4",
- "slice-ansi": "0.0.4",
- "string-width": "2.1.1"
- },
- "dependencies": {
- "ansi-regex": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
- },
- "is-fullwidth-code-point": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
- "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
- },
- "string-width": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
- "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
- }
- },
- "strip-ansi": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
- "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
- "requires": {
- "ansi-regex": "3.0.0"
- }
- }
- }
- },
- "text-table": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
- "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ="
- },
- "through": {
- "version": "2.3.8",
- "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
- "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU="
- },
- "to-double-quotes": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/to-double-quotes/-/to-double-quotes-1.0.2.tgz",
- "integrity": "sha1-u27TbHhjTD1k/YelGtWGDcWU7f0=",
- "requires": {
- "get-stdin": "3.0.2"
- }
- },
- "to-single-quotes": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/to-single-quotes/-/to-single-quotes-1.0.4.tgz",
- "integrity": "sha1-LuqBma8myhFx9TV8WeGS1WXuUxM=",
- "requires": {
- "get-stdin": "3.0.2"
- }
- },
- "tryit": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
- "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics="
- },
- "type-check": {
- "version": "0.3.2",
- "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
- "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
- "requires": {
- "prelude-ls": "1.1.2"
- }
- },
- "type-detect": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-1.0.0.tgz",
- "integrity": "sha1-diIXzAbbJY7EiQihKY6LlRIejqI="
- },
- "typedarray": {
- "version": "0.0.6",
- "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
- "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
- },
- "uglify-js": {
- "version": "2.8.29",
- "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-2.8.29.tgz",
- "integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
- "optional": true,
- "requires": {
- "source-map": "0.5.7",
- "uglify-to-browserify": "1.0.2",
- "yargs": "3.10.0"
- },
- "dependencies": {
- "source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
- "optional": true
- }
- }
- },
- "uglify-to-browserify": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
- "integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
- "optional": true
- },
- "user-home": {
+ "read-pkg-up": {
"version": "2.0.0",
- "resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
- "integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz",
+ "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
+ "dev": true,
"requires": {
- "os-homedir": "1.0.2"
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
}
},
- "util-deprecate": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
- "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
- },
- "window-size": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
- "integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
- "optional": true
- },
- "wordwrap": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
- "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
- },
- "wrappy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
- "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8="
- },
- "wreck": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/wreck/-/wreck-6.3.0.tgz",
- "integrity": "sha1-oTaXafB7u2LWo3gzanhx/Hc8dAs=",
+ "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": {
- "boom": "2.10.1",
- "hoek": "2.16.3"
- },
- "dependencies": {
- "boom": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
- "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
- "dev": true,
- "requires": {
- "hoek": "2.16.3"
- }
- },
- "hoek": {
- "version": "2.16.3",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
- "dev": true
- }
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
}
},
- "write": {
- "version": "0.2.1",
- "resolved": "https://registry.npmjs.org/write/-/write-0.2.1.tgz",
- "integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
+ "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": {
- "mkdirp": "0.5.1"
+ "ansi-regex": "^3.0.0"
}
},
- "xml-escape": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/xml-escape/-/xml-escape-1.0.0.tgz",
- "integrity": "sha1-AJY9aXsq3wwYXE4E5zF0upsojrI="
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
},
- "xtend": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
- "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68="
+ "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": "3.10.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.10.0.tgz",
- "integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
- "optional": true,
+ "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": "1.2.1",
- "cliui": "2.1.0",
- "decamelize": "1.2.0",
- "window-size": "0.1.0"
+ "camelcase": "^4.1.0"
}
}
}
@@ -15259,8 +11680,9 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.1.tgz",
"integrity": "sha1-mSms32KPwsQQmN6rgqxYDPFJquQ=",
+ "dev": true,
"requires": {
- "boolbase": "1.0.0"
+ "boolbase": "~1.0.0"
}
},
"nugget": {
@@ -15269,21 +11691,15 @@
"integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=",
"dev": true,
"requires": {
- "debug": "2.6.9",
- "minimist": "1.2.0",
- "pretty-bytes": "1.0.4",
- "progress-stream": "1.2.0",
- "request": "2.82.0",
- "single-line-log": "1.1.2",
+ "debug": "^2.1.3",
+ "minimist": "^1.1.0",
+ "pretty-bytes": "^1.0.2",
+ "progress-stream": "^1.1.0",
+ "request": "^2.45.0",
+ "single-line-log": "^1.1.2",
"throttleit": "0.0.2"
},
"dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
- },
"throttleit": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
@@ -15304,9 +11720,9 @@
"integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0="
},
"nwmatcher": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.2.tgz",
- "integrity": "sha512-QMkCGQFYp5p+zwU3INntLmz1HMfSx9dMVJMYKmE1yuSf/22Wjo6VPFa405mCLUuQn9lbQvH2DZN9lt10ZNvtAg=="
+ "version": "1.4.4",
+ "resolved": "https://registry.npmjs.org/nwmatcher/-/nwmatcher-1.4.4.tgz",
+ "integrity": "sha512-3iuY4N5dhgMpCUrOVnuAdGrgxVqV2cJpM+XNccjR2DKOB1RUP0aA+wGXEiNziG/UKboFyGBIoKOaNlJxx8bciQ=="
},
"oauth-sign": {
"version": "0.8.2",
@@ -15318,6 +11734,37 @@
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
},
+ "object-copy": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz",
+ "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=",
+ "dev": true,
+ "requires": {
+ "copy-descriptor": "^0.1.0",
+ "define-property": "^0.2.5",
+ "kind-of": "^3.0.3"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
"object-is": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/object-is/-/object-is-1.0.1.tgz",
@@ -15330,15 +11777,25 @@
"integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY=",
"dev": true
},
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
"object.assign": {
- "version": "4.0.4",
- "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.0.4.tgz",
- "integrity": "sha1-scnMBE7xuf5jYG/BQau7MuFHMMw=",
+ "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",
- "object-keys": "1.0.11"
+ "define-properties": "^1.1.2",
+ "function-bind": "^1.1.1",
+ "has-symbols": "^1.0.0",
+ "object-keys": "^1.0.11"
},
"dependencies": {
"object-keys": {
@@ -15355,27 +11812,10 @@
"integrity": "sha1-On+GgzS0B96gbaFtiNXNKeQ1/s8=",
"dev": true,
"requires": {
- "array-each": "1.0.1",
- "array-slice": "1.0.0",
- "for-own": "1.0.0",
- "isobject": "3.0.1"
- },
- "dependencies": {
- "for-own": {
- "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.2"
- }
- },
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- }
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
}
},
"object.entries": {
@@ -15384,10 +11824,20 @@
"integrity": "sha1-G/mk3SKI9bM/Opk9JXZh8F0WGl8=",
"dev": true,
"requires": {
- "define-properties": "1.1.2",
- "es-abstract": "1.8.2",
- "function-bind": "1.1.1",
- "has": "1.0.1"
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.6.1",
+ "function-bind": "^1.1.0",
+ "has": "^1.0.1"
+ }
+ },
+ "object.map": {
+ "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"
}
},
"object.omit": {
@@ -15396,8 +11846,19 @@
"integrity": "sha1-Gpx0SCnznbuFjHbKNXmuKlTr0fo=",
"dev": true,
"requires": {
- "for-own": "0.1.5",
- "is-extendable": "0.1.1"
+ "for-own": "^0.1.4",
+ "is-extendable": "^0.1.1"
+ },
+ "dependencies": {
+ "for-own": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/for-own/-/for-own-0.1.5.tgz",
+ "integrity": "sha1-UmXGgaTylNq78XyVCbZ2OqhFEM4=",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ }
}
},
"object.pick": {
@@ -15406,15 +11867,7 @@
"integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
"dev": true,
"requires": {
- "isobject": "3.0.1"
- },
- "dependencies": {
- "isobject": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
- "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
- "dev": true
- }
+ "isobject": "^3.0.1"
}
},
"object.values": {
@@ -15423,22 +11876,23 @@
"integrity": "sha1-5STaCbT2b/Bd9FdUbscqyZ8TBpo=",
"dev": true,
"requires": {
- "define-properties": "1.1.2",
- "es-abstract": "1.8.2",
- "function-bind": "1.1.1",
- "has": "1.0.1"
+ "define-properties": "^1.1.2",
+ "es-abstract": "^1.6.1",
+ "function-bind": "^1.1.0",
+ "has": "^1.0.1"
}
},
"obuf": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.1.tgz",
- "integrity": "sha1-EEEktsYCxnlogaBCVB0220OlJk4=",
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz",
+ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==",
"dev": true
},
"on-finished": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
"integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "dev": true,
"requires": {
"ee-first": "1.1.1"
}
@@ -15446,14 +11900,15 @@
"on-headers": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.1.tgz",
- "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c="
+ "integrity": "sha1-ko9dD0cNSTQmUepnlLCFfBAGk/c=",
+ "dev": true
},
"once": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
"requires": {
- "wrappy": "1.0.2"
+ "wrappy": "1"
}
},
"onetime": {
@@ -15461,7 +11916,123 @@
"resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
"integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
"requires": {
- "mimic-fn": "1.1.0"
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "opencollective": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/opencollective/-/opencollective-1.0.3.tgz",
+ "integrity": "sha1-ruY3K8KBRFg2kMPKja7PwSDdDvE=",
+ "dev": true,
+ "requires": {
+ "babel-polyfill": "6.23.0",
+ "chalk": "1.1.3",
+ "inquirer": "3.0.6",
+ "minimist": "1.2.0",
+ "node-fetch": "1.6.3",
+ "opn": "4.0.2"
+ },
+ "dependencies": {
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "babel-polyfill": {
+ "version": "6.23.0",
+ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.23.0.tgz",
+ "integrity": "sha1-g2TKYt+Or7gwSZ9pkXdGbDsDSZ0=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.22.0",
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.10.0"
+ }
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "inquirer": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz",
+ "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^1.1.0",
+ "chalk": "^1.0.0",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^2.0.1",
+ "figures": "^2.0.0",
+ "lodash": "^4.3.0",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rx": "^4.1.0",
+ "string-width": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "through": "^2.3.6"
+ }
+ },
+ "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
+ },
+ "node-fetch": {
+ "version": "1.6.3",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-1.6.3.tgz",
+ "integrity": "sha1-3CNO3WSJmC1Y6PDbT2lQKavNjAQ=",
+ "dev": true,
+ "requires": {
+ "encoding": "^0.1.11",
+ "is-stream": "^1.0.1"
+ }
+ },
+ "regenerator-runtime": {
+ "version": "0.10.5",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.10.5.tgz",
+ "integrity": "sha1-M2w+/BIgrc7dosn6tntaeVWjNlg=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ }
}
},
"opn": {
@@ -15470,8 +12041,8 @@
"integrity": "sha1-erwi5kTf9jsKltWrfyeQwPAavJU=",
"dev": true,
"requires": {
- "object-assign": "4.1.1",
- "pinkie-promise": "2.0.1"
+ "object-assign": "^4.0.1",
+ "pinkie-promise": "^2.0.0"
}
},
"optimist": {
@@ -15480,10 +12051,16 @@
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
"dev": true,
"requires": {
- "minimist": "0.0.8",
- "wordwrap": "0.0.3"
+ "minimist": "~0.0.1",
+ "wordwrap": "~0.0.2"
},
"dependencies": {
+ "minimist": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz",
+ "integrity": "sha1-3j+YVD2/lggr5IrRoMfNqDYwHc8=",
+ "dev": true
+ },
"wordwrap": {
"version": "0.0.3",
"resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz",
@@ -15497,12 +12074,12 @@
"resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
"integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
"requires": {
- "deep-is": "0.1.3",
- "fast-levenshtein": "2.0.6",
- "levn": "0.3.0",
- "prelude-ls": "1.1.2",
- "type-check": "0.3.2",
- "wordwrap": "1.0.0"
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
}
},
"orchestrator": {
@@ -15511,9 +12088,9 @@
"integrity": "sha1-FOfp4nZPcxX7rBhOUGx6pt+UrX4=",
"dev": true,
"requires": {
- "end-of-stream": "0.1.5",
- "sequencify": "0.0.7",
- "stream-consume": "0.1.0"
+ "end-of-stream": "~0.1.5",
+ "sequencify": "~0.0.7",
+ "stream-consume": "~0.1.0"
},
"dependencies": {
"end-of-stream": {
@@ -15522,7 +12099,7 @@
"integrity": "sha1-jhdyBsPICDfYVjLouTWd/osvbq8=",
"dev": true,
"requires": {
- "once": "1.3.3"
+ "once": "~1.3.0"
}
},
"once": {
@@ -15531,7 +12108,7 @@
"integrity": "sha1-suJhVXzkwxTsgwTz+oJmPkKXyiA=",
"dev": true,
"requires": {
- "wrappy": "1.0.2"
+ "wrappy": "1"
}
}
}
@@ -15543,30 +12120,12 @@
"dev": true
},
"original": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/original/-/original-1.0.0.tgz",
- "integrity": "sha1-kUf5P6FpbQS+YeAb1QuurKZWvTs=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/original/-/original-1.0.1.tgz",
+ "integrity": "sha512-IEvtB5vM5ULvwnqMxWBLxkS13JIEXbakizMSo3yoPNPCIWzg8TG3Usn/UhXoZFM/m+FuEA20KdzPSFq/0rS+UA==",
"dev": true,
"requires": {
- "url-parse": "1.0.5"
- },
- "dependencies": {
- "requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
- "dev": true
- },
- "url-parse": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.0.5.tgz",
- "integrity": "sha1-CFSGBCKv3P7+tsllxmLUgAFpkns=",
- "dev": true,
- "requires": {
- "querystringify": "0.0.4",
- "requires-port": "1.0.0"
- }
- }
+ "url-parse": "~1.4.0"
}
},
"os-browserify": {
@@ -15585,7 +12144,7 @@
"resolved": "https://registry.npmjs.org/os-locale/-/os-locale-1.4.0.tgz",
"integrity": "sha1-IPnxeuKe00XoveWDsT0gCYA8FNk=",
"requires": {
- "lcid": "1.0.0"
+ "lcid": "^1.0.0"
}
},
"os-shim": {
@@ -15600,13 +12159,13 @@
"integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ="
},
"osenv": {
- "version": "0.1.4",
- "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.4.tgz",
- "integrity": "sha1-Qv5tWVPfBsgGS+bxdsPQWqqjRkQ=",
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/osenv/-/osenv-0.1.5.tgz",
+ "integrity": "sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==",
"dev": true,
"requires": {
- "os-homedir": "1.0.2",
- "os-tmpdir": "1.0.2"
+ "os-homedir": "^1.0.0",
+ "os-tmpdir": "^1.0.0"
}
},
"p-finally": {
@@ -15616,82 +12175,42 @@
"dev": true
},
"p-limit": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.1.0.tgz",
- "integrity": "sha1-sH/y2aXYi+yAYDWJWiurZqJ5iLw="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.2.0.tgz",
+ "integrity": "sha512-Y/OtIaXtUPr4/YpMv1pCL5L5ed0rumAaAeBSj12F+bSlMdys7i8oQF/GUJmfpTS/QoaRrS/k6pma29haJpsMng==",
+ "requires": {
+ "p-try": "^1.0.0"
+ }
},
"p-locate": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
"integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
"requires": {
- "p-limit": "1.1.0"
- }
- },
- "p-map": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
- "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
- "dev": true
- },
- "pac-proxy-agent": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-2.0.0.tgz",
- "integrity": "sha512-t57UiJpi5mFLTvjheC1SNSwIhml3+ElNOj69iRrydtQXZJr8VIFYSDtyPi/3ZysA62kD2dmww6pDlzk0VaONZg==",
- "requires": {
- "agent-base": "2.1.1",
- "debug": "2.6.9",
- "get-uri": "2.0.1",
- "http-proxy-agent": "1.0.0",
- "https-proxy-agent": "1.0.0",
- "pac-resolver": "3.0.0",
- "raw-body": "2.3.2",
- "socks-proxy-agent": "3.0.1"
- },
- "dependencies": {
- "socks-proxy-agent": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-3.0.1.tgz",
- "integrity": "sha512-ZwEDymm204mTzvdqyUqOdovVr2YRd2NYskrYrF2LXyZ9qDiMAoFESGK8CRphiO7rtbo2Y757k2Nia3x2hGtalA==",
- "requires": {
- "agent-base": "4.1.2",
- "socks": "1.1.10"
- },
- "dependencies": {
- "agent-base": {
- "version": "4.1.2",
- "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.1.2.tgz",
- "integrity": "sha512-VE6QoEdaugY86BohRtfGmTDabxdU5sCKOkbcPA6PXKJsRzEi/7A3RCTxJal1ft/4qSfPht5/iQLhMh/wzSkkNw==",
- "requires": {
- "es6-promisify": "5.0.0"
- }
- }
- }
- }
- }
- },
- "pac-resolver": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-3.0.0.tgz",
- "integrity": "sha512-tcc38bsjuE3XZ5+4vP96OfhOugrX+JcnpUbhfuc4LuXBLQhoTthOstZeoQJBDnQUDYzYmdImKsbz0xSl1/9qeA==",
- "requires": {
- "co": "4.6.0",
- "degenerator": "1.0.4",
- "ip": "1.1.5",
- "netmask": "1.0.6",
- "thunkify": "2.1.2"
+ "p-limit": "^1.1.0"
}
},
+ "p-map": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/p-map/-/p-map-1.2.0.tgz",
+ "integrity": "sha512-r6zKACMNhjPJMTl8KcFH4li//gkrXWfbD6feV8l6doRHlzljFWGJ2AP6iKaCJXyZmAUMOPtvbW7EXkbWO/pLEA==",
+ "dev": true
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M="
+ },
"package-json": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/package-json/-/package-json-4.0.1.tgz",
"integrity": "sha1-iGmgQBJTZhxMTKPabCEh7VVfXu0=",
"dev": true,
"requires": {
- "got": "6.7.1",
- "registry-auth-token": "3.3.1",
- "registry-url": "3.1.0",
- "semver": "5.4.1"
+ "got": "^6.7.1",
+ "registry-auth-token": "^3.0.1",
+ "registry-url": "^3.0.3",
+ "semver": "^5.1.0"
}
},
"package-json-versionify": {
@@ -15699,7 +12218,7 @@
"resolved": "https://registry.npmjs.org/package-json-versionify/-/package-json-versionify-1.0.4.tgz",
"integrity": "sha1-WGBYepRIc6a35tJujlH/siMVvxc=",
"requires": {
- "browserify-package-json": "1.0.1"
+ "browserify-package-json": "^1.0.0"
}
},
"pako": {
@@ -15714,54 +12233,22 @@
"integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=",
"dev": true,
"requires": {
- "cyclist": "0.2.2",
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "cyclist": "~0.2.2",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.1.5"
}
},
"parse-asn1": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.0.tgz",
- "integrity": "sha1-N8T5t+06tlx0gXtfJICTf7+XxxI=",
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.1.tgz",
+ "integrity": "sha512-KPx7flKXg775zZpnp9SxJlz00gTd4BmJ2yJufSc44gMCRrRQ7NSzAcSJQfifuOLgW6bEi+ftrALtsgALeB2Adw==",
"dev": true,
"requires": {
- "asn1.js": "4.9.1",
- "browserify-aes": "1.0.8",
- "create-hash": "1.1.3",
- "evp_bytestokey": "1.0.3",
- "pbkdf2": "3.0.14"
+ "asn1.js": "^4.0.0",
+ "browserify-aes": "^1.0.0",
+ "create-hash": "^1.1.0",
+ "evp_bytestokey": "^1.0.0",
+ "pbkdf2": "^3.0.3"
}
},
"parse-author": {
@@ -15770,7 +12257,7 @@
"integrity": "sha1-00YL8d3Q367tQtp1QkLmX7aEqB8=",
"optional": true,
"requires": {
- "author-regex": "1.0.0"
+ "author-regex": "^1.0.0"
}
},
"parse-bmfont-ascii": {
@@ -15788,8 +12275,8 @@
"resolved": "https://registry.npmjs.org/parse-bmfont-xml/-/parse-bmfont-xml-1.1.3.tgz",
"integrity": "sha1-1rZqNxr9OcUAfZ8O6yYqTyzOe3w=",
"requires": {
- "xml-parse-from-string": "1.0.1",
- "xml2js": "0.4.19"
+ "xml-parse-from-string": "^1.0.0",
+ "xml2js": "^0.4.5"
}
},
"parse-cache-control": {
@@ -15803,18 +12290,26 @@
"integrity": "sha1-e3SLlag/A/FqlPU15S1/PZRlhhk=",
"dev": true,
"requires": {
- "color-convert": "0.5.3"
+ "color-convert": "~0.5.0"
+ },
+ "dependencies": {
+ "color-convert": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-0.5.3.tgz",
+ "integrity": "sha1-vbbGnOZg+t/+CwAHzER+G59ygr0=",
+ "dev": true
+ }
}
},
"parse-filepath": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.1.tgz",
- "integrity": "sha1-FZ1hVdQ5BNFsEO9piRHaHpGWm3M=",
+ "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": "0.2.6",
- "map-cache": "0.2.2",
- "path-root": "0.1.1"
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
}
},
"parse-glob": {
@@ -15823,10 +12318,27 @@
"integrity": "sha1-ssN2z7EfNVE7rdFz7wu246OIORw=",
"dev": true,
"requires": {
- "glob-base": "0.3.0",
- "is-dotfile": "1.0.3",
- "is-extglob": "1.0.0",
- "is-glob": "2.0.1"
+ "glob-base": "^0.3.0",
+ "is-dotfile": "^1.0.0",
+ "is-extglob": "^1.0.0",
+ "is-glob": "^2.0.0"
+ },
+ "dependencies": {
+ "is-extglob": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz",
+ "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=",
+ "dev": true
+ },
+ "is-glob": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz",
+ "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^1.0.0"
+ }
+ }
}
},
"parse-headers": {
@@ -15834,7 +12346,7 @@
"resolved": "https://registry.npmjs.org/parse-headers/-/parse-headers-2.0.1.tgz",
"integrity": "sha1-aug6eqJanZtwCswoaYzR8e1+lTY=",
"requires": {
- "for-each": "0.3.2",
+ "for-each": "^0.3.2",
"trim": "0.0.1"
}
},
@@ -15843,7 +12355,7 @@
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
"integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
"requires": {
- "error-ex": "1.3.1"
+ "error-ex": "^1.2.0"
}
},
"parse-passwd": {
@@ -15853,51 +12365,38 @@
"dev": true
},
"parse-torrent": {
- "version": "5.8.3",
- "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-5.8.3.tgz",
- "integrity": "sha1-+V7yMwEjlgneQGeUrZ+VihvKG2w=",
- "requires": {
- "blob-to-buffer": "1.2.6",
- "get-stdin": "5.0.1",
- "magnet-uri": "5.1.7",
- "parse-torrent-file": "4.0.3",
- "simple-get": "2.7.0"
- },
- "dependencies": {
- "simple-get": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
- "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
- "requires": {
- "decompress-response": "3.3.0",
- "once": "1.4.0",
- "simple-concat": "1.0.0"
- }
- }
- }
- },
- "parse-torrent-file": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/parse-torrent-file/-/parse-torrent-file-4.0.3.tgz",
- "integrity": "sha512-Ob1IK1FC165T6dslPBdgxfbQIZI1+QE0sqOfoB+YS/XfDda2Xa2xDZmE0vcGD4ei5Lw6FQYNhsHX9RzZzHwFtQ==",
+ "version": "5.9.1",
+ "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-5.9.1.tgz",
+ "integrity": "sha512-yy7UTSmliOT/7Yl+P4hwwW2W7PbCTAMcD0lasaVG+k4/2laj42YWzLm468bLFGDoFPIb29g3BuwBcA3gLopKww==",
"requires": {
- "bencode": "1.0.0",
- "simple-sha1": "2.1.0",
- "uniq": "1.0.1"
+ "bencode": "^2.0.0",
+ "blob-to-buffer": "^1.2.6",
+ "get-stdin": "^6.0.0",
+ "magnet-uri": "^5.1.3",
+ "simple-get": "^2.0.0",
+ "simple-sha1": "^2.0.0",
+ "uniq": "^1.0.1"
}
},
"parse5": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.2.tgz",
- "integrity": "sha1-Be/1fw70V3+xRKefi5qWemzERRA=",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
+ "integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
"requires": {
- "@types/node": "6.0.88"
+ "@types/node": "*"
}
},
"parseurl": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
- "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
+ "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M=",
+ "dev": true
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
},
"path-browserify": {
"version": "0.0.0",
@@ -15944,7 +12443,7 @@
"integrity": "sha1-mkpoFMrBwM1zNgqV8yCDyOpHRbc=",
"dev": true,
"requires": {
- "path-root-regex": "0.1.2"
+ "path-root-regex": "^0.1.0"
}
},
"path-root-regex": {
@@ -15956,29 +12455,29 @@
"path-to-regexp": {
"version": "0.1.7",
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
- "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
+ "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=",
+ "dev": true
},
"path-type": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-1.1.0.tgz",
"integrity": "sha1-WcRPfuSR2nBNpBXaWkBwuk+P5EE=",
"requires": {
- "graceful-fs": "4.1.11",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1"
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
}
},
"pbkdf2": {
- "version": "3.0.14",
- "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.14.tgz",
- "integrity": "sha512-gjsZW9O34fm0R7PaLHRJmLLVfSoesxztjPjE9o6R+qtVJij90ltg1joIovN9GKrRW3t1PzhDDG3UMEMFfZ+1wA==",
- "dev": true,
+ "version": "3.0.16",
+ "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.16.tgz",
+ "integrity": "sha512-y4CXP3thSxqf7c0qmOF+9UeOTrifiVTIM+u7NWlq+PRsHbr7r7dpCmvzrZxa96JJUNi0Y5w9VqG5ZNeCVMoDcA==",
"requires": {
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
- "ripemd160": "2.0.1",
- "safe-buffer": "5.1.1",
- "sha.js": "2.4.9"
+ "create-hash": "^1.1.2",
+ "create-hmac": "^1.1.4",
+ "ripemd160": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "sha.js": "^2.4.8"
}
},
"pend": {
@@ -15997,7 +12496,7 @@
"resolved": "https://registry.npmjs.org/piece-length/-/piece-length-1.0.0.tgz",
"integrity": "sha1-TbcWcVf9af7xTK9yYs058YmyRQg=",
"requires": {
- "closest-to": "2.0.0"
+ "closest-to": "~2.0.0"
}
},
"pify": {
@@ -16015,7 +12514,7 @@
"resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
"integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=",
"requires": {
- "pinkie": "2.0.4"
+ "pinkie": "^2.0.0"
}
},
"pixelmatch": {
@@ -16023,31 +12522,47 @@
"resolved": "https://registry.npmjs.org/pixelmatch/-/pixelmatch-4.0.2.tgz",
"integrity": "sha1-j0fc7FARtHe2fbA8JDvB8wheiFQ=",
"requires": {
- "pngjs": "3.3.0"
+ "pngjs": "^3.0.0"
}
},
"pkg-conf": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.0.0.tgz",
- "integrity": "sha1-BxyHZQQDvM+5xif1h1G/5HwGcnk=",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pkg-conf/-/pkg-conf-2.1.0.tgz",
+ "integrity": "sha1-ISZRTKbyq/69FoWW3xi6V4Z/AFg=",
"dev": true,
"requires": {
- "find-up": "2.1.0",
- "load-json-file": "2.0.0"
+ "find-up": "^2.0.0",
+ "load-json-file": "^4.0.0"
},
"dependencies": {
"load-json-file": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz",
- "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "parse-json": "2.2.0",
- "pify": "2.3.0",
- "strip-bom": "3.0.0"
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
}
},
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ },
"strip-bom": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
@@ -16062,9 +12577,9 @@
"integrity": "sha1-VX7yLXPaPIg3EHdmxS6tq94pj+Q=",
"dev": true,
"requires": {
- "debug-log": "1.0.1",
- "find-root": "1.1.0",
- "xtend": "4.0.1"
+ "debug-log": "^1.0.0",
+ "find-root": "^1.0.0",
+ "xtend": "^4.0.1"
}
},
"pkg-dir": {
@@ -16072,7 +12587,7 @@
"resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz",
"integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=",
"requires": {
- "find-up": "2.1.0"
+ "find-up": "^2.1.0"
}
},
"pkg-up": {
@@ -16081,7 +12596,7 @@
"integrity": "sha1-Pgj7RhUlxEIWJKM7n35tCvWwWiY=",
"dev": true,
"requires": {
- "find-up": "1.1.2"
+ "find-up": "^1.0.0"
},
"dependencies": {
"find-up": {
@@ -16090,8 +12605,8 @@
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
"dev": true,
"requires": {
- "path-exists": "2.1.0",
- "pinkie-promise": "2.0.1"
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
}
},
"path-exists": {
@@ -16100,7 +12615,7 @@
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
"dev": true,
"requires": {
- "pinkie-promise": "2.0.1"
+ "pinkie-promise": "^2.0.0"
}
}
}
@@ -16113,7 +12628,7 @@
"requires": {
"base64-js": "1.2.0",
"xmlbuilder": "8.2.2",
- "xmldom": "0.1.27"
+ "xmldom": "0.1.x"
},
"dependencies": {
"base64-js": {
@@ -16121,82 +12636,29 @@
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.2.0.tgz",
"integrity": "sha1-o5mS1yNYSBGYK+XikLtqU9hnAPE=",
"dev": true
+ },
+ "xmlbuilder": {
+ "version": "8.2.2",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz",
+ "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=",
+ "dev": true
}
}
},
"pluralize": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
- "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
- "dev": true
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-7.0.0.tgz",
+ "integrity": "sha512-ARhBOdzS3e41FbkW/XWrTEtukqqLoK5+Z/4UeDaLuSW+39JPeFgs4gCGqsrJHVZX0fUrx//4OF0K1CUGwlIFow=="
},
"pn": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/pn/-/pn-1.0.0.tgz",
- "integrity": "sha1-HPWjCw2AbNGPiPxBprXUrWFbO6k="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA=="
},
"pngjs": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.0.tgz",
- "integrity": "sha1-H1cwwYnJSTO4G+2iqy+OKFUmOo8="
- },
- "popsicle": {
- "version": "6.2.2",
- "resolved": "https://registry.npmjs.org/popsicle/-/popsicle-6.2.2.tgz",
- "integrity": "sha1-4nPIvUgYH3OlmxmeKl4ltpKz4jc=",
- "requires": {
- "any-promise": "1.3.0",
- "arrify": "1.0.1",
- "concat-stream": "1.6.0",
- "form-data": "0.2.0",
- "make-error-cause": "1.2.2",
- "throwback": "1.1.1",
- "tough-cookie": "2.3.3",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "async": {
- "version": "0.9.2",
- "resolved": "https://registry.npmjs.org/async/-/async-0.9.2.tgz",
- "integrity": "sha1-rqdNXmHB+JlhO/ZL2mbUx48v0X0="
- },
- "combined-stream": {
- "version": "0.0.7",
- "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-0.0.7.tgz",
- "integrity": "sha1-ATfmV7qlp1QcV6w3rF/AfXO03B8=",
- "requires": {
- "delayed-stream": "0.0.5"
- }
- },
- "delayed-stream": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-0.0.5.tgz",
- "integrity": "sha1-1LH0OpPoKW3+AmlPRoC8N6MTxz8="
- },
- "form-data": {
- "version": "0.2.0",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-0.2.0.tgz",
- "integrity": "sha1-Jvi8JtpkQOKZy9z7aQNcT3em5GY=",
- "requires": {
- "async": "0.9.2",
- "combined-stream": "0.0.7",
- "mime-types": "2.0.14"
- }
- },
- "mime-db": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.12.0.tgz",
- "integrity": "sha1-PQxjGA9FjrENMlqqN9fFiuMS6dc="
- },
- "mime-types": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.0.14.tgz",
- "integrity": "sha1-MQ4VnbI+B3+Lsit0jav6SVcUCqY=",
- "requires": {
- "mime-db": "1.12.0"
- }
- }
- }
+ "version": "3.3.3",
+ "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-3.3.3.tgz",
+ "integrity": "sha512-1n3Z4p3IOxArEs1VRXnZ/RXdfEniAUS9jb68g58FIXMNkPJeZd+Qh4Uq7/e0LVxAQGos1eIUrqrt4FpjdnEd+Q=="
},
"portfinder": {
"version": "1.0.13",
@@ -16204,9 +12666,9 @@
"integrity": "sha1-uzLs2HwnEErm7kS1o8y/Drsa7ek=",
"dev": true,
"requires": {
- "async": "1.5.2",
- "debug": "2.6.9",
- "mkdirp": "0.5.1"
+ "async": "^1.5.2",
+ "debug": "^2.2.0",
+ "mkdirp": "0.5.x"
},
"dependencies": {
"async": {
@@ -16217,114 +12679,154 @@
}
}
},
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
"postcss": {
- "version": "4.1.16",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-4.1.16.tgz",
- "integrity": "sha1-TESbTIr53zyvbTf44eV10DYXWNw=",
+ "version": "5.2.18",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-5.2.18.tgz",
+ "integrity": "sha512-zrUjRRe1bpXKsX1qAJNJjqZViErVuyEkMTRrwu4ud4sbTtIBRmtaYDrHmcGgmrbsW3MHfmtIf+vJumgQn+PrXg==",
"dev": true,
"requires": {
- "es6-promise": "2.3.0",
- "js-base64": "2.1.9",
- "source-map": "0.4.4"
+ "chalk": "^1.1.3",
+ "js-base64": "^2.1.9",
+ "source-map": "^0.5.6",
+ "supports-color": "^3.2.3"
},
"dependencies": {
- "es6-promise": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
- "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "has-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
+ "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
"dev": true
},
"source-map": {
- "version": "0.4.4",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
- "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "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": {
- "amdefine": "1.0.1"
+ "has-flag": "^1.0.0"
}
}
}
},
"postcss-calc": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-4.1.0.tgz",
- "integrity": "sha1-vuf/ySjHmGmZ7vF7LdiXDIk31HI=",
+ "version": "5.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-5.3.1.tgz",
+ "integrity": "sha1-d7rnypKK2FcW4v2kLyYb98HWW14=",
"dev": true,
"requires": {
- "postcss": "4.1.16",
- "postcss-message-helpers": "2.0.0",
- "reduce-css-calc": "1.3.0"
+ "postcss": "^5.0.2",
+ "postcss-message-helpers": "^2.0.0",
+ "reduce-css-calc": "^1.2.6"
}
},
"postcss-colormin": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-1.2.7.tgz",
- "integrity": "sha1-63Pb6DgE6pGYNWsTL2+Z9GAP1lQ=",
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-2.2.2.tgz",
+ "integrity": "sha1-ZjFBfV8OkJo9fsJrJMio0eT5bks=",
"dev": true,
"requires": {
- "color": "0.10.1",
- "colormin": "1.1.2",
- "postcss": "4.1.16",
- "reduce-function-call": "1.0.2"
+ "colormin": "^1.0.5",
+ "postcss": "^5.0.13",
+ "postcss-value-parser": "^3.2.3"
}
},
"postcss-convert-values": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-1.3.1.tgz",
- "integrity": "sha1-I/GHxhP6d7Y3p4BblIteCJlpDkY=",
+ "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": "4.1.16",
- "postcss-value-parser": "1.4.2"
+ "postcss": "^5.0.11",
+ "postcss-value-parser": "^3.1.2"
}
},
"postcss-discard-comments": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-1.2.1.tgz",
- "integrity": "sha1-hR3Ka5NUwPtjFssaEEj29eOWCtA=",
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-2.0.4.tgz",
+ "integrity": "sha1-vv6J+v1bPazlzM5Rt2uBUUvgDj0=",
"dev": true,
"requires": {
- "node-balanced": "0.0.14",
- "postcss": "4.1.16"
+ "postcss": "^5.0.14"
}
},
"postcss-discard-duplicates": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-1.2.1.tgz",
- "integrity": "sha1-SbsztNNHcQWwDQSDlfc6KQK8miU=",
+ "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": "4.1.16"
+ "postcss": "^5.0.4"
}
},
"postcss-discard-empty": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-1.1.2.tgz",
- "integrity": "sha1-KsVayPy4HCMEPmMQaTT9Y0cNXA0=",
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-2.1.0.tgz",
+ "integrity": "sha1-0rS9nVztXr2Nyt52QMfXzX9PkrU=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.14"
+ }
+ },
+ "postcss-discard-overridden": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-0.1.1.tgz",
+ "integrity": "sha1-ix6vVU9ob7KIzYdMVWZ7CqNmjVg=",
"dev": true,
"requires": {
- "postcss": "4.1.16"
+ "postcss": "^5.0.16"
}
},
"postcss-discard-unused": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-1.0.3.tgz",
- "integrity": "sha1-Xsy5v6xGXqa+VjQpepx3gczQmIY=",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-discard-unused/-/postcss-discard-unused-2.2.3.tgz",
+ "integrity": "sha1-vOMLLMWR/8Y0Mitfs0ZLbZNPRDM=",
"dev": true,
"requires": {
- "flatten": "0.0.1",
- "postcss": "4.1.16",
- "uniqs": "2.0.0"
+ "postcss": "^5.0.14",
+ "uniqs": "^2.0.0"
}
},
"postcss-filter-plugins": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-1.0.1.tgz",
- "integrity": "sha1-J/gnnV76t6o8FwmIE5hrS50dUOI=",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-filter-plugins/-/postcss-filter-plugins-2.0.2.tgz",
+ "integrity": "sha1-bYWGJTTXNaxCDkqFgG4fXUKG2Ew=",
"dev": true,
"requires": {
- "postcss": "4.1.16",
- "uniqid": "1.0.0"
+ "postcss": "^5.0.4",
+ "uniqid": "^4.0.0"
}
},
"postcss-font-family": {
@@ -16333,45 +12835,94 @@
"integrity": "sha1-dQJSSzmDox5q9k5LqhA07W7YQYw=",
"dev": true,
"requires": {
- "object-assign": "3.0.0",
- "postcss": "4.1.16",
- "uniqs": "2.0.0"
+ "object-assign": "^3.0.0",
+ "postcss": "^4.1.16",
+ "uniqs": "^2.0.0"
},
"dependencies": {
+ "es6-promise": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
+ "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
+ "dev": true
+ },
+ "js-base64": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
+ "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=",
+ "dev": true
+ },
"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=",
"dev": true
+ },
+ "postcss": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-4.1.16.tgz",
+ "integrity": "sha1-TESbTIr53zyvbTf44eV10DYXWNw=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "~2.3.0",
+ "js-base64": "~2.1.8",
+ "source-map": "~0.4.2"
+ }
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
}
}
},
"postcss-merge-idents": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-1.0.2.tgz",
- "integrity": "sha1-qToNrXj2UugjfZrew0LkHSwd01s=",
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/postcss-merge-idents/-/postcss-merge-idents-2.1.7.tgz",
+ "integrity": "sha1-TFUwMTwI4dWzu/PSu8dH4njuonA=",
"dev": true,
"requires": {
- "css-list": "0.1.3",
- "postcss": "4.1.16"
+ "has": "^1.0.1",
+ "postcss": "^5.0.10",
+ "postcss-value-parser": "^3.1.1"
}
},
"postcss-merge-longhand": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-1.0.2.tgz",
- "integrity": "sha1-QxcgZfz4We4RztMUH1ZkFMZzBX4=",
+ "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": "4.1.16"
+ "postcss": "^5.0.4"
}
},
"postcss-merge-rules": {
- "version": "1.3.6",
- "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-1.3.6.tgz",
- "integrity": "sha1-sUrRf31AEqMYut032r1ZuT8TUy8=",
+ "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": {
- "postcss": "4.1.16"
+ "browserslist": "^1.5.2",
+ "caniuse-api": "^1.5.2",
+ "postcss": "^5.0.4",
+ "postcss-selector-parser": "^2.2.2",
+ "vendors": "^1.0.0"
+ },
+ "dependencies": {
+ "browserslist": {
+ "version": "1.7.7",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-1.7.7.tgz",
+ "integrity": "sha1-C9dnBCWL6CmyOYu1Dkti0aFmsLk=",
+ "dev": true,
+ "requires": {
+ "caniuse-db": "^1.0.30000639",
+ "electron-to-chromium": "^1.2.7"
+ }
+ }
}
},
"postcss-message-helpers": {
@@ -16380,55 +12931,187 @@
"integrity": "sha1-pPL0+rbk/gAvCu0ABHjN9S+bpg4=",
"dev": true
},
+ "postcss-minify-font-values": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-1.0.5.tgz",
+ "integrity": "sha1-S1jttWZB66fIR0qzUmyv17vey2k=",
+ "dev": true,
+ "requires": {
+ "object-assign": "^4.0.1",
+ "postcss": "^5.0.4",
+ "postcss-value-parser": "^3.0.2"
+ }
+ },
"postcss-minify-font-weight": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/postcss-minify-font-weight/-/postcss-minify-font-weight-1.0.1.tgz",
"integrity": "sha1-aI5CzfI27Osb1WOojPHSTQOgWIg=",
"dev": true,
"requires": {
- "postcss": "4.1.16"
+ "postcss": "^4.1.11"
+ },
+ "dependencies": {
+ "es6-promise": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
+ "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
+ "dev": true
+ },
+ "js-base64": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
+ "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-4.1.16.tgz",
+ "integrity": "sha1-TESbTIr53zyvbTf44eV10DYXWNw=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "~2.3.0",
+ "js-base64": "~2.1.8",
+ "source-map": "~0.4.2"
+ }
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
+ }
+ }
+ },
+ "postcss-minify-gradients": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-1.0.5.tgz",
+ "integrity": "sha1-Xb2hE3NwP4PPtKPqOIHY11/15uE=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.12",
+ "postcss-value-parser": "^3.3.0"
+ }
+ },
+ "postcss-minify-params": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-1.2.2.tgz",
+ "integrity": "sha1-rSzgcTc7lDs9kwo/pZo1jCjW8fM=",
+ "dev": true,
+ "requires": {
+ "alphanum-sort": "^1.0.1",
+ "postcss": "^5.0.2",
+ "postcss-value-parser": "^3.0.2",
+ "uniqs": "^2.0.0"
}
},
"postcss-minify-selectors": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-1.5.0.tgz",
- "integrity": "sha1-5ZxWxtSVXaFXz30iv4Bptur1Jic=",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-2.1.1.tgz",
+ "integrity": "sha1-ssapjAByz5G5MtGkllCBFDEXNb8=",
"dev": true,
"requires": {
- "javascript-natural-sort": "0.7.1",
- "normalize-selector": "0.2.0",
- "postcss": "4.1.16",
- "postcss-selector-parser": "1.3.3",
- "uniqs": "2.0.0"
+ "alphanum-sort": "^1.0.2",
+ "has": "^1.0.1",
+ "postcss": "^5.0.14",
+ "postcss-selector-parser": "^2.0.0"
}
},
"postcss-modules-extract-imports": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-0.0.5.tgz",
- "integrity": "sha1-zMy0Cz3SmFmZOEodumDGLJYKbaA=",
+ "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": "4.1.16"
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "postcss": {
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
"postcss-modules-local-by-default": {
- "version": "0.0.12",
- "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-0.0.12.tgz",
- "integrity": "sha1-qTQxpLHQt6QCHiOPwn1ejkSSgsI=",
+ "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.5.4",
- "postcss": "4.1.16"
+ "css-selector-tokenizer": "^0.7.0",
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "postcss": {
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
"postcss-modules-scope": {
- "version": "0.0.8",
- "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-0.0.8.tgz",
- "integrity": "sha1-gck1+/KJJyOIyLoulqEcohugmgQ=",
+ "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.5.4",
- "postcss": "4.1.16"
+ "css-selector-tokenizer": "^0.7.0",
+ "postcss": "^6.0.1"
+ },
+ "dependencies": {
+ "postcss": {
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
}
},
"postcss-modules-values": {
@@ -16437,111 +13120,102 @@
"integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=",
"dev": true,
"requires": {
- "icss-replace-symbols": "1.1.0",
- "postcss": "6.0.12"
+ "icss-replace-symbols": "^1.1.0",
+ "postcss": "^6.0.1"
},
"dependencies": {
- "ansi-styles": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.0.tgz",
- "integrity": "sha512-NnSOmMEYtVR2JVMIGTzynRkkaxtiq1xnFBcdQD/DnNCYPoEPsVJhM98BDyaoNOQIi7p4okdi3E27eN7GQbsUug==",
- "dev": true,
- "requires": {
- "color-convert": "1.9.0"
- }
- },
- "chalk": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.1.0.tgz",
- "integrity": "sha512-LUHGS/dge4ujbXMJrnihYMcL4AoOweGnw9Tp3kQuqy1Kx5c1qKjqvMJZ6nVJPMWJtKCTN72ZogH3oeSO9g9rXQ==",
- "dev": true,
- "requires": {
- "ansi-styles": "3.2.0",
- "escape-string-regexp": "1.0.5",
- "supports-color": "4.4.0"
- }
- },
- "color-convert": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.0.tgz",
- "integrity": "sha1-Gsz5fdc5uYO/mU1W/sj5WFNkG3o=",
- "dev": true,
- "requires": {
- "color-name": "1.1.3"
- }
- },
"postcss": {
- "version": "6.0.12",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.12.tgz",
- "integrity": "sha512-K6SLofXEK43FBSyZ6/ExQV7ji24OEw4tEY6x1CAf7+tcoMWJoO24Rf3rVFVpk+5IQL1e1Cy3sTKfg7hXuLzafg==",
+ "version": "6.0.22",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.22.tgz",
+ "integrity": "sha512-Toc9lLoUASwGqxBSJGTVcOQiDqjK+Z2XlWBg+IgYwQMY9vA2f7iMpXVc1GpPcfTSyM5lkxNo0oDwDRO+wm7XHA==",
"dev": true,
"requires": {
- "chalk": "2.1.0",
- "source-map": "0.5.7",
- "supports-color": "4.4.0"
+ "chalk": "^2.4.1",
+ "source-map": "^0.6.1",
+ "supports-color": "^5.4.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==",
+ "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": "2.0.0"
+ "has-flag": "^3.0.0"
}
}
}
},
+ "postcss-normalize-charset": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz",
+ "integrity": "sha1-757nEhLX/nWceO0WL2HtYrXLk/E=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.5"
+ }
+ },
"postcss-normalize-url": {
- "version": "2.1.3",
- "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-2.1.3.tgz",
- "integrity": "sha1-8StfShFDyV6gJfx/jgBQkFmPNgI=",
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-3.0.8.tgz",
+ "integrity": "sha1-EI90s/L82viRov+j6kWSJ5/HgiI=",
"dev": true,
"requires": {
- "is-absolute-url": "2.1.0",
- "normalize-url": "1.9.1",
- "object-assign": "4.1.1",
- "postcss": "4.1.16",
- "postcss-value-parser": "1.4.2"
+ "is-absolute-url": "^2.0.0",
+ "normalize-url": "^1.4.0",
+ "postcss": "^5.0.14",
+ "postcss-value-parser": "^3.2.3"
}
},
"postcss-ordered-values": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-1.1.1.tgz",
- "integrity": "sha1-nu1PrS55Kr/D0EAs93O6+G/ne4E=",
+ "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": "4.1.16",
- "postcss-value-parser": "1.4.2"
+ "postcss": "^5.0.4",
+ "postcss-value-parser": "^3.0.1"
}
},
"postcss-reduce-idents": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-1.0.3.tgz",
- "integrity": "sha1-p58bJIXiPZs8x6gfXsY6XCvewg0=",
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-idents/-/postcss-reduce-idents-2.4.0.tgz",
+ "integrity": "sha1-wsbSDMlYKE9qv75j92Cb9AkFmtM=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4",
+ "postcss-value-parser": "^3.0.2"
+ }
+ },
+ "postcss-reduce-initial": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-1.0.1.tgz",
+ "integrity": "sha1-aPgGlfBF0IJjqHmtJA343WT2ROo=",
+ "dev": true,
+ "requires": {
+ "postcss": "^5.0.4"
+ }
+ },
+ "postcss-reduce-transforms": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-1.0.4.tgz",
+ "integrity": "sha1-/3b02CEkN7McKYpC0uFEQCV3GuE=",
"dev": true,
"requires": {
- "postcss": "4.1.16",
- "reduce-function-call": "1.0.2"
+ "has": "^1.0.1",
+ "postcss": "^5.0.8",
+ "postcss-value-parser": "^3.0.1"
}
},
"postcss-selector-parser": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-1.3.3.tgz",
- "integrity": "sha1-0u4Z33pk+O8hwacchvfUg1yIwoE=",
+ "version": "2.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-2.2.3.tgz",
+ "integrity": "sha1-+UN3iGBsPJrO4W/+jYsWKX8nu5A=",
"dev": true,
"requires": {
- "flatten": "1.0.2",
- "indexes-of": "1.0.1",
- "uniq": "1.0.1"
- },
- "dependencies": {
- "flatten": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/flatten/-/flatten-1.0.2.tgz",
- "integrity": "sha1-2uRqnXj74lKSJYzB54CkHZXAN4I=",
- "dev": true
- }
+ "flatten": "^1.0.2",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
}
},
"postcss-single-charset": {
@@ -16550,62 +13224,109 @@
"integrity": "sha1-2n/Q3szPYy8bdMei7j41vilFZXM=",
"dev": true,
"requires": {
- "fs-extra": "0.14.0",
- "postcss": "4.1.16"
+ "fs-extra": "^0.14.0",
+ "postcss": "^4.1.0"
},
"dependencies": {
+ "es6-promise": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
+ "integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
+ "dev": true
+ },
"fs-extra": {
"version": "0.14.0",
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-0.14.0.tgz",
"integrity": "sha1-RmCWxroticIAA4DaskULeFn/Z0M=",
"dev": true,
"requires": {
- "jsonfile": "2.4.0",
- "ncp": "1.0.1",
- "rimraf": "2.6.2"
+ "jsonfile": "^2.0.0",
+ "ncp": "^1.0.1",
+ "rimraf": "^2.2.8"
}
},
+ "js-base64": {
+ "version": "2.1.9",
+ "resolved": "https://registry.npmjs.org/js-base64/-/js-base64-2.1.9.tgz",
+ "integrity": "sha1-8OgK4DmkvWVLXygfyT8EqRSn/M4=",
+ "dev": true
+ },
"ncp": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/ncp/-/ncp-1.0.1.tgz",
"integrity": "sha1-0VNn5cuHQyuhF9K/gP30Wuz7QkY=",
"dev": true
+ },
+ "postcss": {
+ "version": "4.1.16",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-4.1.16.tgz",
+ "integrity": "sha1-TESbTIr53zyvbTf44eV10DYXWNw=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "~2.3.0",
+ "js-base64": "~2.1.8",
+ "source-map": "~0.4.2"
+ }
+ },
+ "source-map": {
+ "version": "0.4.4",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.4.4.tgz",
+ "integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
+ "dev": true,
+ "requires": {
+ "amdefine": ">=0.0.4"
+ }
}
}
},
+ "postcss-svgo": {
+ "version": "2.1.6",
+ "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-2.1.6.tgz",
+ "integrity": "sha1-tt8YqmE7Zm4TPwittSGcJoSsEI0=",
+ "dev": true,
+ "requires": {
+ "is-svg": "^2.0.0",
+ "postcss": "^5.0.14",
+ "postcss-value-parser": "^3.2.3",
+ "svgo": "^0.7.0"
+ }
+ },
"postcss-unique-selectors": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-1.0.1.tgz",
- "integrity": "sha1-SBfnTHtPmZzgTI5mRRoZaRT12zw=",
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-2.0.2.tgz",
+ "integrity": "sha1-mB1X0p3csz57Hf4f1DuGSfkzyh0=",
"dev": true,
"requires": {
- "javascript-natural-sort": "0.7.1",
- "postcss": "4.1.16",
- "uniqs": "2.0.0"
+ "alphanum-sort": "^1.0.1",
+ "postcss": "^5.0.4",
+ "uniqs": "^2.0.0"
}
},
"postcss-value-parser": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-1.4.2.tgz",
- "integrity": "sha1-GGVjPhNwH4pyHng02tGFyxRKrQw=",
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.0.tgz",
+ "integrity": "sha1-h/OPnxj3dKSrTIojL1xc6IcqnRU=",
"dev": true
},
"postcss-zindex": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-1.1.3.tgz",
- "integrity": "sha1-SVZKtJ092hcGf42sHIM11/LQDOE=",
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/postcss-zindex/-/postcss-zindex-2.2.0.tgz",
+ "integrity": "sha1-0hCd3AVbka9n/EyzsCWUZjnSryI=",
"dev": true,
"requires": {
- "postcss": "4.1.16"
+ "has": "^1.0.1",
+ "postcss": "^5.0.4",
+ "uniqs": "^2.0.0"
}
},
"pre-commit": {
"version": "github:brave/pre-commit#67aef1db3066f298a25e930c06a8c9f2b19f2a3e",
+ "from": "github:brave/pre-commit",
"dev": true,
"requires": {
- "cross-spawn": "4.0.2",
- "spawn-sync": "1.0.15",
- "which": "1.2.14"
+ "cross-spawn": "^4.0.0",
+ "spawn-sync": "^1.0.15",
+ "which": "1.2.x"
},
"dependencies": {
"cross-spawn": {
@@ -16614,18 +13335,18 @@
"integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
"dev": true,
"requires": {
- "lru-cache": "4.1.1",
- "which": "1.2.14"
+ "lru-cache": "^4.0.1",
+ "which": "^1.2.9"
}
},
"lru-cache": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
- "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "version": "4.1.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.3.tgz",
+ "integrity": "sha512-fFEhvcgzuIoJVUF8fYr5KR0YqxD238zgObTps31YdADwPPAp82a4M8TrckkWyx7ekNlf9aBcVn81cFwwXngrJA==",
"dev": true,
"requires": {
- "pseudomap": "1.0.2",
- "yallist": "2.1.2"
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
}
},
"which": {
@@ -16634,7 +13355,7 @@
"integrity": "sha1-mofEN48D6CfOyvGs31bHNsAcFOU=",
"dev": true,
"requires": {
- "isexe": "2.0.0"
+ "isexe": "^2.0.0"
}
}
}
@@ -16645,7 +13366,7 @@
"integrity": "sha1-Kip5gn0kOnbJEImJescH9F5xaqw=",
"dev": true,
"requires": {
- "shelljs": "0.3.0"
+ "shelljs": "0.3.x"
},
"dependencies": {
"shelljs": {
@@ -16657,30 +13378,37 @@
}
},
"prebuild-install": {
- "version": "2.2.2",
- "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-2.2.2.tgz",
- "integrity": "sha512-F46pcvDxtQhbV3B+dm+exHuKxIyJK26fVNiJRmbTW/5D7o0Z2yzc8CKeu7UWbo9XxQZoVOC88aKgySAsza+cWw==",
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-4.0.0.tgz",
+ "integrity": "sha512-7tayxeYboJX0RbVzdnKyGl2vhQRWr6qfClEXDhOkXjuaOKCw2q8aiuFhONRYVsG/czia7KhpykIlI2S2VaPunA==",
+ "optional": true,
"requires": {
- "expand-template": "1.1.0",
+ "detect-libc": "^1.0.3",
+ "expand-template": "^1.0.2",
"github-from-package": "0.0.0",
- "minimist": "1.2.0",
- "mkdirp": "0.5.1",
- "node-abi": "2.1.1",
- "noop-logger": "0.1.1",
- "npmlog": "4.1.2",
- "os-homedir": "1.0.2",
- "pump": "1.0.2",
- "rc": "1.2.1",
- "simple-get": "1.4.3",
- "tar-fs": "1.15.3",
- "tunnel-agent": "0.6.0",
- "xtend": "4.0.1"
+ "minimist": "^1.2.0",
+ "mkdirp": "^0.5.1",
+ "node-abi": "^2.2.0",
+ "noop-logger": "^0.1.1",
+ "npmlog": "^4.0.1",
+ "os-homedir": "^1.0.1",
+ "pump": "^2.0.1",
+ "rc": "^1.1.6",
+ "simple-get": "^2.7.0",
+ "tar-fs": "^1.13.0",
+ "tunnel-agent": "^0.6.0",
+ "which-pm-runs": "^1.0.0"
},
"dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "optional": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
}
}
},
@@ -16712,8 +13440,8 @@
"integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
"dev": true,
"requires": {
- "get-stdin": "4.0.1",
- "meow": "3.7.0"
+ "get-stdin": "^4.0.1",
+ "meow": "^3.1.0"
},
"dependencies": {
"get-stdin": {
@@ -16731,26 +13459,24 @@
"dev": true
},
"private": {
- "version": "0.1.7",
- "resolved": "https://registry.npmjs.org/private/-/private-0.1.7.tgz",
- "integrity": "sha1-aM5eih7woju1cMwoU3tTMqumPvE="
+ "version": "0.1.8",
+ "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz",
+ "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg=="
},
"process": {
- "version": "0.11.10",
- "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz",
- "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=",
- "dev": true
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/process/-/process-0.5.2.tgz",
+ "integrity": "sha1-FjjYqONML0QKkduVq5rrZ3/Bhc8="
},
"process-nextick-args": {
- "version": "1.0.7",
- "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-1.0.7.tgz",
- "integrity": "sha1-FQ4gt1ZZCtP5EJPyWk8q2L/zC6M="
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
},
"progress": {
- "version": "1.1.8",
- "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
- "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
- "dev": true
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.0.tgz",
+ "integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8="
},
"progress-stream": {
"version": "1.2.0",
@@ -16758,20 +13484,26 @@
"integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=",
"dev": true,
"requires": {
- "speedometer": "0.1.4",
- "through2": "0.2.3"
+ "speedometer": "~0.1.2",
+ "through2": "~0.2.3"
},
"dependencies": {
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
+ "dev": true
+ },
"readable-stream": {
"version": "1.1.14",
"resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz",
"integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=",
"dev": true,
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
"isarray": "0.0.1",
- "string_decoder": "0.10.31"
+ "string_decoder": "~0.10.x"
}
},
"speedometer": {
@@ -16780,14 +13512,20 @@
"integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0=",
"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
+ },
"through2": {
"version": "0.2.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
"integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
"dev": true,
"requires": {
- "readable-stream": "1.1.14",
- "xtend": "2.1.2"
+ "readable-stream": "~1.1.9",
+ "xtend": "~2.1.1"
}
},
"xtend": {
@@ -16796,7 +13534,7 @@
"integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
"dev": true,
"requires": {
- "object-keys": "0.4.0"
+ "object-keys": "~0.4.0"
}
}
}
@@ -16806,7 +13544,7 @@
"resolved": "https://registry.npmjs.org/promise/-/promise-7.3.1.tgz",
"integrity": "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg==",
"requires": {
- "asap": "2.0.6"
+ "asap": "~2.0.3"
}
},
"promise-inflight": {
@@ -16816,141 +13554,37 @@
"dev": true
},
"prop-types": {
- "version": "15.6.0",
- "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.0.tgz",
- "integrity": "sha1-zq8IMCL8RrSjX2nhPvda7Q1jmFY=",
+ "version": "15.6.1",
+ "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.6.1.tgz",
+ "integrity": "sha512-4ec7bY1Y66LymSUOH/zARVYObB23AT2h8cf6e/O6ZALB/N0sqZFEx7rq6EYPX2MkOdKORuooI/H5k9TlR4q7kQ==",
"requires": {
- "fbjs": "0.8.16",
- "loose-envify": "1.3.1",
- "object-assign": "4.1.1"
- }
- },
- "prova-lib": {
- "version": "0.2.9",
- "resolved": "https://registry.npmjs.org/prova-lib/-/prova-lib-0.2.9.tgz",
- "integrity": "sha512-YaulnI8L3LozBjwy64afOYmQdz2SzMiZgGvhHSU1BA7TIH8VlHZVN5/PrZ4roKS9tOPT7rl5A0C4RB63BlnVow==",
- "requires": {
- "bigi": "1.4.2",
- "bitcoin-ops": "1.3.0",
- "bitcoinjs-lib": "3.0.3",
- "bs58check": "2.0.2",
- "ecurve": "1.0.6",
- "lodash": "4.17.4",
- "secp256k1": "3.3.1",
- "typeforce": "1.10.6",
- "varuint-bitcoin": "1.0.4"
- },
- "dependencies": {
- "bigi": {
- "version": "1.4.2",
- "resolved": "https://registry.npmjs.org/bigi/-/bigi-1.4.2.tgz",
- "integrity": "sha1-nGZalfiLiwj8Bc/XMfVhhZ1yWCU="
- },
- "bitcoin-ops": {
- "version": "1.3.0",
- "resolved": "https://registry.npmjs.org/bitcoin-ops/-/bitcoin-ops-1.3.0.tgz",
- "integrity": "sha1-axJrWFU3vGebAu1JnxRFDP/DfhM="
- },
- "bitcoinjs-lib": {
- "version": "3.0.3",
- "resolved": "https://registry.npmjs.org/bitcoinjs-lib/-/bitcoinjs-lib-3.0.3.tgz",
- "integrity": "sha1-NHDu1dZ3i1QEt3Dv+9D8uyvYllU=",
- "requires": {
- "bigi": "1.4.2",
- "bip66": "1.1.5",
- "bitcoin-ops": "1.3.0",
- "bs58check": "2.0.2",
- "create-hash": "1.1.3",
- "create-hmac": "1.1.6",
- "ecurve": "1.0.6",
- "merkle-lib": "2.0.10",
- "pushdata-bitcoin": "1.0.1",
- "randombytes": "2.0.5",
- "typeforce": "1.10.6",
- "varuint-bitcoin": "1.0.4",
- "wif": "2.0.6"
- }
- },
- "bs58": {
- "version": "4.0.1",
- "resolved": "https://registry.npmjs.org/bs58/-/bs58-4.0.1.tgz",
- "integrity": "sha1-vhYedsNU9veIrkBx9j806MTwpCo=",
- "requires": {
- "base-x": "3.0.2"
- }
- },
- "bs58check": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-2.0.2.tgz",
- "integrity": "sha1-BvY7AcL6YXMDPJDrh/H+PS4T2Jo=",
- "requires": {
- "bs58": "4.0.1",
- "create-hash": "1.1.3"
- }
- },
- "secp256k1": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.3.1.tgz",
- "integrity": "sha512-lygjgfjzjBHblEDDkppUF5KK1EeVk6P/Dv2MsJZpYIR3vW5TKFRexOFkf0hHy9J5YxEpjQZ6x98Y3XQpMQO/vA==",
- "optional": true,
- "requires": {
- "bindings": "1.3.0",
- "bip66": "1.1.5",
- "bn.js": "4.11.8",
- "create-hash": "1.1.3",
- "drbg.js": "1.0.1",
- "elliptic": "6.4.0",
- "nan": "2.7.0",
- "prebuild-install": "2.2.2",
- "safe-buffer": "5.1.1"
- }
- },
- "typeforce": {
- "version": "1.10.6",
- "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.10.6.tgz",
- "integrity": "sha1-cb3KNbTmNbYSRTcbV8AIzt++xNs=",
- "requires": {
- "inherits": "2.0.3"
- }
- }
+ "fbjs": "^0.8.16",
+ "loose-envify": "^1.3.1",
+ "object-assign": "^4.1.1"
}
},
"proxy-addr": {
- "version": "1.1.5",
- "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-1.1.5.tgz",
- "integrity": "sha1-ccDuOxAt4/IC87ZPYI0XP8uhqRg=",
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.3.tgz",
+ "integrity": "sha512-jQTChiCJteusULxjBp8+jftSQE5Obdl3k4cnmLA6WXtK6XFuWRnvVL7aCiBqaLPM8c4ph0S4tKna8XvmIwEnXQ==",
"dev": true,
"requires": {
- "forwarded": "0.1.2",
- "ipaddr.js": "1.4.0"
- }
- },
- "proxy-agent": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-2.1.0.tgz",
- "integrity": "sha512-I23qaUnXmU/ItpXWQcMj9wMcZQTXnJNI7nakSR+q95Iht8H0+w3dCgTJdfnOQqOCX1FZwKLSgurCyEt11LM6OA==",
- "requires": {
- "agent-base": "2.1.1",
- "debug": "2.6.9",
- "extend": "3.0.0",
- "http-proxy-agent": "1.0.0",
- "https-proxy-agent": "1.0.0",
- "lru-cache": "2.6.5",
- "pac-proxy-agent": "2.0.0",
- "socks-proxy-agent": "2.1.1"
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.6.0"
},
"dependencies": {
- "lru-cache": {
- "version": "2.6.5",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-2.6.5.tgz",
- "integrity": "sha1-5W1jVBSO3o13B7WNFDIg/QjfD9U="
+ "ipaddr.js": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.6.0.tgz",
+ "integrity": "sha1-4/o1e3c9phnybpXwSdBVxyeW+Gs=",
+ "dev": true
}
}
},
"prr": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/prr/-/prr-0.0.0.tgz",
- "integrity": "sha1-GoS4WQgyVQFBGFPQCB7j+obikmo=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz",
+ "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=",
"dev": true
},
"pseudomap": {
@@ -16959,55 +13593,59 @@
"integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM="
},
"public-encrypt": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.0.tgz",
- "integrity": "sha1-OfaZ86RlYN1eusvKaTyvfGXBjMY=",
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.2.tgz",
+ "integrity": "sha512-4kJ5Esocg8X3h8YgJsKAuoesBgB7mqH3eowiDzMUPKiRDDE7E/BqqZD1hnTByIaAFiwAw246YEltSq7tdrOH0Q==",
"dev": true,
"requires": {
- "bn.js": "4.11.8",
- "browserify-rsa": "4.0.1",
- "create-hash": "1.1.3",
- "parse-asn1": "5.1.0",
- "randombytes": "2.0.5"
+ "bn.js": "^4.1.0",
+ "browserify-rsa": "^4.0.0",
+ "create-hash": "^1.1.0",
+ "parse-asn1": "^5.0.0",
+ "randombytes": "^2.0.1"
}
},
"pump": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.2.tgz",
- "integrity": "sha1-Oz7mUS+U8OV1U4wXmV+fFpkKXVE=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
"requires": {
- "end-of-stream": "1.4.0",
- "once": "1.4.0"
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
}
},
"pumpify": {
- "version": "1.3.5",
- "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.3.5.tgz",
- "integrity": "sha1-G2ccYZlAq8rqwK0OOjwWS+dgmTs=",
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz",
+ "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==",
"dev": true,
"requires": {
- "duplexify": "3.5.1",
- "inherits": "2.0.3",
- "pump": "1.0.2"
+ "duplexify": "^3.6.0",
+ "inherits": "^2.0.3",
+ "pump": "^2.0.0"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz",
+ "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
}
},
"punycode": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.0.tgz",
- "integrity": "sha1-X4Y+3Im5bbCQdLrXlHvwkFbKTn0="
- },
- "pushdata-bitcoin": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/pushdata-bitcoin/-/pushdata-bitcoin-1.0.1.tgz",
- "integrity": "sha1-FZMdPNlnreUiBvUjqnMxrvfUOvc=",
- "requires": {
- "bitcoin-ops": "1.4.0"
- }
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
},
"q": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/q/-/q-1.5.0.tgz",
- "integrity": "sha1-3QG6ydBtMObyGa7LglPunr3DCPE="
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc="
},
"qr-image": {
"version": "3.2.0",
@@ -17015,9 +13653,9 @@
"integrity": "sha1-n6gpW+rlDEoUnPn5CaHbRkqGcug="
},
"qs": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz",
- "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ="
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
},
"query-string": {
"version": "4.3.4",
@@ -17025,8 +13663,8 @@
"integrity": "sha1-u7aTucqRXCMlFbIosaArYJBD2+s=",
"dev": true,
"requires": {
- "object-assign": "4.1.1",
- "strict-uri-encode": "1.1.0"
+ "object-assign": "^4.1.0",
+ "strict-uri-encode": "^1.0.0"
}
},
"querystring": {
@@ -17042,21 +13680,26 @@
"dev": true
},
"querystringify": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-0.0.4.tgz",
- "integrity": "sha1-DPf4T5Rj/wrlHExLFC2VvjdyTZw=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.0.0.tgz",
+ "integrity": "sha512-eTPo5t/4bgaMNZxyjWx6N2a6AuE0mq51KWvpc7nU/MAqixcI6v6KrGUKES0HaomdnolQBBXU/++X6/QQ9KL4tw==",
"dev": true
},
"random-access-file": {
- "version": "1.8.1",
- "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-1.8.1.tgz",
- "integrity": "sha512-+Uhk0Of+dWHWjpbL2hizcwSV1UomcN3S0iUGV6BTZ2Js1BP9jHx3E5CT7y0eLbqTQNkVi4iehkHmia7Mdqa47w==",
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/random-access-file/-/random-access-file-2.0.1.tgz",
+ "integrity": "sha512-nb4fClpzoUY+v1SHrro+9yykN90eMA1rc+xM39tnZ5R3BgFY+J/NxPZ0KuUpishEsvnwou9Fvm2wa3cjeuG7vg==",
"requires": {
- "buffer-alloc-unsafe": "1.0.0",
- "debug": "2.6.9",
- "inherits": "2.0.3",
- "mkdirp": "0.5.1",
- "thunky": "1.0.2"
+ "mkdirp": "^0.5.1",
+ "random-access-storage": "^1.1.1"
+ }
+ },
+ "random-access-storage": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/random-access-storage/-/random-access-storage-1.2.0.tgz",
+ "integrity": "sha512-KASq0p0d4Tri71p1w9+gvKBhUpjt9/9TGtVMschfwNjdw93rZFnKlsZ+4CKFq/qi2GvdobIFLu0CjnQpfsr05Q==",
+ "requires": {
+ "inherits": "^2.0.3"
}
},
"random-iterate": {
@@ -17069,58 +13712,46 @@
"resolved": "https://registry.npmjs.org/random-lib/-/random-lib-2.1.0.tgz",
"integrity": "sha1-PrOXD/J8Gvc8WIq5EHXY8KBDjfU=",
"requires": {
- "dezalgo": "1.0.3",
- "es6-promise": "3.3.1",
- "object-assign": "4.1.1"
+ "dezalgo": "^1.0.3",
+ "es6-promise": "^3.1.2",
+ "object-assign": "^4.0.1"
}
},
"randomatic": {
- "version": "1.1.7",
- "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-1.1.7.tgz",
- "integrity": "sha512-D5JUjPyJbaJDkuAazpVnSfVkLlpeO3wDlPROTMLGKG1zMFNFRgrciKo1ltz/AzNTkqE0HzDx655QOL51N06how==",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/randomatic/-/randomatic-3.0.0.tgz",
+ "integrity": "sha512-VdxFOIEY3mNO5PtSRkkle/hPJDHvQhK21oa73K4yAc9qmp6N429gAyF1gZMOTMeS0/AYzaV/2Trcef+NaIonSA==",
"dev": true,
"requires": {
- "is-number": "3.0.0",
- "kind-of": "4.0.0"
+ "is-number": "^4.0.0",
+ "kind-of": "^6.0.0",
+ "math-random": "^1.0.1"
},
"dependencies": {
"is-number": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
- "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
- "dev": true,
- "requires": {
- "kind-of": "3.2.2"
- },
- "dependencies": {
- "kind-of": {
- "version": "3.2.2",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
- "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
- "dev": true,
- "requires": {
- "is-buffer": "1.1.5"
- }
- }
- }
- },
- "kind-of": {
"version": "4.0.0",
- "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz",
- "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=",
- "dev": true,
- "requires": {
- "is-buffer": "1.1.5"
- }
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-4.0.0.tgz",
+ "integrity": "sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==",
+ "dev": true
}
}
},
"randombytes": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.5.tgz",
- "integrity": "sha512-8T7Zn1AhMsQ/HI1SjcCfT/t4ii3eAqco3yOcSzS4mozsOz69lHLsoMXmF9nZgnFanYscnSlUSgs8uZyKzpE6kg==",
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.0.6.tgz",
+ "integrity": "sha512-CIQ5OFxf4Jou6uOKe9t1AOgqpeU5fd70A8NPdHSGeYXqXsPe6peOwI0cUl88RWZ6sP1vPMV3avd/R6cZ5/sP1A==",
+ "requires": {
+ "safe-buffer": "^5.1.0"
+ }
+ },
+ "randomfill": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz",
+ "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==",
+ "dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "randombytes": "^2.0.5",
+ "safe-buffer": "^5.1.0"
}
},
"range-parser": {
@@ -17133,43 +13764,15 @@
"resolved": "https://registry.npmjs.org/range-slice-stream/-/range-slice-stream-1.2.0.tgz",
"integrity": "sha1-AbqVQnYFK3g5AOY9YRjY/POHXX8=",
"requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.0.5"
}
},
"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",
@@ -17177,29 +13780,41 @@
"unpipe": "1.0.0"
},
"dependencies": {
- "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=="
+ "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
}
}
},
"rc": {
- "version": "1.2.1",
- "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.1.tgz",
- "integrity": "sha1-LgPo5C7kULjLPc5lvhv4l04d/ZU=",
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.7.tgz",
+ "integrity": "sha512-LdLD8xD4zzLsAT5xyushXDNscEjB7+2ulnl8+r1pnESlYtlJtVSoCMBGr30eDRJ3+2Gq89jK9P9e4tCEH1+ywA==",
"requires": {
- "deep-extend": "0.4.2",
- "ini": "1.3.4",
- "minimist": "1.2.0",
- "strip-json-comments": "2.0.1"
- },
- "dependencies": {
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
- }
+ "deep-extend": "^0.5.1",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
}
},
"rcedit": {
@@ -17213,11 +13828,11 @@
"resolved": "https://registry.npmjs.org/react/-/react-15.6.2.tgz",
"integrity": "sha1-26BDSrQ5z+gvEI8PURZjkIF5qnI=",
"requires": {
- "create-react-class": "15.6.2",
- "fbjs": "0.8.16",
- "loose-envify": "1.3.1",
- "object-assign": "4.1.1",
- "prop-types": "15.6.0"
+ "create-react-class": "^15.6.0",
+ "fbjs": "^0.8.9",
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.0",
+ "prop-types": "^15.5.10"
}
},
"react-addons-perf": {
@@ -17226,8 +13841,8 @@
"integrity": "sha1-EQvc9cRZxPd8uF7WNLzTOXU2ODs=",
"dev": true,
"requires": {
- "fbjs": "0.8.16",
- "object-assign": "4.1.1"
+ "fbjs": "^0.8.4",
+ "object-assign": "^4.1.0"
}
},
"react-addons-test-utils": {
@@ -17237,24 +13852,24 @@
"dev": true
},
"react-dnd": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-2.5.1.tgz",
- "integrity": "sha1-7O8dnYR4y3av1Zdc1RI+98O+v+U=",
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/react-dnd/-/react-dnd-2.6.0.tgz",
+ "integrity": "sha1-f6JWds+CfViokSk+PBq1naACVFo=",
"requires": {
- "disposables": "1.0.1",
- "dnd-core": "2.5.1",
- "hoist-non-react-statics": "2.3.1",
- "invariant": "2.2.2",
- "lodash": "4.17.4",
- "prop-types": "15.6.0"
+ "disposables": "^1.0.1",
+ "dnd-core": "^2.6.0",
+ "hoist-non-react-statics": "^2.1.0",
+ "invariant": "^2.1.0",
+ "lodash": "^4.2.0",
+ "prop-types": "^15.5.10"
}
},
"react-dnd-html5-backend": {
- "version": "2.5.1",
- "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-2.5.1.tgz",
- "integrity": "sha1-02VuUUsMRpkCpIX/+nX4aE4hx3c=",
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/react-dnd-html5-backend/-/react-dnd-html5-backend-2.6.0.tgz",
+ "integrity": "sha1-WQzRzKeEQbsnTt1XH+9MCxbdz44=",
"requires": {
- "lodash": "4.17.4"
+ "lodash": "^4.2.0"
}
},
"react-dom": {
@@ -17262,10 +13877,10 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-15.6.2.tgz",
"integrity": "sha1-Qc+t9pO3V/rycIRDodH9WgK+9zA=",
"requires": {
- "fbjs": "0.8.16",
- "loose-envify": "1.3.1",
- "object-assign": "4.1.1",
- "prop-types": "15.6.0"
+ "fbjs": "^0.8.9",
+ "loose-envify": "^1.1.0",
+ "object-assign": "^4.1.0",
+ "prop-types": "^15.5.10"
}
},
"react-input-autosize": {
@@ -17278,8 +13893,8 @@
"resolved": "https://registry.npmjs.org/react-select/-/react-select-0.9.1.tgz",
"integrity": "sha1-4yKi0KBjlqSCBrBVPfXsR9Fgg7o=",
"requires": {
- "classnames": "2.2.5",
- "react-input-autosize": "0.6.13"
+ "classnames": "^2.2.0",
+ "react-input-autosize": "^0.6.2"
}
},
"react-test-renderer": {
@@ -17288,21 +13903,18 @@
"integrity": "sha1-0DM0NPwsQ4CSaWyncNpe1IA376g=",
"dev": true,
"requires": {
- "fbjs": "0.8.16",
- "object-assign": "4.1.1"
+ "fbjs": "^0.8.9",
+ "object-assign": "^4.1.0"
}
},
"react-transition-group": {
- "version": "2.2.1",
- "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.2.1.tgz",
- "integrity": "sha512-q54UBM22bs/CekG8r3+vi9TugSqh0t7qcEVycaRc9M0p0aCEu+h6rp/RFiW7fHfgd1IKpd9oILFTl5QK+FpiPA==",
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.3.1.tgz",
+ "integrity": "sha512-hu4/LAOFSKjWt1+1hgnOv3ldxmt6lvZGTWz4KUkFrqzXrNDIVSu6txIcPszw7PNduR8en9YTN55JLRyd/L1ZiQ==",
"requires": {
- "chain-function": "1.0.0",
- "classnames": "2.2.5",
- "dom-helpers": "3.2.1",
- "loose-envify": "1.3.1",
- "prop-types": "15.6.0",
- "warning": "3.0.0"
+ "dom-helpers": "^3.3.1",
+ "loose-envify": "^1.3.1",
+ "prop-types": "^15.6.1"
}
},
"read-all-stream": {
@@ -17311,40 +13923,8 @@
"integrity": "sha1-NcPhd/IHjveJ7kv6+kNzB06u9Po=",
"dev": true,
"requires": {
- "pinkie-promise": "2.0.1",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "pinkie-promise": "^2.0.0",
+ "readable-stream": "^2.0.0"
}
},
"read-chunk": {
@@ -17358,74 +13938,15 @@
"integrity": "sha512-tzV5MRYA1OIbjy0ZC3cKlQZMLyRYMJ7k37Inff0CH0fQGXFP9p0s0eJ3bQxnnvQDhPSspnW9fw9v2K0b+6TODg==",
"dev": true,
"requires": {
- "ajv": "5.5.2",
- "ajv-keywords": "2.1.0",
- "bluebird-lst": "1.0.5",
- "dotenv": "4.0.0",
- "dotenv-expand": "4.0.1",
- "fs-extra-p": "4.5.0",
- "js-yaml": "3.10.0",
- "json5": "0.5.1",
- "lazy-val": "1.0.3"
- },
- "dependencies": {
- "ajv": {
- "version": "5.5.2",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-5.5.2.tgz",
- "integrity": "sha1-c7Xuyj+rZT49P5Qis0GtQiBdyWU=",
- "dev": true,
- "requires": {
- "co": "4.6.0",
- "fast-deep-equal": "1.0.0",
- "fast-json-stable-stringify": "2.0.0",
- "json-schema-traverse": "0.3.1"
- }
- },
- "bluebird": {
- "version": "3.5.1",
- "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.1.tgz",
- "integrity": "sha512-MKiLiV+I1AA596t9w1sQJ8jkiSr5+ZKi0WKrYGUn6d1Fx+Ij4tIj+m2WMQSGczs5jZVxV339chE8iwk6F64wjA==",
- "dev": true
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.0.0"
- }
- },
- "jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
- }
+ "ajv": "^5.5.0",
+ "ajv-keywords": "^2.1.0",
+ "bluebird-lst": "^1.0.5",
+ "dotenv": "^4.0.0",
+ "dotenv-expand": "^4.0.1",
+ "fs-extra-p": "^4.5.0",
+ "js-yaml": "^3.10.0",
+ "json5": "^0.5.1",
+ "lazy-val": "^1.0.3"
}
},
"read-file-stdin": {
@@ -17434,7 +13955,7 @@
"integrity": "sha1-JezP86FTtoCa+ssj7hU4fbng7mE=",
"dev": true,
"requires": {
- "gather-stream": "1.0.0"
+ "gather-stream": "^1.0.0"
}
},
"read-pkg": {
@@ -17442,9 +13963,9 @@
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
"integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
"requires": {
- "load-json-file": "1.1.0",
- "normalize-package-data": "2.4.0",
- "path-type": "1.1.0"
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
}
},
"read-pkg-up": {
@@ -17452,8 +13973,8 @@
"resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
"integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
"requires": {
- "find-up": "1.1.2",
- "read-pkg": "1.1.0"
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
},
"dependencies": {
"find-up": {
@@ -17461,8 +13982,8 @@
"resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
"integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
"requires": {
- "path-exists": "2.1.0",
- "pinkie-promise": "2.0.1"
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
}
},
"path-exists": {
@@ -17470,20 +13991,23 @@
"resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
"integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
"requires": {
- "pinkie-promise": "2.0.1"
+ "pinkie-promise": "^2.0.0"
}
}
}
},
"readable-stream": {
- "version": "1.0.27-1",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
- "integrity": "sha1-a2eYPCA1fO/QfwFlABoW1xDZEHg=",
+ "version": "2.3.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "0.0.1",
- "string_decoder": "0.10.31"
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
}
},
"readdirp": {
@@ -17492,42 +14016,10 @@
"integrity": "sha1-TtCtBg3zBzMAxIRANz9y0cxkLXg=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "minimatch": "3.0.4",
- "readable-stream": "2.3.3",
- "set-immediate-shim": "1.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "graceful-fs": "^4.1.2",
+ "minimatch": "^3.0.2",
+ "readable-stream": "^2.0.2",
+ "set-immediate-shim": "^1.0.1"
}
},
"readline2": {
@@ -17536,8 +14028,8 @@
"integrity": "sha1-QQWWCP/BVHV7cV2ZidGZ/783LjU=",
"dev": true,
"requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
"mute-stream": "0.0.5"
},
"dependencies": {
@@ -17555,34 +14047,22 @@
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
"dev": true,
"requires": {
- "resolve": "1.4.0"
+ "resolve": "^1.1.6"
}
},
+ "record-cache": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/record-cache/-/record-cache-1.1.0.tgz",
+ "integrity": "sha512-u8rbtLEJV7HRacl/ZYwSBFD8NFyB3PfTTfGLP37IW3hftQCwu6z4Q2RLyxo1YJUNRTEzJfpLpGwVuEYdaIkG9Q=="
+ },
"redent": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
"integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
"dev": true,
"requires": {
- "indent-string": "2.1.0",
- "strip-indent": "1.0.1"
- }
- },
- "redeyed": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/redeyed/-/redeyed-1.0.1.tgz",
- "integrity": "sha1-6WwZO0DAgWsArshCaY5hGF5VSYo=",
- "dev": true,
- "requires": {
- "esprima": "3.0.0"
- },
- "dependencies": {
- "esprima": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.0.0.tgz",
- "integrity": "sha1-U88kes2ncxPlUcOqLnM0LT+099k=",
- "dev": true
- }
+ "indent-string": "^2.1.0",
+ "strip-indent": "^1.0.1"
}
},
"reduce-component": {
@@ -17596,9 +14076,9 @@
"integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
"dev": true,
"requires": {
- "balanced-match": "0.4.2",
- "math-expression-evaluator": "1.2.17",
- "reduce-function-call": "1.0.2"
+ "balanced-match": "^0.4.2",
+ "math-expression-evaluator": "^1.2.14",
+ "reduce-function-call": "^1.0.1"
},
"dependencies": {
"balanced-match": {
@@ -17615,7 +14095,7 @@
"integrity": "sha1-WiAL+S4ON3UXUv5FsKszD9S2vpk=",
"dev": true,
"requires": {
- "balanced-match": "0.4.2"
+ "balanced-match": "^0.4.2"
},
"dependencies": {
"balanced-match": {
@@ -17631,22 +14111,22 @@
"resolved": "https://registry.npmjs.org/redux/-/redux-3.7.2.tgz",
"integrity": "sha512-pNqnf9q1hI5HHZRBkj3bAngGZW/JMCmexDlOxw4XagXY2o1327nHH54LoTjiPJ0gizoqPDRqWyX/00g0hD6w+A==",
"requires": {
- "lodash": "4.17.4",
- "lodash-es": "4.17.4",
- "loose-envify": "1.3.1",
- "symbol-observable": "1.0.4"
+ "lodash": "^4.2.1",
+ "lodash-es": "^4.2.1",
+ "loose-envify": "^1.1.0",
+ "symbol-observable": "^1.0.3"
}
},
"regenerate": {
- "version": "1.3.3",
- "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.3.3.tgz",
- "integrity": "sha512-jVpo1GadrDAK59t/0jRx5VxYWQEDkkEKi6+HjE3joFVLfDOh9Xrdh0dF1eSq+BI/SwvTQ44gSscJ8N5zYL61sg==",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
+ "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
"dev": true
},
"regenerator-runtime": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.0.tgz",
- "integrity": "sha512-/aA0kLeRb5N9K0d4fw7ooEbI+xDe+DKD499EQqygGqeS8N3xto15p09uY2xj7ixP81sNPXvRLnAQIqdVStgb1A=="
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg=="
},
"regenerator-transform": {
"version": "0.10.1",
@@ -17654,9 +14134,9 @@
"integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==",
"dev": true,
"requires": {
- "babel-runtime": "6.26.0",
- "babel-types": "6.26.0",
- "private": "0.1.7"
+ "babel-runtime": "^6.18.0",
+ "babel-types": "^6.19.0",
+ "private": "^0.1.6"
}
},
"regex-cache": {
@@ -17665,13 +14145,23 @@
"integrity": "sha512-nVIZwtCjkC9YgvWkpM55B5rBhBYRZhAaJbgcFYXXsHnbZ9UZI9nnVWYZpBlCqv9ho2eZryPnWrZGsOdPwVWXWQ==",
"dev": true,
"requires": {
- "is-equal-shallow": "0.1.3"
+ "is-equal-shallow": "^0.1.3"
}
},
- "regexp-quote": {
- "version": "0.0.0",
- "resolved": "https://registry.npmjs.org/regexp-quote/-/regexp-quote-0.0.0.tgz",
- "integrity": "sha1-Hg9GUMhi3L/tVP1CsUjpuxch/PI="
+ "regex-not": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz",
+ "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.2",
+ "safe-regex": "^1.1.0"
+ }
+ },
+ "regexpp": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-1.1.0.tgz",
+ "integrity": "sha512-LOPw8FpgdQF9etWMaAfG/WRthIdXJGYp4mJ2Jgn/2lpkbod9jPn0t9UqN7AxBOKNfzRbYyVfgc7Vk4t/MpnXgw=="
},
"regexpu-core": {
"version": "2.0.0",
@@ -17679,19 +14169,19 @@
"integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=",
"dev": true,
"requires": {
- "regenerate": "1.3.3",
- "regjsgen": "0.2.0",
- "regjsparser": "0.1.5"
+ "regenerate": "^1.2.1",
+ "regjsgen": "^0.2.0",
+ "regjsparser": "^0.1.4"
}
},
"registry-auth-token": {
- "version": "3.3.1",
- "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.1.tgz",
- "integrity": "sha1-+w0yie4Nmtosu1KvXf5mywcNMAY=",
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz",
+ "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==",
"dev": true,
"requires": {
- "rc": "1.2.1",
- "safe-buffer": "5.1.1"
+ "rc": "^1.1.6",
+ "safe-buffer": "^5.0.1"
}
},
"registry-url": {
@@ -17700,7 +14190,7 @@
"integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=",
"dev": true,
"requires": {
- "rc": "1.2.1"
+ "rc": "^1.0.1"
}
},
"regjsgen": {
@@ -17715,7 +14205,7 @@
"integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=",
"dev": true,
"requires": {
- "jsesc": "0.5.0"
+ "jsesc": "~0.5.0"
},
"dependencies": {
"jsesc": {
@@ -17733,15 +14223,25 @@
"dev": true
},
"render-media": {
- "version": "2.10.0",
- "resolved": "https://registry.npmjs.org/render-media/-/render-media-2.10.0.tgz",
- "integrity": "sha1-V/OfigJn5KZ5XPuhlImYK0BxdFo=",
- "requires": {
- "debug": "2.6.9",
- "is-ascii": "1.0.0",
- "mediasource": "2.1.3",
- "stream-to-blob-url": "2.1.0",
- "videostream": "2.4.2"
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/render-media/-/render-media-3.1.0.tgz",
+ "integrity": "sha512-rTNcgMHJ/MrQbt96bTTwlfBY1A87EqNx0buJ2pPHTuLGwk0Aw99e1BrHgr6SpB4D7Cb7AMdiL/Gzx+UYrHliVw==",
+ "requires": {
+ "debug": "^3.1.0",
+ "is-ascii": "^1.0.0",
+ "mediasource": "^2.1.0",
+ "stream-to-blob-url": "^2.0.0",
+ "videostream": "^2.3.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
}
},
"repeat-element": {
@@ -17761,7 +14261,7 @@
"resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
"integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
"requires": {
- "is-finite": "1.0.2"
+ "is-finite": "^1.0.0"
}
},
"replace-ext": {
@@ -17771,53 +14271,36 @@
"dev": true
},
"request": {
- "version": "2.82.0",
- "resolved": "https://registry.npmjs.org/request/-/request-2.82.0.tgz",
- "integrity": "sha512-/QWqfmyTfQ4OYs6EhB1h2wQsX9ZxbuNePCvCm0Mdz/mxw73mjdg0D4QdIl0TQBFs35CZmMXLjk0iCGK395CUDg==",
- "requires": {
- "aws-sign2": "0.7.0",
- "aws4": "1.6.0",
- "caseless": "0.12.0",
- "combined-stream": "1.0.5",
- "extend": "3.0.1",
- "forever-agent": "0.6.1",
- "form-data": "2.3.1",
- "har-validator": "5.0.3",
- "hawk": "6.0.2",
- "http-signature": "1.2.0",
- "is-typedarray": "1.0.0",
- "isstream": "0.1.2",
- "json-stringify-safe": "5.0.1",
- "mime-types": "2.1.17",
- "oauth-sign": "0.8.2",
- "performance-now": "2.1.0",
- "qs": "6.5.1",
- "safe-buffer": "5.1.1",
- "stringstream": "0.0.5",
- "tough-cookie": "2.3.3",
- "tunnel-agent": "0.6.0",
- "uuid": "3.1.0"
+ "version": "2.87.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.87.0.tgz",
+ "integrity": "sha512-fcogkm7Az5bsS6Sl0sibkbhcKsnyon/jV1kF3ajGmF0c8HrttdKTPRT9hieOaQHA5HEq6r8OyWOo/o781C1tNw==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.6.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.1",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.1",
+ "har-validator": "~5.0.3",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.17",
+ "oauth-sign": "~0.8.2",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.1",
+ "safe-buffer": "^5.1.1",
+ "tough-cookie": "~2.3.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.1.0"
},
"dependencies": {
"extend": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
"integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ="
- },
- "form-data": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.1.tgz",
- "integrity": "sha1-b7lPvXGIUwbXPRXMSX/kzE7NRL8=",
- "requires": {
- "asynckit": "0.4.0",
- "combined-stream": "1.0.5",
- "mime-types": "2.1.17"
- }
- },
- "qs": {
- "version": "6.5.1",
- "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
- "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
}
}
},
@@ -17826,7 +14309,7 @@
"resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.1.tgz",
"integrity": "sha1-Pu4AssWqgyOc+wTFcA2jb4HNCLY=",
"requires": {
- "lodash": "4.17.4"
+ "lodash": "^4.13.1"
}
},
"request-promise-native": {
@@ -17835,8 +14318,8 @@
"integrity": "sha1-UoF3D2jgyXGeUWP9P6tIIhX0/aU=",
"requires": {
"request-promise-core": "1.1.1",
- "stealthy-require": "1.1.1",
- "tough-cookie": "2.3.3"
+ "stealthy-require": "^1.1.0",
+ "tough-cookie": ">=2.3.3"
}
},
"require-directory": {
@@ -17854,32 +14337,50 @@
"resolved": "https://registry.npmjs.org/require-uncached/-/require-uncached-1.0.3.tgz",
"integrity": "sha1-Tg1W1slmL9MeQwEcS5WqSZVUIdM=",
"requires": {
- "caller-path": "0.1.0",
- "resolve-from": "1.0.1"
+ "caller-path": "^0.1.0",
+ "resolve-from": "^1.0.0"
}
},
"requires-port": {
- "version": "0.0.1",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-0.0.1.tgz",
- "integrity": "sha1-S0QUQR2d98hVmV3YmajHiilRwW0="
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
+ "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
+ "dev": true
},
"resolve": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.4.0.tgz",
- "integrity": "sha512-aW7sVKPufyHqOmyyLzg/J+8606v5nevBgaliIlV7nUpVMsDnoBGV/cbSLNjZAg9q0Cfd/+easKVKQ8vOu8fn1Q==",
+ "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"
+ }
+ },
+ "resolve-cwd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz",
+ "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=",
"dev": true,
"requires": {
- "path-parse": "1.0.5"
+ "resolve-from": "^3.0.0"
+ },
+ "dependencies": {
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
}
},
"resolve-dir": {
- "version": "0.1.1",
- "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-0.1.1.tgz",
- "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=",
+ "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": "1.2.2",
- "global-modules": "0.2.3"
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
}
},
"resolve-from": {
@@ -17898,10 +14399,16 @@
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
"integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
"requires": {
- "onetime": "2.0.1",
- "signal-exit": "3.0.2"
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
}
},
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
"rgb2hex": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.0.tgz",
@@ -17914,174 +14421,57 @@
"integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
"dev": true,
"requires": {
- "align-text": "0.1.4"
+ "align-text": "^0.1.1"
}
},
"rimraf": {
- "version": "2.6.2",
- "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz",
- "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
- "requires": {
- "glob": "7.1.2"
- }
- },
- "ripemd160": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.1.tgz",
- "integrity": "sha1-D0WEKVxTo2KK9+bXmsohzlfRxuc=",
- "requires": {
- "hash-base": "2.0.2",
- "inherits": "2.0.3"
- }
- },
- "ripple-address-codec": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/ripple-address-codec/-/ripple-address-codec-2.0.1.tgz",
- "integrity": "sha1-7dvjp5YNLgLFwcdPuan6DS37ZXE=",
- "requires": {
- "hash.js": "1.1.3",
- "x-address-codec": "0.7.2"
- }
- },
- "ripple-binary-codec": {
- "version": "0.1.12",
- "resolved": "https://registry.npmjs.org/ripple-binary-codec/-/ripple-binary-codec-0.1.12.tgz",
- "integrity": "sha1-MPthqNW/YTAYmWFsb4QuOTCC44U=",
- "requires": {
- "babel-runtime": "6.26.0",
- "bn.js": "4.11.8",
- "create-hash": "1.1.3",
- "decimal.js": "5.0.8",
- "inherits": "2.0.3",
- "lodash": "4.17.4",
- "ripple-address-codec": "2.0.1"
- }
- },
- "ripple-hashes": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/ripple-hashes/-/ripple-hashes-0.3.1.tgz",
- "integrity": "sha1-8vRvH/BeZIdQCpmDkBkRTNJIJBE=",
+ "version": "2.4.5",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
+ "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=",
"requires": {
- "bignumber.js": "4.1.0",
- "create-hash": "1.1.3",
- "ripple-address-codec": "2.0.1",
- "ripple-binary-codec": "0.1.12"
- },
- "dependencies": {
- "bignumber.js": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
- "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA=="
- }
- }
- },
- "ripple-keypairs": {
- "version": "0.10.1",
- "resolved": "https://registry.npmjs.org/ripple-keypairs/-/ripple-keypairs-0.10.1.tgz",
- "integrity": "sha1-73lrUZuyAmglFefN1gY3YmNpQ+Y=",
- "requires": {
- "babel-runtime": "5.8.38",
- "bn.js": "3.3.0",
- "brorand": "1.1.0",
- "elliptic": "5.2.1",
- "hash.js": "1.1.3",
- "ripple-address-codec": "2.0.1"
+ "glob": "^6.0.1"
},
"dependencies": {
- "babel-runtime": {
- "version": "5.8.38",
- "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-5.8.38.tgz",
- "integrity": "sha1-HAsC62MxL18If/IEUIJ7QlydTBk=",
- "requires": {
- "core-js": "1.2.7"
- }
- },
- "bn.js": {
- "version": "3.3.0",
- "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-3.3.0.tgz",
- "integrity": "sha1-ETjld4if3Je72rUYRPIZDfwK49c="
- },
- "core-js": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/core-js/-/core-js-1.2.7.tgz",
- "integrity": "sha1-ZSKUwUZR2yj6k70tX/KYOk8IxjY="
- },
- "elliptic": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-5.2.1.tgz",
- "integrity": "sha1-+ilLZWPG3bybo9yFlGh66ECFjxA=",
+ "glob": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+ "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
"requires": {
- "bn.js": "3.3.0",
- "brorand": "1.1.0",
- "hash.js": "1.1.3",
- "inherits": "2.0.3"
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "2 || 3",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
}
}
}
},
- "ripple-lib": {
- "version": "0.17.9",
- "resolved": "https://registry.npmjs.org/ripple-lib/-/ripple-lib-0.17.9.tgz",
- "integrity": "sha1-eSipZejwoEKmUjm9XNi/PdIuyBw=",
- "requires": {
- "bignumber.js": "4.1.0",
- "https-proxy-agent": "1.0.0",
- "jsonschema": "1.2.0",
- "lodash": "4.17.4",
- "ripple-address-codec": "2.0.1",
- "ripple-binary-codec": "0.1.12",
- "ripple-hashes": "0.3.1",
- "ripple-keypairs": "0.10.1",
- "ripple-lib-transactionparser": "0.6.2",
- "ws": "3.3.2"
- },
- "dependencies": {
- "bignumber.js": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
- "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA=="
- }
- }
- },
- "ripple-lib-transactionparser": {
- "version": "0.6.2",
- "resolved": "https://registry.npmjs.org/ripple-lib-transactionparser/-/ripple-lib-transactionparser-0.6.2.tgz",
- "integrity": "sha1-6xF4NIFsqzOYRFp07Dys7JW2tfo=",
+ "ripemd160": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz",
+ "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==",
"requires": {
- "bignumber.js": "4.1.0",
- "lodash": "4.17.4"
- },
- "dependencies": {
- "bignumber.js": {
- "version": "4.1.0",
- "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-4.1.0.tgz",
- "integrity": "sha512-eJzYkFYy9L4JzXsbymsFn3p54D+llV27oTQ+ziJG7WFRheJcNZilgVXMG0LoZtlQSKBsJdWtLFqOD0u+U0jZKA=="
- }
+ "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=",
- "optional": true
- },
"run-async": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
"integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
"requires": {
- "is-promise": "2.1.0"
+ "is-promise": "^2.1.0"
}
},
"run-parallel": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.6.tgz",
- "integrity": "sha1-KQA8miFj4B4tLfyQV18sbB1hoDk="
+ "version": "1.1.9",
+ "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz",
+ "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q=="
},
"run-parallel-limit": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.0.3.tgz",
- "integrity": "sha1-bDkwzHwLR9Na50IBCfZgqt4kAeM="
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/run-parallel-limit/-/run-parallel-limit-1.0.5.tgz",
+ "integrity": "sha512-NsY+oDngvrvMxKB3G8ijBzIema6aYbQMD2bHOamvN52BysbIGTnEY2xsNyfrcr9GhY995/t/0nQN3R3oZvaDlg=="
},
"run-queue": {
"version": "1.0.3",
@@ -18089,41 +14479,58 @@
"integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=",
"dev": true,
"requires": {
- "aproba": "1.2.0"
+ "aproba": "^1.1.1"
}
},
"run-series": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.4.tgz",
- "integrity": "sha1-iac93F51ye+KtjIMChYA1qQRebk="
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.8.tgz",
+ "integrity": "sha512-+GztYEPRpIsQoCSraWHDBs9WVy4eVME16zhOtDB4H9J4xN0XRhknnmLOl+4gRgZtu8dpp9N/utSPjKH/xmDzXg=="
},
"rusha": {
- "version": "0.8.6",
- "resolved": "https://registry.npmjs.org/rusha/-/rusha-0.8.6.tgz",
- "integrity": "sha1-smTdqk1JodZzAAYYWLqTWMStyhQ="
+ "version": "0.8.13",
+ "resolved": "https://registry.npmjs.org/rusha/-/rusha-0.8.13.tgz",
+ "integrity": "sha1-mghOe4YLF7/zAVuSxnpqM2GRUTo="
},
"rx": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/rx/-/rx-4.1.0.tgz",
- "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I="
+ "integrity": "sha1-pfE/957zt0D+MKqAP7CfmIBdR4I=",
+ "dev": true
},
"rx-lite": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
- "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
- "dev": true
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+ "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ="
+ },
+ "rx-lite-aggregates": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+ "requires": {
+ "rx-lite": "*"
+ }
},
"safe-buffer": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
- "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
},
"safe-json-stringify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.0.4.tgz",
- "integrity": "sha1-gaCY9Efku8P/MxKiQ1IbwGDvWRE=",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz",
+ "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==",
"optional": true
},
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
"samsam": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/samsam/-/samsam-1.1.2.tgz",
@@ -18136,17 +14543,7 @@
"integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=",
"dev": true,
"requires": {
- "truncate-utf8-bytes": "1.0.2"
- }
- },
- "sanitize-html": {
- "version": "1.13.0",
- "resolved": "https://registry.npmjs.org/sanitize-html/-/sanitize-html-1.13.0.tgz",
- "integrity": "sha1-TuF8vsUWv+MvLOZoaladfmtPNjE=",
- "requires": {
- "htmlparser2": "3.9.2",
- "regexp-quote": "0.0.0",
- "xtend": "4.0.1"
+ "truncate-utf8-bytes": "^1.0.0"
}
},
"sax": {
@@ -18159,36 +14556,16 @@
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.3.0.tgz",
"integrity": "sha1-9YdyIs4+kx7a4DnxfrNxbnE3+M8=",
"requires": {
- "ajv": "5.2.3"
- }
- },
- "secp256k1": {
- "version": "3.2.5",
- "resolved": "https://registry.npmjs.org/secp256k1/-/secp256k1-3.2.5.tgz",
- "integrity": "sha1-Dd5bJ+UCFmX23/ynssPgEMbBPJM=",
- "requires": {
- "bindings": "1.3.0",
- "bip66": "1.1.5",
- "bn.js": "4.11.8",
- "create-hash": "1.1.3",
- "drbg.js": "1.0.1",
- "elliptic": "6.4.0",
- "nan": "2.7.0",
- "prebuild-install": "2.2.2"
+ "ajv": "^5.0.0"
}
},
- "secrets.js-grempe": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/secrets.js-grempe/-/secrets.js-grempe-1.1.0.tgz",
- "integrity": "sha1-uztgbdaGN8okRoGhD97mxRIEkpQ="
- },
"seek-bzip": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/seek-bzip/-/seek-bzip-1.0.5.tgz",
"integrity": "sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w=",
"dev": true,
"requires": {
- "commander": "2.8.1"
+ "commander": "~2.8.1"
},
"dependencies": {
"commander": {
@@ -18197,7 +14574,7 @@
"integrity": "sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ=",
"dev": true,
"requires": {
- "graceful-readlink": "1.0.1"
+ "graceful-readlink": ">= 1.0.0"
}
}
}
@@ -18209,26 +14586,18 @@
"dev": true
},
"selfsigned": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.1.tgz",
- "integrity": "sha1-v4y3uDJWxFUeMTR8YxF3jbme7FI=",
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.3.tgz",
+ "integrity": "sha512-vmZenZ+8Al3NLHkWnhBQ0x6BkML1eCP2xEi3JE+f3D9wW9fipD9NNJHYtE9XJM4TsPaHGZJIamrSI6MTg1dU2Q==",
"dev": true,
"requires": {
- "node-forge": "0.6.33"
- },
- "dependencies": {
- "node-forge": {
- "version": "0.6.33",
- "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.6.33.tgz",
- "integrity": "sha1-RjgRh59XPUUVWtap9D3ClujoXrw=",
- "dev": true
- }
+ "node-forge": "0.7.5"
}
},
"semver": {
- "version": "5.4.1",
- "resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
- "integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg=="
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
+ "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
},
"semver-diff": {
"version": "2.1.0",
@@ -18236,28 +14605,36 @@
"integrity": "sha1-S7uEN8jTfksM8aaP1ybsbWRdbTY=",
"dev": true,
"requires": {
- "semver": "5.4.1"
+ "semver": "^5.0.3"
}
},
"send": {
- "version": "0.15.6",
- "resolved": "https://registry.npmjs.org/send/-/send-0.15.6.tgz",
- "integrity": "sha1-IPI6nJJbdiq4JwX+L52yUqzkfjQ=",
+ "version": "0.16.2",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.16.2.tgz",
+ "integrity": "sha512-E64YFPUssFHEFBvpbbjr44NCLtI1AohxQ8ZSiJjQLskAdKuriYEP6VyGEsRDH8ScozGpkaX1BGvhanqCwkcEZw==",
"dev": true,
"requires": {
"debug": "2.6.9",
- "depd": "1.1.1",
- "destroy": "1.0.4",
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "etag": "1.8.1",
- "fresh": "0.5.2",
- "http-errors": "1.6.2",
- "mime": "1.3.4",
+ "depd": "~1.1.2",
+ "destroy": "~1.0.4",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "fresh": "0.5.2",
+ "http-errors": "~1.6.2",
+ "mime": "1.4.1",
"ms": "2.0.0",
- "on-finished": "2.3.0",
- "range-parser": "1.2.0",
- "statuses": "1.3.1"
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.0",
+ "statuses": "~1.4.0"
+ },
+ "dependencies": {
+ "mime": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
+ "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
+ "dev": true
+ }
}
},
"sequencify": {
@@ -18266,42 +14643,37 @@
"integrity": "sha1-kM/xnQLgcCf9dn9erT57ldHnOAw=",
"dev": true
},
+ "serialize-javascript": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.5.0.tgz",
+ "integrity": "sha512-Ga8c8NjAAp46Br4+0oZ2WxJCwIzwP60Gq1YPgU+39PiTVxyed/iKE/zyZI6+UlVYH5Q4PaQdHhcegIFPZTUfoQ==",
+ "dev": true
+ },
"serve-index": {
- "version": "1.9.0",
- "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.0.tgz",
- "integrity": "sha1-0rKA/FYNYW7oG0i/D6gqvtJIXOc=",
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz",
+ "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=",
"dev": true,
"requires": {
- "accepts": "1.3.4",
+ "accepts": "~1.3.4",
"batch": "0.6.1",
- "debug": "2.6.8",
- "escape-html": "1.0.3",
- "http-errors": "1.6.2",
- "mime-types": "2.1.17",
- "parseurl": "1.3.2"
- },
- "dependencies": {
- "debug": {
- "version": "2.6.8",
- "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.8.tgz",
- "integrity": "sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=",
- "dev": true,
- "requires": {
- "ms": "2.0.0"
- }
- }
+ "debug": "2.6.9",
+ "escape-html": "~1.0.3",
+ "http-errors": "~1.6.2",
+ "mime-types": "~2.1.17",
+ "parseurl": "~1.3.2"
}
},
"serve-static": {
- "version": "1.12.6",
- "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.12.6.tgz",
- "integrity": "sha1-uXN3P2NEmTTaVOW+ul4x2fQhFXc=",
+ "version": "1.13.2",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.2.tgz",
+ "integrity": "sha512-p/tdJrO4U387R9oMjb1oj7qSMaMfmOyd4j9hOFoxZe2baQszgHcSWjuya/CiT5kgZZKRudHNOA0pYXOl8rQ5nw==",
"dev": true,
"requires": {
- "encodeurl": "1.0.1",
- "escape-html": "1.0.3",
- "parseurl": "1.3.2",
- "send": "0.15.6"
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.2",
+ "send": "0.16.2"
}
},
"set-blocking": {
@@ -18315,32 +14687,54 @@
"integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=",
"dev": true
},
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
+ }
+ },
"setimmediate": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
"integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU="
},
"setprototypeof": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
- "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
+ "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==",
+ "dev": true
},
"sha.js": {
- "version": "2.4.9",
- "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.9.tgz",
- "integrity": "sha512-G8zektVqbiPHrylgew9Zg1VRB1L/DtXNUVAM6q4QLy8NE3qtHlFXTf8VLL4k1Yl6c7NMjtZUTdXV+X44nFaT6A==",
+ "version": "2.4.11",
+ "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz",
+ "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==",
"requires": {
- "inherits": "2.0.3",
- "safe-buffer": "5.1.1"
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1"
}
},
"sha3": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/sha3/-/sha3-1.2.0.tgz",
- "integrity": "sha1-aYnxtwpJhwWHajc+LGKs6WqpOZo=",
- "optional": true,
+ "version": "github:brave/node-sha3#d44d293e997c061560c2bd8a41451ab979e5a4ca",
+ "from": "github:brave/node-sha3",
"requires": {
- "nan": "2.7.0"
+ "nan": "^2.0.5"
}
},
"shebang-command": {
@@ -18348,7 +14742,7 @@
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
"integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
"requires": {
- "shebang-regex": "1.0.0"
+ "shebang-regex": "^1.0.0"
}
},
"shebang-regex": {
@@ -18362,9 +14756,9 @@
"integrity": "sha1-svXHfvlxSPS09uImguELuoZnz/E=",
"dev": true,
"requires": {
- "glob": "7.1.2",
- "interpret": "1.0.4",
- "rechoir": "0.6.2"
+ "glob": "^7.0.0",
+ "interpret": "^1.0.0",
+ "rechoir": "^0.6.2"
}
},
"shellwords": {
@@ -18390,123 +14784,73 @@
"integrity": "sha1-c0TLuLbib7J9ZrL8hvn21Zl1IcY="
},
"simple-get": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-1.4.3.tgz",
- "integrity": "sha1-6XVe2kB+ltpAxeUVjJ6jezO+y+s=",
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.8.1.tgz",
+ "integrity": "sha512-lSSHRSw3mQNUGPAYRqo7xy9dhKmxFXIjLjp4KHpf99GEH2VH7C3AM+Qfx6du6jhfUi6Vm7XnbEVEf7Wb6N8jRw==",
"requires": {
- "once": "1.4.0",
- "unzip-response": "1.0.2",
- "xtend": "4.0.1"
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
}
},
"simple-peer": {
- "version": "8.1.1",
- "resolved": "https://registry.npmjs.org/simple-peer/-/simple-peer-8.1.1.tgz",
- "integrity": "sha512-t2zRYgj1HE5lbfkuL2bJ8s8Q60TQfPwOfDj/TA1/N/Qvi8pdj4uEU0bctrZIsHZlzuU7HM+RFR/YBbiLJjHpxQ==",
- "requires": {
- "debug": "2.6.9",
- "get-browser-rtc": "1.0.2",
- "inherits": "2.0.3",
- "randombytes": "2.0.5",
- "readable-stream": "2.3.3"
+ "version": "9.1.1",
+ "resolved": "https://registry.npmjs.org/simple-peer/-/simple-peer-9.1.1.tgz",
+ "integrity": "sha512-Q1R/QHZPXpIp/2ozVtTXQa9dZaM3irXxqCRhCRyksbjqxp6t50IDmw15NNg1PzEa0PrGJG7jbZYFZn2B6sjUjg==",
+ "requires": {
+ "debug": "^3.1.0",
+ "get-browser-rtc": "^1.0.0",
+ "inherits": "^2.0.1",
+ "randombytes": "^2.0.3",
+ "readable-stream": "^2.3.4"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
- "safe-buffer": "5.1.1"
+ "ms": "2.0.0"
}
}
}
},
"simple-sha1": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/simple-sha1/-/simple-sha1-2.1.0.tgz",
- "integrity": "sha1-lCe7lv8SY8wQqEFM7dUaGLkZ6LM=",
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/simple-sha1/-/simple-sha1-2.1.1.tgz",
+ "integrity": "sha512-pFMPd+I/lQkpf4wFUeS/sED5IqdIG1lUlrQviBMV4u4mz8BRAcB5fvUx5Ckfg3kBigEglAjHg7E9k/yy2KlCqA==",
"requires": {
- "rusha": "0.8.6"
+ "rusha": "^0.8.1"
}
},
"simple-websocket": {
- "version": "5.0.2",
- "resolved": "https://registry.npmjs.org/simple-websocket/-/simple-websocket-5.0.2.tgz",
- "integrity": "sha1-BA2Q3qnkGZqXYTOUzmiTLErvPUQ=",
- "requires": {
- "debug": "2.6.9",
- "inherits": "2.0.3",
- "randombytes": "2.0.5",
- "readable-stream": "2.3.3",
- "safe-buffer": "5.1.1",
- "ws": "2.3.1"
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/simple-websocket/-/simple-websocket-7.0.2.tgz",
+ "integrity": "sha512-cAjSaqHMtO2qc1HHSrW44aTrb2Xa7wZzHajvH6An4IhCFjTuPUXfmSByd9Z0B5Bc6bmiwQ2bFHMUMA8vGC5Bug==",
+ "requires": {
+ "debug": "^3.1.0",
+ "inherits": "^2.0.1",
+ "randombytes": "^2.0.3",
+ "readable-stream": "^2.0.5",
+ "safe-buffer": "^5.0.1",
+ "ws": "^4.0.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
- "safe-buffer": "5.1.1"
+ "ms": "2.0.0"
}
},
- "ultron": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.0.tgz",
- "integrity": "sha1-sHoualQagV/Go0zNRTO67DB8qGQ="
- },
"ws": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/ws/-/ws-2.3.1.tgz",
- "integrity": "sha1-a5Sz5EfLajY/eF6vlK9jWejoHIA=",
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-4.1.0.tgz",
+ "integrity": "sha512-ZGh/8kF9rrRNffkLFV4AzhvooEclrOH0xaugmqGsIfFgOE/pIz4fMc4Ef+5HSQqTEug2S9JZIWDR47duDSLfaA==",
"requires": {
- "safe-buffer": "5.0.1",
- "ultron": "1.1.0"
- },
- "dependencies": {
- "safe-buffer": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.0.1.tgz",
- "integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c="
- }
+ "async-limiter": "~1.0.0",
+ "safe-buffer": "~5.1.0"
}
}
}
@@ -18517,7 +14861,7 @@
"integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=",
"dev": true,
"requires": {
- "string-width": "1.0.2"
+ "string-width": "^1.0.1"
}
},
"sinon": {
@@ -18529,7 +14873,7 @@
"formatio": "1.1.1",
"lolex": "1.3.2",
"samsam": "1.1.2",
- "util": "0.10.3"
+ "util": ">=0.10.3 <1"
}
},
"slash": {
@@ -18538,101 +14882,201 @@
"integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU="
},
"slice-ansi": {
- "version": "0.0.4",
- "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
- "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
- "dev": true
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-1.0.0.tgz",
+ "integrity": "sha512-POqxBK6Lb3q6s047D/XsDVNPnF9Dl8JSaqe9h9lURl0OdNqy/ujDrOiIHtsqXMGbWWTIomRzAMaTyawAU//Reg==",
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0"
+ },
+ "dependencies": {
+ "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="
+ }
+ }
},
- "smart-buffer": {
- "version": "1.1.15",
- "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz",
- "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY="
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
},
- "snazzy": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-7.0.0.tgz",
- "integrity": "sha1-le2szEqNb4D0rFzHtSDo+PmsIyU=",
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
"requires": {
- "chalk": "1.1.3",
- "inherits": "2.0.3",
- "minimist": "1.2.0",
- "readable-stream": "2.3.3",
- "standard-json": "1.0.2",
- "text-table": "0.2.0"
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
},
"dependencies": {
- "isarray": {
+ "define-property": {
"version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
+ "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"
+ }
},
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ "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"
+ }
},
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
+ "kind-of": "^6.0.0"
}
},
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
}
}
}
},
- "sntp": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-2.0.2.tgz",
- "integrity": "sha1-UGQRDwr4X3z9t9a2ekACjOUrSys=",
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
"requires": {
- "hoek": "4.2.0"
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
}
},
- "sockjs": {
- "version": "0.3.18",
- "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.18.tgz",
- "integrity": "sha1-2bKJMWyn33dZXvKZ4HXw+TfrQgc=",
+ "snazzy": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/snazzy/-/snazzy-7.1.1.tgz",
+ "integrity": "sha512-gJ46s+jcwOeRhO9uEkTyzcREFZ0c5LZOgcVakLxTPIvhRIywKvbvArvMg5e8bBbpWe4InC/8eyEQOGXgJVNOfw==",
+ "requires": {
+ "chalk": "^2.3.0",
+ "inherits": "^2.0.1",
+ "minimist": "^1.1.1",
+ "readable-stream": "^2.0.6",
+ "standard-json": "^1.0.0",
+ "strip-ansi": "^4.0.0",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "sntp": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
+ "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
"dev": true,
"requires": {
- "faye-websocket": "0.10.0",
- "uuid": "2.0.3"
+ "hoek": "2.x.x"
},
"dependencies": {
- "uuid": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/uuid/-/uuid-2.0.3.tgz",
- "integrity": "sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho=",
+ "hoek": {
+ "version": "2.16.3",
+ "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
+ "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
"dev": true
}
}
},
+ "sockjs": {
+ "version": "0.3.19",
+ "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.19.tgz",
+ "integrity": "sha512-V48klKZl8T6MzatbLlzzRNhMepEys9Y4oGFpypBFFn1gLI/QQ9HtLLyWJNbPlwGLelOVOEijUbTTJeLLI59jLw==",
+ "dev": true,
+ "requires": {
+ "faye-websocket": "^0.10.0",
+ "uuid": "^3.0.1"
+ }
+ },
"sockjs-client": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.1.4.tgz",
"integrity": "sha1-W6vjhrd15M8U51IJEUUmVAFsixI=",
"dev": true,
"requires": {
- "debug": "2.6.9",
+ "debug": "^2.6.6",
"eventsource": "0.1.6",
- "faye-websocket": "0.11.1",
- "inherits": "2.0.3",
- "json3": "3.3.2",
- "url-parse": "1.1.9"
+ "faye-websocket": "~0.11.0",
+ "inherits": "^2.0.1",
+ "json3": "^3.3.2",
+ "url-parse": "^1.1.8"
},
"dependencies": {
"faye-websocket": {
@@ -18641,60 +15085,42 @@
"integrity": "sha1-8O/hjE9W5PQK/H4Gxxn9XuYYjzg=",
"dev": true,
"requires": {
- "websocket-driver": "0.7.0"
+ "websocket-driver": ">=0.5.1"
}
}
}
},
- "socks": {
- "version": "1.1.10",
- "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz",
- "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=",
- "requires": {
- "ip": "1.1.5",
- "smart-buffer": "1.1.15"
- }
- },
- "socks-proxy-agent": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz",
- "integrity": "sha512-sFtmYqdUK5dAMh85H0LEVFUCO7OhJJe1/z2x/Z6mxp3s7/QPf1RkZmpZy+BpuU0bEjcV9npqKjq9Y3kwFUjnxw==",
- "requires": {
- "agent-base": "2.1.1",
- "extend": "3.0.0",
- "socks": "1.1.10"
- }
- },
"sort-keys": {
"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.1.0"
+ "is-plain-obj": "^1.0.0"
}
},
"source-list-map": {
- "version": "0.1.8",
- "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-0.1.8.tgz",
- "integrity": "sha1-xVCyq1Qn9rPyH1r+rYjE9Vh7IQY=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
+ "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
"dev": true
},
"source-map": {
- "version": "0.5.7",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
- "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
+ "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="
},
"source-map-resolve": {
- "version": "0.3.1",
- "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.3.1.tgz",
- "integrity": "sha1-YQ9hIqRFuN1RU1oqcbeD38Ekh2E=",
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
"dev": true,
"requires": {
- "atob": "1.1.3",
- "resolve-url": "0.2.1",
- "source-map-url": "0.3.0",
- "urix": "0.1.0"
+ "atob": "^2.1.1",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
}
},
"source-map-support": {
@@ -18702,19 +15128,26 @@
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz",
"integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==",
"requires": {
- "source-map": "0.5.7"
+ "source-map": "^0.5.6"
+ },
+ "dependencies": {
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w="
+ }
}
},
"source-map-url": {
- "version": "0.3.0",
- "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.3.0.tgz",
- "integrity": "sha1-fsrxO1e80J2opAxdJp2zN5nUqvk=",
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "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=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/sparkles/-/sparkles-1.0.1.tgz",
+ "integrity": "sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==",
"dev": true
},
"spawn-sync": {
@@ -18723,107 +15156,87 @@
"integrity": "sha1-sAeZVX63+wyDdsKdROih6mfldHY=",
"dev": true,
"requires": {
- "concat-stream": "1.6.0",
- "os-shim": "0.1.3"
+ "concat-stream": "^1.4.7",
+ "os-shim": "^0.1.2"
}
},
"spdx-correct": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-1.0.2.tgz",
- "integrity": "sha1-SzBz2TP/UfORLwOsVRlJikFQ20A=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.0.0.tgz",
+ "integrity": "sha512-N19o9z5cEyc8yQQPukRCZ9EUmb4HUpnrmaL/fxS2pBo2jbfcFRVuFZ/oFC+vZz0MNNk0h80iMn5/S6qGZOL5+g==",
"requires": {
- "spdx-license-ids": "1.2.2"
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
}
},
+ "spdx-exceptions": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.1.0.tgz",
+ "integrity": "sha512-4K1NsmrlCU1JJgUrtgEeTVyfx8VaYea9J9LvARxhbHtVtohPs/gFGG5yy49beySjlIMhhXZ4QqujIZEfS4l6Cg=="
+ },
"spdx-expression-parse": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz",
- "integrity": "sha1-m98vIOH0DtRH++JzJmGR/O1RYmw="
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
},
"spdx-license-ids": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz",
- "integrity": "sha1-yd96NCRZSt5r0RkA1ZZpbcBrrFc="
+ "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=="
},
"spdy": {
"version": "3.4.7",
"resolved": "https://registry.npmjs.org/spdy/-/spdy-3.4.7.tgz",
"integrity": "sha1-Qv9B7OXMD5mjpsKKq7c/XDsDrLw=",
"dev": true,
- "requires": {
- "debug": "2.6.9",
- "handle-thing": "1.2.5",
- "http-deceiver": "1.2.7",
- "safe-buffer": "5.1.1",
- "select-hose": "2.0.0",
- "spdy-transport": "2.0.20"
- }
- },
- "spdy-transport": {
- "version": "2.0.20",
- "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.0.20.tgz",
- "integrity": "sha1-c15yBUxIayNU/onnAiVgBKOazk0=",
- "dev": true,
- "requires": {
- "debug": "2.6.9",
- "detect-node": "2.0.3",
- "hpack.js": "2.1.6",
- "obuf": "1.1.1",
- "readable-stream": "2.3.3",
- "safe-buffer": "5.1.1",
- "wbuf": "1.7.2"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "requires": {
+ "debug": "^2.6.8",
+ "handle-thing": "^1.2.5",
+ "http-deceiver": "^1.2.7",
+ "safe-buffer": "^5.0.1",
+ "select-hose": "^2.0.0",
+ "spdy-transport": "^2.0.18"
+ }
+ },
+ "spdy-transport": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-2.1.0.tgz",
+ "integrity": "sha512-bpUeGpZcmZ692rrTiqf9/2EUakI6/kXX1Rpe0ib/DyOzbiexVfXkw6GnvI9hVGvIwVaUhkaBojjCZwLNRGQg1g==",
+ "dev": true,
+ "requires": {
+ "debug": "^2.6.8",
+ "detect-node": "^2.0.3",
+ "hpack.js": "^2.1.6",
+ "obuf": "^1.1.1",
+ "readable-stream": "^2.2.9",
+ "safe-buffer": "^5.0.1",
+ "wbuf": "^1.7.2"
}
},
"spectron": {
"version": "github:brave/spectron#375698c8a4b8a2298e808d8e8714813b7636a834",
+ "from": "github:brave/spectron#chromium60",
"dev": true,
"requires": {
- "dev-null": "0.1.1",
+ "dev-null": "^0.1.1",
"electron-chromedriver": "github:brave/electron-chromedriver#772ace180da97768478ce9683b871449c621205a",
- "request": "2.82.0",
- "split": "1.0.1",
- "webdriverio": "4.7.1"
+ "request": "^2.65.0",
+ "split": "^1.0.0",
+ "webdriverio": "^4.0.4"
},
"dependencies": {
"electron-chromedriver": {
"version": "github:brave/electron-chromedriver#772ace180da97768478ce9683b871449c621205a",
+ "from": "github:brave/electron-chromedriver#chromium59",
"dev": true,
"requires": {
- "decompress": "3.0.0",
- "mkdirp": "0.5.1",
- "request": "2.82.0"
+ "decompress": "^3.0.0",
+ "mkdirp": "^0.5.1",
+ "request": "^2.65.0"
}
}
}
@@ -18838,7 +15251,16 @@
"resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
"integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
"requires": {
- "through": "2.3.8"
+ "through": "2"
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
}
},
"split2": {
@@ -18846,43 +15268,16 @@
"resolved": "https://registry.npmjs.org/split2/-/split2-2.2.0.tgz",
"integrity": "sha512-RAb22TG39LhI31MbreBgIuKiIKhVsawfTgEGqKHTK87aG+ul/PB8Sqoi3I7kVdRWiCfrKxK3uo4/YUkpNvhPbw==",
"requires": {
- "through2": "2.0.3"
+ "through2": "^2.0.2"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
}
}
}
@@ -18893,18 +15288,27 @@
"integrity": "sha1-Nr54Mgr+WAH2zqPueLblqrlA6gw="
},
"sshpk": {
- "version": "1.13.1",
- "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.13.1.tgz",
- "integrity": "sha1-US322mKHFEMW3EwY/hzx2UBzm+M=",
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.14.1.tgz",
+ "integrity": "sha1-Ew9Zde3a2WPx1W+SuaxsUfqfg+s=",
"requires": {
- "asn1": "0.2.3",
- "assert-plus": "1.0.0",
- "bcrypt-pbkdf": "1.0.1",
- "dashdash": "1.14.1",
- "ecc-jsbn": "0.1.1",
- "getpass": "0.1.7",
- "jsbn": "0.1.1",
- "tweetnacl": "0.14.5"
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "ssri": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.3.0.tgz",
+ "integrity": "sha512-XRSIPqLij52MtgoQavH/x/dU1qVKtWUAAZeOHsR9c2Ddi4XerFy3mc1alf+dLJKl9EUIm/Ht+EowFkTUOA6GAQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.1.1"
}
},
"standard": {
@@ -18913,34 +15317,59 @@
"integrity": "sha512-JURZ+85ExKLQULckDFijdX5WHzN6RC7fgiZNSV4jFQVo+3tPoQGHyBrGekye/yf0aOfb4210EM5qPNlc2cRh4w==",
"dev": true,
"requires": {
- "eslint": "3.19.0",
+ "eslint": "~3.19.0",
"eslint-config-standard": "10.2.1",
"eslint-config-standard-jsx": "4.0.2",
- "eslint-plugin-import": "2.2.0",
- "eslint-plugin-node": "4.2.3",
- "eslint-plugin-promise": "3.5.0",
- "eslint-plugin-react": "6.10.3",
- "eslint-plugin-standard": "3.0.1",
- "standard-engine": "7.0.0"
+ "eslint-plugin-import": "~2.2.0",
+ "eslint-plugin-node": "~4.2.2",
+ "eslint-plugin-promise": "~3.5.0",
+ "eslint-plugin-react": "~6.10.0",
+ "eslint-plugin-standard": "~3.0.1",
+ "standard-engine": "~7.0.0"
},
"dependencies": {
- "cli-cursor": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
- "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+ "ajv": {
+ "version": "4.11.8",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
+ "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
"dev": true,
"requires": {
- "restore-cursor": "1.0.1"
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
}
},
- "doctrine": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.0.0.tgz",
- "integrity": "sha1-xz2NKQnSIpHhoAejlYBNqLZl/mM=",
+ "ajv-keywords": {
+ "version": "1.5.1",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
+ "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
+ "dev": true
+ },
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+ "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": {
- "esutils": "2.0.2",
- "isarray": "1.0.0"
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "cli-cursor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-1.0.2.tgz",
+ "integrity": "sha1-ZNo/fValRBLll5S9Ytw1KV6PKYc=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^1.0.1"
}
},
"eslint": {
@@ -18949,149 +15378,112 @@
"integrity": "sha1-yPxiAcf0DdCJQbh8CFdnOGpnmsw=",
"dev": true,
"requires": {
- "babel-code-frame": "6.26.0",
- "chalk": "1.1.3",
- "concat-stream": "1.6.0",
- "debug": "2.6.9",
- "doctrine": "2.0.0",
- "escope": "3.6.0",
- "espree": "3.5.1",
- "esquery": "1.0.0",
- "estraverse": "4.2.0",
- "esutils": "2.0.2",
- "file-entry-cache": "2.0.0",
- "glob": "7.1.2",
- "globals": "9.18.0",
- "ignore": "3.3.5",
- "imurmurhash": "0.1.4",
- "inquirer": "0.12.0",
- "is-my-json-valid": "2.16.1",
- "is-resolvable": "1.0.0",
- "js-yaml": "3.10.0",
- "json-stable-stringify": "1.0.1",
- "levn": "0.3.0",
- "lodash": "4.17.4",
- "mkdirp": "0.5.1",
- "natural-compare": "1.4.0",
- "optionator": "0.8.2",
- "path-is-inside": "1.0.2",
- "pluralize": "1.2.1",
- "progress": "1.1.8",
- "require-uncached": "1.0.3",
- "shelljs": "0.7.7",
- "strip-bom": "3.0.0",
- "strip-json-comments": "2.0.1",
- "table": "3.8.3",
- "text-table": "0.2.0",
- "user-home": "2.0.0"
- }
- },
- "eslint-config-standard": {
- "version": "10.2.1",
- "resolved": "https://registry.npmjs.org/eslint-config-standard/-/eslint-config-standard-10.2.1.tgz",
- "integrity": "sha1-wGHk0GbzedwXzVYsZOgZtN1FRZE=",
- "dev": true
- },
- "eslint-config-standard-jsx": {
- "version": "4.0.2",
- "resolved": "https://registry.npmjs.org/eslint-config-standard-jsx/-/eslint-config-standard-jsx-4.0.2.tgz",
- "integrity": "sha512-F8fRh2WFnTek7dZH9ZaE0PCBwdVGkwVWZmizla/DDNOmg7Tx6B/IlK5+oYpiX29jpu73LszeJj5i1axEZv6VMw==",
- "dev": true
- },
- "eslint-plugin-promise": {
- "version": "3.5.0",
- "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-3.5.0.tgz",
- "integrity": "sha1-ePu2/+BHIBYnVp6FpsU3OvKmj8o=",
- "dev": true
- },
- "eslint-plugin-react": {
- "version": "6.10.3",
- "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-6.10.3.tgz",
- "integrity": "sha1-xUNb6wZ3ThLH2y9qut3L+QDNP3g=",
- "dev": true,
- "requires": {
- "array.prototype.find": "2.0.4",
- "doctrine": "1.5.0",
- "has": "1.0.1",
- "jsx-ast-utils": "1.4.1",
- "object.assign": "4.0.4"
- },
- "dependencies": {
- "doctrine": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz",
- "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=",
- "dev": true,
- "requires": {
- "esutils": "2.0.2",
- "isarray": "1.0.0"
- }
- }
+ "babel-code-frame": "^6.16.0",
+ "chalk": "^1.1.3",
+ "concat-stream": "^1.5.2",
+ "debug": "^2.1.1",
+ "doctrine": "^2.0.0",
+ "escope": "^3.6.0",
+ "espree": "^3.4.0",
+ "esquery": "^1.0.0",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^2.0.0",
+ "glob": "^7.0.3",
+ "globals": "^9.14.0",
+ "ignore": "^3.2.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^0.12.0",
+ "is-my-json-valid": "^2.10.0",
+ "is-resolvable": "^1.0.0",
+ "js-yaml": "^3.5.1",
+ "json-stable-stringify": "^1.0.0",
+ "levn": "^0.3.0",
+ "lodash": "^4.0.0",
+ "mkdirp": "^0.5.0",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.1",
+ "pluralize": "^1.2.1",
+ "progress": "^1.1.8",
+ "require-uncached": "^1.0.2",
+ "shelljs": "^0.7.5",
+ "strip-bom": "^3.0.0",
+ "strip-json-comments": "~2.0.1",
+ "table": "^3.7.8",
+ "text-table": "~0.2.0",
+ "user-home": "^2.0.0"
}
},
- "eslint-plugin-standard": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/eslint-plugin-standard/-/eslint-plugin-standard-3.0.1.tgz",
- "integrity": "sha1-NNDJFbRe3G8BA5PH7vOCOwhWXPI=",
- "dev": true
- },
"figures": {
"version": "1.7.0",
"resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
"integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
"dev": true,
"requires": {
- "escape-string-regexp": "1.0.5",
- "object-assign": "4.1.1"
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
}
},
+ "globals": {
+ "version": "9.18.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz",
+ "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==",
+ "dev": true
+ },
"inquirer": {
"version": "0.12.0",
"resolved": "https://registry.npmjs.org/inquirer/-/inquirer-0.12.0.tgz",
"integrity": "sha1-HvK/1jUE3wvHV4X/+MLEHfEvB34=",
"dev": true,
"requires": {
- "ansi-escapes": "1.4.0",
- "ansi-regex": "2.1.1",
- "chalk": "1.1.3",
- "cli-cursor": "1.0.2",
- "cli-width": "2.2.0",
- "figures": "1.7.0",
- "lodash": "4.17.4",
- "readline2": "1.0.1",
- "run-async": "0.1.0",
- "rx-lite": "3.1.2",
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1",
- "through": "2.3.8"
+ "ansi-escapes": "^1.1.0",
+ "ansi-regex": "^2.0.0",
+ "chalk": "^1.0.0",
+ "cli-cursor": "^1.0.1",
+ "cli-width": "^2.0.0",
+ "figures": "^1.3.5",
+ "lodash": "^4.3.0",
+ "readline2": "^1.0.1",
+ "run-async": "^0.1.0",
+ "rx-lite": "^3.1.2",
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.0",
+ "through": "^2.3.6"
}
},
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+ "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
},
"onetime": {
"version": "1.1.0",
- "resolved": "https://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
+ "resolved": "http://registry.npmjs.org/onetime/-/onetime-1.1.0.tgz",
"integrity": "sha1-ofeDj4MUxRbwXs78vEzP4EtO14k=",
"dev": true
},
+ "pluralize": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-1.2.1.tgz",
+ "integrity": "sha1-0aIUg/0iu0HlihL6NCGCMUCJfEU=",
+ "dev": true
+ },
+ "progress": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-1.1.8.tgz",
+ "integrity": "sha1-4mDHj2Fhzdmw5WzD4Khd4Xx6V74=",
+ "dev": true
+ },
"restore-cursor": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-1.0.1.tgz",
"integrity": "sha1-NGYfRohjJ/7SmRR5FSJS35LapUE=",
"dev": true,
"requires": {
- "exit-hook": "1.1.1",
- "onetime": "1.1.0"
+ "exit-hook": "^1.0.0",
+ "onetime": "^1.0.0"
}
},
"run-async": {
@@ -19100,20 +15492,20 @@
"integrity": "sha1-yK1KXhEGYeQCp9IbUw4AnyX444k=",
"dev": true,
"requires": {
- "once": "1.4.0"
+ "once": "^1.3.0"
}
},
- "standard-engine": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz",
- "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=",
- "dev": true,
- "requires": {
- "deglob": "2.1.0",
- "get-stdin": "5.0.1",
- "minimist": "1.2.0",
- "pkg-conf": "2.0.0"
- }
+ "rx-lite": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-3.1.2.tgz",
+ "integrity": "sha1-Gc5QLKVyZl87ZHsQk5+X/RYV8QI=",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-0.0.4.tgz",
+ "integrity": "sha1-7b+JA/ZvfOL46v1s7tZeJkyDGzU=",
+ "dev": true
},
"strip-bom": {
"version": "3.0.0",
@@ -19121,17 +15513,78 @@
"integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
"dev": true
},
+ "table": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
+ "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
+ "dev": true,
+ "requires": {
+ "ajv": "^4.7.0",
+ "ajv-keywords": "^1.0.0",
+ "chalk": "^1.1.1",
+ "lodash": "^4.0.0",
+ "slice-ansi": "0.0.4",
+ "string-width": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "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"
+ }
+ }
+ }
+ },
"user-home": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/user-home/-/user-home-2.0.0.tgz",
"integrity": "sha1-nHC/2Babwdy/SGBODwS4tJzenp8=",
"dev": true,
"requires": {
- "os-homedir": "1.0.2"
+ "os-homedir": "^1.0.0"
}
}
}
},
+ "standard-engine": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/standard-engine/-/standard-engine-7.0.0.tgz",
+ "integrity": "sha1-67d7nI/CyBZf+jU72Rug3/Qa9pA=",
+ "dev": true,
+ "requires": {
+ "deglob": "^2.1.0",
+ "get-stdin": "^5.0.1",
+ "minimist": "^1.1.0",
+ "pkg-conf": "^2.0.0"
+ },
+ "dependencies": {
+ "get-stdin": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-5.0.1.tgz",
+ "integrity": "sha1-Ei4WFZHiH/TFJTAwVpPyDmOTo5g=",
+ "dev": true
+ }
+ }
+ },
"standard-error": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/standard-error/-/standard-error-1.1.0.tgz",
@@ -19142,15 +15595,15 @@
"resolved": "https://registry.npmjs.org/standard-http-error/-/standard-http-error-2.0.1.tgz",
"integrity": "sha1-+K6RcuPO+cs40ucIShkl9Xp8NL0=",
"requires": {
- "standard-error": "1.1.0"
+ "standard-error": ">= 1.1.0 < 2"
}
},
"standard-json": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/standard-json/-/standard-json-1.0.2.tgz",
- "integrity": "sha1-gt6koUx4zZ4104zeS4isa2JZaiM=",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/standard-json/-/standard-json-1.0.3.tgz",
+ "integrity": "sha512-lhMP+KREBcfyyMe2ObJlEjJ0lc0ItA9uny83d9ZL6ggYtB79DuaAKCxJVoiflg5EV3D2rpuWn+n4+zXjWXk0sQ==",
"requires": {
- "concat-stream": "1.6.0"
+ "concat-stream": "^1.5.0"
}
},
"stat-mode": {
@@ -19159,10 +15612,32 @@
"integrity": "sha1-5sgLYjEj19gM8TLOU480YokHJQI=",
"dev": true
},
+ "static-extend": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz",
+ "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=",
+ "dev": true,
+ "requires": {
+ "define-property": "^0.2.5",
+ "object-copy": "^0.1.0"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
"statuses": {
- "version": "1.3.1",
- "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
- "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.4.0.tgz",
+ "integrity": "sha512-zhSCtt8v2NDrRlPQpCNtw/heZLtfUDqxBM1udqikb/Hbk52LK4nQSwr10u77iopCW5LsyHpuXS0GnEc48mLeew==",
+ "dev": true
},
"stealthy-require": {
"version": "1.1.1",
@@ -19180,40 +15655,8 @@
"integrity": "sha1-ZiZu5fm9uZQKTkUUyvtDu3Hlyds=",
"dev": true,
"requires": {
- "inherits": "2.0.3",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "inherits": "~2.0.1",
+ "readable-stream": "^2.0.2"
}
},
"stream-combiner2": {
@@ -19222,112 +15665,50 @@
"integrity": "sha1-+02KFCDqNidk4hrUeAOXvry0HL4=",
"dev": true,
"requires": {
- "duplexer2": "0.1.4",
- "readable-stream": "2.3.3"
+ "duplexer2": "~0.1.0",
+ "readable-stream": "^2.0.2"
},
"dependencies": {
"duplexer2": {
"version": "0.1.4",
"resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz",
- "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
- "dev": true,
- "requires": {
- "readable-stream": "2.3.3"
- }
- },
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
- }
- },
- "stream-consume": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.0.tgz",
- "integrity": "sha1-pB6tGm1ggc63n2WwYZAbbY89HQ8=",
- "dev": true
- },
- "stream-each": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.0.tgz",
- "integrity": "sha1-HpXUdXP1gNgU3A/4zQ9m8c5TyZE=",
- "dev": true,
- "requires": {
- "end-of-stream": "1.4.0",
- "stream-shift": "1.0.0"
- }
- },
- "stream-http": {
- "version": "2.7.2",
- "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.7.2.tgz",
- "integrity": "sha512-c0yTD2rbQzXtSsFSVhtpvY/vS6u066PcXOX9kBB3mSO76RiUQzL340uJkGBWnlBg4/HZzqiUXtaVA7wcRcJgEw==",
- "dev": true,
- "requires": {
- "builtin-status-codes": "3.0.0",
- "inherits": "2.0.3",
- "readable-stream": "2.3.3",
- "to-arraybuffer": "1.0.1",
- "xtend": "4.0.1"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "integrity": "sha1-ixLauHjA1p4+eJEFFmKjL8a93ME=",
"dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "readable-stream": "^2.0.2"
}
}
}
},
+ "stream-consume": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/stream-consume/-/stream-consume-0.1.1.tgz",
+ "integrity": "sha512-tNa3hzgkjEP7XbCkbRXe1jpg+ievoa0O4SCFlMOYEscGSS4JJsckGL8swUyAa/ApGU3Ae4t6Honor4HhL+tRyg==",
+ "dev": true
+ },
+ "stream-each": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.2.tgz",
+ "integrity": "sha512-mc1dbFhGBxvTM3bIWmAAINbqiuAk9TATcfIQC8P+/+HJefgaiTlMn2dHvkX8qlI12KeYKSQ1Ua9RrIqrn1VPoA==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "stream-shift": "^1.0.0"
+ }
+ },
+ "stream-http": {
+ "version": "2.8.2",
+ "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.2.tgz",
+ "integrity": "sha512-QllfrBhqF1DPcz46WxKTs6Mz1Bpc+8Qm6vbqOpVav5odAXwbyzwnEczoWqtxrsmlO+cJqtPrp/8gWKWjaKLLlA==",
+ "dev": true,
+ "requires": {
+ "builtin-status-codes": "^3.0.0",
+ "inherits": "^2.0.1",
+ "readable-stream": "^2.3.6",
+ "to-arraybuffer": "^1.0.0",
+ "xtend": "^4.0.0"
+ }
+ },
"stream-shift": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz",
@@ -19344,7 +15725,7 @@
"resolved": "https://registry.npmjs.org/stream-to-blob/-/stream-to-blob-1.0.0.tgz",
"integrity": "sha1-n3oa2jnhbqKC67fkzaMH7aveZY0=",
"requires": {
- "once": "1.4.0"
+ "once": "^1.3.3"
}
},
"stream-to-blob-url": {
@@ -19352,7 +15733,7 @@
"resolved": "https://registry.npmjs.org/stream-to-blob-url/-/stream-to-blob-url-2.1.0.tgz",
"integrity": "sha1-w0HRBQLsUSUGBzJyWOwvWGsH1iY=",
"requires": {
- "stream-to-blob": "1.0.0"
+ "stream-to-blob": "^1.0.0"
}
},
"stream-to-buffer": {
@@ -19360,15 +15741,15 @@
"resolved": "https://registry.npmjs.org/stream-to-buffer/-/stream-to-buffer-0.1.0.tgz",
"integrity": "sha1-JnmdkDqyAlyb1VCsRxcbAPjdgKk=",
"requires": {
- "stream-to": "0.2.2"
+ "stream-to": "~0.2.0"
}
},
"stream-with-known-length-to-buffer": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/stream-with-known-length-to-buffer/-/stream-with-known-length-to-buffer-1.0.0.tgz",
- "integrity": "sha1-fmFTQRW1w2CGOQ6116jGNhSVEfU=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/stream-with-known-length-to-buffer/-/stream-with-known-length-to-buffer-1.0.1.tgz",
+ "integrity": "sha512-rlVUS1N6SVCfluLIUuQcCIcxvOUjLx5plFGp2937buLBtajF8/LtP0RmdbRGSoPMJ1HSTZKKG2y5uTS8+Mn/Dg==",
"requires": {
- "once": "1.4.0"
+ "once": "^1.3.3"
}
},
"strict-uri-encode": {
@@ -19377,19 +15758,14 @@
"integrity": "sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM=",
"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="
- },
"string-width": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz",
"integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=",
"requires": {
- "code-point-at": "1.1.0",
- "is-fullwidth-code-point": "1.0.0",
- "strip-ansi": "3.0.1"
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
}
},
"string.prototype.endswith": {
@@ -19403,25 +15779,34 @@
"integrity": "sha1-2miYLjU6TprEpDtFCiBF0cRFrns="
},
"string2compact": {
- "version": "1.2.2",
- "resolved": "https://registry.npmjs.org/string2compact/-/string2compact-1.2.2.tgz",
- "integrity": "sha1-Qgs6nuHEaFSRm0oq6sZcQ/pQWXs=",
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/string2compact/-/string2compact-1.2.5.tgz",
+ "integrity": "sha512-WujFln3AWQhpd/0UXjR8Ctcy/lCCb1jmED8h1Loa6938stww6LSSuP7FWqTMFlb4dxn/6l54jrAqlJhIAUlBWw==",
+ "requires": {
+ "addr-to-ip-port": "^1.0.1",
+ "ipaddr.js": "^1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
"requires": {
- "addr-to-ip-port": "1.4.2",
- "ipaddr.js": "1.4.0"
+ "safe-buffer": "~5.1.0"
}
},
"stringstream": {
- "version": "0.0.5",
- "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.5.tgz",
- "integrity": "sha1-TkhM1N5aC7vuGORjB3EKioFiGHg="
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/stringstream/-/stringstream-0.0.6.tgz",
+ "integrity": "sha512-87GEBAkegbBcweToUrdzf3eLhWNg06FJTebl4BVJz/JgWy8CvEr9dRtX5qWphiynMSQlxxi+QqN0z5T32SLlhA==",
+ "dev": true
},
"strip-ansi": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz",
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
"requires": {
- "ansi-regex": "2.1.1"
+ "ansi-regex": "^2.0.0"
}
},
"strip-bom": {
@@ -19429,7 +15814,7 @@
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
"integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
"requires": {
- "is-utf8": "0.2.1"
+ "is-utf8": "^0.2.0"
}
},
"strip-bom-stream": {
@@ -19438,8 +15823,8 @@
"integrity": "sha1-5xRDmFd9Uaa+0PoZlPoF9D/ZiO4=",
"dev": true,
"requires": {
- "first-chunk-stream": "1.0.0",
- "strip-bom": "2.0.0"
+ "first-chunk-stream": "^1.0.0",
+ "strip-bom": "^2.0.0"
}
},
"strip-dirs": {
@@ -19448,14 +15833,27 @@
"integrity": "sha1-lgu9EoeETzl1pFWKoQOoJV4kVqA=",
"dev": true,
"requires": {
- "chalk": "1.1.3",
- "get-stdin": "4.0.1",
- "is-absolute": "0.1.7",
- "is-natural-number": "2.1.1",
- "minimist": "1.2.0",
- "sum-up": "1.0.3"
+ "chalk": "^1.0.0",
+ "get-stdin": "^4.0.1",
+ "is-absolute": "^0.1.5",
+ "is-natural-number": "^2.0.0",
+ "minimist": "^1.1.0",
+ "sum-up": "^1.0.1"
},
"dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
"get-stdin": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
@@ -19468,7 +15866,7 @@
"integrity": "sha1-hHSREZ/MtftDYhfMc39/qtUPYD8=",
"dev": true,
"requires": {
- "is-relative": "0.1.3"
+ "is-relative": "^0.1.0"
}
},
"is-relative": {
@@ -19476,12 +15874,6 @@
"resolved": "https://registry.npmjs.org/is-relative/-/is-relative-0.1.3.tgz",
"integrity": "sha1-kF/uiuhvRbPsYUvDwVyGnfCHboI=",
"dev": true
- },
- "minimist": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
- "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
- "dev": true
}
}
},
@@ -19497,7 +15889,7 @@
"integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
"dev": true,
"requires": {
- "get-stdin": "4.0.1"
+ "get-stdin": "^4.0.1"
},
"dependencies": {
"get-stdin": {
@@ -19514,13 +15906,13 @@
"integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
},
"style-loader": {
- "version": "0.19.0",
- "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.0.tgz",
- "integrity": "sha512-9mx9sC9nX1dgP96MZOODpGC6l1RzQBITI2D5WJhu+wnbrSYVKLGuy14XJSLVQih/0GFrPpjelt+s//VcZQ2Evw==",
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.19.1.tgz",
+ "integrity": "sha512-IRE+ijgojrygQi3rsqT0U4dd+UcPCqcVvauZpCnQrGAlEe+FUIyrK93bUDScamesjP08JlQNsFJU+KmPedP5Og==",
"dev": true,
"requires": {
- "loader-utils": "1.1.0",
- "schema-utils": "0.3.0"
+ "loader-utils": "^1.0.2",
+ "schema-utils": "^0.3.0"
}
},
"sum-up": {
@@ -19529,7 +15921,22 @@
"integrity": "sha1-HGYfZnBX9jvLeHWqFDi8FiUlFW4=",
"dev": true,
"requires": {
- "chalk": "1.1.3"
+ "chalk": "^1.0.0"
+ },
+ "dependencies": {
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ }
}
},
"sumchecker": {
@@ -19538,7 +15945,7 @@
"integrity": "sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=",
"dev": true,
"requires": {
- "debug": "2.6.9"
+ "debug": "^2.2.0"
}
},
"superagent": {
@@ -19546,26 +15953,70 @@
"resolved": "https://registry.npmjs.org/superagent/-/superagent-1.8.5.tgz",
"integrity": "sha1-HA3cOvMOgOuE68BcshItqP6UC1U=",
"requires": {
- "component-emitter": "1.2.1",
+ "component-emitter": "~1.2.0",
"cookiejar": "2.0.6",
- "debug": "2.6.9",
+ "debug": "2",
"extend": "3.0.0",
"form-data": "1.0.0-rc3",
- "formidable": "1.0.17",
- "methods": "1.1.2",
+ "formidable": "~1.0.14",
+ "methods": "~1.1.1",
"mime": "1.3.4",
"qs": "2.3.3",
"readable-stream": "1.0.27-1",
"reduce-component": "1.0.1"
- }
- },
- "superagent-proxy": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/superagent-proxy/-/superagent-proxy-1.0.2.tgz",
- "integrity": "sha1-ktNmBXj2GO1DqCz4yseZ/ik4ui0=",
- "requires": {
- "debug": "2.6.9",
- "proxy-agent": "2.1.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo="
+ },
+ "extend": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.0.tgz",
+ "integrity": "sha1-WkdDU7nzNT3dgXbf03uRyDpG8dQ="
+ },
+ "form-data": {
+ "version": "1.0.0-rc3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-1.0.0-rc3.tgz",
+ "integrity": "sha1-01vGLn+8KTeuePlIqqDTjZBgdXc=",
+ "requires": {
+ "async": "^1.4.0",
+ "combined-stream": "^1.0.5",
+ "mime-types": "^2.1.3"
+ }
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "mime": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.3.4.tgz",
+ "integrity": "sha1-EV+eO2s9rylZmDyzjxSaLUDrXVM="
+ },
+ "qs": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-2.3.3.tgz",
+ "integrity": "sha1-6eha2+ddoLvkyOBHaghikPhjtAQ="
+ },
+ "readable-stream": {
+ "version": "1.0.27-1",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.0.27-1.tgz",
+ "integrity": "sha1-a2eYPCA1fO/QfwFlABoW1xDZEHg=",
+ "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="
+ }
}
},
"supports-color": {
@@ -19573,10 +16024,43 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc="
},
+ "svgo": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/svgo/-/svgo-0.7.2.tgz",
+ "integrity": "sha1-n1dyQTlSE1xv779Ar+ak+qiLS7U=",
+ "dev": true,
+ "requires": {
+ "coa": "~1.0.1",
+ "colors": "~1.1.2",
+ "csso": "~2.3.1",
+ "js-yaml": "~3.7.0",
+ "mkdirp": "~0.5.1",
+ "sax": "~1.2.1",
+ "whet.extend": "~0.9.9"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "2.7.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-2.7.3.tgz",
+ "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"
+ }
+ }
+ }
+ },
"symbol-observable": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.0.4.tgz",
- "integrity": "sha1-Kb9hXUqnEhvdiYsi1LP5vE4qoD0="
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/symbol-observable/-/symbol-observable-1.2.0.tgz",
+ "integrity": "sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ=="
},
"symbol-tree": {
"version": "3.2.2",
@@ -19584,72 +16068,51 @@
"integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY="
},
"table": {
- "version": "3.8.3",
- "resolved": "https://registry.npmjs.org/table/-/table-3.8.3.tgz",
- "integrity": "sha1-K7xULw/amGGnVdOUf+/Ys/UThV8=",
- "dev": true,
- "requires": {
- "ajv": "4.11.8",
- "ajv-keywords": "1.5.1",
- "chalk": "1.1.3",
- "lodash": "4.17.4",
- "slice-ansi": "0.0.4",
- "string-width": "2.1.1"
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/table/-/table-4.0.2.tgz",
+ "integrity": "sha512-UUkEAPdSGxtRpiV9ozJ5cMTtYiqz7Ni1OGqLXRCynrvzdtR1p+cfOWe2RJLwvUG8hNanaSRjecIqwOjqeatDsA==",
+ "requires": {
+ "ajv": "^5.2.3",
+ "ajv-keywords": "^2.1.0",
+ "chalk": "^2.1.0",
+ "lodash": "^4.17.4",
+ "slice-ansi": "1.0.0",
+ "string-width": "^2.1.1"
},
"dependencies": {
- "ajv": {
- "version": "4.11.8",
- "resolved": "https://registry.npmjs.org/ajv/-/ajv-4.11.8.tgz",
- "integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
- "dev": true,
- "requires": {
- "co": "4.6.0",
- "json-stable-stringify": "1.0.1"
- }
- },
- "ajv-keywords": {
- "version": "1.5.1",
- "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-1.5.1.tgz",
- "integrity": "sha1-MU3QpLM2j609/NxU7eYXG4htrzw=",
- "dev": true
- },
"ansi-regex": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
- "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
- "dev": true
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg="
},
"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
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8="
},
"string-width": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
"integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
- "dev": true,
"requires": {
- "is-fullwidth-code-point": "2.0.0",
- "strip-ansi": "4.0.0"
+ "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"
+ "ansi-regex": "^3.0.0"
}
}
}
},
"tablesort": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/tablesort/-/tablesort-5.0.1.tgz",
- "integrity": "sha1-WYzts2I8glmVdLZ8QvkVo1wzbGk="
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/tablesort/-/tablesort-5.0.2.tgz",
+ "integrity": "sha512-l0mDC2pDQJfXZbUogT+IYDHeYoqsW/Whqd2xMLAPltNrN0A8bVHtQXoU1sIc7/DofkgYnnINF5k7tlaG+QJJtw=="
},
"tapable": {
"version": "0.2.8",
@@ -19663,69 +16126,54 @@
"integrity": "sha1-jk0qJWwOIYXGsYrWlK7JaLg8sdE=",
"dev": true,
"requires": {
- "block-stream": "0.0.9",
- "fstream": "1.0.11",
- "inherits": "2.0.3"
+ "block-stream": "*",
+ "fstream": "^1.0.2",
+ "inherits": "2"
}
},
"tar-fs": {
- "version": "1.15.3",
- "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.15.3.tgz",
- "integrity": "sha1-7M+TXpQUk9gVECjmNuUc5MPKfyA=",
- "requires": {
- "chownr": "1.0.1",
- "mkdirp": "0.5.1",
- "pump": "1.0.2",
- "tar-stream": "1.5.4"
- }
- },
- "tar-stream": {
- "version": "1.5.4",
- "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.5.4.tgz",
- "integrity": "sha1-NlSc8E7RrumyowwBQyUiONr5QBY=",
- "requires": {
- "bl": "1.2.1",
- "end-of-stream": "1.4.0",
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "version": "1.16.2",
+ "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-1.16.2.tgz",
+ "integrity": "sha512-LdknWjPEiZC1nOBwhv0JBzfJBGPJar08dZg2rwZe0ZTLQoRGEzgrl7vF3qUEkCHpI/wN9e7RyCuDhMsJUCLPPQ==",
+ "requires": {
+ "chownr": "^1.0.1",
+ "mkdirp": "^0.5.1",
+ "pump": "^1.0.0",
+ "tar-stream": "^1.1.2"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
+ "pump": {
"version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
+ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
"requires": {
- "safe-buffer": "5.1.1"
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
}
}
}
},
+ "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==",
+ "requires": {
+ "bl": "^1.0.0",
+ "buffer-alloc": "^1.1.0",
+ "end-of-stream": "^1.0.0",
+ "fs-constants": "^1.0.0",
+ "readable-stream": "^2.3.0",
+ "to-buffer": "^1.1.0",
+ "xtend": "^4.0.0"
+ }
+ },
"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"
+ "os-tmpdir": "^1.0.0",
+ "rimraf": "~2.2.6"
},
"dependencies": {
"rimraf": {
@@ -19736,62 +16184,15 @@
}
},
"temp-file": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.1.1.tgz",
- "integrity": "sha512-W/6SJgtg2SE/5rxgwUwoDhdSXrvUWQBpgKJglaAe6S7mk1kLkI+LUbY/jPZBu3UhydDJZstNNd7AJhnZ0UZHtw==",
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.1.2.tgz",
+ "integrity": "sha512-s5JJnUbvV6QaKBxBJm6wDpKIVVvr/ssrb8Cdaz2iaXcjFMtWX+OGBwY+UTvARoWYI5HlKaoD7xFJSpo0jJUlbA==",
"dev": true,
"requires": {
- "async-exit-hook": "2.0.1",
- "bluebird-lst": "1.0.5",
- "fs-extra-p": "4.5.0",
- "lazy-val": "1.0.3"
- },
- "dependencies": {
- "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
- },
- "bluebird-lst": {
- "version": "1.0.5",
- "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.5.tgz",
- "integrity": "sha512-Ey0bDNys5qpYPhZ/oQ9vOEvD0TYQDTILMXWP2iGfvMg7rSDde+oV4aQQgqRH+CvBFNz2BSDQnPGMUl6LKBUUQA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.1"
- }
- },
- "fs-extra": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-5.0.0.tgz",
- "integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11",
- "jsonfile": "4.0.0",
- "universalify": "0.1.1"
- }
- },
- "fs-extra-p": {
- "version": "4.5.0",
- "resolved": "https://registry.npmjs.org/fs-extra-p/-/fs-extra-p-4.5.0.tgz",
- "integrity": "sha512-V/sdZmV+Yx3+nfXmjRTdBP4mVWCt7hZ0+ZOv+IZo+6fdkBxafaGsI7mYeNv/J3rWyz+mIToCFQORFSwt1bZw8Q==",
- "dev": true,
- "requires": {
- "bluebird-lst": "1.0.5",
- "fs-extra": "5.0.0"
- }
- },
- "jsonfile": {
- "version": "4.0.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
- "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
- "dev": true,
- "requires": {
- "graceful-fs": "4.1.11"
- }
- }
+ "async-exit-hook": "^2.0.1",
+ "bluebird-lst": "^1.0.5",
+ "fs-extra-p": "^4.6.0",
+ "lazy-val": "^1.0.3"
}
},
"term-size": {
@@ -19800,7 +16201,7 @@
"integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=",
"dev": true,
"requires": {
- "execa": "0.7.0"
+ "execa": "^0.7.0"
}
},
"text-table": {
@@ -19828,20 +16229,30 @@
"resolved": "https://registry.npmjs.org/through2/-/through2-0.6.5.tgz",
"integrity": "sha1-QaucZ7KdVyCQcUEOHXp6lozTrUg=",
"requires": {
- "readable-stream": "1.0.34",
- "xtend": "4.0.1"
+ "readable-stream": ">=1.0.33-1 <1.1.0-0",
+ "xtend": ">=4.0.0 <4.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="
+ },
"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",
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.1",
"isarray": "0.0.1",
- "string_decoder": "0.10.31"
+ "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="
}
}
},
@@ -19851,65 +16262,22 @@
"integrity": "sha1-YLxVoNrLdghdsfna6Zq0P4PWIuw=",
"dev": true,
"requires": {
- "through2": "2.0.3",
- "xtend": "4.0.1"
+ "through2": "~2.0.0",
+ "xtend": "~4.0.0"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- },
"through2": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/through2/-/through2-2.0.3.tgz",
"integrity": "sha1-AARWmzfHx0ujnEPzzteNGtlBQL4=",
"dev": true,
"requires": {
- "readable-stream": "2.3.3",
- "xtend": "4.0.1"
+ "readable-stream": "^2.1.5",
+ "xtend": "~4.0.1"
}
}
}
},
- "throwback": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/throwback/-/throwback-1.1.1.tgz",
- "integrity": "sha1-8AfnwXYEptFtegfEGqDo/txhhKQ=",
- "requires": {
- "any-promise": "1.3.0"
- }
- },
- "thunkify": {
- "version": "2.1.2",
- "resolved": "https://registry.npmjs.org/thunkify/-/thunkify-2.1.2.tgz",
- "integrity": "sha1-+qDp0jDFGsyVyhOjYawFyn4EVT0="
- },
"thunky": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/thunky/-/thunky-1.0.2.tgz",
@@ -19921,7 +16289,7 @@
"integrity": "sha1-3OwD9V3Km3qj5bBPIYF+tW5jWIo=",
"dev": true,
"requires": {
- "os-homedir": "1.0.2"
+ "os-homedir": "^1.0.0"
}
},
"time-stamp": {
@@ -19937,12 +16305,12 @@
"dev": true
},
"timers-browserify": {
- "version": "2.0.4",
- "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.4.tgz",
- "integrity": "sha512-uZYhyU3EX8O7HQP+J9fTVYwsq90Vr68xPEFo7yrVImIxYvHgukBEgOB/SgGoorWVTzGM/3Z+wUNnboA4M8jWrg==",
+ "version": "2.0.10",
+ "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.10.tgz",
+ "integrity": "sha512-YvC1SV1XdOUaL6gx5CoGroT3Gu49pK9+TZ38ErPldOWW4j49GI1HKs9DV+KGq/w6y+LZ72W1c8cKz2vzY+qpzg==",
"dev": true,
"requires": {
- "setimmediate": "1.0.5"
+ "setimmediate": "^1.0.4"
}
},
"tinycolor2": {
@@ -19950,22 +16318,27 @@
"resolved": "https://registry.npmjs.org/tinycolor2/-/tinycolor2-1.4.1.tgz",
"integrity": "sha1-9PrTM0R7wLB9TcjpIJ2POaisd+g="
},
- "title-case-minors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/title-case-minors/-/title-case-minors-1.0.0.tgz",
- "integrity": "sha1-UfFwN8KUdHodHNpCS1AEyG2OsRU="
- },
"tldjs": {
- "version": "1.6.2",
- "resolved": "https://registry.npmjs.org/tldjs/-/tldjs-1.6.2.tgz",
- "integrity": "sha1-DYtxRWUfEFKsCzxoiEMpZjYYOxM="
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/tldjs/-/tldjs-2.3.1.tgz",
+ "integrity": "sha512-W/YVH/QczLUxVjnQhFC61Iq232NWu3TqDdO0S/MtXVz4xybejBov4ud+CIwN9aYqjOecEqIy0PscGkwpG9ZyTw==",
+ "requires": {
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ }
+ }
},
"tmp": {
- "version": "0.0.28",
- "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.28.tgz",
- "integrity": "sha1-Fyc1t/YU6nrzlmT6hM8N5OUV0SA=",
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
"requires": {
- "os-tmpdir": "1.0.2"
+ "os-tmpdir": "~1.0.2"
}
},
"to-absolute-glob": {
@@ -19974,7 +16347,18 @@
"integrity": "sha1-HN+kcqnvUMI57maZm2YsoOs5k38=",
"dev": true,
"requires": {
- "extend-shallow": "2.0.1"
+ "extend-shallow": "^2.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ }
}
},
"to-arraybuffer": {
@@ -19982,13 +16366,10 @@
"resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz",
"integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M="
},
- "to-capital-case": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/to-capital-case/-/to-capital-case-1.0.0.tgz",
- "integrity": "sha1-pXxQFP1aNyF88FCZ/4pCG7+cm38=",
- "requires": {
- "to-space-case": "1.0.0"
- }
+ "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=="
},
"to-fast-properties": {
"version": "1.0.3",
@@ -20001,57 +16382,77 @@
"integrity": "sha1-TcGeZk38y+Jb2NtQiwDG2hWCVdE=",
"dev": true
},
- "to-no-case": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/to-no-case/-/to-no-case-1.0.2.tgz",
- "integrity": "sha1-xyKQcWTvaxeBMsjmmTAhLRtKoWo="
- },
- "to-sentence-case": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/to-sentence-case/-/to-sentence-case-1.0.0.tgz",
- "integrity": "sha1-xIO/NkdzflxzjvcAb+Ng1fmcVy4=",
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
"requires": {
- "to-no-case": "1.0.2"
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
}
},
- "to-space-case": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/to-space-case/-/to-space-case-1.0.0.tgz",
- "integrity": "sha1-sFLar7Gysp3HcM6gFj5ewOvJ/Bc=",
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
"requires": {
- "to-no-case": "1.0.2"
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
}
},
- "to-title-case": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/to-title-case/-/to-title-case-1.0.0.tgz",
- "integrity": "sha1-rKiPidYGTeUBCKl86g20SCfoAGE=",
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
"requires": {
- "escape-regexp-component": "1.0.2",
- "title-case-minors": "1.0.0",
- "to-capital-case": "1.0.0",
- "to-sentence-case": "1.0.0"
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
}
},
"topo": {
- "version": "2.0.2",
- "resolved": "https://registry.npmjs.org/topo/-/topo-2.0.2.tgz",
- "integrity": "sha1-zVYVdSU5BXwNwEkaYhw7xvvh0YI=",
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/topo/-/topo-3.0.0.tgz",
+ "integrity": "sha512-Tlu1fGlR90iCdIPURqPiufqAlCZYzLjHYVVbcFWDMcX7+tK8hdZWAfsMrD/pBul9jqHHwFjNdf1WaxA9vTRRhw==",
"requires": {
- "hoek": "4.2.0"
+ "hoek": "5.x.x"
}
},
"torrent-discovery": {
- "version": "8.3.1",
- "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-8.3.1.tgz",
- "integrity": "sha1-e0+jOQwqlau4e0sDJDazCArWrdY=",
- "requires": {
- "bittorrent-dht": "7.6.0",
- "bittorrent-tracker": "9.2.3",
- "debug": "2.6.9",
- "inherits": "2.0.3",
- "run-parallel": "1.1.6",
- "xtend": "4.0.1"
+ "version": "8.4.1",
+ "resolved": "https://registry.npmjs.org/torrent-discovery/-/torrent-discovery-8.4.1.tgz",
+ "integrity": "sha512-PHy/H+S2pxBMK8ZdiZxp16mIPfs50rdzYjOWJLJg974BCE/VbdxHirQv117kVl9STKKXKZWo5NADGAYfmIXH0w==",
+ "requires": {
+ "bittorrent-dht": "^8.0.1",
+ "bittorrent-tracker": "^9.0.0",
+ "debug": "^3.1.0",
+ "inherits": "^2.0.1",
+ "run-parallel": "^1.1.2",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
}
},
"torrent-piece": {
@@ -20064,7 +16465,7 @@
"resolved": "https://registry.npmjs.org/touch/-/touch-0.0.3.tgz",
"integrity": "sha1-Ua7z1ElXHU8oel2Hyci0kYGg2x0=",
"requires": {
- "nopt": "1.0.10"
+ "nopt": "~1.0.10"
},
"dependencies": {
"nopt": {
@@ -20072,17 +16473,17 @@
"resolved": "https://registry.npmjs.org/nopt/-/nopt-1.0.10.tgz",
"integrity": "sha1-bd0hvSoxQXuScn3Vhfim83YI6+4=",
"requires": {
- "abbrev": "1.1.0"
+ "abbrev": "1"
}
}
}
},
"tough-cookie": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.3.tgz",
- "integrity": "sha1-C2GKVWW23qkL80JdBNVe3EdadWE=",
+ "version": "2.3.4",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.3.4.tgz",
+ "integrity": "sha512-TZ6TTfI5NtZnuyy/Kecv+CnoROnyXn2DN97LontgQpCwsX2XyLYCC0ENhYkehSOwAp8rTQKc/NUIF7BkQ5rKLA==",
"requires": {
- "punycode": "1.4.1"
+ "punycode": "^1.4.1"
},
"dependencies": {
"punycode": {
@@ -20097,7 +16498,7 @@
"resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
"integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
"requires": {
- "punycode": "2.1.0"
+ "punycode": "^2.1.0"
}
},
"traverse": {
@@ -20127,14 +16528,9 @@
"integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
"dev": true,
"requires": {
- "utf8-byte-length": "1.0.4"
+ "utf8-byte-length": "^1.0.1"
}
},
- "tryit": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/tryit/-/tryit-1.0.3.tgz",
- "integrity": "sha1-OTvnMKlEb9Hq1tpZoBQwjzbCics="
- },
"tty-browserify": {
"version": "0.0.0",
"resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz",
@@ -20146,7 +16542,7 @@
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
"requires": {
- "safe-buffer": "5.1.1"
+ "safe-buffer": "^5.0.1"
}
},
"tweetnacl": {
@@ -20160,7 +16556,7 @@
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
"integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
"requires": {
- "prelude-ls": "1.1.2"
+ "prelude-ls": "~1.1.2"
}
},
"type-detect": {
@@ -20170,12 +16566,13 @@
"dev": true
},
"type-is": {
- "version": "1.6.15",
- "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
- "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
+ "version": "1.6.16",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.16.tgz",
+ "integrity": "sha512-HRkVv/5qY2G6I8iab9cI7v1bOIdhm94dVjQCPFElW9W+3GeDOSHmy2EBYe4VTApuzolPcmgFTN3ftVJRKR2J9Q==",
+ "dev": true,
"requires": {
"media-typer": "0.3.0",
- "mime-types": "2.1.17"
+ "mime-types": "~2.1.18"
}
},
"typedarray": {
@@ -20184,46 +16581,17 @@
"integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
},
"typedarray-to-buffer": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.2.tgz",
- "integrity": "sha1-EBezLZhP9VbroQD1AViauhrOLgQ=",
+ "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==",
"requires": {
- "is-typedarray": "1.0.0"
+ "is-typedarray": "^1.0.0"
}
},
- "typeforce": {
- "version": "1.11.5",
- "resolved": "https://registry.npmjs.org/typeforce/-/typeforce-1.11.5.tgz",
- "integrity": "sha512-Glwf7h3CW1YaQrLVeNnMg6KumszBe4adBccF4Ukc8J3nkdgapEkpiMdoPTv3APoqMva3mNN4ZFklGaPNvRfiMQ=="
- },
"ua-parser-js": {
- "version": "0.7.14",
- "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.14.tgz",
- "integrity": "sha1-EQ1T+kw/MmwSEpK76skE0uAzh8o="
- },
- "uglify-es": {
- "version": "3.2.0",
- "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.2.0.tgz",
- "integrity": "sha512-eD4rjK4o6rzrvE1SMZJLQFEVMnWRUyIu6phJ0BXk5TIthMmP5B4QP0HI8o3bkQB5wf1N4WHA0leZAQyQBAd+Jg==",
- "dev": true,
- "requires": {
- "commander": "2.12.2",
- "source-map": "0.6.1"
- },
- "dependencies": {
- "commander": {
- "version": "2.12.2",
- "resolved": "https://registry.npmjs.org/commander/-/commander-2.12.2.tgz",
- "integrity": "sha512-BFnaq5ZOGcDN7FlrtBT4xxkgIToalIIxwjxLWVJ8bGTpe1LroqMiqQXdA7ygc7CRvaYS+9zfPGFnJqFSayx+AA==",
- "dev": true
- },
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
- "dev": true
- }
- }
+ "version": "0.7.18",
+ "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.18.tgz",
+ "integrity": "sha512-LtzwHlVHwFGTptfNSgezHp7WUlwiqb0gA9AALRbKaERfxwJoiX0A73QbTToxteIAuIaFshhgIZfqK8s7clqgnA=="
},
"uglify-js": {
"version": "2.8.29",
@@ -20231,9 +16599,9 @@
"integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
"dev": true,
"requires": {
- "source-map": "0.5.7",
- "uglify-to-browserify": "1.0.2",
- "yargs": "3.10.0"
+ "source-map": "~0.5.1",
+ "uglify-to-browserify": "~1.0.0",
+ "yargs": "~3.10.0"
},
"dependencies": {
"camelcase": {
@@ -20248,11 +16616,17 @@
"integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
"dev": true,
"requires": {
- "center-align": "0.1.3",
- "right-align": "0.1.3",
+ "center-align": "^0.1.1",
+ "right-align": "^0.1.1",
"wordwrap": "0.0.2"
}
},
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
"window-size": {
"version": "0.1.0",
"resolved": "https://registry.npmjs.org/window-size/-/window-size-0.1.0.tgz",
@@ -20271,9 +16645,9 @@
"integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
"dev": true,
"requires": {
- "camelcase": "1.2.1",
- "cliui": "2.1.0",
- "decamelize": "1.2.0",
+ "camelcase": "^1.0.2",
+ "cliui": "^2.1.0",
+ "decamelize": "^1.0.0",
"window-size": "0.1.0"
}
}
@@ -20287,64 +16661,69 @@
"optional": true
},
"uglifyjs-webpack-plugin": {
- "version": "1.1.1",
- "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.1.1.tgz",
- "integrity": "sha512-JPs2UFQxIbaPd7iOvWx1beA7My7YMo3tjTLTAmxuKFoKHQkt6fB70Jm6nm25ponWp4+gu/7U4eamelgDlu0Y3g==",
- "dev": true,
- "requires": {
- "cacache": "10.0.1",
- "find-cache-dir": "1.0.0",
- "schema-utils": "0.3.0",
- "source-map": "0.6.1",
- "uglify-es": "3.2.0",
- "webpack-sources": "1.0.1",
- "worker-farm": "1.5.0"
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/uglifyjs-webpack-plugin/-/uglifyjs-webpack-plugin-1.2.5.tgz",
+ "integrity": "sha512-hIQJ1yxAPhEA2yW/i7Fr+SXZVMp+VEI3d42RTHBgQd2yhp/1UdBcR3QEWPV5ahBxlqQDMEMTuTEvDHSFINfwSw==",
+ "dev": true,
+ "requires": {
+ "cacache": "^10.0.4",
+ "find-cache-dir": "^1.0.0",
+ "schema-utils": "^0.4.5",
+ "serialize-javascript": "^1.4.0",
+ "source-map": "^0.6.1",
+ "uglify-es": "^3.3.4",
+ "webpack-sources": "^1.1.0",
+ "worker-farm": "^1.5.2"
},
"dependencies": {
- "cacache": {
- "version": "10.0.1",
- "resolved": "https://registry.npmjs.org/cacache/-/cacache-10.0.1.tgz",
- "integrity": "sha512-dRHYcs9LvG9cHgdPzjiI+/eS7e1xRhULrcyOx04RZQsszNJXU2SL9CyG60yLnge282Qq5nwTv+ieK2fH+WPZmA==",
- "dev": true,
- "requires": {
- "bluebird": "3.5.0",
- "chownr": "1.0.1",
- "glob": "7.1.2",
- "graceful-fs": "4.1.11",
- "lru-cache": "4.1.1",
- "mississippi": "1.3.0",
- "mkdirp": "0.5.1",
- "move-concurrently": "1.0.1",
- "promise-inflight": "1.0.1",
- "rimraf": "2.6.2",
- "ssri": "5.0.0",
- "unique-filename": "1.1.0",
- "y18n": "3.2.1"
- }
- },
- "lru-cache": {
- "version": "4.1.1",
- "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.1.tgz",
- "integrity": "sha512-q4spe4KTfsAS1SUHLO0wz8Qiyf1+vMIAgpRYioFYDMNqKfHQbg+AVDH3i4fvpl71/P1L0dBl+fQi+P37UYf0ew==",
+ "ajv": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz",
+ "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==",
"dev": true,
"requires": {
- "pseudomap": "1.0.2",
- "yallist": "2.1.2"
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.3.0",
+ "uri-js": "^4.2.1"
}
},
- "source-map": {
- "version": "0.6.1",
- "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
- "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
+ "ajv-keywords": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.13.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.13.0.tgz",
+ "integrity": "sha512-MVuS359B+YzaWqjCL/c+22gfryv+mCBPHAv3zyVI2GN8EY6IRP8VwtasXn8jyyhvvq84R4ImN1OKRtcbIasjYA==",
+ "dev": true
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
"dev": true
},
- "ssri": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/ssri/-/ssri-5.0.0.tgz",
- "integrity": "sha512-728D4yoQcQm1ooZvSbywLkV1RjfITZXh0oWrhM/lnsx3nAHx7LsRGJWB/YyvoceAYRq98xqbstiN4JBv1/wNHg==",
+ "schema-utils": {
+ "version": "0.4.5",
+ "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.5.tgz",
+ "integrity": "sha512-yYrjb9TX2k/J1Y5UNy3KYdZq10xhYcF8nMpAW6o3hy6Q8WSIEf9lJHG/ePnOBfziPM3fvQwfOwa13U/Fh8qTfA==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.1.0",
+ "ajv-keywords": "^3.1.0"
+ }
+ },
+ "uglify-es": {
+ "version": "3.3.9",
+ "resolved": "https://registry.npmjs.org/uglify-es/-/uglify-es-3.3.9.tgz",
+ "integrity": "sha512-r+MU0rfv4L/0eeW3xZrd16t4NZfK8Ld4SWVglYBb7ez5uXFWHuVRs6xCTrf1yirs9a4j4Y27nn7SRfO6v67XsQ==",
"dev": true,
"requires": {
- "safe-buffer": "5.1.1"
+ "commander": "~2.13.0",
+ "source-map": "~0.6.1"
}
}
}
@@ -20357,7 +16736,8 @@
"ultron": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
- "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
+ "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+ "dev": true
},
"unc-path-regex": {
"version": "0.1.2",
@@ -20371,9 +16751,48 @@
"integrity": "sha1-Tz+1OxBuYJf8+ctBCfKl6b36UCI="
},
"underscore.string": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-2.4.0.tgz",
- "integrity": "sha1-jN2PusTi0uoefi6Al8QvRCKA+Fs="
+ "version": "3.3.4",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.4.tgz",
+ "integrity": "sha1-LCo/n4PmR2L9xF5s6sZRQoZCE9s=",
+ "requires": {
+ "sprintf-js": "^1.0.3",
+ "util-deprecate": "^1.0.2"
+ }
+ },
+ "union-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz",
+ "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "get-value": "^2.0.6",
+ "is-extendable": "^0.1.1",
+ "set-value": "^0.4.3"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz",
+ "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=",
+ "dev": true,
+ "requires": {
+ "is-extendable": "^0.1.0"
+ }
+ },
+ "set-value": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz",
+ "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.1",
+ "to-object-path": "^0.3.0"
+ }
+ }
+ }
},
"uniq": {
"version": "1.0.1",
@@ -20381,10 +16800,13 @@
"integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8="
},
"uniqid": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-1.0.0.tgz",
- "integrity": "sha1-JYJSTgdASESkLelPviv1SeG3RVU=",
- "dev": true
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/uniqid/-/uniqid-4.1.1.tgz",
+ "integrity": "sha1-iSIN32t1GuUrX3JISGNShZa7hME=",
+ "dev": true,
+ "requires": {
+ "macaddress": "^0.2.8"
+ }
},
"uniqs": {
"version": "2.0.0",
@@ -20398,7 +16820,7 @@
"integrity": "sha1-0F8v5AMlYIcfMOk8vnNe6iAVFPM=",
"dev": true,
"requires": {
- "unique-slug": "2.0.0"
+ "unique-slug": "^2.0.0"
}
},
"unique-slug": {
@@ -20407,7 +16829,7 @@
"integrity": "sha1-22Z258fMBimHj/GWCXx4hVrp9Ks=",
"dev": true,
"requires": {
- "imurmurhash": "0.1.4"
+ "imurmurhash": "^0.1.4"
}
},
"unique-stream": {
@@ -20422,7 +16844,7 @@
"integrity": "sha1-nhBXzKhRq7kzmPizOuGHuZyuwRo=",
"dev": true,
"requires": {
- "crypto-random-string": "1.0.0"
+ "crypto-random-string": "^1.0.0"
}
},
"universalify": {
@@ -20436,15 +16858,95 @@
"resolved": "https://registry.npmjs.org/unordered-array-remove/-/unordered-array-remove-1.0.2.tgz",
"integrity": "sha1-xUbo+I4xegzyZEyX7LV9umbSUO8="
},
+ "unorm": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unorm/-/unorm-1.4.1.tgz",
+ "integrity": "sha1-NkIA1fE2RsqLzURJAnEzVhR5IwA="
+ },
"unpipe": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
- "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=",
+ "dev": true
+ },
+ "unset-value": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz",
+ "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=",
+ "dev": true,
+ "requires": {
+ "has-value": "^0.3.1",
+ "isobject": "^3.0.0"
+ },
+ "dependencies": {
+ "has-value": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz",
+ "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=",
+ "dev": true,
+ "requires": {
+ "get-value": "^2.0.3",
+ "has-values": "^0.1.4",
+ "isobject": "^2.0.0"
+ },
+ "dependencies": {
+ "isobject": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz",
+ "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=",
+ "dev": true,
+ "requires": {
+ "isarray": "1.0.0"
+ }
+ }
+ }
+ },
+ "has-values": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz",
+ "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=",
+ "dev": true
+ }
+ }
},
"unzip-response": {
- "version": "1.0.2",
- "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-1.0.2.tgz",
- "integrity": "sha1-uYTwh3/AqJwsdzzB73tbIytbBv4="
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/unzip-response/-/unzip-response-2.0.1.tgz",
+ "integrity": "sha1-0vD3N9FrBhXnKmk17QQhRXLVb5c=",
+ "dev": true
+ },
+ "upath": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.0.tgz",
+ "integrity": "sha512-bzpH/oBhoS/QI/YtbkqCg6VEiPYjSZtrHQM6/QnJS6OL9pKUFLqb3aFh4Scvwm45+7iAgiMkLhSbaZxUqmrprw==",
+ "dev": true
+ },
+ "update-notifier": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/update-notifier/-/update-notifier-2.5.0.tgz",
+ "integrity": "sha512-gwMdhgJHGuj/+wHJJs9e6PcCszpxR1b236igrOkUofGhqJuG+amlIKwApH1IW1WWl7ovZxsX49lMBWLxSdm5Dw==",
+ "dev": true,
+ "requires": {
+ "boxen": "^1.2.1",
+ "chalk": "^2.0.1",
+ "configstore": "^3.0.0",
+ "import-lazy": "^2.1.0",
+ "is-ci": "^1.0.10",
+ "is-installed-globally": "^0.1.0",
+ "is-npm": "^1.0.0",
+ "latest-version": "^3.0.0",
+ "semver-diff": "^2.0.0",
+ "xdg-basedir": "^3.0.0"
+ }
+ },
+ "uri-js": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.1.tgz",
+ "integrity": "sha512-jpKCA3HjsBfSDOEgxRDAxQCNyHfCPSbq57PqCkd3gAyBuPb3IWxw54EHncqESznIdqSetHfw3D7ylThu2Kcc9A==",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
},
"urix": {
"version": "0.1.0",
@@ -20475,40 +16977,19 @@
"resolved": "https://registry.npmjs.org/url-loader/-/url-loader-0.6.2.tgz",
"integrity": "sha512-h3qf9TNn53BpuXTTcpC+UehiRrl0Cv45Yr/xWayApjw6G8Bg2dGke7rIwDQ39piciWCWrC+WiqLjOh3SUp9n0Q==",
"requires": {
- "loader-utils": "1.1.0",
- "mime": "1.4.1",
- "schema-utils": "0.3.0"
- },
- "dependencies": {
- "mime": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
- "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
- }
+ "loader-utils": "^1.0.2",
+ "mime": "^1.4.1",
+ "schema-utils": "^0.3.0"
}
},
"url-parse": {
- "version": "1.1.9",
- "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.1.9.tgz",
- "integrity": "sha1-xn8dd11R8KGJEd17P/rSe7nlvRk=",
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.0.tgz",
+ "integrity": "sha512-ERuGxDiQ6Xw/agN4tuoCRbmwRuZP0cJ1lJxJubXr5Q/5cDa78+Dc4wfvtxzhzhkm5VvmW6Mf8EVj9SPGN4l8Lg==",
"dev": true,
"requires": {
- "querystringify": "1.0.0",
- "requires-port": "1.0.0"
- },
- "dependencies": {
- "querystringify": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-1.0.0.tgz",
- "integrity": "sha1-YoYkIRLFtxL6ZU5SZlK/ahP/Bcs=",
- "dev": true
- },
- "requires-port": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
- "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
- "dev": true
- }
+ "querystringify": "^2.0.0",
+ "requires-port": "^1.0.0"
}
},
"url-parse-lax": {
@@ -20517,7 +16998,7 @@
"integrity": "sha1-evjzA2Rem9eaJy56FKxovAYJ2nM=",
"dev": true,
"requires": {
- "prepend-http": "1.0.4"
+ "prepend-http": "^1.0.1"
}
},
"url-regex": {
@@ -20525,7 +17006,16 @@
"resolved": "https://registry.npmjs.org/url-regex/-/url-regex-3.2.0.tgz",
"integrity": "sha1-260eDJ4p4QXdCx8J9oYvf9tIJyQ=",
"requires": {
- "ip-regex": "1.0.3"
+ "ip-regex": "^1.0.1"
+ }
+ },
+ "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"
}
},
"user-home": {
@@ -20535,27 +17025,37 @@
"dev": true
},
"ut_metadata": {
- "version": "3.0.11",
- "resolved": "https://registry.npmjs.org/ut_metadata/-/ut_metadata-3.0.11.tgz",
- "integrity": "sha512-PbDsUBK3zyiL3q4i785QtLMpuYHDToGFt2HGnb6Ax9dGIYYVfeGKmAiRf4n0wvz3bqoIvESDBO/He/6QErpakg==",
- "requires": {
- "bencode": "1.0.0",
- "bitfield": "1.1.2",
- "debug": "2.6.9",
- "inherits": "2.0.3",
- "safe-buffer": "5.1.1",
- "simple-sha1": "2.1.0"
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ut_metadata/-/ut_metadata-3.2.1.tgz",
+ "integrity": "sha512-tvnzaAo/fxkbvC+dn1h5J2ezIx2uxqarHTHfCRn/FFBV6r4h2553qlB0RjvUU32xu96XCANUbRrLYhsjVjYOGg==",
+ "requires": {
+ "bencode": "^2.0.0",
+ "bitfield": "^2.0.0",
+ "debug": "^3.1.0",
+ "inherits": "^2.0.1",
+ "safe-buffer": "^5.0.1",
+ "simple-sha1": "^2.0.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
}
},
"ut_pex": {
- "version": "1.1.6",
- "resolved": "https://registry.npmjs.org/ut_pex/-/ut_pex-1.1.6.tgz",
- "integrity": "sha512-cgIQHCp7FSGFmuD8qzDL0cSBT0rnImYwxWkCzpfhgCc6XMKqmZdNT8+fgw4U0Fbba/Az/q8uZR2loR8EymFmLg==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/ut_pex/-/ut_pex-1.2.1.tgz",
+ "integrity": "sha512-ZrxMCbffYtxQDqvREN9kBXK2CB9tPnd5PylHoqQX9ai+3HV9/S39FnA5JnhLOC82dxIQQg0nTN2wmhtAdGNtOA==",
"requires": {
- "bencode": "1.0.0",
- "compact2string": "1.4.0",
- "inherits": "2.0.3",
- "string2compact": "1.2.2"
+ "bencode": "^2.0.0",
+ "compact2string": "^1.2.0",
+ "inherits": "^2.0.1",
+ "string2compact": "^1.2.5"
}
},
"utf8-byte-length": {
@@ -20568,6 +17068,7 @@
"version": "0.10.3",
"resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
"integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=",
+ "dev": true,
"requires": {
"inherits": "2.0.1"
},
@@ -20575,7 +17076,8 @@
"inherits": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz",
- "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE="
+ "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=",
+ "dev": true
}
}
},
@@ -20585,9 +17087,9 @@
"integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
},
"utils-merge": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.0.tgz",
- "integrity": "sha1-ApT7kiu5N1FTVBxPcJYjHyh8ivg=",
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=",
"dev": true
},
"uuid": {
@@ -20596,9 +17098,9 @@
"integrity": "sha512-DIWtzUkw04M4k3bf1IcpS2tngXEL26YUD2M0tMDUpnUrz2hgzUBlD55a4FjdLGPvfHxS6uluGWvaVEqgBcVa+g=="
},
"v8-compile-cache": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.0.tgz",
- "integrity": "sha1-HcKjQPuOX4AKMrzb+4wjzXRwIbk="
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz",
+ "integrity": "sha512-ejdrifsIydN1XDH7EuR2hn8ZrkRKUYF7tUcBjBy/lhrCvs2K+zRlbW9UHc0IQ9RsYFZJFqJrieoIHfkCa0DBRA=="
},
"v8flags": {
"version": "2.1.1",
@@ -20606,7 +17108,7 @@
"integrity": "sha1-qrGh+jDUX4jdMhFIh1rALAtV5bQ=",
"dev": true,
"requires": {
- "user-home": "1.1.1"
+ "user-home": "^1.1.1"
}
},
"vali-date": {
@@ -20616,12 +17118,12 @@
"dev": true
},
"validate-npm-package-license": {
- "version": "3.0.1",
- "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz",
- "integrity": "sha1-KAS6vnEq0zeUWaz74kdGqywwP7w=",
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.3.tgz",
+ "integrity": "sha512-63ZOUnL4SIXj4L0NixR3L1lcjO38crAbgrTpl28t8jjrfuiOBL5Iygm+60qPs/KsZGzPNg6Smnc/oY16QTjF0g==",
"requires": {
- "spdx-correct": "1.0.2",
- "spdx-expression-parse": "1.0.4"
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
}
},
"validator": {
@@ -20640,28 +17142,30 @@
"resolved": "https://registry.npmjs.org/validator.js-asserts/-/validator.js-asserts-3.1.0.tgz",
"integrity": "sha1-O8ouCt6htbMRP3+WXtTxrmOkqCM=",
"requires": {
- "lodash": "4.17.4",
- "validator.js": "2.0.3"
+ "lodash": "^4.8.2",
+ "validator.js": "^2.0.0"
}
},
- "varuint-bitcoin": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/varuint-bitcoin/-/varuint-bitcoin-1.0.4.tgz",
- "integrity": "sha1-2BLF2uFuMvYFRLat7h1L4TB9AoM="
- },
"vary": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
- "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=",
+ "dev": true
+ },
+ "vendors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.2.tgz",
+ "integrity": "sha512-w/hry/368nO21AN9QljsaIhb9ZiZtZARoVH5f3CsFbawdLdayCgKRPup7CggujvySMxx0I91NOyxdVENohprLQ==",
+ "dev": true
},
"verror": {
"version": "1.10.0",
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
"requires": {
- "assert-plus": "1.0.0",
+ "assert-plus": "^1.0.0",
"core-util-is": "1.0.2",
- "extsprintf": "1.3.0"
+ "extsprintf": "^1.2.0"
}
},
"videostream": {
@@ -20669,14 +17173,25 @@
"resolved": "https://registry.npmjs.org/videostream/-/videostream-2.4.2.tgz",
"integrity": "sha1-lWAlTQD6vcQJVcGjwoIFfY2x0RU=",
"requires": {
- "binary-search": "1.3.2",
- "inherits": "2.0.3",
- "mediasource": "2.1.3",
- "mp4-box-encoding": "1.1.2",
- "mp4-stream": "2.0.2",
- "multistream": "2.1.0",
- "pump": "1.0.2",
- "range-slice-stream": "1.2.0"
+ "binary-search": "^1.2.0",
+ "inherits": "^2.0.1",
+ "mediasource": "^2.0.0",
+ "mp4-box-encoding": "^1.1.1",
+ "mp4-stream": "^2.0.0",
+ "multistream": "^2.0.2",
+ "pump": "^1.0.1",
+ "range-slice-stream": "^1.2.0"
+ },
+ "dependencies": {
+ "pump": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-1.0.3.tgz",
+ "integrity": "sha512-8k0JupWme55+9tCVE+FS5ULT3K6AbgqrGa58lTT49RpyfwwcGedHqaC5LlQNdEAumn/wFsu6aPwkuPMioy8kqw==",
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ }
}
},
"vinyl": {
@@ -20685,9 +17200,17 @@
"integrity": "sha1-sEVbOPxeDPMNQyUTLkYZcMIJHN4=",
"dev": true,
"requires": {
- "clone": "1.0.2",
- "clone-stats": "0.0.1",
+ "clone": "^1.0.0",
+ "clone-stats": "^0.0.1",
"replace-ext": "0.0.1"
+ },
+ "dependencies": {
+ "clone": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
+ "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=",
+ "dev": true
+ }
}
},
"vinyl-assign": {
@@ -20696,40 +17219,8 @@
"integrity": "sha1-TRmIkbVRWRHXcajNnFSApGoHSkU=",
"dev": true,
"requires": {
- "object-assign": "4.1.1",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "object-assign": "^4.0.1",
+ "readable-stream": "^2.0.0"
}
},
"vinyl-fs": {
@@ -20738,14 +17229,14 @@
"integrity": "sha1-mmhRzhysHBzqX+hsCTHWIMLPqeY=",
"dev": true,
"requires": {
- "defaults": "1.0.3",
- "glob-stream": "3.1.18",
- "glob-watcher": "0.0.6",
- "graceful-fs": "3.0.11",
- "mkdirp": "0.5.1",
- "strip-bom": "1.0.0",
- "through2": "0.6.5",
- "vinyl": "0.4.6"
+ "defaults": "^1.0.0",
+ "glob-stream": "^3.1.5",
+ "glob-watcher": "^0.0.6",
+ "graceful-fs": "^3.0.0",
+ "mkdirp": "^0.5.0",
+ "strip-bom": "^1.0.0",
+ "through2": "^0.6.1",
+ "vinyl": "^0.4.0"
},
"dependencies": {
"clone": {
@@ -20760,7 +17251,7 @@
"integrity": "sha1-dhPHeKGv6mLyXGMKCG1/Osu92Bg=",
"dev": true,
"requires": {
- "natives": "1.1.0"
+ "natives": "^1.1.0"
}
},
"strip-bom": {
@@ -20769,8 +17260,8 @@
"integrity": "sha1-hbiGLzhEtabV7IRnqTWYFzo295Q=",
"dev": true,
"requires": {
- "first-chunk-stream": "1.0.0",
- "is-utf8": "0.2.1"
+ "first-chunk-stream": "^1.0.0",
+ "is-utf8": "^0.2.0"
}
},
"vinyl": {
@@ -20779,8 +17270,8 @@
"integrity": "sha1-LzVsh6VQolVGHza76ypbqL94SEc=",
"dev": true,
"requires": {
- "clone": "0.2.0",
- "clone-stats": "0.0.1"
+ "clone": "^0.2.0",
+ "clone-stats": "^0.0.1"
}
}
}
@@ -20800,32 +17291,24 @@
"integrity": "sha1-oW0CXrkxvQO1LzCMrtD0D86+lTI=",
"dev": true
},
- "warning": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/warning/-/warning-3.0.0.tgz",
- "integrity": "sha1-MuU3fLVy3kqwR1O9+IIcAe1gW3w=",
- "requires": {
- "loose-envify": "1.3.1"
- }
- },
"watchpack": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.4.0.tgz",
- "integrity": "sha1-ShRyvLuVK9Cpu0A2gB+VTfs5+qw=",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz",
+ "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==",
"dev": true,
"requires": {
- "async": "2.5.0",
- "chokidar": "1.7.0",
- "graceful-fs": "4.1.11"
+ "chokidar": "^2.0.2",
+ "graceful-fs": "^4.1.2",
+ "neo-async": "^2.5.0"
}
},
"wbuf": {
- "version": "1.7.2",
- "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.2.tgz",
- "integrity": "sha1-1pe5nx9ZUS3ydRvkJ2nBWAtYAf4=",
+ "version": "1.7.3",
+ "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz",
+ "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==",
"dev": true,
"requires": {
- "minimalistic-assert": "1.0.0"
+ "minimalistic-assert": "^1.0.0"
}
},
"wdio-dot-reporter": {
@@ -20840,28 +17323,28 @@
"integrity": "sha1-IkjRxqLgWonIQNTWLp5VCZekOFQ=",
"dev": true,
"requires": {
- "archiver": "1.3.0",
- "babel-runtime": "6.23.0",
- "css-parse": "2.0.0",
- "css-value": "0.0.1",
- "deepmerge": "1.3.2",
- "ejs": "2.5.7",
- "gaze": "1.1.2",
- "glob": "7.1.2",
- "inquirer": "3.0.6",
- "json-stringify-safe": "5.0.1",
- "mkdirp": "0.5.1",
- "npm-install-package": "2.1.0",
- "optimist": "0.6.1",
- "q": "1.5.0",
- "request": "2.81.0",
- "rgb2hex": "0.1.0",
- "safe-buffer": "5.0.1",
- "supports-color": "3.2.3",
- "url": "0.11.0",
- "validator": "7.0.0",
- "wdio-dot-reporter": "0.0.9",
- "wgxpath": "1.0.0"
+ "archiver": "~1.3.0",
+ "babel-runtime": "~6.23.0",
+ "css-parse": "~2.0.0",
+ "css-value": "~0.0.1",
+ "deepmerge": "~1.3.2",
+ "ejs": "~2.5.6",
+ "gaze": "~1.1.2",
+ "glob": "~7.1.1",
+ "inquirer": "~3.0.6",
+ "json-stringify-safe": "~5.0.1",
+ "mkdirp": "~0.5.1",
+ "npm-install-package": "~2.1.0",
+ "optimist": "~0.6.1",
+ "q": "~1.5.0",
+ "request": "~2.81.0",
+ "rgb2hex": "~0.1.0",
+ "safe-buffer": "~5.0.1",
+ "supports-color": "~3.2.3",
+ "url": "~0.11.0",
+ "validator": "~7.0.0",
+ "wdio-dot-reporter": "~0.0.8",
+ "wgxpath": "~1.0.0"
},
"dependencies": {
"ajv": {
@@ -20870,10 +17353,22 @@
"integrity": "sha1-gv+wKynmYq5TvcIK8VlHcGc5xTY=",
"dev": true,
"requires": {
- "co": "4.6.0",
- "json-stable-stringify": "1.0.1"
+ "co": "^4.6.0",
+ "json-stable-stringify": "^1.0.1"
}
},
+ "ansi-escapes": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-1.4.0.tgz",
+ "integrity": "sha1-06ioOzGapneTZisT52HHkRQiMG4=",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
"assert-plus": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-0.2.0.tgz",
@@ -20892,26 +17387,29 @@
"integrity": "sha1-CpSJ8UTecO+zzkMArM2zKeL8VDs=",
"dev": true,
"requires": {
- "core-js": "2.5.1",
- "regenerator-runtime": "0.10.5"
- }
- },
- "boom": {
- "version": "2.10.1",
- "resolved": "https://registry.npmjs.org/boom/-/boom-2.10.1.tgz",
- "integrity": "sha1-OciRjO/1eZ+D+UkqhI9iWt0Mdm8=",
- "dev": true,
- "requires": {
- "hoek": "2.16.3"
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.10.0"
}
},
- "cryptiles": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/cryptiles/-/cryptiles-2.0.5.tgz",
- "integrity": "sha1-O9/s3GCBR8HGcgL6KR59ylnqo7g=",
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
"dev": true,
"requires": {
- "boom": "2.10.1"
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
}
},
"deepmerge": {
@@ -20920,24 +17418,36 @@
"integrity": "sha1-FmNpFinU2/42T6EqKk8KqGqjoFA=",
"dev": true
},
+ "ejs": {
+ "version": "2.5.9",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.9.tgz",
+ "integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ==",
+ "dev": true
+ },
+ "extend": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.1.tgz",
+ "integrity": "sha1-p1Xqe8Gt/MWjHOfnYtuq3F5jZEQ=",
+ "dev": true
+ },
"form-data": {
"version": "2.1.4",
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.1.4.tgz",
"integrity": "sha1-M8GDrPGTJ27KqYFDpp6Uv+4XUNE=",
"dev": true,
"requires": {
- "asynckit": "0.4.0",
- "combined-stream": "1.0.5",
- "mime-types": "2.1.17"
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.5",
+ "mime-types": "^2.1.12"
}
},
"gaze": {
- "version": "1.1.2",
- "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.2.tgz",
- "integrity": "sha1-hHIkZ3rbiHDWeSV+0ziP22HkAQU=",
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
"dev": true,
"requires": {
- "globule": "1.2.0"
+ "globule": "^1.0.0"
}
},
"globule": {
@@ -20946,9 +17456,9 @@
"integrity": "sha1-HcScaCLdnoovoAuiopUAboZkvQk=",
"dev": true,
"requires": {
- "glob": "7.1.2",
- "lodash": "4.17.4",
- "minimatch": "3.0.4"
+ "glob": "~7.1.1",
+ "lodash": "~4.17.4",
+ "minimatch": "~3.0.2"
}
},
"har-schema": {
@@ -20963,8 +17473,8 @@
"integrity": "sha1-M0gdDxu/9gDdID11gSpqX7oALio=",
"dev": true,
"requires": {
- "ajv": "4.11.8",
- "har-schema": "1.0.5"
+ "ajv": "^4.9.1",
+ "har-schema": "^1.0.5"
}
},
"has-flag": {
@@ -20973,35 +17483,44 @@
"integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
"dev": true
},
- "hawk": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/hawk/-/hawk-3.1.3.tgz",
- "integrity": "sha1-B4REvXwWQLD+VA0sm3PVlnjo4cQ=",
- "dev": true,
- "requires": {
- "boom": "2.10.1",
- "cryptiles": "2.0.5",
- "hoek": "2.16.3",
- "sntp": "1.0.9"
- }
- },
- "hoek": {
- "version": "2.16.3",
- "resolved": "https://registry.npmjs.org/hoek/-/hoek-2.16.3.tgz",
- "integrity": "sha1-ILt0A9POo5jpHcRxCo/xuCdKJe0=",
- "dev": true
- },
"http-signature": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.1.1.tgz",
"integrity": "sha1-33LiZwZs0Kxn+3at+OE0qPvPkb8=",
"dev": true,
"requires": {
- "assert-plus": "0.2.0",
- "jsprim": "1.4.1",
- "sshpk": "1.13.1"
+ "assert-plus": "^0.2.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "inquirer": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.0.6.tgz",
+ "integrity": "sha1-4EqqnQW3o8ubD0B9BDdfBEcZA0c=",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^1.1.0",
+ "chalk": "^1.0.0",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^2.0.1",
+ "figures": "^2.0.0",
+ "lodash": "^4.3.0",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rx": "^4.1.0",
+ "string-width": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "through": "^2.3.6"
}
},
+ "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
+ },
"performance-now": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-0.2.0.tgz",
@@ -21026,28 +17545,28 @@
"integrity": "sha1-xpKJRqDgbF+Nb4qTM0af/aRimKA=",
"dev": true,
"requires": {
- "aws-sign2": "0.6.0",
- "aws4": "1.6.0",
- "caseless": "0.12.0",
- "combined-stream": "1.0.5",
- "extend": "3.0.0",
- "forever-agent": "0.6.1",
- "form-data": "2.1.4",
- "har-validator": "4.2.1",
- "hawk": "3.1.3",
- "http-signature": "1.1.1",
- "is-typedarray": "1.0.0",
- "isstream": "0.1.2",
- "json-stringify-safe": "5.0.1",
- "mime-types": "2.1.17",
- "oauth-sign": "0.8.2",
- "performance-now": "0.2.0",
- "qs": "6.4.0",
- "safe-buffer": "5.0.1",
- "stringstream": "0.0.5",
- "tough-cookie": "2.3.3",
- "tunnel-agent": "0.6.0",
- "uuid": "3.1.0"
+ "aws-sign2": "~0.6.0",
+ "aws4": "^1.2.1",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.5",
+ "extend": "~3.0.0",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.1.1",
+ "har-validator": "~4.2.1",
+ "hawk": "~3.1.3",
+ "http-signature": "~1.1.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.7",
+ "oauth-sign": "~0.8.1",
+ "performance-now": "^0.2.0",
+ "qs": "~6.4.0",
+ "safe-buffer": "^5.0.1",
+ "stringstream": "~0.0.4",
+ "tough-cookie": "~2.3.0",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.0.0"
}
},
"safe-buffer": {
@@ -21056,13 +17575,25 @@
"integrity": "sha1-0mPKVGls2KMGtcplUekt5XkY++c=",
"dev": true
},
- "sntp": {
- "version": "1.0.9",
- "resolved": "https://registry.npmjs.org/sntp/-/sntp-1.0.9.tgz",
- "integrity": "sha1-ZUEYTMkK7qbG57NeJlkIJEPGYZg=",
+ "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": {
- "hoek": "2.16.3"
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
}
},
"supports-color": {
@@ -21071,7 +17602,7 @@
"integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
"dev": true,
"requires": {
- "has-flag": "1.0.0"
+ "has-flag": "^1.0.0"
}
}
}
@@ -21082,39 +17613,57 @@
"integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg=="
},
"webpack": {
- "version": "3.8.1",
- "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.8.1.tgz",
- "integrity": "sha512-5ZXLWWsMqHKFr5y0N3Eo5IIisxeEeRAajNq4mELb/WELOR7srdbQk2N5XiyNy2A/AgvlR3AmeBCZJW8lHrolbw==",
- "dev": true,
- "requires": {
- "acorn": "5.2.1",
- "acorn-dynamic-import": "2.0.2",
- "ajv": "5.2.3",
- "ajv-keywords": "2.1.0",
- "async": "2.5.0",
- "enhanced-resolve": "3.4.1",
- "escope": "3.6.0",
- "interpret": "1.0.4",
- "json-loader": "0.5.7",
- "json5": "0.5.1",
- "loader-runner": "2.3.0",
- "loader-utils": "1.1.0",
- "memory-fs": "0.4.1",
- "mkdirp": "0.5.1",
- "node-libs-browser": "2.0.0",
- "source-map": "0.5.7",
- "supports-color": "4.5.0",
- "tapable": "0.2.8",
- "uglifyjs-webpack-plugin": "0.4.6",
- "watchpack": "1.4.0",
- "webpack-sources": "1.0.1",
- "yargs": "8.0.2"
+ "version": "3.12.0",
+ "resolved": "https://registry.npmjs.org/webpack/-/webpack-3.12.0.tgz",
+ "integrity": "sha512-Sw7MdIIOv/nkzPzee4o0EdvCuPmxT98+vVpIvwtcwcF1Q4SDSNp92vwcKc4REe7NItH9f1S4ra9FuQ7yuYZ8bQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "^5.0.0",
+ "acorn-dynamic-import": "^2.0.0",
+ "ajv": "^6.1.0",
+ "ajv-keywords": "^3.1.0",
+ "async": "^2.1.2",
+ "enhanced-resolve": "^3.4.0",
+ "escope": "^3.6.0",
+ "interpret": "^1.0.0",
+ "json-loader": "^0.5.4",
+ "json5": "^0.5.1",
+ "loader-runner": "^2.3.0",
+ "loader-utils": "^1.1.0",
+ "memory-fs": "~0.4.1",
+ "mkdirp": "~0.5.0",
+ "node-libs-browser": "^2.0.0",
+ "source-map": "^0.5.3",
+ "supports-color": "^4.2.1",
+ "tapable": "^0.2.7",
+ "uglifyjs-webpack-plugin": "^0.4.6",
+ "watchpack": "^1.4.0",
+ "webpack-sources": "^1.0.1",
+ "yargs": "^8.0.2"
},
"dependencies": {
"acorn": {
- "version": "5.2.1",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.2.1.tgz",
- "integrity": "sha512-jG0u7c4Ly+3QkkW18V+NRDN+4bWHdln30NL1ZL2AvFZZmQe/BfopYCtghCKKVBUSetZ4QKcyA0pY6/4Gw8Pv8w==",
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.5.3.tgz",
+ "integrity": "sha512-jd5MkIUlbbmb07nXH0DT3y7rDVtkzDi4XZOUVWAer8ajmF/DTSSbl5oNFyDOl/OXA33Bl79+ypHhl2pN20VeOQ==",
+ "dev": true
+ },
+ "ajv": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.0.tgz",
+ "integrity": "sha512-VDUX1oSajablmiyFyED9L1DFndg0P9h7p1F+NO8FkIzei6EPrR6Zu1n18rd5P8PqaSRd/FrWv3G1TVBqpM83gA==",
+ "dev": true,
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.3.0",
+ "uri-js": "^4.2.1"
+ }
+ },
+ "ajv-keywords": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.2.0.tgz",
+ "integrity": "sha1-6GuBnGAs+IIa1jdBNpjx3sAhhHo=",
"dev": true
},
"ansi-regex": {
@@ -21129,6 +17678,18 @@
"integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
"dev": true
},
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
+ "dev": true
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
"is-fullwidth-code-point": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
@@ -21141,10 +17702,10 @@
"integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "parse-json": "2.2.0",
- "pify": "2.3.0",
- "strip-bom": "3.0.0"
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "strip-bom": "^3.0.0"
}
},
"os-locale": {
@@ -21153,9 +17714,9 @@
"integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
"dev": true,
"requires": {
- "execa": "0.7.0",
- "lcid": "1.0.0",
- "mem": "1.1.0"
+ "execa": "^0.7.0",
+ "lcid": "^1.0.0",
+ "mem": "^1.1.0"
}
},
"path-type": {
@@ -21164,7 +17725,7 @@
"integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=",
"dev": true,
"requires": {
- "pify": "2.3.0"
+ "pify": "^2.0.0"
}
},
"read-pkg": {
@@ -21173,9 +17734,9 @@
"integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=",
"dev": true,
"requires": {
- "load-json-file": "2.0.0",
- "normalize-package-data": "2.4.0",
- "path-type": "2.0.0"
+ "load-json-file": "^2.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^2.0.0"
}
},
"read-pkg-up": {
@@ -21184,18 +17745,24 @@
"integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=",
"dev": true,
"requires": {
- "find-up": "2.1.0",
- "read-pkg": "2.0.0"
+ "find-up": "^2.0.0",
+ "read-pkg": "^2.0.0"
}
},
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ },
"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"
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
}
},
"strip-ansi": {
@@ -21204,7 +17771,7 @@
"integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
"dev": true,
"requires": {
- "ansi-regex": "3.0.0"
+ "ansi-regex": "^3.0.0"
}
},
"strip-bom": {
@@ -21219,7 +17786,7 @@
"integrity": "sha1-vnoN5ITexcXN34s9WRJQRJEvY1s=",
"dev": true,
"requires": {
- "has-flag": "2.0.0"
+ "has-flag": "^2.0.0"
}
},
"uglifyjs-webpack-plugin": {
@@ -21228,9 +17795,9 @@
"integrity": "sha1-uVH0q7a9YX5m9j64kUmOORdj4wk=",
"dev": true,
"requires": {
- "source-map": "0.5.7",
- "uglify-js": "2.8.29",
- "webpack-sources": "1.0.1"
+ "source-map": "^0.5.6",
+ "uglify-js": "^2.8.29",
+ "webpack-sources": "^1.0.1"
}
},
"which-module": {
@@ -21245,19 +17812,19 @@
"integrity": "sha1-YpmpBVsc78lp/355wdkY3Osiw2A=",
"dev": true,
"requires": {
- "camelcase": "4.1.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.2",
- "os-locale": "2.1.0",
- "read-pkg-up": "2.0.0",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "2.1.1",
- "which-module": "2.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "7.0.0"
+ "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": {
@@ -21266,22 +17833,22 @@
"integrity": "sha1-jQrELxbqVd69MyyvTEA4s+P139k=",
"dev": true,
"requires": {
- "camelcase": "4.1.0"
+ "camelcase": "^4.1.0"
}
}
}
},
"webpack-dev-middleware": {
- "version": "1.12.0",
- "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.0.tgz",
- "integrity": "sha1-007++y7dp+HTtdvgcolRMhllFwk=",
+ "version": "1.12.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-1.12.2.tgz",
+ "integrity": "sha512-FCrqPy1yy/sN6U/SaEZcHKRXGlqU0DUaEBL45jkUYoB8foVb6wCnbIJ1HKIx+qUFTW+3JpVcCJCxZ8VATL4e+A==",
"dev": true,
"requires": {
- "memory-fs": "0.4.1",
- "mime": "1.3.4",
- "path-is-absolute": "1.0.1",
- "range-parser": "1.2.0",
- "time-stamp": "2.0.0"
+ "memory-fs": "~0.4.1",
+ "mime": "^1.5.0",
+ "path-is-absolute": "^1.0.0",
+ "range-parser": "^1.0.3",
+ "time-stamp": "^2.0.0"
},
"dependencies": {
"time-stamp": {
@@ -21293,47 +17860,67 @@
}
},
"webpack-dev-server": {
- "version": "2.6.1",
- "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.6.1.tgz",
- "integrity": "sha1-Cykqnaltr4CmWYj2n4e0Fm5d7+c=",
+ "version": "2.11.2",
+ "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-2.11.2.tgz",
+ "integrity": "sha512-zrPoX97bx47vZiAXfDrkw8pe9QjJ+lunQl3dypojyWwWr1M5I2h0VSrMPfTjopHQPRNn+NqfjcMmhoLcUJe2gA==",
"dev": true,
"requires": {
"ansi-html": "0.0.7",
- "bonjour": "3.5.0",
- "chokidar": "1.7.0",
- "compression": "1.7.0",
- "connect-history-api-fallback": "1.3.0",
- "del": "3.0.0",
- "express": "4.15.5",
- "html-entities": "1.2.1",
- "http-proxy-middleware": "0.17.4",
+ "array-includes": "^3.0.3",
+ "bonjour": "^3.5.0",
+ "chokidar": "^2.0.0",
+ "compression": "^1.5.2",
+ "connect-history-api-fallback": "^1.3.0",
+ "debug": "^3.1.0",
+ "del": "^3.0.0",
+ "express": "^4.16.2",
+ "html-entities": "^1.2.0",
+ "http-proxy-middleware": "~0.17.4",
+ "import-local": "^1.0.0",
"internal-ip": "1.2.0",
- "loglevel": "1.5.0",
- "opn": "4.0.2",
- "portfinder": "1.0.13",
- "selfsigned": "1.10.1",
- "serve-index": "1.9.0",
- "sockjs": "0.3.18",
+ "ip": "^1.1.5",
+ "killable": "^1.0.0",
+ "loglevel": "^1.4.1",
+ "opn": "^5.1.0",
+ "portfinder": "^1.0.9",
+ "selfsigned": "^1.9.1",
+ "serve-index": "^1.7.2",
+ "sockjs": "0.3.19",
"sockjs-client": "1.1.4",
- "spdy": "3.4.7",
- "strip-ansi": "3.0.1",
- "supports-color": "3.2.3",
- "webpack-dev-middleware": "1.12.0",
+ "spdy": "^3.4.1",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^5.1.0",
+ "webpack-dev-middleware": "1.12.2",
"yargs": "6.6.0"
},
"dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "dev": true
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
"del": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/del/-/del-3.0.0.tgz",
"integrity": "sha1-U+z2mf/LyzljdpGrE7rxYIGXZuU=",
"dev": true,
"requires": {
- "globby": "6.1.0",
- "is-path-cwd": "1.0.0",
- "is-path-in-cwd": "1.0.0",
- "p-map": "1.2.0",
- "pify": "3.0.0",
- "rimraf": "2.6.2"
+ "globby": "^6.1.0",
+ "is-path-cwd": "^1.0.0",
+ "is-path-in-cwd": "^1.0.0",
+ "p-map": "^1.1.1",
+ "pify": "^3.0.0",
+ "rimraf": "^2.2.8"
}
},
"globby": {
@@ -21342,11 +17929,11 @@
"integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=",
"dev": true,
"requires": {
- "array-union": "1.0.2",
- "glob": "7.1.2",
- "object-assign": "4.1.1",
- "pify": "2.3.0",
- "pinkie-promise": "2.0.1"
+ "array-union": "^1.0.1",
+ "glob": "^7.0.3",
+ "object-assign": "^4.0.1",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
},
"dependencies": {
"pify": {
@@ -21357,11 +17944,14 @@
}
}
},
- "has-flag": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-1.0.0.tgz",
- "integrity": "sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=",
- "dev": true
+ "opn": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/opn/-/opn-5.3.0.tgz",
+ "integrity": "sha512-bYJHo/LOmoTd+pfiYhfZDnf9zekVJrY+cnS2a5F2x+w5ppvTqObojTP7WiFG+kVZs9Inw+qQ/lw7TroWwhdd2g==",
+ "dev": true,
+ "requires": {
+ "is-wsl": "^1.1.0"
+ }
},
"pify": {
"version": "3.0.0",
@@ -21370,12 +17960,12 @@
"dev": true
},
"supports-color": {
- "version": "3.2.3",
- "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-3.2.3.tgz",
- "integrity": "sha1-ZawFBLOVQXHYpklGsq48u4pfVPY=",
+ "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": "1.0.0"
+ "has-flag": "^3.0.0"
}
},
"yargs": {
@@ -21384,19 +17974,19 @@
"integrity": "sha1-eC7CHvQDNF+DCoCMo9UTr1YGUgg=",
"dev": true,
"requires": {
- "camelcase": "3.0.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.2",
- "os-locale": "1.4.0",
- "read-pkg-up": "1.0.1",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "1.0.2",
- "which-module": "1.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "4.2.1"
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^4.2.0"
}
},
"yargs-parser": {
@@ -21405,38 +17995,30 @@
"integrity": "sha1-KczqwNxPA8bIe0qfIX3RjJ90hxw=",
"dev": true,
"requires": {
- "camelcase": "3.0.0"
+ "camelcase": "^3.0.0"
}
}
}
},
"webpack-notifier": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.5.0.tgz",
- "integrity": "sha1-wBAAfUSM68NN78mezyiPpejGuvY=",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.6.0.tgz",
+ "integrity": "sha1-/6yOVf+MRpdSuMG7sBGhbxCYbgI=",
"dev": true,
"requires": {
- "node-notifier": "4.6.1",
- "object-assign": "4.1.1",
- "strip-ansi": "3.0.1"
+ "node-notifier": "^5.1.2",
+ "object-assign": "^4.1.0",
+ "strip-ansi": "^3.0.1"
}
},
"webpack-sources": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.0.1.tgz",
- "integrity": "sha512-05tMxipUCwHqYaVS8xc7sYPTly8PzXayRCB4dTxLhWTqlKUiwH6ezmEe0OSreL1c30LAuA3Zqmc+uEBUGFJDjw==",
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.1.0.tgz",
+ "integrity": "sha512-aqYp18kPphgoO5c/+NaUvEeACtZjMESmDChuD3NBciVpah3XpMEU9VAAtIaB1BsfJWWTSdv8Vv1m3T0aRk2dUw==",
"dev": true,
"requires": {
- "source-list-map": "2.0.0",
- "source-map": "0.5.7"
- },
- "dependencies": {
- "source-list-map": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.0.tgz",
- "integrity": "sha512-I2UmuJSRr/T8jisiROLU3A3ltr+swpniSmNPI4Ml3ZCX6tVnDsuZzK7F2hl5jTqbZBWCEKlj5HRQiPExXLgE8A==",
- "dev": true
- }
+ "source-list-map": "^2.0.0",
+ "source-map": "~0.6.1"
}
},
"websocket-driver": {
@@ -21445,100 +18027,100 @@
"integrity": "sha1-DK+dLXVdk67gSdS90NP+LMoqJOs=",
"dev": true,
"requires": {
- "http-parser-js": "0.4.8",
- "websocket-extensions": "0.1.2"
+ "http-parser-js": ">=0.4.0",
+ "websocket-extensions": ">=0.1.1"
}
},
"websocket-extensions": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.2.tgz",
- "integrity": "sha1-Dhh4HeYpoYMIzhSBZQ9n/6JpOl0=",
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.3.tgz",
+ "integrity": "sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==",
"dev": true
},
"webtorrent": {
- "version": "0.98.19",
- "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-0.98.19.tgz",
- "integrity": "sha512-w4P08zHaDFLPe6xO4KEjD5gr8cHbPT80KfH82LIAf22FCAt2mEAftYdXJA1T4aDGPr4MQ/x5ZAg0tkG74wl+lA==",
- "requires": {
- "addr-to-ip-port": "1.4.2",
- "bitfield": "1.1.2",
- "bittorrent-dht": "7.6.0",
- "bittorrent-protocol": "2.2.3",
- "chunk-store-stream": "2.0.2",
- "create-torrent": "3.29.2",
- "debug": "2.6.9",
- "end-of-stream": "1.4.0",
- "fs-chunk-store": "1.6.5",
- "immediate-chunk-store": "1.0.8",
- "inherits": "2.0.3",
- "load-ip-set": "1.3.1",
- "memory-chunk-store": "1.3.0",
- "mime": "1.3.4",
- "multistream": "2.1.0",
- "package-json-versionify": "1.0.4",
- "parse-torrent": "5.8.3",
- "pump": "1.0.2",
- "random-iterate": "1.0.1",
- "randombytes": "2.0.5",
- "range-parser": "1.2.0",
- "readable-stream": "2.3.3",
- "render-media": "2.10.0",
- "run-parallel": "1.1.6",
- "run-parallel-limit": "1.0.3",
- "safe-buffer": "5.1.1",
- "simple-concat": "1.0.0",
- "simple-get": "2.7.0",
- "simple-peer": "8.1.1",
- "simple-sha1": "2.1.0",
- "speedometer": "1.0.0",
- "stream-to-blob": "1.0.0",
- "stream-to-blob-url": "2.1.0",
- "stream-with-known-length-to-buffer": "1.0.0",
- "torrent-discovery": "8.3.1",
- "torrent-piece": "1.1.1",
- "uniq": "1.0.1",
- "unordered-array-remove": "1.0.2",
- "ut_metadata": "3.0.11",
- "ut_pex": "1.1.6",
- "xtend": "4.0.1",
- "zero-fill": "2.2.3"
+ "version": "0.99.4",
+ "resolved": "https://registry.npmjs.org/webtorrent/-/webtorrent-0.99.4.tgz",
+ "integrity": "sha512-coJ61iJOFDrSzyCwmhlLaU8tvcchI5ZA0fH9Toj4wwUq/OTUNdjXtNXwpCb6ldbBnJ04lQzxyDeuSR3KtN0MWg==",
+ "requires": {
+ "addr-to-ip-port": "^1.4.2",
+ "bitfield": "^2.0.0",
+ "bittorrent-dht": "^8.0.0",
+ "bittorrent-protocol": "^2.1.5",
+ "chunk-store-stream": "^2.0.2",
+ "create-torrent": "^3.24.5",
+ "debug": "^3.1.0",
+ "end-of-stream": "^1.1.0",
+ "fs-chunk-store": "^1.6.2",
+ "immediate-chunk-store": "^1.0.8",
+ "inherits": "^2.0.1",
+ "load-ip-set": "^1.2.7",
+ "memory-chunk-store": "^1.2.0",
+ "mime": "^2.2.0",
+ "multistream": "^2.0.5",
+ "package-json-versionify": "^1.0.2",
+ "parse-torrent": "^6.0.0",
+ "pump": "^3.0.0",
+ "random-iterate": "^1.0.1",
+ "randombytes": "^2.0.3",
+ "range-parser": "^1.2.0",
+ "readable-stream": "^2.1.4",
+ "render-media": "^3.0.0",
+ "run-parallel": "^1.1.6",
+ "run-parallel-limit": "^1.0.3",
+ "safe-buffer": "^5.0.1",
+ "simple-concat": "^1.0.0",
+ "simple-get": "^3.0.1",
+ "simple-peer": "^9.0.0",
+ "simple-sha1": "^2.0.8",
+ "speedometer": "^1.0.0",
+ "stream-to-blob": "^1.0.0",
+ "stream-to-blob-url": "^2.1.0",
+ "stream-with-known-length-to-buffer": "^1.0.0",
+ "torrent-discovery": "^8.3.1",
+ "torrent-piece": "^1.1.0",
+ "uniq": "^1.0.1",
+ "unordered-array-remove": "^1.0.2",
+ "ut_metadata": "^3.0.8",
+ "ut_pex": "^1.1.1",
+ "xtend": "^4.0.1",
+ "zero-fill": "^2.2.3"
},
"dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE="
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
"requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
+ "ms": "2.0.0"
}
},
- "simple-get": {
- "version": "2.7.0",
- "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-2.7.0.tgz",
- "integrity": "sha512-RkE9rGPHcxYZ/baYmgJtOSM63vH0Vyq+ma5TijBcLla41SWlh8t6XYIGMR/oeZcmr+/G8k+zrClkkVrtnQ0esg==",
+ "mime": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-2.3.1.tgz",
+ "integrity": "sha512-OEUllcVoydBHGN1z84yfQDimn58pZNNNXgZlHXSboxMlFvgI6MXSWpWKpFRra7H1HxpVhHTkrghfRW49k6yjeg=="
+ },
+ "parse-torrent": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/parse-torrent/-/parse-torrent-6.0.0.tgz",
+ "integrity": "sha512-JjQ6D11KmC1W5YXF0SDghPxeeDU4HPZzBzVwqVcPeRWTxgWdhpijHa4TLibkX+k14+LlK82Zf8vTgeLVsomQfQ==",
"requires": {
- "decompress-response": "3.3.0",
- "once": "1.4.0",
- "simple-concat": "1.0.0"
+ "bencode": "^2.0.0",
+ "blob-to-buffer": "^1.2.6",
+ "get-stdin": "^6.0.0",
+ "magnet-uri": "^5.1.3",
+ "simple-get": "^3.0.1",
+ "simple-sha1": "^2.0.0",
+ "uniq": "^1.0.1"
}
},
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
+ "simple-get": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-3.0.2.tgz",
+ "integrity": "sha512-dU3TBVIGkP5Hzw6o74hJx+VzTBTX2rqIiLfugs0HdmdVQCQp76XGg2jlBCqfRJfW/n6/mUKTi+s3rnzX7SgbBA==",
"requires": {
- "safe-buffer": "5.1.1"
+ "decompress-response": "^3.3.0",
+ "once": "^1.3.1",
+ "simple-concat": "^1.0.0"
}
}
}
@@ -21548,9 +18130,9 @@
"resolved": "https://registry.npmjs.org/webtorrent-remote/-/webtorrent-remote-2.1.0.tgz",
"integrity": "sha512-40nk0CG76CeGtHFvc+Y4rRxTjtK6dhIHlsxR6slMa8lYASh7S8vEjDsE8JFicIvfM1cRK0dIMvosPTjO7xbkuQ==",
"requires": {
- "debug": "2.6.9",
- "throttleit": "1.0.0",
- "webtorrent": "0.98.19"
+ "debug": "^2.6.3",
+ "throttleit": "^1.0.0",
+ "webtorrent": "0.x"
}
},
"wgxpath": {
@@ -21560,58 +18142,40 @@
"dev": true
},
"whatwg-encoding": {
- "version": "1.0.1",
- "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.1.tgz",
- "integrity": "sha1-PGxFGhmO567FWx7GHQkgxngBpfQ=",
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.3.tgz",
+ "integrity": "sha512-jLBwwKUhi8WtBfsMQlL4bUUcT8sMkAtQinscJAe/M4KHCkHuUJAF6vuB0tueNIw4c8ziO6AkRmgY+jL3a0iiPw==",
"requires": {
- "iconv-lite": "0.4.13"
- },
- "dependencies": {
- "iconv-lite": {
- "version": "0.4.13",
- "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.13.tgz",
- "integrity": "sha1-H4irpKsLFQjoMSrMOTRfNumS4vI="
- }
+ "iconv-lite": "0.4.19"
}
},
"whatwg-fetch": {
- "version": "2.0.3",
- "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz",
- "integrity": "sha1-nITsLc9oGH/wC8ZOEnS0QhduHIQ="
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz",
+ "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng=="
},
"whatwg-url": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.3.0.tgz",
- "integrity": "sha512-rM+hE5iYKGPAOu05mIdJR47pYSR2vDzfrTEFRc/S8D3L60yW8BuXmUJ7Kog7x/DrokFN7JNaHKadpzjouKRRAw==",
+ "version": "6.4.1",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.4.1.tgz",
+ "integrity": "sha512-FwygsxsXx27x6XXuExA/ox3Ktwcbf+OAvrKmLulotDAiO1Q6ixchPFaHYsis2zZBZSJTR0+dR+JVtf7MlbqZjw==",
"requires": {
- "lodash.sortby": "4.7.0",
- "tr46": "1.0.1",
- "webidl-conversions": "4.0.2"
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
}
},
- "whatwg-url-compat": {
- "version": "0.6.5",
- "resolved": "https://registry.npmjs.org/whatwg-url-compat/-/whatwg-url-compat-0.6.5.tgz",
- "integrity": "sha1-AImBEa9om7CXVBzVpFymyHmERb8=",
- "optional": true,
- "requires": {
- "tr46": "0.0.3"
- },
- "dependencies": {
- "tr46": {
- "version": "0.0.3",
- "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
- "integrity": "sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=",
- "optional": true
- }
- }
+ "whet.extend": {
+ "version": "0.9.9",
+ "resolved": "https://registry.npmjs.org/whet.extend/-/whet.extend-0.9.9.tgz",
+ "integrity": "sha1-+HfVv2SMl+WqVC+twW1qJZucEaE=",
+ "dev": true
},
"which": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/which/-/which-1.3.0.tgz",
"integrity": "sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==",
"requires": {
- "isexe": "2.0.0"
+ "isexe": "^2.0.0"
}
},
"which-module": {
@@ -21619,29 +18183,59 @@
"resolved": "https://registry.npmjs.org/which-module/-/which-module-1.0.0.tgz",
"integrity": "sha1-u6Y8qGGUiZT/MHc2CJ47lgJsKk8="
},
+ "which-pm-runs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz",
+ "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs="
+ },
"wide-align": {
"version": "1.1.2",
"resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.2.tgz",
"integrity": "sha512-ijDLlyQ7s6x1JgCLur53osjm/UXUYD9+0PbYKrBsYisYXzCxN+HC3mYDNy/dWdmf3AwqwU3CXwDCvsNgGK1S0w==",
"requires": {
- "string-width": "1.0.2"
+ "string-width": "^1.0.2"
}
},
"widest-line": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-1.0.0.tgz",
- "integrity": "sha1-DAnIXCqUaD0Nfq+O4JfVZL8OEFw=",
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.0.tgz",
+ "integrity": "sha1-AUKk6KJD+IgsAjOqDgKBqnYVInM=",
"dev": true,
"requires": {
- "string-width": "1.0.2"
- }
- },
- "wif": {
- "version": "2.0.6",
- "resolved": "https://registry.npmjs.org/wif/-/wif-2.0.6.tgz",
- "integrity": "sha1-CNP1IFbGZnkplyb63g1DKudLRwQ=",
- "requires": {
- "bs58check": "1.0.4"
+ "string-width": "^2.1.1"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
}
},
"window-size": {
@@ -21661,13 +18255,12 @@
"integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus="
},
"worker-farm": {
- "version": "1.5.0",
- "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.5.0.tgz",
- "integrity": "sha512-DHRiUggxtbruaTwnLDm2/BRDKZIoOYvrgYUj5Bam4fU6Gtvc0FaEyoswFPBjMXAweGW2H4BDNIpy//1yXXuaqQ==",
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.6.0.tgz",
+ "integrity": "sha512-6w+3tHbM87WnSWnENBUvA2pxJPLhQUg5LKwUQHq3r+XPhIM+Gh2R5ycbwPCyuGbNg+lPgdcnQUhuC02kJCvffQ==",
"dev": true,
"requires": {
- "errno": "0.1.4",
- "xtend": "4.0.1"
+ "errno": "~0.1.7"
}
},
"wrap-ansi": {
@@ -21675,8 +18268,8 @@
"resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
"integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
"requires": {
- "string-width": "1.0.2",
- "strip-ansi": "3.0.1"
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
}
},
"wrappy": {
@@ -21684,12 +18277,39 @@
"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",
"integrity": "sha1-X8A4KOJkzqP+kUVUdvejxWbLB1c=",
"requires": {
- "mkdirp": "0.5.1"
+ "mkdirp": "^0.5.1"
}
},
"write-file-atomic": {
@@ -21698,9 +18318,9 @@
"integrity": "sha512-xuPeK4OdjWqtfi59ylvVL0Yn35SF3zgcAcv7rBPFHVaEapaDr4GdGgm3j7ckTwH9wHL7fGmgfAnb0+THrHb8tA==",
"dev": true,
"requires": {
- "graceful-fs": "4.1.11",
- "imurmurhash": "0.1.4",
- "signal-exit": "3.0.2"
+ "graceful-fs": "^4.1.11",
+ "imurmurhash": "^0.1.4",
+ "signal-exit": "^3.0.2"
}
},
"write-file-stdout": {
@@ -21710,28 +18330,11 @@
"dev": true
},
"ws": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.2.tgz",
- "integrity": "sha512-t+WGpsNxhMR4v6EClXS8r8km5ZljKJzyGhJf7goJz9k5Ye3+b5Bvno5rjqPuIBn5mnn5GBb7o8IrIWHxX1qOLQ==",
- "requires": {
- "async-limiter": "1.0.0",
- "safe-buffer": "5.1.1",
- "ultron": "1.1.1"
- }
- },
- "x-address-codec": {
- "version": "0.7.2",
- "resolved": "https://registry.npmjs.org/x-address-codec/-/x-address-codec-0.7.2.tgz",
- "integrity": "sha1-Ki97sAJ4UgvRNzOnlZoFRD1oAuA=",
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.0.tgz",
+ "integrity": "sha512-c18dMeW+PEQdDFzkhDsnBAlS4Z8KGStBQQUcQ5mf7Nf689jyGk0594L+i9RaQuf4gog6SvWLJorz2NfSaqxZ7w==",
"requires": {
- "base-x": "1.1.0"
- },
- "dependencies": {
- "base-x": {
- "version": "1.1.0",
- "resolved": "https://registry.npmjs.org/base-x/-/base-x-1.1.0.tgz",
- "integrity": "sha1-QtPXF0dPnqAiB/bRqh9CaRPut6w="
- }
+ "async-limiter": "~1.0.0"
}
},
"xdg-basedir": {
@@ -21741,14 +18344,14 @@
"dev": true
},
"xhr": {
- "version": "2.4.0",
- "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.4.0.tgz",
- "integrity": "sha1-4W5mpF+GmGHu76tBbV7/ci3ECZM=",
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/xhr/-/xhr-2.5.0.tgz",
+ "integrity": "sha512-4nlO/14t3BNUZRXIXfXe+3N6w3s1KoxcJUUURctd64BLRe67E4gRwp4PjywtDY72fXpZ1y6Ch0VZQRY/gMPzzQ==",
"requires": {
- "global": "4.3.2",
- "is-function": "1.0.1",
- "parse-headers": "2.0.1",
- "xtend": "4.0.1"
+ "global": "~4.3.0",
+ "is-function": "^1.0.1",
+ "parse-headers": "^2.0.0",
+ "xtend": "^4.0.0"
}
},
"xml-name-validator": {
@@ -21766,22 +18369,14 @@
"resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
"integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
"requires": {
- "sax": "1.2.4",
- "xmlbuilder": "9.0.4"
- },
- "dependencies": {
- "xmlbuilder": {
- "version": "9.0.4",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.4.tgz",
- "integrity": "sha1-UZy0ymhtAFqEINNJbz8MruzKWA8="
- }
+ "sax": ">=0.6.0",
+ "xmlbuilder": "~9.0.1"
}
},
"xmlbuilder": {
- "version": "8.2.2",
- "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-8.2.2.tgz",
- "integrity": "sha1-aSSGc0ELS6QuGmE2VR0pIjNap3M=",
- "dev": true
+ "version": "9.0.7",
+ "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
+ "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
},
"xmldom": {
"version": "0.1.27",
@@ -21789,11 +18384,6 @@
"integrity": "sha1-1QH5ezvbQDr4757MIFcxh6rawOk=",
"dev": true
},
- "xregexp": {
- "version": "2.0.0",
- "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz",
- "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM="
- },
"xtend": {
"version": "4.0.1",
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
@@ -21810,24 +18400,17 @@
"integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI="
},
"yargs": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-7.1.0.tgz",
- "integrity": "sha1-a6MY6xaWFyf10oT46gA+jWFU0Mg=",
- "optional": true,
+ "version": "3.32.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-3.32.0.tgz",
+ "integrity": "sha1-AwiOnr+edWtpdRYR0qXvWRSCyZU=",
"requires": {
- "camelcase": "3.0.0",
- "cliui": "3.2.0",
- "decamelize": "1.2.0",
- "get-caller-file": "1.0.2",
- "os-locale": "1.4.0",
- "read-pkg-up": "1.0.1",
- "require-directory": "2.1.1",
- "require-main-filename": "1.0.1",
- "set-blocking": "2.0.0",
- "string-width": "1.0.2",
- "which-module": "1.0.0",
- "y18n": "3.2.1",
- "yargs-parser": "5.0.0"
+ "camelcase": "^2.0.1",
+ "cliui": "^3.0.3",
+ "decamelize": "^1.1.1",
+ "os-locale": "^1.4.0",
+ "string-width": "^1.0.1",
+ "window-size": "^0.1.4",
+ "y18n": "^3.2.0"
}
},
"yargs-parser": {
@@ -21836,7 +18419,15 @@
"integrity": "sha1-J17PDX/+Bcd+ZOfIbkzZS/DhIoo=",
"optional": true,
"requires": {
- "camelcase": "3.0.0"
+ "camelcase": "^3.0.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha1-MvxLn82vhF/N9+c7uXysImHwqwo=",
+ "optional": true
+ }
}
},
"yauzl": {
@@ -21845,7 +18436,7 @@
"integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
"dev": true,
"requires": {
- "fd-slicer": "1.0.1"
+ "fd-slicer": "~1.0.1"
}
},
"zero-fill": {
@@ -21859,42 +18450,10 @@
"integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
"dev": true,
"requires": {
- "archiver-utils": "1.3.0",
- "compress-commons": "1.2.0",
- "lodash": "4.17.4",
- "readable-stream": "2.3.3"
- },
- "dependencies": {
- "isarray": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
- "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
- "dev": true
- },
- "readable-stream": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.3.tgz",
- "integrity": "sha512-m+qzzcn7KUxEmd1gMbchF+Y2eIUbieUaxkWtptyHywrX0rE8QEYqPC07Vuy4Wm32/xE16NcdBctb8S0Xe/5IeQ==",
- "dev": true,
- "requires": {
- "core-util-is": "1.0.2",
- "inherits": "2.0.3",
- "isarray": "1.0.0",
- "process-nextick-args": "1.0.7",
- "safe-buffer": "5.1.1",
- "string_decoder": "1.0.3",
- "util-deprecate": "1.0.2"
- }
- },
- "string_decoder": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.0.3.tgz",
- "integrity": "sha512-4AH6Z5fzNNBcH+6XDMfA/BTt87skxqJlO0lAh3Dker5zThcAxG6mKz+iGu308UKoPPQ8Dcqx/4JhujzltRa+hQ==",
- "dev": true,
- "requires": {
- "safe-buffer": "5.1.1"
- }
- }
+ "archiver-utils": "^1.3.0",
+ "compress-commons": "^1.2.0",
+ "lodash": "^4.8.0",
+ "readable-stream": "^2.0.0"
}
}
}
diff --git a/package.json b/package.json
index a97bf798d65..4b3537e99d5 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "brave",
- "version": "0.22.0",
+ "version": "0.24.0",
"description": "Brave laptop and desktop browser",
"main": "./app/index.js",
"config": {
@@ -34,8 +34,8 @@
"start-brk": "node ./tools/start.js --debug-brk=5858 -enable-logging --v=0 --enable-dcheck --user-data-dir-name=brave-development",
"test": "cross-env NODE_ENV=test mocha \"test/**/*Test.js\"",
"testsuite": "node ./tools/test.js",
- "unittest": "cross-env NODE_ENV=test mocha \"test/unit/**/*Test.js\"",
- "unittest-cov": "node --harmony node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha --report lcovonly --report html --report text -x \"test/unit/**/*Test.js\" -- \"test/unit/**/*Test.js\"",
+ "unittest": "cross-env NODE_ENV=test mocha \"test/unit/**/*Test.js\" --globals chrome,DOMParser,XMLSerializer",
+ "unittest-cov": "node --harmony node_modules/istanbul/lib/cli.js cover ./node_modules/mocha/bin/_mocha --globals chrome,DOMParser,XMLSerializer --report lcovonly --report html --report text -x \"test/unit/**/*Test.js\" -- \"test/unit/**/*Test.js\"",
"update-pdfjs": "rm -r app/extensions/pdfjs/; cp -r ../pdf.js/build/chromium/ app/extensions/pdfjs/",
"update-psl": "./tools/updatepsl.sh",
"vagrant-destroy-linux": "VAGRANT_CWD=./test/vms/vagrant/ubuntu-14.04 vagrant destroy",
@@ -88,15 +88,16 @@
"acorn": "3.2.0",
"aphrodite": "1.1.0",
"async": "^2.0.1",
- "bat-balance": "^1.0.4",
- "bat-client": "^2.0.7",
- "bat-publisher": "^2.0.3",
+ "bat-balance": "^1.0.7",
+ "bat-client": "^3.0.0",
+ "bat-publisher": "^2.0.15",
"bignumber.js": "^4.0.4",
"bloodhound-js": "brave/bloodhound",
"clipboard-copy": "^1.0.0",
"compare-versions": "^3.0.1",
"date-fns": "^1.29.0",
"deepmerge": "^2.0.1",
+ "dtrace-provider": "brave/node-dtrace-provider",
"electron-localshortcut": "^0.6.0",
"electron-squirrel-startup": "brave/electron-squirrel-startup",
"emoji-regex": "^6.5.1",
@@ -106,9 +107,10 @@
"immutable": "^3.7.5",
"immutablediff": "^0.4.2",
"immutablepatch": "brave/immutable-js-patch",
+ "ip": "^1.1.5",
"l20n": "^3.5.1",
"lru-cache": "^1.0.0",
- "moment": "~2.18.1",
+ "nan": "2.8.0",
"niceware": "^1.0.4",
"parse-torrent": "^5.8.1",
"prettier-bytes": "^1.0.3",
@@ -122,11 +124,12 @@
"react-dom": "^15.5.4",
"react-select": "^0.9.1",
"react-transition-group": "^2.2.1",
+ "sha3": "brave/node-sha3",
"snazzy": "^7.0.0",
"string.prototype.endswith": "^0.2.0",
"string.prototype.startswith": "^0.2.0",
- "tablesort": "5.0.1",
- "tldjs": "1.6.2",
+ "tablesort": "5.0.2",
+ "tldjs": "^2.3.1",
"underscore": "1.8.3",
"url-loader": "~0.6.2",
"v8-compile-cache": "^1.1.0",
@@ -173,7 +176,8 @@
"jsonfile": "^2.2.3",
"less": "^2.5.3",
"less-loader": "^2.2.1",
- "level": "^1.7.0",
+ "level": "^2.1.1",
+ "lolex": "~1.3.2",
"mkdirp": "^0.5.1",
"mocha": "^2.3.4",
"mockery": "^2.1.0",
@@ -182,7 +186,7 @@
"node-gyp": "^3.3.1",
"node-libs-browser": "~2.0.0",
"node-static": "^0.7.7",
- "nsp": "^2.2.0",
+ "nsp": "^3.2.1",
"pre-commit": "brave/pre-commit",
"pre-push": "^0.1.1",
"react-addons-perf": "^15.2.1",
@@ -198,8 +202,7 @@
"webdriverio": "4.7.1",
"webpack": "^3.8.1",
"webpack-dev-server": "^2.6.1",
- "webpack-notifier": "^1.2.1",
- "xml2js": "^0.4.15"
+ "webpack-notifier": "^1.2.1"
},
"optionalDependencies": {
"electron-installer-debian": "brave/electron-installer-debian",
diff --git a/res/beta/app.icns b/res/beta/app.icns
index 281a7f2b2e4..f47bee90017 100644
Binary files a/res/beta/app.icns and b/res/beta/app.icns differ
diff --git a/res/beta/app.ico b/res/beta/app.ico
index 0962d96d19a..f40b4b30285 100644
Binary files a/res/beta/app.ico and b/res/beta/app.ico differ
diff --git a/res/beta/app.png b/res/beta/app.png
index 128f3fac859..a4d6aabc0ea 100644
Binary files a/res/beta/app.png and b/res/beta/app.png differ
diff --git a/res/beta/brave_installer.icns b/res/beta/brave_installer.icns
index e3c368739d4..7b4a51d3565 100644
Binary files a/res/beta/brave_installer.icns and b/res/beta/brave_installer.icns differ
diff --git a/res/beta/brave_installer.ico b/res/beta/brave_installer.ico
index d192404dcbc..747acb70ba2 100644
Binary files a/res/beta/brave_installer.ico and b/res/beta/brave_installer.ico differ
diff --git a/res/beta/brave_installer.png b/res/beta/brave_installer.png
index 402bdfe5dfa..26c5910fd5a 100644
Binary files a/res/beta/brave_installer.png and b/res/beta/brave_installer.png differ
diff --git a/res/dev/app.icns b/res/dev/app.icns
index b7e67ea41c5..960d78557a2 100644
Binary files a/res/dev/app.icns and b/res/dev/app.icns differ
diff --git a/res/dev/app.ico b/res/dev/app.ico
index 938b87bbb05..3090154e29c 100644
Binary files a/res/dev/app.ico and b/res/dev/app.ico differ
diff --git a/res/dev/app.png b/res/dev/app.png
index 0fd9b8be1a0..728ccb1706d 100644
Binary files a/res/dev/app.png and b/res/dev/app.png differ
diff --git a/res/dev/brave_installer.icns b/res/dev/brave_installer.icns
index 84f43c2430a..a893e88990f 100644
Binary files a/res/dev/brave_installer.icns and b/res/dev/brave_installer.icns differ
diff --git a/res/dev/brave_installer.ico b/res/dev/brave_installer.ico
index 6272eba0625..c848ef15669 100644
Binary files a/res/dev/brave_installer.ico and b/res/dev/brave_installer.ico differ
diff --git a/res/dev/brave_installer.png b/res/dev/brave_installer.png
index cd0756a07a3..4ec18417dc1 100644
Binary files a/res/dev/brave_installer.png and b/res/dev/brave_installer.png differ
diff --git a/res/developer/app.icns b/res/developer/app.icns
index 49189e6e44c..11d277468bf 100644
Binary files a/res/developer/app.icns and b/res/developer/app.icns differ
diff --git a/res/developer/app.ico b/res/developer/app.ico
index 2e59f39fe01..0d38c0fe17a 100644
Binary files a/res/developer/app.ico and b/res/developer/app.ico differ
diff --git a/res/developer/app.png b/res/developer/app.png
index 31912059826..80ae9cc1c54 100644
Binary files a/res/developer/app.png and b/res/developer/app.png differ
diff --git a/res/developer/brave_installer.icns b/res/developer/brave_installer.icns
index 05f92a0eed7..8c41b3c7155 100644
Binary files a/res/developer/brave_installer.icns and b/res/developer/brave_installer.icns differ
diff --git a/res/developer/brave_installer.ico b/res/developer/brave_installer.ico
index a18eef03108..41f782c60d0 100644
Binary files a/res/developer/brave_installer.ico and b/res/developer/brave_installer.ico differ
diff --git a/res/developer/brave_installer.png b/res/developer/brave_installer.png
index bcdc72e9be1..c79b8c55bf5 100644
Binary files a/res/developer/brave_installer.png and b/res/developer/brave_installer.png differ
diff --git a/res/nightly/app.icns b/res/nightly/app.icns
index 39f069d1b57..f726538407e 100644
Binary files a/res/nightly/app.icns and b/res/nightly/app.icns differ
diff --git a/res/nightly/app.ico b/res/nightly/app.ico
index 5357b2e880c..33555ead819 100644
Binary files a/res/nightly/app.ico and b/res/nightly/app.ico differ
diff --git a/res/nightly/app.png b/res/nightly/app.png
index 4ed96a97e26..6bbccc5a549 100644
Binary files a/res/nightly/app.png and b/res/nightly/app.png differ
diff --git a/res/nightly/brave_installer.icns b/res/nightly/brave_installer.icns
index ef2f90b7f8f..eb8da5abf97 100644
Binary files a/res/nightly/brave_installer.icns and b/res/nightly/brave_installer.icns differ
diff --git a/res/nightly/brave_installer.ico b/res/nightly/brave_installer.ico
index 1756ef20893..8885d7a99a3 100644
Binary files a/res/nightly/brave_installer.ico and b/res/nightly/brave_installer.ico differ
diff --git a/res/nightly/brave_installer.png b/res/nightly/brave_installer.png
index 1ff8d6a8a2a..4004d56abf9 100644
Binary files a/res/nightly/brave_installer.png and b/res/nightly/brave_installer.png differ
diff --git a/test/about/ledgerPanelAdvancedPanelTest.js b/test/about/ledgerPanelAdvancedPanelTest.js
index e544f725c78..fec6e9c7ee6 100644
--- a/test/about/ledgerPanelAdvancedPanelTest.js
+++ b/test/about/ledgerPanelAdvancedPanelTest.js
@@ -1,7 +1,7 @@
/* global describe, it, beforeEach */
const Brave = require('../lib/brave')
-const {urlInput, paymentsWelcomePage, paymentsTab, walletSwitch, backupWallet, recoverWallet, saveWalletFile, advancedSettingsButton, recoverWalletFromFileButton, balanceRecovered, balanceNotRecovered, recoveryOverlayOkButton} = require('../lib/selectors')
+const {urlInput, paymentsWelcomePage, paymentsTab, walletSwitch, backupWallet, recoverWallet, saveWalletFile, advancedSettingsButton, recoverWalletFromFileButton, balanceRecovered, balanceNotRecovered, recoveryOverlayOkButton, modalOverlay, recoveryOverlayErrorButton} = require('../lib/selectors')
const messages = require('../../js/constants/messages')
const assert = require('assert')
@@ -186,4 +186,14 @@ describe.skip('Advanced payment panel tests', function () {
yield this.app.client
.waitForVisible(balanceNotRecovered, ledgerAPIWaitTimeout)
})
+
+ it('keeps ledger recovery modal open if there was a recovery error', function * () {
+ generateAndSaveRecoveryFile(context.recoveryFilePathname, '')
+ yield recoverWalletFromFile(this.app.client)
+ yield this.app.client
+ .waitForVisible(balanceNotRecovered, ledgerAPIWaitTimeout)
+ .click(recoveryOverlayErrorButton)
+ .pause(1000)
+ .waitForVisible(modalOverlay, ledgerAPIWaitTimeout)
+ })
})
diff --git a/test/contents/contentLoadingTest.js b/test/contents/contentLoadingTest.js
index 84906d71275..f9c637673d3 100644
--- a/test/contents/contentLoadingTest.js
+++ b/test/contents/contentLoadingTest.js
@@ -51,4 +51,20 @@ describe('content loading', function () {
.windowByUrl(Brave.browserWindowUrl)
.waitForTextValue('[data-test-id="tabTitle"]', 'fail')
})
+
+ it('does not support bluetooth API', function * () {
+ const page1 = Brave.fixtureUrl('navigator.html')
+ yield this.app.client
+ .tabByIndex(0)
+ .url(page1)
+ .waitForTextValue('#bluetooth', 'undefined')
+ })
+
+ it('does not support webusb API', function * () {
+ const page1 = Brave.fixtureUrl('navigator.html')
+ yield this.app.client
+ .tabByIndex(0)
+ .url(page1)
+ .waitForTextValue('#webusb', 'undefined')
+ })
})
diff --git a/test/fixtures/navigator.html b/test/fixtures/navigator.html
new file mode 100644
index 00000000000..ee1763dc795
--- /dev/null
+++ b/test/fixtures/navigator.html
@@ -0,0 +1,12 @@
+
+
+ testing...
+
+
+ testing...
+
+
+
diff --git a/test/lib/brave.js b/test/lib/brave.js
index 50c49597da2..3600d2e6260 100644
--- a/test/lib/brave.js
+++ b/test/lib/brave.js
@@ -10,7 +10,6 @@ const path = require('path')
const fs = require('fs-extra')
const os = require('os')
const {getTargetAboutUrl, isSourceAboutUrl, getBraveExtIndexHTML} = require('../../js/lib/appUrlUtil')
-const pinnedSiteUtils = require('../../app/common/lib/pinnedSitesUtil')
var chaiAsPromised = require('chai-as-promised')
chai.should()
@@ -366,7 +365,7 @@ var exports = {
})
this.app.client.addCommand('waitForTextValue', function (selector, text) {
- logVerbose('waitForSelectedText("' + selector + '", "' + text + '")')
+ logVerbose('waitForTextValue("' + selector + '", "' + text + '")')
return this
.waitForVisible(selector)
.waitUntil(function () {
@@ -645,36 +644,6 @@ var exports = {
}, sourceKey, destinationKey, prepend)
})
- this.app.client.addCommand('movePinnedTabByFrameKey', async function (sourceKey, destinationKey, prepend, windowId = 1) {
- logVerbose(`movePinnedTabByFrameKey(${sourceKey}, ${destinationKey}, ${prepend})`)
- // get info on tabs to move
- const state = await this.getAppState()
- const sourceTab = state.value.tabs.find(tab => tab.windowId === windowId && tab.frame.key === sourceKey)
- if (!sourceTab) {
- throw new Error(`movePinnedTabByIndex could not find source tab with key ${sourceKey} in window ${windowId}`)
- }
- const destinationTab = state.value.tabs.find(tab => tab.windowId === windowId && tab.frame.key === destinationKey)
- if (!destinationTab) {
- throw new Error(`movePinnedTabByIndex could not find destination tab with key ${destinationKey} in window ${windowId}`)
- }
- const sourceTabSiteDetail = Immutable.fromJS({
- location: sourceTab.url,
- partitionNumber: sourceTab.partitionNumber
- })
- const destinationTabSiteDetail = Immutable.fromJS({
- location: destinationTab.url,
- paritionNumber: destinationTab.partitionNumber
- })
- // do actual move
- await this.moveTabByFrameKey(sourceKey, destinationKey, prepend)
- // notify pinned tabs have changed, required for state change
- const sourcePinKey = pinnedSiteUtils.getKey(sourceTabSiteDetail)
- const destinationPinKey = pinnedSiteUtils.getKey(destinationTabSiteDetail)
- return this.execute(function (sourcePinKey, destinationPinKey, prepend) {
- return devTools('appActions').onPinnedTabReorder(sourcePinKey, destinationPinKey, prepend)
- }, sourcePinKey, destinationPinKey, prepend)
- })
-
this.app.client.addCommand('moveTabIncrementally', function (moveNext, windowId = 1) {
logVerbose(`moveTabIncrementally(${moveNext}, ${windowId}`)
return this.execute(function (moveNext, windowId) {
diff --git a/test/lib/selectors.js b/test/lib/selectors.js
index 3d3d718e325..7c05469c0ee 100644
--- a/test/lib/selectors.js
+++ b/test/lib/selectors.js
@@ -109,6 +109,7 @@ module.exports = {
recoverWallet: '[data-test-id="recoverLedgerButton"]',
recoverWalletFromFileButton: '[data-test-id="recoverFromFileButton"]',
recoveryOverlayOkButton: '[data-test-id="recoveryOverlayOkButton"]',
+ recoveryOverlayErrorButton: '[data-test-id="recoveryOverlayErrorButton"]',
saveWalletFile: '[data-test-id="saveRecoveryFileButton"]',
balanceRecovered: '[data-test-id="balanceRecoveredMessage"]',
balanceNotRecovered: '[data-test-id="ledgerRecoveryFailedMessage"]',
diff --git a/test/misc-components/muonTest.js b/test/misc-components/muonTest.js
index 3b212cacf86..16a8bad0ac4 100644
--- a/test/misc-components/muonTest.js
+++ b/test/misc-components/muonTest.js
@@ -3,6 +3,7 @@
const Brave = require('../lib/brave')
const testUrl = 'chrome-extension://mnojpmjdmbbfmejpflffifhffcmidifd/muon-tests.html'
+const testCases = require('../muon-native').collect()
function * setup (client) {
yield client.waitForUrl(Brave.newTabUrl).waitForBrowserWindow()
@@ -16,24 +17,46 @@ describe('muon tests', function () {
.tabByIndex(0)
.url(testUrl)
})
- it('muon.url.parse', function * () {
- yield this.app.client
- .waitForTextValue('#urlParseSimple', 'success')
- .waitForTextValue('#urlParseComplex', 'success')
- .waitForTextValue('#urlParseIssue10270', 'success')
- })
- it('urlUtil.getOrigin', function * () {
- yield this.app.client
- .waitForTextValue('#getOriginSimple', 'success')
- .waitForTextValue('#getOriginFile', 'success')
- .waitForTextValue('#getOriginWithPort', 'success')
- .waitForTextValue('#getOriginIP', 'success')
- .waitForTextValue('#getOriginAbout', 'success')
- .waitForTextValue('#getOriginNull', 'success')
- .waitForTextValue('#getOriginInvalid', 'success')
- })
- it('suggestion', function * () {
- yield this.app.client
- .waitForTextValue('#suggestionSimpleCheck', 'success')
- })
+
+ const makeKey = (key, ext) => `${key} → ${ext}`
+ // selector must match the pattern used in muonTest.entry.js
+ const makeSelector = (key) => `#${key.replace(/[^a-zA-Z0-9_-]/g, '_')}`
+
+ const executeTests = (name, successKey, tests) => {
+ const runnableTests = Object.keys(tests).filter((k) => typeof tests[k] === 'function')
+ if (runnableTests.length) {
+ // actual tests, with a `function`
+ for (let testName of runnableTests) {
+ it(testName, function * () {
+ const selector = makeSelector(makeKey(successKey, testName))
+ yield this.app.client.waitForVisible(selector).then(() => {
+ // got the element for this particular test, check the pass/fail and report from there
+ return this.app.client.getText(`${selector}>.passFail`).then((value) => {
+ if (Array.isArray(value)) {
+ // it's possible to have multiple tests with the same key, mainly due to the
+ // selector character clobbering, these show up as an array of elements
+ throw new Error(`Multiple tests with same selector "${selector}", please modify their names`)
+ }
+ if (value !== 'PASS') {
+ return this.app.client.getText(`${selector}>.failure`).then((value) => {
+ // attempt to get at least some of the error message from the .failure element to report back
+ throw new Error(value)
+ })
+ }
+ })
+ })
+ })
+ }
+ }
+
+ const testGroups = Object.keys(tests).filter((k) => typeof tests[k] === 'object')
+ for (let groupKey of testGroups) {
+ // groups of tests, nested objects presumably containing functions
+ describe(groupKey, () => {
+ executeTests(groupKey, makeKey(successKey, groupKey), tests[groupKey])
+ })
+ }
+ }
+
+ executeTests('muon', 'muon', testCases)
})
diff --git a/test/muon-native/index.js b/test/muon-native/index.js
new file mode 100644
index 00000000000..1b6b438269b
--- /dev/null
+++ b/test/muon-native/index.js
@@ -0,0 +1,89 @@
+// test cases in this directory, should be resolvable with `require('./X')`
+const testCases = [
+ 'urlParseTest',
+ 'urlutilTest',
+ 'suggestionTest',
+ 'siteSuggestionTest'
+]
+
+// load all of the tests into a single large nested object
+const collect = () => {
+ const testList = {}
+ for (let testCase of testCases) {
+ testList[testCase] = require(`./${testCase}`)
+ }
+ return testList
+}
+
+const run = (testRunner) => {
+ // first collect an array of ordered runnable tests, each is async-ish in that it has a
+ // callback but the underlying test may not, we just treat them all that way
+ const runQueue = []
+
+ const buildRunQueue = (successKey, tests) => {
+ const ctx = {} // for `this` within a current nested block
+
+ const makeTestExecutor = (testName, key) => {
+ const beforeAfter = testName === 'before' || testName === 'after'
+ const testFn = tests[testName]
+
+ runQueue.push((cb) => {
+ const thisRunner = testRunner(key)
+ // before and after are async if they have 1 arg, a callback
+ // all other tests take a `test` argument first and if they have a second argument it's a callback
+ if (testFn.length > (beforeAfter ? 0 : 1)) {
+ const _cb = (err) => {
+ thisRunner.ok(!err)
+ thisRunner.done()
+ cb()
+ }
+ testFn.call(ctx, beforeAfter ? _cb : thisRunner, beforeAfter ? undefined : _cb)
+ } else {
+ testFn.call(ctx, beforeAfter ? undefined : thisRunner)
+ thisRunner.done()
+ cb()
+ }
+ })
+ }
+
+ // before() always goes first within a block
+ if (typeof tests.before === 'function') {
+ makeTestExecutor('before', `${successKey} → before`)
+ }
+
+ for (let name of Object.keys(tests)) {
+ if (name === 'before' || name === 'after') {
+ continue
+ }
+ let key = `${successKey} → ${name}`
+ if (typeof tests[name] === 'object') {
+ buildRunQueue(key, tests[name]) // recursive for a nested block of tests
+ } else {
+ makeTestExecutor(name, key)
+ }
+ }
+
+ // after() always goes last within a block
+ if (typeof tests.after === 'function') {
+ makeTestExecutor('after', `${successKey} → after`)
+ }
+ }
+
+ buildRunQueue('muon', collect())
+
+ // now we have a queue of ordered tests, execute in order, async-ish
+ const executeQueue = () => {
+ if (!runQueue.length) {
+ return
+ }
+ const fn = runQueue.shift()
+ fn(() => {
+ setImmediate(executeQueue)
+ })
+ }
+
+ executeQueue()
+}
+
+module.exports.collect = collect
+module.exports.run = run
diff --git a/test/muon-native/siteSuggestionTest.js b/test/muon-native/siteSuggestionTest.js
new file mode 100644
index 00000000000..ed8078deacb
--- /dev/null
+++ b/test/muon-native/siteSuggestionTest.js
@@ -0,0 +1 @@
+module.exports = require('../unit/app/common/lib/siteSuggestionsTestComponents')
diff --git a/test/muon-native/suggestionTest.js b/test/muon-native/suggestionTest.js
new file mode 100644
index 00000000000..c0640fa2dcb
--- /dev/null
+++ b/test/muon-native/suggestionTest.js
@@ -0,0 +1,12 @@
+// lazy load requires for dual use in and outside muon
+const suggestion = () => require('../../app/common/lib/suggestion')
+
+module.exports = {
+ suggestionSimpleCheck: (test) => {
+ test.deepEqual(suggestion().isSimpleDomainNameValue('http://test.com') &&
+ suggestion().isSimpleDomainNameValue('http://test.com/') &&
+ suggestion().isSimpleDomainNameValue('http://test.com#') &&
+ !suggestion().isSimpleDomainNameValue('http://test.com/test'),
+ true)
+ }
+}
diff --git a/test/muon-native/urlParseTest.js b/test/muon-native/urlParseTest.js
new file mode 100644
index 00000000000..086c9528ad9
--- /dev/null
+++ b/test/muon-native/urlParseTest.js
@@ -0,0 +1,50 @@
+// lazy load requires for dual use in and outside muon
+const urlParse = () => require('../../app/common/urlParse')
+
+const defaultParsedUrl = {
+ hash: '',
+ host: '',
+ hostname: '',
+ href: '',
+ origin: '',
+ path: '/',
+ pathname: '/',
+ port: '',
+ protocol: 'http:',
+ query: '',
+ search: ''
+}
+
+module.exports = {
+ urlParseSimple: (test) => {
+ test.deepEqual(urlParse()('http://bing.com'), Object.assign(defaultParsedUrl, {
+ host: 'bing.com',
+ hostname: 'bing.com',
+ origin: 'http://bing.com/',
+ href: 'http://bing.com/'
+ }))
+ },
+ urlParseComplex: (test) => {
+ test.deepEqual(urlParse()('https://brave.com:333/test?abc=123&def#fff'), {
+ host: 'brave.com:333',
+ hostname: 'brave.com',
+ origin: 'https://brave.com:333/',
+ protocol: 'https:',
+ port: '333',
+ hash: '#fff',
+ pathname: '/test',
+ path: '/test?abc=123&def',
+ search: '?abc=123&def',
+ query: 'abc=123&def',
+ href: 'https://brave.com:333/test?abc=123&def#fff'
+ })
+ },
+ urlParseIssue10270: (test) => {
+ test.deepEqual(urlParse()('http://brave.com%60x.code-fu.org/'), Object.assign(defaultParsedUrl, {
+ host: 'brave.com%60x.code-fu.org',
+ hostname: 'brave.com%60x.code-fu.org',
+ href: 'http://brave.com%60x.code-fu.org/',
+ origin: 'http://brave.com%60x.code-fu.org/'
+ }))
+ }
+}
diff --git a/test/muon-native/urlutilTest.js b/test/muon-native/urlutilTest.js
new file mode 100644
index 00000000000..8789d34d752
--- /dev/null
+++ b/test/muon-native/urlutilTest.js
@@ -0,0 +1 @@
+module.exports = require('../unit/lib/urlutilTestComponents')
diff --git a/test/tab-components/pinnedTabTest.js b/test/tab-components/pinnedTabTest.js
index b0287071a43..1cf636eb0fb 100644
--- a/test/tab-components/pinnedTabTest.js
+++ b/test/tab-components/pinnedTabTest.js
@@ -90,7 +90,7 @@ describe('pinnedTabs', function () {
.windowByUrl(Brave.browserWindowUrl)
.waitForExist('[data-test-id="tab"][data-frame-key="4"]')
// change pinned tabs order
- .movePinnedTabByFrameKey(3, 2, true)
+ .moveTabByFrameKey(3, 2, true)
// check the move worked
.waitForExist('[data-test-id="tab-area"][data-frame-key="3"] + [data-test-id="tab-area"][data-frame-key="2"]')
// create another tab and pin it
diff --git a/test/unit/about/preferencesTest.js b/test/unit/about/preferencesTest.js
index 3ef3742f174..e25089ac750 100644
--- a/test/unit/about/preferencesTest.js
+++ b/test/unit/about/preferencesTest.js
@@ -57,6 +57,8 @@ describe('Preferences component unittest', function () {
// Mocks the icon used in payments tab
mockery.registerMock('../../../extensions/brave/img/ledger/cryptoIcons/BAT_icon.svg')
mockery.registerMock('../../../../../img/toolbar/stoploading_btn.svg')
+ mockery.registerMock('../../../../extensions/brave/img/ledger/BAT_captcha_dragicon.png')
+ mockery.registerMock('../../../../extensions/brave/img/ledger/BAT_captcha_BG_arrow.png')
// Mocks the icons used in addFundsDialog and its steps
mockery.registerMock('../../../../../../extensions/brave/img/ledger/wallet_icon.svg')
mockery.registerMock('../../../../../../extensions/brave/img/ledger/cryptoIcons/ETH_icon.svg')
diff --git a/test/unit/app/browser/ads/adBlockUtilTest.js b/test/unit/app/browser/ads/adBlockUtilTest.js
index 44b043cdd1e..68a5e3f73db 100644
--- a/test/unit/app/browser/ads/adBlockUtilTest.js
+++ b/test/unit/app/browser/ads/adBlockUtilTest.js
@@ -1,4 +1,4 @@
-/* global before, describe, it */
+/* global before, after, describe, it */
require('../../../braveUnit')
const assert = require('assert')
@@ -21,6 +21,10 @@ describe('adBlockUtil test', function () {
mockery.registerMock('ad-block', fakeAdBlock)
shouldDoAdBlockCheck = require('../../../../../app/browser/ads/adBlockUtil').shouldDoAdBlockCheck
})
+ after(function () {
+ mockery.deregisterAll()
+ mockery.disable()
+ })
describe('shouldDoAdBlockCheck', function () {
it('http protocol allows ad block checks', function () {
assert.ok(shouldDoAdBlockCheck('script', new URL('https://www.brave.com'), thirdPartyResource, false))
diff --git a/test/unit/app/browser/api/ledgerNotificationsTest.js b/test/unit/app/browser/api/ledgerNotificationsTest.js
index fb785866c43..f3644ecdae5 100644
--- a/test/unit/app/browser/api/ledgerNotificationsTest.js
+++ b/test/unit/app/browser/api/ledgerNotificationsTest.js
@@ -8,22 +8,25 @@ const assert = require('assert')
const sinon = require('sinon')
const mockery = require('mockery')
const settings = require('../../../../../js/constants/settings')
+const ledgerUtil = require('../../../../../app/common/lib/ledgerUtil')
+const aboutPreferencesState = require('../../../../../app/common/state/aboutPreferencesState')
describe('ledgerNotifications unit test', function () {
let fakeClock
- let ledgerApi
let ledgerNotificationsApi
let appAction
let paymentsEnabled
- let paymentsNotifications
+ let paymentsNotifications = true
let paymentsMinVisitTime = 5000
let paymentsContributionAmount = 25
let paymentsAllowPromotions = true
const defaultAppState = Immutable.fromJS({
- ledger: {},
- migrations: {}
+ about: {
+ preferences: {}
+ },
+ ledger: {}
})
before(function () {
@@ -58,7 +61,6 @@ describe('ledgerNotifications unit test', function () {
})
fakeClock = sinon.useFakeTimers()
- ledgerApi = require('../../../../../app/browser/api/ledger')
ledgerNotificationsApi = require('../../../../../app/browser/api/ledgerNotifications')
appAction = require('../../../../../js/actions/appActions')
})
@@ -94,224 +96,6 @@ describe('ledgerNotifications unit test', function () {
})
})
- describe('onLaunch', function () {
- let showBraveWalletUpdatedStub
- let transitionWalletToBatStub
- beforeEach(function () {
- showBraveWalletUpdatedStub = sinon.stub(ledgerNotificationsApi, 'showBraveWalletUpdated')
- transitionWalletToBatStub = sinon.stub(ledgerApi, 'transitionWalletToBat')
- })
- afterEach(function () {
- showBraveWalletUpdatedStub.restore()
- transitionWalletToBatStub.restore()
- })
-
- describe('with BAT Mercury', function () {
- let ledgerStateWithBalance
-
- before(function () {
- ledgerStateWithBalance = defaultAppState.merge(Immutable.fromJS({
- ledger: {
- info: {
- balance: 200
- }
- },
- firstRunTimestamp: 12345,
- migrations: {
- batMercuryTimestamp: 12345,
- btc2BatTimestamp: 12345,
- btc2BatNotifiedTimestamp: 12345
- }
- }))
- })
-
- describe('with wallet update message', function () {
- describe('when payment notifications are disabled', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = false
- })
- it('does not notify the user', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 54321)
- .setIn(['migrations', 'btc2BatNotifiedTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(showBraveWalletUpdatedStub.notCalled)
- })
- })
-
- describe('when payments are disabled', function () {
- before(function () {
- paymentsEnabled = false
- paymentsNotifications = true
- })
- it('does not notify the user', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 54321)
- .setIn(['migrations', 'btc2BatNotifiedTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(showBraveWalletUpdatedStub.notCalled)
- })
- })
-
- describe('user does not have funds', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('does not notify the user', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['ledger', 'info', 'balance'], 0)
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 54321)
- .setIn(['migrations', 'btc2BatNotifiedTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(showBraveWalletUpdatedStub.notCalled)
- })
- })
-
- describe('user did not have a session before BAT Mercury', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('does not notify the user', function () {
- ledgerNotificationsApi.onLaunch(ledgerStateWithBalance)
- assert(showBraveWalletUpdatedStub.notCalled)
- })
- })
-
- describe('user has not had the wallet transitioned from BTC to BAT', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('does not notify the user', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatNotifiedTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(showBraveWalletUpdatedStub.notCalled)
- })
- })
-
- describe('user has already seen the notification', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('does not notify the user', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 54321)
- .setIn(['migrations', 'btc2BatNotifiedTimestamp'], 54321)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(showBraveWalletUpdatedStub.notCalled)
- })
- })
-
- describe('when payment notifications are enabled, payments are enabled, user has funds, user had wallet before BAT Mercury, wallet has been transitioned, and user not been shown message yet', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('notifies the user', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 54321)
- .setIn(['migrations', 'btc2BatNotifiedTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(showBraveWalletUpdatedStub.calledOnce)
- })
- })
- })
-
- describe('with the wallet transition from bitcoin to BAT', function () {
- describe('when payment notifications are disabled', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = false
- })
- it('calls ledger.transitionWalletToBat', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(transitionWalletToBatStub.calledOnce)
- })
- })
-
- describe('when payments are disabled', function () {
- before(function () {
- paymentsEnabled = false
- paymentsNotifications = true
- })
- it('does not call ledger.transitionWalletToBat', function () {
- ledgerNotificationsApi.onLaunch(ledgerStateWithBalance)
- assert(transitionWalletToBatStub.notCalled)
- })
- })
-
- describe('user does not have funds', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('calls ledger.transitionWalletToBat', function () {
- const ledgerStateWithoutBalance = ledgerStateWithBalance
- .setIn(['ledger', 'info', 'balance'], 0)
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(ledgerStateWithoutBalance)
- assert(transitionWalletToBatStub.calledOnce)
- })
- })
-
- describe('user did not have a session before BAT Mercury', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('does not call ledger.transitionWalletToBat', function () {
- ledgerNotificationsApi.onLaunch(ledgerStateWithBalance)
- assert(transitionWalletToBatStub.notCalled)
- })
- })
-
- describe('user has already upgraded', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('does not call ledger.transitionWalletToBat', function () {
- const ledgerStateSeenNotification = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 54321)
- ledgerNotificationsApi.onLaunch(ledgerStateSeenNotification)
- assert(transitionWalletToBatStub.notCalled)
- })
- })
-
- describe('when payments are enabled and user had wallet before BAT Mercury', function () {
- before(function () {
- paymentsEnabled = true
- paymentsNotifications = true
- })
- it('calls ledger.transitionWalletToBat', function () {
- const targetSession = ledgerStateWithBalance
- .setIn(['migrations', 'batMercuryTimestamp'], 32145)
- .setIn(['migrations', 'btc2BatTimestamp'], 32145)
- ledgerNotificationsApi.onLaunch(targetSession)
- assert(transitionWalletToBatStub.calledOnce)
- })
- })
- })
- })
- })
-
describe('onInterval', function () {
let showEnabledNotificationsSpy, showDisabledNotificationsSpy, onIntervalDynamicSpy
@@ -354,13 +138,93 @@ describe('ledgerNotifications unit test', function () {
it('payments enabled and notifications enabled', function () {
paymentsNotifications = true
- ledgerNotificationsApi.onInterval(defaultAppState)
+ ledgerNotificationsApi.onInterval(defaultAppState.setIn(['ledger', 'info', 'userHasFunded'], false))
assert(showDisabledNotificationsSpy.notCalled)
assert(showEnabledNotificationsSpy.calledOnce)
assert(onIntervalDynamicSpy.calledOnce)
})
})
+ describe('showBackupKeys', function () {
+ paymentsEnabled = true
+ paymentsNotifications = true
+ let fakeClock, showBackupKeysSpy
+ let state = defaultAppState
+ .setIn(['ledger', 'info', 'reconcileStamp'], ledgerUtil.milliseconds.year) // set to skip over reconciliation
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
+
+ before(function () {
+ fakeClock = sinon.useFakeTimers()
+ showBackupKeysSpy = sinon.spy(ledgerNotificationsApi, 'showBackupKeys')
+ })
+
+ afterEach(function () {
+ showBackupKeysSpy.reset()
+ })
+
+ after(function () {
+ fakeClock.restore()
+ showBackupKeysSpy.restore()
+ })
+
+ it('not time to yet show backup keys notification for first time (not yet 7 days from funds being added)', function () {
+ fakeClock.tick(1)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.notCalled)
+ })
+
+ it('first notification (7 days from funds being added)', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.day * 7 + 1)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.calledOnce, 'showBackupKeys should be called once')
+ })
+
+ it('second notification (14 days days later [21 days from funds being added])', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.day * 14)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.calledOnce, 'showBackupKeys should be called once')
+ })
+
+ it('third and subsequent notification occur monthly until backup or opt out. (one day before the month, no notification)', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.month - ledgerUtil.milliseconds.day)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.notCalled, 'showBackupKeys should not be called')
+ })
+
+ it('third notification after one more day of completing the month', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.day)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.calledOnce, 'showBackupKeys should be called once')
+ })
+
+ it('second monthly notification (fourth notification)', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.month)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.calledOnce, 'showBackupKeys should be called once')
+ })
+
+ it('day before the third monthly notification (should not notify)', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.month - ledgerUtil.milliseconds.day)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.notCalled, 'showBackupKeys should not be called')
+ })
+ it('day of the third monthly notification (fifth notification)', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.day)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.calledOnce, 'showBackupKeys should be called once')
+ })
+ it('day before the fourth monthly notification (sixth notification)', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.month - ledgerUtil.milliseconds.day)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.notCalled, 'showBackupKeys should not be called')
+ })
+ it('day of the fourth monthly notification (sixth notification)', function () {
+ fakeClock.tick(ledgerUtil.milliseconds.day)
+ state = ledgerNotificationsApi.showEnabledNotifications(state)
+ assert(showBackupKeysSpy.calledOnce, 'showBackupKeys should be called once')
+ })
+ })
+
describe('onIntervalDynamic', function () {
let fakeClock, showPromotionNotificationSpy
@@ -683,4 +547,63 @@ describe('ledgerNotifications unit test', function () {
paymentsContributionAmount = 25
})
})
+
+ describe('hasFunded', function () {
+ it('null case', function () {
+ paymentsEnabled = true
+ const result = ledgerNotificationsApi.hasFunded(defaultAppState)
+ assert.equal(result, false)
+ })
+ it('has never funded', function () {
+ paymentsEnabled = true
+ const state = defaultAppState.setIn(['ledger', 'info', 'userHasFunded'], false)
+ const result = ledgerNotificationsApi.hasFunded(state)
+ assert.equal(result, false)
+ })
+ it('user has funded', function () {
+ paymentsEnabled = true
+ const state = defaultAppState.setIn(['ledger', 'info', 'userHasFunded'], true)
+ const result = ledgerNotificationsApi.hasFunded(state)
+ assert.equal(result, true)
+ })
+ })
+
+ // result will always be the amount of time until the -next- notification
+ describe('getNextBackupNotification', function () {
+ it('user hasn\'t received any notification yet', function () {
+ const result = ledgerNotificationsApi.getNextBackupNotification(defaultAppState, aboutPreferencesState
+ .getPreferencesProp(defaultAppState, 'backupNotifyCount') || 0, [1 * ledgerUtil.milliseconds.day, 2 * ledgerUtil.milliseconds.day])
+ assert.equal(result, ledgerUtil.milliseconds.day)
+ })
+ it('user is going to receive third notification with 2 intervals specified', function () {
+ const state = aboutPreferencesState.setPreferencesProp(defaultAppState, 'backupNotifyCount', 2)
+ const result = ledgerNotificationsApi.getNextBackupNotification(state, aboutPreferencesState
+ .getPreferencesProp(state, 'backupNotifyCount') || 0, [2 * ledgerUtil.milliseconds.day, 4 * ledgerUtil.milliseconds.day])
+ assert.equal(result, (ledgerUtil.milliseconds.month))
+ })
+ it('user is going to receive third notification with 3 intervals specified', function () {
+ const state = aboutPreferencesState.setPreferencesProp(defaultAppState, 'backupNotifyCount', 2)
+ const result = ledgerNotificationsApi.getNextBackupNotification(state, aboutPreferencesState
+ .getPreferencesProp(state, 'backupNotifyCount') || 0, [2 * ledgerUtil.milliseconds.day, 4 * ledgerUtil.milliseconds.day, 10 * ledgerUtil.milliseconds.day])
+ assert.equal(result, (ledgerUtil.milliseconds.day * 10))
+ })
+ it('user is going to receive third notification with 6 intervals specified', function () {
+ const state = aboutPreferencesState.setPreferencesProp(defaultAppState, 'backupNotifyCount', 2)
+ const result = ledgerNotificationsApi.getNextBackupNotification(state, aboutPreferencesState
+ .getPreferencesProp(state, 'backupNotifyCount') || 0, [2 * ledgerUtil.milliseconds.day, 4 * ledgerUtil.milliseconds.day, 7 * ledgerUtil.milliseconds.day, 10 * ledgerUtil.milliseconds.day, 11 * ledgerUtil.milliseconds.day, 20 * ledgerUtil.milliseconds.day])
+ assert.equal(result, (ledgerUtil.milliseconds.day * 7))
+ })
+ it('user is going to receive fifth notification with 3 intervals specified', function () {
+ const state = aboutPreferencesState.setPreferencesProp(defaultAppState, 'backupNotifyCount', 4)
+ const result = ledgerNotificationsApi.getNextBackupNotification(state, aboutPreferencesState
+ .getPreferencesProp(state, 'backupNotifyCount') || 0, [100 * ledgerUtil.milliseconds.day, 20 * ledgerUtil.milliseconds.day, 10 * ledgerUtil.milliseconds.day])
+ assert.equal(result, (ledgerUtil.milliseconds.month))
+ })
+ it('user is going to receive fifth notification with 10 intervals specified', function () {
+ const state = aboutPreferencesState.setPreferencesProp(defaultAppState, 'backupNotifyCount', 4)
+ const result = ledgerNotificationsApi.getNextBackupNotification(state, aboutPreferencesState
+ .getPreferencesProp(state, 'backupNotifyCount') || 0, [100 * ledgerUtil.milliseconds.day, 20 * ledgerUtil.milliseconds.day, 10 * ledgerUtil.milliseconds.day, 7 * ledgerUtil.milliseconds.day, 23 * ledgerUtil.milliseconds.day, 2 * ledgerUtil.milliseconds.day, 8 * ledgerUtil.milliseconds.day, 9 * ledgerUtil.milliseconds.day, 11 * ledgerUtil.milliseconds.day, 70 * ledgerUtil.milliseconds.day])
+ assert.equal(result, (ledgerUtil.milliseconds.day * 23))
+ })
+ })
})
diff --git a/test/unit/app/browser/api/ledgerTest.js b/test/unit/app/browser/api/ledgerTest.js
index eb537e9e633..3bfcdd72cba 100644
--- a/test/unit/app/browser/api/ledgerTest.js
+++ b/test/unit/app/browser/api/ledgerTest.js
@@ -9,10 +9,11 @@ const sinon = require('sinon')
const mockery = require('mockery')
const settings = require('../../../../../js/constants/settings')
const appActions = require('../../../../../js/actions/appActions')
-const migrationState = require('../../../../../app/common/state/migrationState')
const batPublisher = require('bat-publisher')
const ledgerMediaProviders = require('../../../../../app/common/constants/ledgerMediaProviders')
const fs = require('fs')
+const ledgerStatuses = require('../../../../../app/common/constants/ledgerStatuses')
+const promotionStatuses = require('../../../../../app/common/constants/promotionStatuses')
describe('ledger api unit tests', function () {
let ledgerApi
@@ -22,6 +23,7 @@ describe('ledger api unit tests', function () {
let ledgerUtil
let isBusy = false
let ledgerClient
+ let ledgerClientObject
let ledgerPublisher
let tabState = Immutable.fromJS({
partition: 'persist:partition-1'
@@ -29,37 +31,33 @@ describe('ledger api unit tests', function () {
let request
let walletPassphraseReturn
let updater
+ let aboutPreferencesState
+ let isReadyToReconcile = false
// constants
- const xhr = 'https://www.youtube.com/api/stats/watchtime?docid=kLiLOkzLetE&st=11.338&et=21.339'
const videoId = 'youtube_kLiLOkzLetE'
const publisherKey = 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg'
// settings
let contributionAmount = 10
+ let paymentsMinVisits = 5
let paymentsMinVisitTime = 5000
let paymentsNotifications = true
let paymentsAllowPromotions = true
let contributionAmountSet = true
// spies
- let ledgerTransitionSpy
- let ledgerTransitionedSpy
- let onBitcoinToBatTransitionedSpy
let onLedgerCallbackSpy
- let onBitcoinToBatBeginTransitionSpy
let onChangeSettingSpy
let ledgersetPromotionSpy
let ledgergetPromotionSpy
let ledgerSetTimeUntilReconcile
- let onPublisherOptionUpdate
const defaultAppState = Immutable.fromJS({
cache: {
ledgerVideos: {}
},
- ledger: {},
- migrations: {}
+ ledger: {}
})
before(function () {
@@ -86,6 +84,8 @@ describe('ledger api unit tests', function () {
: null
case settings.PAYMENTS_MINIMUM_VISIT_TIME:
return paymentsMinVisitTime
+ case settings.PAYMENTS_MINIMUM_VISITS:
+ return paymentsMinVisits
case settings.PAYMENTS_NOTIFICATIONS:
return paymentsNotifications
case settings.PAYMENTS_ALLOW_PROMOTIONS:
@@ -97,11 +97,8 @@ describe('ledger api unit tests', function () {
request = require('../../../../../js/lib/request')
mockery.registerMock('../../../js/lib/request', request)
mockery.registerMock('../../../js/actions/appActions', appActions)
- onBitcoinToBatTransitionedSpy = sinon.spy(appActions, 'onBitcoinToBatTransitioned')
onLedgerCallbackSpy = sinon.spy(appActions, 'onLedgerCallback')
- onBitcoinToBatBeginTransitionSpy = sinon.spy(appActions, 'onBitcoinToBatBeginTransition')
onChangeSettingSpy = sinon.spy(appActions, 'changeSetting')
- onPublisherOptionUpdate = sinon.spy(appActions, 'onPublisherOptionUpdate')
mockery.registerMock('fs', fs)
// default to tab state which should be tracked
@@ -111,7 +108,10 @@ describe('ledger api unit tests', function () {
// ledger client stubbing
ledgerClient = sinon.stub()
- const lc = {
+ ledgerClientObject = {
+ ballots: function () {
+ return 1
+ },
sync: function (callback) { return false },
getBraveryProperties: function () {
return {
@@ -133,20 +133,15 @@ describe('ledger api unit tests', function () {
getWalletProperties: function (amount, currency, callback) {
callback(null, {})
},
- transition: function (paymentId, callback) {
- callback()
- },
getPaymentId: function () {
return 'payementIdGoesHere'
},
+ memo: () => {},
properties: {
wallet: {
paymentId: 12345
}
},
- transitioned: function () {
- return {}
- },
setBraveryProperties: function (clientProperties, callback) {
if (typeof callback === 'function') {
const err = undefined
@@ -165,21 +160,26 @@ describe('ledger api unit tests', function () {
},
getPromotion: () => {},
setPromotion: () => {},
- setTimeUntilReconcile: () => {}
+ setTimeUntilReconcile: () => {},
+ isReadyToReconcile: () => isReadyToReconcile,
+ recoverWallet: () => {},
+ getPromotionCaptcha: () => {}
}
window.getWalletPassphrase = (parsedData) => {
+ if (walletPassphraseReturn === 'error') {
+ throw TypeError('Invalid entropy')
+ }
+
return walletPassphraseReturn
}
ledgerClient.prototype.boolion = function (value) { return false }
ledgerClient.prototype.getWalletPassphrase = function (parsedData) {
return window.getWalletPassphrase(parsedData)
}
- ledgerTransitionSpy = sinon.spy(lc, 'transition')
- ledgerTransitionedSpy = sinon.spy(lc, 'transitioned')
- ledgersetPromotionSpy = sinon.spy(lc, 'setPromotion')
- ledgergetPromotionSpy = sinon.spy(lc, 'getPromotion')
- ledgerSetTimeUntilReconcile = sinon.spy(lc, 'setTimeUntilReconcile')
- ledgerClient.returns(lc)
+ ledgersetPromotionSpy = sinon.spy(ledgerClientObject, 'setPromotion')
+ ledgergetPromotionSpy = sinon.spy(ledgerClientObject, 'getPromotion')
+ ledgerSetTimeUntilReconcile = sinon.spy(ledgerClientObject, 'setTimeUntilReconcile')
+ ledgerClient.returns(ledgerClientObject)
mockery.registerMock('bat-client', ledgerClient)
// ledger publisher stubbing
@@ -208,15 +208,14 @@ describe('ledger api unit tests', function () {
ledgerUtil = require('../../../../../app/common/lib/ledgerUtil')
ledgerState = require('../../../../../app/common/state/ledgerState')
updateState = require('../../../../../app/common/state/updateState')
+ aboutPreferencesState = require('../../../../../app/common/state/aboutPreferencesState')
updater = require('../../../../../app/updater')
// once everything is stubbed, load the ledger
ledgerApi = require('../../../../../app/browser/api/ledger')
})
after(function () {
- onBitcoinToBatTransitionedSpy.restore()
onLedgerCallbackSpy.restore()
- onBitcoinToBatBeginTransitionSpy.restore()
onChangeSettingSpy.restore()
mockery.deregisterAll()
mockery.disable()
@@ -253,7 +252,6 @@ describe('ledger api unit tests', function () {
describe('onInitRead', function () {
let parsedLedgerData
- let onLaunchSpy
let setPaymentInfoSpy
before(function () {
parsedLedgerData = {
@@ -268,19 +266,12 @@ describe('ledger api unit tests', function () {
contributionAmount = 10
})
before(function () {
- onLaunchSpy = sinon.spy(ledgerNotificationsApi, 'onLaunch')
setPaymentInfoSpy = sinon.spy(ledgerApi, 'setPaymentInfo')
})
after(function () {
- onLaunchSpy.restore()
setPaymentInfoSpy.restore()
ledgerApi.setSynopsis(undefined)
})
- it('calls notifications.onLaunch', function () {
- onLaunchSpy.reset()
- ledgerApi.onInitRead(defaultAppState, parsedLedgerData)
- assert(onLaunchSpy.calledOnce)
- })
it('calls setPaymentInfo with contribution amount', function () {
setPaymentInfoSpy.reset()
ledgerApi.onInitRead(defaultAppState, parsedLedgerData)
@@ -288,77 +279,6 @@ describe('ledger api unit tests', function () {
})
})
- describe('checkBtcBatMigrated', function () {
- let transitionWalletToBatStub
- before(function () {
- transitionWalletToBatStub = sinon.stub(ledgerApi, 'transitionWalletToBat')
- })
- after(function () {
- transitionWalletToBatStub.restore()
- })
-
- describe('when not a new install and wallet has not been upgraded', function () {
- let result
- before(function () {
- const notMigratedYet = defaultAppState.merge(Immutable.fromJS({
- firstRunTimestamp: 12345,
- migrations: {
- batMercuryTimestamp: 34512,
- btc2BatTimestamp: 34512,
- btc2BatNotifiedTimestamp: 34512,
- btc2BatTransitionPending: false
- }
- }))
- assert.equal(migrationState.inTransition(notMigratedYet), false)
- transitionWalletToBatStub.reset()
- result = ledgerApi.checkBtcBatMigrated(notMigratedYet, true)
- })
- it('sets transition status to true', function () {
- assert(migrationState.inTransition(result))
- })
- it('calls transitionWalletToBat', function () {
- assert(transitionWalletToBatStub.calledOnce)
- })
- })
-
- describe('when a transition is already being shown', function () {
- it('sets transition to false if new install', function () {
- const stuckOnMigrate = defaultAppState.merge(Immutable.fromJS({
- firstRunTimestamp: 12345,
- migrations: {
- batMercuryTimestamp: 12345,
- btc2BatTimestamp: 12345,
- btc2BatNotifiedTimestamp: 12345,
- btc2BatTransitionPending: true
- }
- }))
- assert(migrationState.isNewInstall(stuckOnMigrate))
- assert.equal(migrationState.hasUpgradedWallet(stuckOnMigrate), false)
- assert(migrationState.inTransition(stuckOnMigrate))
-
- const result = ledgerApi.checkBtcBatMigrated(stuckOnMigrate, true)
- assert.equal(migrationState.inTransition(result), false)
- })
- it('sets transition to false if wallet has been upgraded', function () {
- const stuckOnMigrate = defaultAppState.merge(Immutable.fromJS({
- firstRunTimestamp: 12345,
- migrations: {
- batMercuryTimestamp: 34512,
- btc2BatTimestamp: 54321,
- btc2BatNotifiedTimestamp: 34512,
- btc2BatTransitionPending: true
- }
- }))
- assert.equal(migrationState.isNewInstall(stuckOnMigrate), false)
- assert(migrationState.hasUpgradedWallet(stuckOnMigrate))
- assert(migrationState.inTransition(stuckOnMigrate))
-
- const result = ledgerApi.checkBtcBatMigrated(stuckOnMigrate, true)
- assert.equal(migrationState.inTransition(result), false)
- })
- })
- })
-
describe('synopsisNormalizer', function () {
after(function () {
ledgerApi.setSynopsis(undefined)
@@ -479,9 +399,6 @@ describe('ledger api unit tests', function () {
.setIn(['ledger', 'synopsis', 'publishers', 'site2', 'weight'], 28.57142857142857)
.setIn(['ledger', 'synopsis', 'publishers', 'site3', 'pinPercentage'], 28)
.setIn(['ledger', 'synopsis', 'publishers', 'site3', 'weight'], 28.57142857142857)
- .setIn(['siteSettings', 'https?://site1', 'ledgerPinPercentage'], 43)
- .setIn(['siteSettings', 'https?://site2', 'ledgerPinPercentage'], 29)
- .setIn(['siteSettings', 'https?://site3', 'ledgerPinPercentage'], 28)
assert.deepEqual(result.toJS(), newState.toJS())
})
@@ -497,9 +414,6 @@ describe('ledger api unit tests', function () {
.setIn(['ledger', 'synopsis', 'publishers', 'site2', 'weight'], 20)
.setIn(['ledger', 'synopsis', 'publishers', 'site3', 'pinPercentage'], 32)
.setIn(['ledger', 'synopsis', 'publishers', 'site3', 'weight'], 32)
- .setIn(['siteSettings', 'https?://site1', 'ledgerPinPercentage'], 48)
- .setIn(['siteSettings', 'https?://site2', 'ledgerPinPercentage'], 20)
- .setIn(['siteSettings', 'https?://site3', 'ledgerPinPercentage'], 32)
assert.deepEqual(result.toJS(), newState.toJS())
})
})
@@ -548,8 +462,7 @@ describe('ledger api unit tests', function () {
}
}
}
- },
- migrations: {}
+ }
}
const result = ledgerApi.pruneSynopsis(defaultAppState)
@@ -558,12 +471,12 @@ describe('ledger api unit tests', function () {
})
describe('checkVerifiedStatus', function () {
- let verifiedPSpy
+ let verifiedPSpy, onPublishersOptionUpdateSpy
let returnValue = false
before(function () {
- onPublisherOptionUpdate.reset()
verifiedPSpy = sinon.spy(ledgerApi, 'verifiedP')
+ onPublishersOptionUpdateSpy = sinon.spy(appActions, 'onPublishersOptionUpdate')
ledgerApi.setClient({
publisherInfo: function (publisherKey, callback) {
@@ -590,12 +503,12 @@ describe('ledger api unit tests', function () {
afterEach(function () {
returnValue = false
verifiedPSpy.reset()
- onPublisherOptionUpdate.reset()
+ onPublishersOptionUpdateSpy.reset()
})
after(function () {
verifiedPSpy.restore()
- onPublisherOptionUpdate.restore()
+ onPublishersOptionUpdateSpy.restore()
ledgerApi.setClient(undefined)
})
@@ -622,8 +535,7 @@ describe('ledger api unit tests', function () {
const result = ledgerApi.checkVerifiedStatus(newState, 'test.io')
assert.deepEqual(result.toJS(), newState.toJS())
- assert(verifiedPSpy.calledOnce)
- assert(onPublisherOptionUpdate.withArgs('test.io', 'verified', true).calledOnce)
+ assert(verifiedPSpy.withArgs(sinon.match.any, ['test.io'], sinon.match.any, 20).calledOnce)
})
it('change publisher verified status from true to false', function () {
@@ -634,8 +546,7 @@ describe('ledger api unit tests', function () {
const result = ledgerApi.checkVerifiedStatus(newState, 'test.io')
assert.deepEqual(result.toJS(), newState.toJS())
- assert(verifiedPSpy.calledOnce)
- assert(onPublisherOptionUpdate.withArgs('test.io', 'verified', false).calledOnce)
+ assert(verifiedPSpy.withArgs(sinon.match.any, ['test.io'], sinon.match.any, 20).calledOnce)
})
it('handle multiple publishers', function () {
@@ -653,15 +564,86 @@ describe('ledger api unit tests', function () {
'test.io'
])
assert.deepEqual(result.toJS(), newState.toJS())
- assert(verifiedPSpy.withArgs(sinon.match.any, ['test1.io', 'test.io'], sinon.match.any).calledOnce)
- assert.deepEqual(onPublisherOptionUpdate.getCall(0).args, ['test1.io', 'verified', false])
- assert.deepEqual(onPublisherOptionUpdate.getCall(2).args, ['test.io', 'verified', false])
+ assert(verifiedPSpy.withArgs(sinon.match.any, ['test1.io', 'test.io'], sinon.match.any, 20).calledOnce)
})
})
describe('onMediaRequest', function () {
+ let processMediaDataSpy
+ const url = 'https://video-edge-f0f586.sjc01.hls.ttvnw.net/v1/segment/CuDNI7xCy5CGJ8g7G3thdHT26OW_DhnEuVw0tRGN-DKhJxrRTeGe...'
+
+ beforeEach(function () {
+ processMediaDataSpy = sinon.spy(ledgerApi, 'processMediaData')
+ })
+
+ afterEach(function () {
+ processMediaDataSpy.restore()
+ })
+
+ it('does nothing if input is null', function () {
+ const result = ledgerApi.onMediaRequest(defaultAppState)
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ assert(processMediaDataSpy.notCalled)
+ })
+
+ it('does nothing if input is null', function () {
+ const result = ledgerApi.onMediaRequest(defaultAppState, url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [{
+ bytes: new Uint8Array([])
+ }]
+ }))
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ assert(processMediaDataSpy.notCalled)
+ })
+
+ it('parsed data is single object', function () {
+ const result = ledgerApi.onMediaRequest(defaultAppState, url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [{
+ bytes: new Uint8Array([
+ 100, 97, 116, 97, 61, 87, 51, 115, 105, 90, 88, 90, 108, 98, 110, 81, 105, 79, 105,
+ 74, 116, 97, 87, 53, 49, 100, 71, 85, 116, 100, 50, 70, 48, 89, 50, 104, 108, 90, 67, 73, 115, 73, 110,
+ 66, 121, 98, 51, 66, 108, 99, 110, 82, 112, 90, 88, 77, 105, 79, 110, 115, 105, 89, 50, 104, 104, 98,
+ 109, 53, 108, 98, 67, 73, 54, 73, 110, 82, 51, 73, 110, 49, 57, 88, 81, 61, 61
+ ])
+ }]
+ }))
+
+ assert(processMediaDataSpy.calledOnce)
+ assert.notDeepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('parsed data is array of objects', function () {
+ const result = ledgerApi.onMediaRequest(defaultAppState, url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [{
+ bytes: new Uint8Array([
+ 100, 97, 116, 97, 61, 87, 51, 115, 105, 90, 88, 90, 108, 98, 110, 81, 105, 79, 105,
+ 74, 50, 97, 87, 82, 108, 98, 121, 49, 119, 98, 71, 70, 53, 73, 105, 119, 105, 99, 72, 74, 118, 99, 71,
+ 86, 121, 100, 71, 108, 108, 99, 121, 73, 54, 101, 121, 74, 106, 97, 71, 70, 117, 98, 109, 86, 115, 73,
+ 106, 111, 105, 100, 72, 99, 105, 102, 88, 48, 115, 101, 121, 74, 108, 100, 109, 86, 117, 100, 67, 73, 54,
+ 73, 110, 90, 112, 90, 71, 86, 118, 88, 50, 86, 121, 99, 109, 57, 121, 73, 105, 119, 105, 99, 72, 74, 118,
+ 99, 71, 86, 121, 100, 71, 108, 108, 99, 121, 73, 54, 101, 121, 74, 106, 97, 71, 70, 117, 98, 109, 86,
+ 115, 73, 106, 111, 105, 100, 72, 99, 105, 102, 88, 49, 100
+ ])
+ }]
+ }))
+
+ assert(processMediaDataSpy.calledTwice)
+ assert.notDeepEqual(result.toJS(), defaultAppState.toJS())
+ })
+ })
+
+ describe('processMediaData', function () {
let mediaSpy, saveVisitSpy
+ const parsedData = {
+ docid: 'kLiLOkzLetE',
+ st: '11.338',
+ et: '21.339'
+ }
+
const cacheAppState = defaultAppState
.setIn(['cache', 'ledgerVideos', videoId], Immutable.fromJS({
publisher: publisherKey
@@ -688,7 +670,7 @@ describe('ledger api unit tests', function () {
})
it('does nothing if input is null', function () {
- const result = ledgerApi.onMediaRequest(defaultAppState)
+ const result = ledgerApi.processMediaData(defaultAppState)
assert.deepEqual(result.toJS(), defaultAppState.toJS())
assert(mediaSpy.notCalled)
assert(saveVisitSpy.notCalled)
@@ -712,22 +694,26 @@ describe('ledger api unit tests', function () {
tabState = savedTabState
})
it('does nothing if tab is private', function () {
- const xhr2 = 'https://www.youtube.com/api/stats/watchtime?docid=kLiLOkzLetE&st=20.338&et=21.339'
- ledgerApi.onMediaRequest(cacheAppState, xhr2, ledgerMediaProviders.YOUTUBE, 1)
+ const data = {
+ docid: 'kLiLOkzLetE',
+ st: '20.338',
+ et: '21.339'
+ }
+ ledgerApi.processMediaData(cacheAppState, data, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 1}))
assert(mediaSpy.notCalled)
assert(saveVisitSpy.notCalled)
})
})
it('set currentMediaKey when it is different than saved', function () {
- ledgerApi.onMediaRequest(defaultAppState, xhr, ledgerMediaProviders.YOUTUBE, 1)
+ ledgerApi.processMediaData(defaultAppState, parsedData, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 1}))
assert.equal(ledgerApi.getCurrentMediaKey(), videoId)
assert(mediaSpy.calledOnce)
assert(saveVisitSpy.notCalled)
})
it('get data from cache, if we have publisher in synopsis', function () {
- ledgerApi.onMediaRequest(cacheAppState, xhr, ledgerMediaProviders.YOUTUBE, 1)
+ ledgerApi.processMediaData(cacheAppState, parsedData, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 1}))
assert(mediaSpy.notCalled)
assert(saveVisitSpy.withArgs(cacheAppState, publisherKey, {
duration: 10001,
@@ -740,14 +726,14 @@ describe('ledger api unit tests', function () {
const state = defaultAppState.setIn(['cache', 'ledgerVideos', videoId], Immutable.fromJS({
publisher: publisherKey
}))
- ledgerApi.onMediaRequest(state, xhr, ledgerMediaProviders.YOUTUBE, 1)
+ ledgerApi.processMediaData(state, parsedData, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 1}))
assert(mediaSpy.calledOnce)
assert(saveVisitSpy.notCalled)
})
it('revisited if visiting the same media in the same tab', function () {
// first call, revisit false
- ledgerApi.onMediaRequest(cacheAppState, xhr, ledgerMediaProviders.YOUTUBE, 1)
+ ledgerApi.processMediaData(cacheAppState, parsedData, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 1}))
assert.equal(ledgerApi.getCurrentMediaKey(), videoId)
assert(saveVisitSpy.withArgs(cacheAppState, publisherKey, {
duration: 10001,
@@ -756,7 +742,7 @@ describe('ledger api unit tests', function () {
}).calledOnce)
// second call, revisit true
- ledgerApi.onMediaRequest(cacheAppState, xhr, ledgerMediaProviders.YOUTUBE, 1)
+ ledgerApi.processMediaData(cacheAppState, parsedData, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 1}))
assert(mediaSpy.notCalled)
assert(saveVisitSpy.withArgs(cacheAppState, publisherKey, {
duration: 10001,
@@ -768,7 +754,7 @@ describe('ledger api unit tests', function () {
it('revisited if visiting media in the background tab', function () {
// first call, revisit false
ledgerApi.setCurrentMediaKey('11')
- ledgerApi.onMediaRequest(cacheAppState, xhr, ledgerMediaProviders.YOUTUBE, 10)
+ ledgerApi.processMediaData(cacheAppState, parsedData, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 10}))
assert.equal(ledgerApi.getCurrentMediaKey(), '11')
assert(saveVisitSpy.withArgs(cacheAppState, publisherKey, {
duration: 10001,
@@ -788,7 +774,7 @@ describe('ledger api unit tests', function () {
}
}))
- ledgerApi.onMediaRequest(badState, xhr, ledgerMediaProviders.YOUTUBE, 10)
+ ledgerApi.processMediaData(badState, parsedData, ledgerMediaProviders.YOUTUBE, Immutable.fromJS({tabId: 10}))
assert(mediaSpy.calledOnce)
assert(saveVisitSpy.notCalled)
})
@@ -820,8 +806,7 @@ describe('ledger api unit tests', function () {
}
}
}
- },
- migrations: {}
+ }
})
const response = Immutable.fromJS({
@@ -899,11 +884,7 @@ describe('ledger api unit tests', function () {
cache: {
ledgerVideos: {
'youtube_kLiLOkzLetE': {
- publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg',
- faviconName: 'Brave',
- providerName: 'Youtube',
- faviconURL: 'data:image/jpeg;base64,...',
- publisherURL: 'https://brave.com'
+ publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg'
}
}
},
@@ -921,8 +902,7 @@ describe('ledger api unit tests', function () {
}
}
}
- },
- migrations: {}
+ }
})
const state = ledgerApi.onMediaPublisher(newState, videoId, response, 1000, false)
@@ -943,11 +923,7 @@ describe('ledger api unit tests', function () {
cache: {
ledgerVideos: {
'youtube_kLiLOkzLetE': {
- publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg',
- faviconName: 'Brave',
- providerName: 'Youtube',
- faviconURL: 'data:image/jpeg;base64,...',
- publisherURL: 'https://brave.com'
+ publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg'
}
}
},
@@ -965,8 +941,7 @@ describe('ledger api unit tests', function () {
}
}
}
- },
- migrations: {}
+ }
})
const state = ledgerApi.onMediaPublisher(newState, videoId, response, 1000, false)
@@ -1071,15 +1046,26 @@ describe('ledger api unit tests', function () {
describe('when timing needs to be checked', function () {
describe('addSiteVisit', function () {
const fakeTabId = 7
+ const tabIdNone = -1
+ const manualAdd = true
let stateWithLocation
+ let stateWithLocationTwo
let fakeClock
+ let saveVisitSpy
before(function () {
const locationData = Immutable.fromJS({
publisher: 'clifton.io',
stickyP: true,
exclude: false
})
+ const locationDataTwo = Immutable.fromJS({
+ publisher: 'brave.com',
+ stickyP: false,
+ exclude: false
+ })
stateWithLocation = defaultAppState.setIn(['ledger', 'locations', 'https://clifton.io/'], locationData)
+ stateWithLocationTwo = defaultAppState.setIn(['ledger', 'locations', 'https://brave.com/'], locationDataTwo)
+ saveVisitSpy = sinon.spy(ledgerApi, 'saveVisit')
})
beforeEach(function () {
fakeClock = sinon.useFakeTimers()
@@ -1088,6 +1074,51 @@ describe('ledger api unit tests', function () {
afterEach(function () {
ledgerApi.setSynopsis(undefined)
fakeClock.restore()
+ saveVisitSpy.restore()
+ })
+ it('duration is equal to the minimum visit time under a manual addition', function () {
+ const location = 'https://brave.com'
+ const state = ledgerApi.initialize(stateWithLocationTwo, true)
+
+ ledgerApi.addSiteVisit(state, 0, location, tabIdNone, manualAdd)
+ const calledDuration = saveVisitSpy.getCall(0).args[2].duration
+
+ assert.equal(paymentsMinVisitTime, calledDuration)
+ })
+ it('revisited is false under a manual addition', function () {
+ const location = 'https://brave.com'
+ const state = ledgerApi.initialize(stateWithLocationTwo, true)
+
+ ledgerApi.addSiteVisit(state, 0, location, tabIdNone, manualAdd)
+ const calledRevisited = saveVisitSpy.getCall(0).args[2].revisited
+
+ assert.equal(false, calledRevisited)
+ })
+ it('saves the visit with a valid publisherKey under a manual addition', function () {
+ const location = 'https://brave.com'
+ const expectedPublisherKey = 'brave.com'
+ const state = ledgerApi.initialize(stateWithLocationTwo, true)
+
+ ledgerApi.addSiteVisit(state, 0, location, tabIdNone, manualAdd)
+ const passedPublisherKey = saveVisitSpy.getCall(0).args[1]
+
+ assert.equal(expectedPublisherKey, passedPublisherKey)
+ })
+ it('saves the visit with a valid publisherKey under a non-manual addition', function () {
+ const location = 'https://brave.com'
+ const expectedPublisherKey = 'brave.com'
+ const state = ledgerApi.initialize(stateWithLocationTwo, true)
+
+ ledgerApi.addSiteVisit(state, 0, location, fakeTabId)
+ const passedPublisherKey = saveVisitSpy.getCall(0).args[1]
+
+ assert.equal(expectedPublisherKey, passedPublisherKey)
+ })
+ it('state is not modified on a null location under a manual addition', function () {
+ const location = null
+ const result = ledgerApi.addSiteVisit(defaultAppState, 0, location, tabIdNone, manualAdd)
+
+ assert.deepEqual(defaultAppState.toJS(), result.toJS())
})
it('records a visit when over the PAYMENTS_MINIMUM_VISIT_TIME threshold', function () {
const state = ledgerApi.initialize(stateWithLocation, true)
@@ -1130,103 +1161,48 @@ describe('ledger api unit tests', function () {
assert(visitsByPublisher['clifton.io'])
})
})
-
- describe('transitionWalletToBat', function () {
- let fakeClock
-
+ describe('addNewLocation', function () {
+ const tabIdNone = -1
+ const keepInfo = false
+ const manualAdd = true
+ let addSiteVisitSpy
+ let shouldTrackTabSpy
before(function () {
- fakeClock = sinon.useFakeTimers()
+ addSiteVisitSpy = sinon.spy(ledgerApi, 'addSiteVisit')
+ shouldTrackTabSpy = sinon.spy(ledgerApi, 'shouldTrackTab')
+ })
+ beforeEach(function () {
+ ledgerApi.clearVisitsByPublisher()
})
after(function () {
+ addSiteVisitSpy.restore()
+ shouldTrackTabSpy.restore()
+ })
+ afterEach(function () {
+ addSiteVisitSpy.reset()
+ shouldTrackTabSpy.reset()
ledgerApi.setSynopsis(undefined)
- fakeClock.restore()
})
+ it('does not call should track tab under a manual addition', function () {
+ const location = 'https://brave.com'
- describe('when client is not busy', function () {
- before(function () {
- ledgerApi.onBootStateFile(defaultAppState)
- ledgerTransitionSpy.reset()
- onBitcoinToBatTransitionedSpy.reset()
- onLedgerCallbackSpy.reset()
- ledgerTransitionedSpy.reset()
- onBitcoinToBatBeginTransitionSpy.reset()
- ledgerClient.reset()
- ledgerApi.resetNewClient()
- isBusy = false
- ledgerApi.transitionWalletToBat()
- })
- it('creates a new instance of ledgerClient', function () {
- assert(ledgerClient.calledOnce)
- })
- it('calls AppActions.onBitcoinToBatBeginTransition', function () {
- assert(onBitcoinToBatBeginTransitionSpy.calledOnce)
- })
- it('calls client.transition', function () {
- assert(ledgerTransitionSpy.calledOnce)
- })
- describe('when transition completes', function () {
- it('calls client.transitioned', function () {
- assert(ledgerTransitionedSpy.calledOnce)
- })
- it('calls AppActions.onLedgerCallback', function () {
- assert(onLedgerCallbackSpy.calledOnce)
- })
- it('calls AppActions.onBitcoinToBatTransitioned', function () {
- assert(onBitcoinToBatTransitionedSpy.calledOnce)
- })
- })
+ ledgerApi.addNewLocation(defaultAppState, location, tabIdNone, keepInfo, manualAdd)
+
+ assert(shouldTrackTabSpy.notCalled)
})
- describe('when client is busy', function () {
- before(function () {
- ledgerApi.onBootStateFile(defaultAppState)
- ledgerTransitionSpy.reset()
- onBitcoinToBatTransitionedSpy.reset()
- onLedgerCallbackSpy.reset()
- ledgerTransitionedSpy.reset()
- onBitcoinToBatBeginTransitionSpy.reset()
- ledgerClient.reset()
- ledgerApi.resetNewClient()
- isBusy = true
- ledgerApi.transitionWalletToBat()
- })
- after(function () {
- isBusy = false
- })
- it('does not call AppActions.onBitcoinToBatBeginTransition', function () {
- assert(onBitcoinToBatBeginTransitionSpy.notCalled)
- })
- it('does not call client.transition', function () {
- assert(ledgerTransitionSpy.notCalled)
- })
+ it('records enough visits to satisfy the minimum criteria under a manual addition', function () {
+ const location = 'https://brave.com'
+
+ ledgerApi.addNewLocation(defaultAppState, location, tabIdNone, keepInfo, manualAdd)
+
+ assert.equal(addSiteVisitSpy.callCount, paymentsMinVisits)
})
- describe('when client is not v1', function () {
- let oldClient
- before(function () {
- const batState = ledgerApi.onBootStateFile(defaultAppState)
- ledgerTransitionSpy.reset()
- onBitcoinToBatTransitionedSpy.reset()
- onLedgerCallbackSpy.reset()
- ledgerTransitionedSpy.reset()
- onBitcoinToBatBeginTransitionSpy.reset()
- ledgerClient.reset()
- oldClient = ledgerApi.getClient()
- ledgerApi.setClient({
- options: {
- version: 'v2'
- }
- })
- ledgerApi.resetNewClient()
- ledgerApi.transitionWalletToBat(batState)
- })
- after(function () {
- ledgerApi.setClient(oldClient)
- })
- it('calls AppActions.onBitcoinToBatTransitioned', function () {
- assert(onBitcoinToBatTransitionedSpy.calledOnce)
- })
- it('does not call client.transition', function () {
- assert(ledgerTransitionSpy.notCalled)
- })
+ it('currentTabId is set to -1 (tabState.TAB_ID_NONE) under a manual addition', function () {
+ const location = 'https://brave.com'
+
+ ledgerApi.addNewLocation(defaultAppState, location, tabIdNone, keepInfo, manualAdd)
+
+ assert.equal(tabIdNone, addSiteVisitSpy.getCall(0).args[3])
})
})
})
@@ -1312,7 +1288,7 @@ describe('ledger api unit tests', function () {
})
it('null case', function () {
- ledgerApi.onWalletProperties()
+ ledgerApi.onWalletProperties(state)
assert(generatePaymentDataSpy.notCalled)
})
@@ -1363,6 +1339,7 @@ describe('ledger api unit tests', function () {
balance: balance.toString()
}))
const expectedState = state.setIn(['ledger', 'info', 'balance'], balance)
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
assert.deepEqual(result.toJS(), expectedState.toJS())
})
})
@@ -1527,18 +1504,18 @@ describe('ledger api unit tests', function () {
const expectedState = state
.setIn(['ledger', 'info', 'probi'], probi)
.setIn(['ledger', 'info', 'balance'], 25)
+ .setIn(['ledger', 'info', 'userFunded'], 25)
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
assert.deepEqual(result.toJS(), expectedState.toJS())
})
it('amount is null', function () {
const result = ledgerApi.onWalletProperties(state, Immutable.fromJS({
- probi: probi,
rates: rates
}))
const expectedState = state
.setIn(['ledger', 'info', 'rates'], Immutable.fromJS(rates))
.setIn(['ledger', 'info', 'currentRate'], rate)
- .setIn(['ledger', 'info', 'probi'], probi)
assert.deepEqual(result.toJS(), expectedState.toJS())
})
@@ -1553,12 +1530,14 @@ describe('ledger api unit tests', function () {
.setIn(['ledger', 'info', 'currentRate'], rate)
.setIn(['ledger', 'info', 'converted'], 3.5836474125)
.setIn(['ledger', 'info', 'balance'], 25)
+ .setIn(['ledger', 'info', 'userFunded'], 25)
.setIn(['ledger', 'info', 'probi'], probi)
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
assert.deepEqual(result.toJS(), expectedState.toJS())
})
it('big probi', function () {
- const bigProbi = '7.309622404968674704085e+21'
+ const bigProbi = 7.309622404968674704085e+21
const result = ledgerApi.onWalletProperties(state, Immutable.fromJS({
probi: bigProbi,
balance: '7309.6224',
@@ -1569,7 +1548,9 @@ describe('ledger api unit tests', function () {
.setIn(['ledger', 'info', 'currentRate'], rate)
.setIn(['ledger', 'info', 'converted'], 1047.8043767167208)
.setIn(['ledger', 'info', 'balance'], 7309.6224)
+ .setIn(['ledger', 'info', 'userFunded'], 7309.622404968675)
.setIn(['ledger', 'info', 'probi'], bigProbi)
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
assert.deepEqual(result.toJS(), expectedState.toJS())
})
})
@@ -1662,6 +1643,55 @@ describe('ledger api unit tests', function () {
contributionAmount = 10
})
})
+
+ describe('grants', function () {
+ const probi = 25000000000000000000
+
+ it('probi is missing', function () {
+ const expectedState = state
+ .setIn(['ledger', 'info', 'balance'], 25)
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
+ const result = ledgerApi.onWalletProperties(state, Immutable.fromJS({
+ balance: 25
+ }))
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+
+ it('is missing', function () {
+ const expectedState = state
+ .setIn(['ledger', 'info', 'balance'], 25)
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
+ .setIn(['ledger', 'info', 'probi'], probi)
+ .setIn(['ledger', 'info', 'userFunded'], 25)
+ const result = ledgerApi.onWalletProperties(state, Immutable.fromJS({
+ probi,
+ balance: 25
+ }))
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+
+ it('grant is saved', function () {
+ const expectedState = state
+ .setIn(['ledger', 'info', 'balance'], 25)
+ .setIn(['ledger', 'info', 'userHasFunded'], true)
+ .setIn(['ledger', 'info', 'probi'], probi)
+ .setIn(['ledger', 'info', 'userFunded'], 15)
+ .setIn(['ledger', 'info', 'grants'], Immutable.fromJS([{
+ expirationDate: 2130600234,
+ amount: 10
+ }]))
+ const result = ledgerApi.onWalletProperties(state, Immutable.fromJS({
+ probi,
+ balance: 25,
+ grants: [{
+ altcurrency: 'BAT',
+ expiryTime: 2130600234,
+ probi: 10000000000000000000
+ }]
+ }))
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
})
describe('claimPromotion', function () {
@@ -1669,6 +1699,7 @@ describe('ledger api unit tests', function () {
.setIn(['ledger', 'promotion', 'promotionId'], '1')
before(function () {
+ ledgerApi.setClient(ledgerClientObject)
ledgersetPromotionSpy.reset()
})
@@ -1691,7 +1722,12 @@ describe('ledger api unit tests', function () {
it('execute', function () {
ledgerApi.claimPromotion(state)
- assert(ledgersetPromotionSpy.calledOnce)
+ assert(ledgersetPromotionSpy.withArgs('1', {x: undefined, y: undefined}, sinon.match.any).calledOnce)
+ })
+
+ it('execute with coordinates', function () {
+ ledgerApi.claimPromotion(state, 5, 6)
+ assert(ledgersetPromotionSpy.withArgs('1', {x: 5, y: 6}, sinon.match.any).calledOnce)
})
})
@@ -1785,6 +1821,52 @@ describe('ledger api unit tests', function () {
ledgerApi.onPromotionResponse(state)
assert(ledgerSetTimeUntilReconcile.notCalled)
})
+
+ describe('status', function () {
+ let getCaptchaSpy
+
+ before(function () {
+ getCaptchaSpy = sinon.spy(ledgerApi, 'getCaptcha')
+ })
+
+ afterEach(function () {
+ getCaptchaSpy.reset()
+ })
+
+ after(function () {
+ getCaptchaSpy.restore()
+ })
+
+ it('promotion expired', function () {
+ const result = ledgerApi.onPromotionResponse(defaultAppState, Immutable.fromJS({
+ statusCode: 422
+ }))
+ const expectedSate = defaultAppState
+ .setIn(['ledger', 'promotion', 'promotionStatus'], promotionStatuses.PROMO_EXPIRED)
+ assert.deepEqual(result.toJS(), expectedSate.toJS())
+ assert(getCaptchaSpy.notCalled)
+ })
+
+ it('captcha error', function () {
+ const result = ledgerApi.onPromotionResponse(defaultAppState, Immutable.fromJS({
+ statusCode: 403
+ }))
+ const expectedSate = defaultAppState
+ .setIn(['ledger', 'promotion', 'promotionStatus'], promotionStatuses.CAPTCHA_ERROR)
+ assert.deepEqual(result.toJS(), expectedSate.toJS())
+ assert(getCaptchaSpy.calledOnce)
+ })
+
+ it('general error', function () {
+ const result = ledgerApi.onPromotionResponse(defaultAppState, Immutable.fromJS({
+ statusCode: 500
+ }))
+ const expectedSate = defaultAppState
+ .setIn(['ledger', 'promotion', 'promotionStatus'], promotionStatuses.GENERAL_ERROR)
+ assert.deepEqual(result.toJS(), expectedSate.toJS())
+ assert(getCaptchaSpy.notCalled)
+ })
+ })
})
describe('onWalletRecovery', function () {
@@ -1836,9 +1918,13 @@ describe('ledger api unit tests', function () {
}
}
})
+ const stateWithAbout = defaultAppState
+ .set('about', Immutable.fromJS({
+ preferences: {}
+ }))
before(function () {
- setRecoveryStatusSpy = sinon.spy(ledgerState, 'setRecoveryStatus')
+ setRecoveryStatusSpy = sinon.spy(aboutPreferencesState, 'setRecoveryStatus')
getBalanceSpy = sinon.spy(ledgerApi, 'getBalance')
onLedgerCallbackSpy.reset()
fakeClock = sinon.useFakeTimers()
@@ -1858,10 +1944,11 @@ describe('ledger api unit tests', function () {
})
it('on error', function () {
- const result = ledgerApi.onWalletRecovery(defaultAppState, 'Wrong key')
+ const result = ledgerApi.onWalletRecovery(stateWithAbout, 'Wrong key')
const expectedSate = defaultAppState
.set('about', Immutable.fromJS({
preferences: {
+ recoveryInProgress: false,
recoverySucceeded: false,
updatedStamp: 0
}
@@ -1875,10 +1962,11 @@ describe('ledger api unit tests', function () {
})
it('success', function () {
- const result = ledgerApi.onWalletRecovery(defaultAppState, null, param)
+ const result = ledgerApi.onWalletRecovery(stateWithAbout, null, param)
const expectedSate = defaultAppState
.set('about', Immutable.fromJS({
preferences: {
+ recoveryInProgress: false,
recoverySucceeded: true,
updatedStamp: 0
}
@@ -2044,6 +2132,29 @@ describe('ledger api unit tests', function () {
}))
assert.deepEqual(result.toJS(), expectedState.toJS())
})
+
+ it('seed is broken', function () {
+ const wrongSeed = Immutable
+ .fromJS(seedData)
+ .setIn(['properties', 'wallet', 'keyinfo', 'seed'], Buffer.from([0, 0]))
+ .toJS()
+
+ walletPassphraseReturn = 'error'
+
+ const result = ledgerApi.getStateInfo(defaultAppState, wrongSeed)
+ const expectedState = defaultAppState
+ .setIn(['ledger', 'info'], Immutable.fromJS({
+ 'created': true,
+ 'creating': false,
+ 'paymentId': '21951877-5998-4acf-9302-4a7b101c9188',
+ 'reconcileFrequency': 30,
+ 'reconcileStamp': 1
+ }))
+ .setIn(['ledger', 'about', 'status'], ledgerStatuses.CORRUPTED_SEED)
+
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ assert(getWalletPassphraseSpy.withArgs(wrongSeed).calledOnce)
+ })
})
})
@@ -2088,7 +2199,7 @@ describe('ledger api unit tests', function () {
it('check publishers', function () {
ledgerApi.onPublisherTimestamp(stateWithData, 10, 20)
- assert(checkVerifiedStatusSpy.withArgs(sinon.match.any, 'clifton.io', 20).calledOnce)
+ assert(checkVerifiedStatusSpy.withArgs(sinon.match.any, ['clifton.io'], 20).calledOnce)
})
it('check multiple publishers', function () {
@@ -2098,8 +2209,7 @@ describe('ledger api unit tests', function () {
}))
ledgerApi.onPublisherTimestamp(multiple, 10, 20)
- assert.equal(checkVerifiedStatusSpy.getCall(0).args[1], 'clifton.io')
- assert.equal(checkVerifiedStatusSpy.getCall(1).args[1], 'brave.com')
+ assert(checkVerifiedStatusSpy.withArgs(sinon.match.any, ['clifton.io', 'brave.com'], 20).calledOnce)
})
})
@@ -2170,6 +2280,40 @@ describe('ledger api unit tests', function () {
assert.deepEqual(result.toJS(), expectedState.toJS())
})
})
+
+ describe('status', function () {
+ it('null case', function () {
+ const result = ledgerApi.onCallback(defaultAppState, null)
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('reconcile is not in progress', function () {
+ const result = ledgerApi.onCallback(defaultAppState, Immutable.fromJS({
+ properties: {}
+ }))
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('reconcile is in progress (first time)', function () {
+ const result = ledgerApi.onCallback(defaultAppState, Immutable.fromJS({
+ currentReconcile: {
+ timestamp: 0
+ }
+ }))
+ const expectedState = defaultAppState
+ .setIn(['ledger', 'about', 'status'], ledgerStatuses.IN_PROGRESS)
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+
+ it('reconcile is in progress (second time)', function () {
+ const result = ledgerApi.onCallback(defaultAppState, Immutable.fromJS({
+ currentReconcile: {
+ timestamp: 1
+ }
+ }))
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+ })
})
describe('uintKeySeed', function () {
@@ -2208,6 +2352,41 @@ describe('ledger api unit tests', function () {
173
])
+ const object = {
+ 0: 32,
+ 1: 87,
+ 2: 30,
+ 3: 26,
+ 4: 223,
+ 5: 56,
+ 6: 224,
+ 7: 31,
+ 8: 213,
+ 9: 136,
+ 10: 248,
+ 11: 95,
+ 12: 136,
+ 13: 56,
+ 14: 250,
+ 15: 78,
+ 16: 179,
+ 17: 121,
+ 18: 255,
+ 19: 162,
+ 20: 195,
+ 21: 39,
+ 22: 143,
+ 23: 136,
+ 24: 18,
+ 25: 140,
+ 26: 49,
+ 27: 216,
+ 28: 221,
+ 29: 154,
+ 30: 78,
+ 31: 173
+ }
+
const uint = new Uint8Array(Object.values(buff))
it('null case', function () {
@@ -2220,10 +2399,15 @@ describe('ledger api unit tests', function () {
assert.deepStrictEqual(result, uint)
})
- it('seed needs to be converted', function () {
+ it('seed needs to be converted (buffer)', function () {
const result = ledgerApi.uintKeySeed(buff)
assert.deepStrictEqual(result, uint)
})
+
+ it('seed needs to be converted (object)', function () {
+ const result = ledgerApi.uintKeySeed(object)
+ assert.deepStrictEqual(result, uint)
+ })
})
describe('loadKeysFromBackupFile', function () {
@@ -2260,6 +2444,68 @@ describe('ledger api unit tests', function () {
})
})
+ describe('fileRecoveryKeys', function () {
+ let stub
+ let setRecoveryInProgressSpy
+
+ before(function () {
+ setRecoveryInProgressSpy = sinon.spy(aboutPreferencesState, 'setRecoveryInProgress')
+ })
+
+ after(function () {
+ stub.restore()
+ setRecoveryInProgressSpy.restore()
+ })
+
+ it('does not modify state if there is no recovery key file', function () {
+ const result = ledgerApi.fileRecoveryKeys(defaultAppState, false)
+ assert.deepEqual(result, defaultAppState)
+ })
+
+ it('sets recovery in progress when a recovery key file is received', function () {
+ ledgerApi.setClient(ledgerClientObject)
+ stub = sinon.stub(fs, 'readFileSync', (path, options) => {
+ return 'Fake file key...'
+ })
+ const stateWithPreferences = defaultAppState
+ .setIn(['about'], Immutable.fromJS({
+ preferences: {}
+ }))
+ ledgerApi.fileRecoveryKeys(stateWithPreferences, 'file.txt')
+ assert.equal(stateWithPreferences, setRecoveryInProgressSpy.getCall(0).args[0])
+ assert.equal(true, setRecoveryInProgressSpy.getCall(0).args[1])
+ })
+ })
+
+ describe('recoverKeys', function () {
+ it('sets recoveryBalanceRecalculated to false when a recovery is started', function () {
+ ledgerApi.setClient(ledgerClientObject)
+ const state = ledgerApi.recoverKeys(defaultAppState
+ .setIn(['about'], Immutable.fromJS({
+ preferences: {}
+ })), false, 'fakeKey')
+ assert.equal(aboutPreferencesState.getPreferencesProp(state, 'recoveryBalanceRecalculated'), false)
+ })
+
+ it('set recoveryBalanceRecalculated to true when balance has been retrieved', function () {
+ const state = ledgerApi.onWalletProperties(defaultAppState
+ .setIn(['about'], Immutable.fromJS({
+ preferences: {
+ recoveryBalanceRecalculated: true
+ }
+ })))
+ assert.equal(aboutPreferencesState.getPreferencesProp(state, 'recoveryBalanceRecalculated'), true)
+ })
+
+ it('skips over setting recoveryBalanceRecalculated if it hasnt been set', function () {
+ const state = ledgerApi.onWalletProperties(defaultAppState
+ .setIn(['about'], Immutable.fromJS({
+ preferences: {}
+ })))
+ assert.equal(aboutPreferencesState.getPreferencesProp(state, 'recoveryBalanceRecalculated'), null)
+ })
+ })
+
describe('checkReferralActivity', function () {
let checkForUpdateSpy, roundtripSpy, fakeClock
@@ -2447,21 +2693,11 @@ describe('ledger api unit tests', function () {
roundtripSpy.restore()
})
- it('null case', function () {
- ledgerApi.onReferralCodeRead()
- assert(roundtripSpy.notCalled)
+ it('code is correct', function () {
+ ledgerApi.onReferralCodeRead('aaa101')
+ assert(roundtripSpy.calledOnce)
})
-
- it('code is empty', function () {
- ledgerApi.onReferralCodeRead('')
- assert(roundtripSpy.notCalled)
- })
-
- it('code is correct', function () {
- ledgerApi.onReferralCodeRead('aaa101')
- assert(roundtripSpy.calledOnce)
- })
- })
+ })
describe('referralCheck', function () {
let deleteUpdatePropSpy, fakeClock
@@ -2503,4 +2739,853 @@ describe('ledger api unit tests', function () {
assert(deleteUpdatePropSpy.calledOnce)
})
})
+
+ describe('onVerifiedPStatus', function () {
+ let onPublishersOptionUpdateSpy
+
+ before(function () {
+ onPublishersOptionUpdateSpy = sinon.spy(appActions, 'onPublishersOptionUpdate')
+ })
+
+ afterEach(function () {
+ onPublishersOptionUpdateSpy.reset()
+ })
+
+ after(function () {
+ onPublishersOptionUpdateSpy.restore()
+ })
+
+ it('null case', function () {
+ ledgerApi.onVerifiedPStatus()
+ assert(onPublishersOptionUpdateSpy.notCalled)
+ })
+
+ it('on error', function () {
+ ledgerApi.onVerifiedPStatus('error')
+ assert(onPublishersOptionUpdateSpy.notCalled)
+ })
+
+ it('convert regular object into array', function () {
+ ledgerApi.onVerifiedPStatus(null, {
+ SLD: 'clifton.io',
+ RLD: '',
+ QLD: '',
+ publisher: 'clifton.io',
+ properties: { timestamp: '6509162935841980427', verified: true }
+ }, 100)
+ assert(onPublishersOptionUpdateSpy.withArgs([
+ {
+ publisherKey: 'clifton.io',
+ verified: true,
+ verifiedTimestamp: 100
+ }
+ ]).calledOnce)
+ })
+
+ it('all publishers has errors', function () {
+ ledgerApi.onVerifiedPStatus(null, [
+ {
+ publisher: 'https://clifton.io/',
+ err: 'error'
+ },
+ {
+ publisher: 'https://brianbondy.com/',
+ err: 'error'
+ }
+ ], 100)
+ assert(onPublishersOptionUpdateSpy.notCalled)
+ })
+
+ it('publishers are ok', function () {
+ ledgerApi.onVerifiedPStatus(null, [
+ {
+ SLD: 'clifton.io',
+ RLD: '',
+ QLD: '',
+ publisher: 'clifton.io',
+ properties: { timestamp: '6509162935841980427', verified: true }
+ },
+ {
+ publisher: 'https://test.com/',
+ err: 'error'
+ },
+ {
+ SLD: 'brianbondy.com',
+ RLD: '',
+ QLD: '',
+ publisher: 'brianbondy.com',
+ properties: { timestamp: '6509162935841940427', verified: false }
+ }
+ ], 100)
+ assert(onPublishersOptionUpdateSpy.withArgs([
+ {
+ publisherKey: 'clifton.io',
+ verified: true,
+ verifiedTimestamp: 100
+ },
+ {
+ publisherKey: 'brianbondy.com',
+ verified: false,
+ verifiedTimestamp: 100
+ }
+ ]).calledOnce)
+ })
+ })
+
+ describe('setPublishersOptions', function () {
+ let savePublisherOptionSpy
+
+ before(function () {
+ savePublisherOptionSpy = sinon.spy(ledgerApi, 'savePublisherOption')
+ })
+
+ afterEach(function () {
+ savePublisherOptionSpy.reset()
+ })
+
+ after(function () {
+ savePublisherOptionSpy.restore()
+ })
+
+ it('null case', function () {
+ const result = ledgerApi.setPublishersOptions(defaultAppState)
+ assert(savePublisherOptionSpy.notCalled)
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('publisher list is empty', function () {
+ const result = ledgerApi.setPublishersOptions(defaultAppState, Immutable.List())
+ assert(savePublisherOptionSpy.notCalled)
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('publisher is missing publisherKey', function () {
+ const result = ledgerApi.setPublishersOptions(defaultAppState, Immutable.fromJS([
+ {
+ verified: true,
+ verifiedTimestamp: 100
+ }
+ ]))
+ assert(savePublisherOptionSpy.notCalled)
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('publisher list is ok', function () {
+ const result = ledgerApi.setPublishersOptions(defaultAppState, Immutable.fromJS([
+ {
+ publisherKey: 'clifton.io',
+ verified: true,
+ verifiedTimestamp: 100
+ },
+ {
+ publisherKey: 'brianbondy.com',
+ verified: false,
+ verifiedTimestamp: 200
+ }
+ ]))
+ const expectedState = defaultAppState
+ .setIn(['ledger', 'synopsis', 'publishers'], Immutable.fromJS({
+ 'clifton.io': {
+ options: {
+ verified: true,
+ verifiedTimestamp: 100
+ }
+ },
+ 'brianbondy.com': {
+ options: {
+ verified: false,
+ verifiedTimestamp: 200
+ }
+ }
+ }))
+
+ assert(savePublisherOptionSpy.withArgs('clifton.io', 'verified', true).calledOnce)
+ assert(savePublisherOptionSpy.withArgs('clifton.io', 'verifiedTimestamp', 100).calledOnce)
+ assert(savePublisherOptionSpy.withArgs('brianbondy.com', 'verified', false).calledOnce)
+ assert(savePublisherOptionSpy.withArgs('brianbondy.com', 'verifiedTimestamp', 200).calledOnce)
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('onFavIconReceived', function () {
+ let savePublisherDataSpy, setPublishersPropSpy
+ const publisherKey = 'clifton.io'
+ const icon = 'blob'
+
+ before(function () {
+ savePublisherDataSpy = sinon.spy(ledgerApi, 'savePublisherData')
+ setPublishersPropSpy = sinon.spy(ledgerState, 'setPublishersProp')
+ })
+
+ afterEach(function () {
+ savePublisherDataSpy.reset()
+ setPublishersPropSpy.reset()
+ })
+
+ after(function () {
+ savePublisherDataSpy.restore()
+ setPublishersPropSpy.restore()
+ })
+
+ it('null case', function () {
+ const result = ledgerApi.onFavIconReceived(defaultAppState)
+ assert(savePublisherDataSpy.notCalled)
+ assert(setPublishersPropSpy.notCalled)
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('icon is saved', function () {
+ const expectedSate = defaultAppState
+ .setIn(['ledger', 'synopsis', 'publishers', publisherKey, 'faviconURL'], icon)
+ const result = ledgerApi.onFavIconReceived(defaultAppState, publisherKey, icon)
+ assert(setPublishersPropSpy.withArgs(sinon.match.any, publisherKey, 'faviconURL', icon).calledOnce)
+ assert(savePublisherDataSpy.calledOnce)
+ assert.deepEqual(result.toJS(), expectedSate.toJS())
+ })
+ })
+
+ describe('savePublisherOption', function () {
+ const expectedSynopsis = {
+ options: {},
+ publishers: {
+ 'clifton.io': {
+ options: {
+ excluded: true
+ }
+ }
+ }
+ }
+
+ after(() => {
+ ledgerApi.setSynopsis(undefined)
+ })
+
+ it('null case', function () {
+ ledgerApi.setSynopsis(undefined)
+ ledgerApi.savePublisherOption()
+ assert.equal(ledgerApi.getSynopsis(), undefined)
+ })
+
+ it('publishers object is missing', function () {
+ ledgerApi.setSynopsis({
+ options: {}
+ })
+ ledgerApi.savePublisherOption('clifton.io', 'excluded', true)
+ assert.deepEqual(ledgerApi.getSynopsis(), {
+ options: {}
+ })
+ })
+
+ it('publisher is missing in the synopsis', function () {
+ ledgerApi.setSynopsis({
+ options: {},
+ publishers: {}
+ })
+ ledgerApi.savePublisherOption('clifton.io', 'excluded', true)
+ assert.deepEqual(ledgerApi.getSynopsis(), expectedSynopsis)
+ })
+
+ it('options is missing in the synopsis', function () {
+ ledgerApi.setSynopsis({
+ options: {},
+ publishers: {
+ 'clifton.io': {}
+ }
+ })
+ ledgerApi.savePublisherOption('clifton.io', 'excluded', true)
+ assert.deepEqual(ledgerApi.getSynopsis(), expectedSynopsis)
+ })
+
+ it('option already exists', function () {
+ ledgerApi.setSynopsis({
+ options: {},
+ publishers: {
+ 'clifton.io': {
+ options: {
+ excluded: false
+ }
+ }
+ }
+ })
+ ledgerApi.savePublisherOption('clifton.io', 'excluded', true)
+ assert.deepEqual(ledgerApi.getSynopsis(), expectedSynopsis)
+ })
+ })
+
+ describe('savePublisherData', function () {
+ const expectedSynopsis = {
+ options: {},
+ publishers: {
+ 'clifton.io': {
+ faviconURL: 'data'
+ }
+ }
+ }
+
+ after(() => {
+ ledgerApi.setSynopsis(undefined)
+ })
+
+ it('null case', function () {
+ ledgerApi.setSynopsis(undefined)
+ ledgerApi.savePublisherData()
+ assert.equal(ledgerApi.getSynopsis(), undefined)
+ })
+
+ it('publishers object is missing', function () {
+ ledgerApi.setSynopsis({
+ options: {}
+ })
+ ledgerApi.savePublisherData('clifton.io', 'faviconURL', 'data')
+ assert.deepEqual(ledgerApi.getSynopsis(), {
+ options: {}
+ })
+ })
+
+ it('publisher is missing in the synopsis', function () {
+ ledgerApi.setSynopsis({
+ options: {},
+ publishers: {}
+ })
+ ledgerApi.savePublisherData('clifton.io', 'faviconURL', 'data')
+ assert.deepEqual(ledgerApi.getSynopsis(), expectedSynopsis)
+ })
+
+ it('publisher already exists', function () {
+ ledgerApi.setSynopsis({
+ options: {},
+ publishers: {
+ 'clifton.io': {
+ faviconURL: 'oldData'
+ }
+ }
+ })
+ ledgerApi.savePublisherData('clifton.io', 'faviconURL', 'data')
+ assert.deepEqual(ledgerApi.getSynopsis(), expectedSynopsis)
+ })
+ })
+
+ describe('roundTripFromWindow', function () {
+ let fetchPublisherInfoSpy
+
+ before(() => {
+ fetchPublisherInfoSpy = sinon.spy(request, 'fetchPublisherInfo')
+ })
+
+ afterEach(() => {
+ fetchPublisherInfoSpy.reset()
+ })
+
+ after(() => {
+ fetchPublisherInfoSpy.restore()
+ })
+
+ it('null case', function () {
+ ledgerApi.roundTripFromWindow()
+ assert(fetchPublisherInfoSpy.notCalled)
+ })
+
+ it('url is missing', function () {
+ ledgerApi.roundTripFromWindow({})
+ assert(fetchPublisherInfoSpy.notCalled)
+ })
+
+ it('fetch is called', function () {
+ ledgerApi.roundTripFromWindow({url: 'test.com'}, () => true)
+ assert(fetchPublisherInfoSpy.withArgs('test.com', sinon.match.any, sinon.match.any))
+ })
+ })
+
+ describe('run', function () {
+ describe('ballots', function () {
+ let clientBallotsSpy
+
+ before(() => {
+ ledgerApi.setSynopsis({
+ toJSON: () => {
+ return {
+ publishers: {
+ 'clifton.io': {
+ visits: 1
+ }
+ }
+ }
+ },
+ winners: () => {
+ return []
+ }
+ })
+ ledgerApi.setClient(ledgerClientObject)
+ clientBallotsSpy = sinon.spy(ledgerClientObject, 'ballots')
+ })
+
+ afterEach(() => {
+ clientBallotsSpy.reset()
+ })
+
+ after(() => {
+ clientBallotsSpy.restore()
+ ledgerApi.setSynopsis(undefined)
+ })
+
+ it('exits if state is undefined', function () {
+ ledgerApi.run(undefined, 10)
+ assert.equal(clientBallotsSpy.notCalled, true)
+ })
+
+ it('exits if delayTime is undefined', function () {
+ ledgerApi.run(defaultAppState)
+ assert.equal(clientBallotsSpy.notCalled, true)
+ })
+
+ it('gets balance count from client', function () {
+ ledgerApi.run(defaultAppState, 10)
+ assert.equal(clientBallotsSpy.calledOnce, true)
+ })
+ })
+
+ describe('publishers check', function () {
+ before(() => {
+ ledgerApi.setClient(ledgerClientObject)
+ ledgerSetTimeUntilReconcile.reset()
+ })
+
+ afterEach(() => {
+ ledgerSetTimeUntilReconcile.reset()
+ isReadyToReconcile = false
+ })
+
+ it('null check', function () {
+ ledgerApi.run(defaultAppState, 10)
+ assert(ledgerSetTimeUntilReconcile.notCalled)
+ })
+
+ it('synopsis is broken', function () {
+ const state = defaultAppState
+ .setIn(['ledger', 'about', 'synopsis'], 'test')
+ ledgerApi.run(state, 10)
+ assert(ledgerSetTimeUntilReconcile.notCalled)
+ })
+
+ it('table is empty and we are not ready to reconcile', function () {
+ const state = defaultAppState
+ .setIn(['ledger', 'about', 'synopsis'], Immutable.fromJS([{
+ publisherKey: 'clifton.io'
+ }]))
+ ledgerApi.run(state, 10)
+ assert(ledgerSetTimeUntilReconcile.notCalled)
+ })
+
+ it('table is not empty and we are not ready to reconcile', function () {
+ const state = defaultAppState
+ .setIn(['ledger', 'about', 'synopsis'], Immutable.fromJS([{
+ publisherKey: 'clifton.io'
+ }]))
+ ledgerApi.run(state, 10)
+ assert(ledgerSetTimeUntilReconcile.notCalled)
+ })
+
+ it('table is not empty and we are ready to reconcile', function () {
+ isReadyToReconcile = true
+ const state = defaultAppState
+ .setIn(['ledger', 'about', 'synopsis'], Immutable.fromJS([{
+ publisherKey: 'clifton.io'
+ }]))
+ ledgerApi.run(state, 10)
+ assert(ledgerSetTimeUntilReconcile.notCalled)
+ })
+
+ it('table is empty and we are ready to reconcile', function () {
+ isReadyToReconcile = true
+ ledgerApi.run(defaultAppState, 10)
+ assert(ledgerSetTimeUntilReconcile.calledOnce)
+ })
+ })
+ })
+
+ describe('checkSeed', function () {
+ let valid = false
+
+ before(() => {
+ ledgerApi.setClient({
+ isValidPassPhrase: () => valid
+ })
+ })
+
+ it('seed is null', function () {
+ const result = ledgerApi.checkSeed(defaultAppState)
+ assert.deepEqual(result.toJS(), defaultAppState.toJS())
+ })
+
+ it('seed is valid', function () {
+ valid = true
+ const state = defaultAppState
+ .setIn(['ledger', 'info', 'passphrase'], 'auten nobbling uncharitable decimation sayee unartful biter floodlight scholar cherubical fadable reconnoiter courtesan concussing asymmetrical test')
+ const result = ledgerApi.checkSeed(state)
+ assert.deepEqual(result.toJS(), state.toJS())
+ valid = false
+ })
+
+ it('seed is invalid', function () {
+ const state = defaultAppState
+ .setIn(['ledger', 'info', 'passphrase'], 'a')
+ const exptedState = state
+ .setIn(['ledger', 'about', 'status'], 'corruptedSeed')
+ const result = ledgerApi.checkSeed(state)
+ assert.deepEqual(result.toJS(), exptedState.toJS())
+ })
+ })
+
+ describe('onReferralRead', function () {
+ let setUpdatePropSpy
+
+ before(function () {
+ setUpdatePropSpy = sinon.spy(updateState, 'setUpdateProp')
+ })
+
+ afterEach(function () {
+ setUpdatePropSpy.reset()
+ })
+
+ after(function () {
+ setUpdatePropSpy.restore()
+ })
+
+ it('body data is not immutable', function () {
+ ledgerApi.onReferralRead(defaultAppState, {
+ download_id: 1,
+ referral_code: 'code'
+ })
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralDownloadId', 1).calledOnce)
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralPromoCode', 'code').calledOnce)
+ })
+
+ it('download id and referral code is saved', function () {
+ ledgerApi.onReferralRead(defaultAppState, Immutable.fromJS({
+ download_id: 1,
+ referral_code: 'code'
+ }))
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralDownloadId', 1).calledOnce)
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralPromoCode', 'code').calledOnce)
+ })
+
+ describe('headers', function () {
+ const headers = Immutable.fromJS({
+ domains: [ 'test.com', 'domain.si' ],
+ headers: { 'X-Brave-Partner': 'partner' },
+ cookieNames: [],
+ expiration: 0
+ })
+
+ it('headers are missing', function () {
+ ledgerApi.onReferralRead(defaultAppState, Immutable.fromJS({}))
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralHeaders', sinon.match.any).notCalled)
+ })
+
+ it('headers are saved', function () {
+ ledgerApi.onReferralRead(defaultAppState, headers)
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralHeaders', headers.get('headers')).calledOnce)
+ })
+ })
+
+ describe('landing page', function () {
+ let createTabRequestedSpy
+ const url = 'https://clifton.io'
+
+ before(function () {
+ createTabRequestedSpy = sinon.spy(appActions, 'createTabRequested')
+ })
+
+ afterEach(function () {
+ createTabRequestedSpy.reset()
+ })
+
+ after(function () {
+ createTabRequestedSpy.restore()
+ })
+
+ it('page is missing', function () {
+ ledgerApi.onReferralRead(defaultAppState, Immutable.fromJS({
+ download_id: 1,
+ referral_code: 'code'
+ }))
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralPage', sinon.match.any).notCalled)
+ assert(createTabRequestedSpy.notCalled)
+ })
+
+ it('page is not an url', function () {
+ ledgerApi.onReferralRead(defaultAppState, Immutable.fromJS({
+ download_id: 1,
+ referral_code: 'code',
+ offer_page_url: 'adasdsadsad'
+ }))
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralPage', sinon.match.any).notCalled)
+ assert(createTabRequestedSpy.notCalled)
+ })
+
+ it('window is not initialized yet', function () {
+ ledgerApi.onReferralRead(defaultAppState, Immutable.fromJS({
+ download_id: 1,
+ referral_code: 'code',
+ offer_page_url: url
+ }), -1)
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralPage', url).calledOnce)
+ assert(createTabRequestedSpy.notCalled)
+ })
+
+ it('window is ready', function () {
+ const windowReadyState = defaultAppState.set('windowReady', true)
+ ledgerApi.onReferralRead(windowReadyState, Immutable.fromJS({
+ download_id: 1,
+ referral_code: 'code',
+ offer_page_url: url
+ }), 1)
+ assert(setUpdatePropSpy.withArgs(sinon.match.any, 'referralPage', null).calledOnce)
+ assert(createTabRequestedSpy.withArgs({
+ url,
+ windowId: 1,
+ active: true
+ }).calledOnce)
+ })
+ })
+ })
+
+ describe('getCaptcha', function () {
+ let getPromotionCaptchaSpy
+
+ before(function () {
+ ledgerApi.setClient(ledgerClientObject)
+ getPromotionCaptchaSpy = sinon.spy(ledgerClientObject, 'getPromotionCaptcha')
+ })
+
+ afterEach(function () {
+ getPromotionCaptchaSpy.reset()
+ })
+
+ after(function () {
+ getPromotionCaptchaSpy.restore()
+ ledgerApi.setClient(undefined)
+ })
+
+ it('no promotion', function () {
+ ledgerApi.getCaptcha(defaultAppState)
+ assert(getPromotionCaptchaSpy.notCalled)
+ })
+
+ it('gets new promotion', function () {
+ const state = defaultAppState
+ .setIn(['ledger', 'promotion'], Immutable.fromJS({
+ promotionId: 1
+ }))
+
+ ledgerApi.getCaptcha(state)
+ assert(getPromotionCaptchaSpy.withArgs(1, sinon.match.any).calledOnce)
+ })
+ })
+
+ describe('onCaptchaResponse', function () {
+ const body = new Uint8Array([255, 216, 255, 219, 0])
+
+ it('null case', function () {
+ const expectedState = defaultAppState
+ .setIn(['ledger', 'promotion', 'promotionStatus'], promotionStatuses.CAPTCHA_ERROR)
+ const result = ledgerApi.onCaptchaResponse(defaultAppState)
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+
+ it('new captcha', function () {
+ const expectedState = defaultAppState
+ .setIn(['ledger', 'promotion', 'promotionStatus'], promotionStatuses.CAPTCHA_CHECK)
+ .setIn(['ledger', 'promotion', 'captcha'], 'data:image/jpeg;base64,/9j/2wA=')
+ const result = ledgerApi.onCaptchaResponse(defaultAppState, body)
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+
+ it('replacing exiting captcha', function () {
+ const state = defaultAppState
+ .setIn(['ledger', 'promotion', 'promotionStatus'], promotionStatuses.CAPTCHA_ERROR)
+ const expectedState = defaultAppState
+ .setIn(['ledger', 'promotion', 'promotionStatus'], promotionStatuses.CAPTCHA_ERROR)
+ .setIn(['ledger', 'promotion', 'captcha'], 'data:image/jpeg;base64,/9j/2wA=')
+ const result = ledgerApi.onCaptchaResponse(state, body)
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('deleteWallet', function () {
+ it('data is cleared', function () {
+ const state = defaultAppState
+ .setIn(['cache', 'ledgerVideos'], Immutable.fromJS({
+ 'youtube_Ece3i74Wces': 'youtube#channel:radio1slovenia'
+ }))
+ .setIn(['settings', 'payments.enabled'], true)
+ .set('pageData', Immutable.fromJS({
+ info: {
+ 'https://www.youtube.com/user/radio1slovenia/videos': {
+ faviconURL: 'https://s.ytimg.com/yts/img/favicon_32-vflOogEID.png',
+ key: 'https://www.youtube.com/user/radio1slovenia/videos',
+ protocol: 'https:',
+ publisher: 'youtube.com',
+ timestamp: 1526367684155,
+ url: 'https://www.youtube.com/user/radio1slovenia/videos'
+ }
+ },
+ last: {
+ closedTabValue: {
+ audible: false,
+ width: 2560,
+ active: true
+ },
+ info: '',
+ tabId: '7'
+ }
+ }))
+ .set('ledger', Immutable.fromJS({
+ about: {
+ synopsis: [
+ {
+ daysSpent: 0,
+ duration: 166431,
+ exclude: false,
+ faviconURL: 'data:image/jpeg;base64',
+ hoursSpent: 0,
+ minutesSpent: 2,
+ percentage: 38,
+ pinPercentage: undefined,
+ providerName: 'YouTube',
+ publisherKey: 'youtube#channel:radio1slovenia',
+ publisherURL: 'https://www.youtube.com/user/radio1slovenia/videos',
+ score: 14.588460435541956,
+ secondsSpent: 46,
+ siteName: 'radio1slovenia on YouTube',
+ verified: false,
+ views: 2,
+ weight: 38.244594657485045
+ }
+ ],
+ synopsisOptions: {
+ _a: 7000,
+ _b: 1000,
+ scorekeeper: 'concave',
+ _d: 0.000033333333333333335
+ }
+ },
+ info: {
+ balance: 0,
+ paymentId: 'ladasda'
+ },
+ locations: {
+ 'https://www.youtube.com/user/radio1slovenia/videos': {
+ publisher: 'youtube.com'
+ }
+ },
+ synopsis: {
+ options: {
+ _a: 7000,
+ _b: 1000,
+ scorekeeper: 'concave',
+ _d: 0.000033333333333333335
+ },
+ publishers: {
+ 'youtube#channel:radio1slovenia': {
+ duration: 166431,
+ options: {
+ exclude: false
+ },
+ pinPercentage: 20,
+ scores: {
+ concave: 3.249426617127623,
+ visits: 2
+ },
+ views: 2,
+ weight: 20
+ }
+ }
+ },
+ promotion: {},
+ publisherTimestamp: 123
+ }))
+
+ const result = ledgerApi.deleteWallet(state)
+
+ const expectedState = state
+ .set('ledger', Immutable.fromJS({
+ about: {
+ synopsis: [],
+ synopsisOptions: {}
+ },
+ info: {},
+ locations: {},
+ synopsis: {
+ options: {},
+ publishers: {}
+ },
+ promotion: {}
+ }))
+ .setIn(['cache', 'ledgerVideos'], Immutable.Map())
+ .setIn(['pageData', 'info'], Immutable.Map())
+ .setIn(['pageData', 'last', 'info'], null)
+ .setIn(['pageData', 'last', 'tabId'], null)
+ .setIn(['pageData', 'last', 'closedTabValue'], null)
+ .setIn(['settings', 'payments.enabled'], false)
+
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ assert.equal(ledgerApi.getClient(), null)
+ assert.equal(ledgerApi.getSynopsis(), null)
+ })
+ })
+
+ describe('clearPaymentHistory', function () {
+ it('execute', function () {
+ const state = defaultAppState
+ .setIn(['ledger', 'info', 'transactions'], Immutable.fromJS([{
+ viewingId: 1
+ }]))
+ .setIn(['ledger', 'info', 'ballots'], Immutable.fromJS([{
+ viewingId: 1
+ }]))
+ .setIn(['ledger', 'info', 'batch'], Immutable.fromJS([{
+ 'clifton.io': {
+ proof: 1
+ }
+ }]))
+
+ const result = ledgerApi.clearPaymentHistory(state)
+
+ const expectedState = defaultAppState
+ .setIn(['ledger', 'info', 'transactions'], Immutable.fromJS([]))
+ .setIn(['ledger', 'info', 'ballots'], Immutable.fromJS([]))
+ .setIn(['ledger', 'info', 'batch'], Immutable.fromJS([]))
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('resetPublishers', function () {
+ let resetPublishersSpy
+
+ before(function () {
+ ledgerApi.setSynopsis({
+ publishers: {
+ 'clifton.io': {
+ time: 1
+ }
+ }
+ })
+ resetPublishersSpy = sinon.spy(ledgerState, 'resetPublishers')
+ })
+
+ afterEach(function () {
+ resetPublishersSpy.reset()
+ })
+
+ after(function () {
+ resetPublishersSpy.restore()
+ })
+
+ it('execute', function () {
+ ledgerApi.resetPublishers(defaultAppState)
+ assert(resetPublishersSpy.calledOnce)
+ assert.deepEqual(ledgerApi.getSynopsis(), {publishers: {}})
+ })
+ })
})
diff --git a/test/unit/app/browser/api/topSitesTest.js b/test/unit/app/browser/api/topSitesTest.js
index 86aa8d88640..6cee99a58e6 100644
--- a/test/unit/app/browser/api/topSitesTest.js
+++ b/test/unit/app/browser/api/topSitesTest.js
@@ -111,19 +111,19 @@ describe('topSites api', function () {
title: 'Brave Software (@brave) | Twitter',
bookmarked: false
},
- { key: 'https://www.facebook.com/BraveSoftware/|0',
+ { key: 'https://github.com/brave/|0',
count: 0,
- favicon: 'chrome-extension://mnojpmjdmbbfmejpflffifhffcmidifd/img/newtab/defaultTopSitesIcon/facebook.png',
- location: 'https://www.facebook.com/BraveSoftware/',
- themeColor: 'rgb(59, 89, 152)',
- title: 'Brave Software | Facebook',
+ favicon: 'chrome-extension://mnojpmjdmbbfmejpflffifhffcmidifd/img/newtab/defaultTopSitesIcon/github.png',
+ location: 'https://github.com/brave/',
+ themeColor: 'rgb(255, 255, 255)',
+ title: 'Brave Software | GitHub',
bookmarked: false
},
- { key: 'https://www.youtube.com/bravesoftware/|0',
+ { key: 'https://youtube.com/bravesoftware/|0',
count: 0,
favicon: 'chrome-extension://mnojpmjdmbbfmejpflffifhffcmidifd/img/newtab/defaultTopSitesIcon/youtube.png',
- location: 'https://www.youtube.com/bravesoftware/',
- themeColor: '#E62117',
+ location: 'https://youtube.com/bravesoftware/',
+ themeColor: 'rgb(255, 255, 255)',
title: 'Brave Browser - YouTube',
bookmarked: false
},
@@ -148,7 +148,7 @@ describe('topSites api', function () {
favicon: 'chrome-extension://mnojpmjdmbbfmejpflffifhffcmidifd/img/newtab/defaultTopSitesIcon/playstore.png',
location: 'https://play.google.com/store/apps/details?id=com.brave.browser',
themeColor: 'rgb(241, 241, 241)',
- title: 'Brave Browser: Fast AdBlock – Apps para Android no Google Play',
+ title: 'Brave Browser: Fast AdBlocker - Apps on Google Play',
bookmarked: false
}
])
diff --git a/test/unit/app/browser/isThirdPartyhostTest.js b/test/unit/app/browser/isThirdPartyhostTest.js
index 07187a35779..264c4dd807e 100644
--- a/test/unit/app/browser/isThirdPartyhostTest.js
+++ b/test/unit/app/browser/isThirdPartyhostTest.js
@@ -12,11 +12,40 @@ describe('isThirdPartyHost test', function () {
})
it('A subdomain URL should not be third party', function () {
assert.ok(!isThirdPartyHost(braveHost, 'ragu.brave.com'))
+ assert.ok(!isThirdPartyHost('ragu.brave.com', braveHost))
+ })
+ it('A 2nd level subdomain URL should not be third party', function () {
+ assert.ok(!isThirdPartyHost(braveHost, 'foo.bar.brave.com'))
+ assert.ok(!isThirdPartyHost('foo.bar.brave.com', braveHost))
})
it('Unrelated URLs should be third party', function () {
assert.ok(isThirdPartyHost(braveHost, 'ragu.com'))
+ assert.ok(isThirdPartyHost('ragu.com', braveHost))
})
it('Checks subdomains properly', function () {
assert.ok(isThirdPartyHost(braveHost, 'brave.ragu.com'))
+ assert.ok(isThirdPartyHost('brave.ragu.com', braveHost))
+ })
+ it('Handles multi-part TLDs', function () {
+ assert.ok(isThirdPartyHost('diracdeltas.github.io', 'brave.github.io'))
+ assert.ok(isThirdPartyHost('github.io', 'brave.github.io'))
+ assert.ok(!isThirdPartyHost('github.io', 'github.io'))
+ assert.ok(isThirdPartyHost('brave.github.io', 'github.io'))
+ assert.ok(isThirdPartyHost('brave.co.uk', 'example.co.uk'))
+ })
+ it('Handles IPv4', function () {
+ assert.ok(isThirdPartyHost('172.217.6.46', '173.217.6.46'))
+ assert.ok(!isThirdPartyHost('172.217.6.46', '172.217.6.46'))
+ })
+ it('Handles IPv6', function () {
+ assert.ok(!isThirdPartyHost('[2001:db8:85a3::8a2e:370:7334]', '[2001:db8:85a3::8a2e:370:7334]'))
+ assert.ok(!isThirdPartyHost('2001:db8:85a3::8a2e:370:7334', '2001:db8:85a3::8a2e:370:7334'))
+ assert.ok(isThirdPartyHost('[2001:db8:85a3::8a2e:370:7334]', '[2002:db8:85a3::8a2e:370:7334]'))
+ assert.ok(isThirdPartyHost('2001:db8:85a3::8a2e:370:7334', '2002:db8:85a3::8a2e:370:7334'))
+ })
+ it('Handles null', function () {
+ assert.ok(isThirdPartyHost('', ''))
+ assert.ok(isThirdPartyHost(null, null))
+ assert.ok(isThirdPartyHost('', null))
})
})
diff --git a/test/unit/app/browser/menuTest.js b/test/unit/app/browser/menuTest.js
index 2141b296391..9e55451b3ca 100644
--- a/test/unit/app/browser/menuTest.js
+++ b/test/unit/app/browser/menuTest.js
@@ -30,6 +30,9 @@ describe('menu reducer unit tests', function () {
createBookmarkTemplateItems: (sites) => {
return []
},
+ createOtherBookmarkTemplateItems: (sites) => {
+ return []
+ },
getMenuItem: (menu, label) => {
return {
click: () => {}
diff --git a/test/unit/app/browser/reducers/autoplayReducerTest.js b/test/unit/app/browser/reducers/autoplayReducerTest.js
index acbe9387b56..a41ac3ae05b 100644
--- a/test/unit/app/browser/reducers/autoplayReducerTest.js
+++ b/test/unit/app/browser/reducers/autoplayReducerTest.js
@@ -23,8 +23,8 @@ describe('autoplayReducer unit tests', function () {
const message = `Allow ${origin} to autoplay media?`
const showNotificationArg = {
buttons: [
- {text: 'Allow'},
- {text: 'Deny'}
+ {text: 'Deny'},
+ {text: 'Allow'}
],
message,
frameOrigin: origin,
@@ -127,7 +127,7 @@ describe('autoplayReducer unit tests', function () {
actionType: appConstants.APP_AUTOPLAY_BLOCKED,
tabId: tabId
}))
- fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 0, false)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 1, false)
})
it('calls local.translation', function () {
@@ -162,7 +162,7 @@ describe('autoplayReducer unit tests', function () {
actionType: appConstants.APP_AUTOPLAY_BLOCKED,
tabId: tabId
}))
- fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 0, true)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 1, true)
})
it('calls local.translation', function () {
@@ -197,7 +197,7 @@ describe('autoplayReducer unit tests', function () {
actionType: appConstants.APP_AUTOPLAY_BLOCKED,
tabId: tabId
}))
- fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 1, false)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 0, false)
})
it('calls local.translation', function () {
@@ -228,7 +228,7 @@ describe('autoplayReducer unit tests', function () {
actionType: appConstants.APP_AUTOPLAY_BLOCKED,
tabId: tabId
}))
- fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 1, true)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 0, true)
})
it('calls local.translation', function () {
@@ -343,7 +343,7 @@ describe('autoplayReducer unit tests', function () {
actionType: appConstants.APP_AUTOPLAY_BLOCKED,
tabId: tabId
}))
- fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 0, true)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 1, true)
removeListenerSpy.reset()
changeSiteSettingSpy.reset()
autoplayReducer(Immutable.Map(), Immutable.fromJS({
@@ -379,7 +379,7 @@ describe('autoplayReducer unit tests', function () {
actionType: appConstants.APP_AUTOPLAY_BLOCKED,
tabId: tabId
}))
- fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 0, false)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 1, false)
autoplayReducer(Immutable.Map(), Immutable.fromJS({
actionType: appConstants.APP_TAB_CLOSED,
tabId: tabId
@@ -412,7 +412,7 @@ describe('autoplayReducer unit tests', function () {
actionType: appConstants.APP_AUTOPLAY_BLOCKED,
tabId: tabId
}))
- fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 0, false)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, message, 1, false)
autoplayReducer(Immutable.Map(), Immutable.fromJS({
actionType: appConstants.APP_SHUTTING_DOWN
}))
diff --git a/test/unit/app/browser/reducers/bookmarkFoldersReducerTest.js b/test/unit/app/browser/reducers/bookmarkFoldersReducerTest.js
index 4758bc52aba..323df58b85e 100644
--- a/test/unit/app/browser/reducers/bookmarkFoldersReducerTest.js
+++ b/test/unit/app/browser/reducers/bookmarkFoldersReducerTest.js
@@ -13,10 +13,11 @@ const fakeAdBlock = require('../../../lib/fakeAdBlock')
const appConstants = require('../../../../../js/constants/appConstants')
const siteTags = require('../../../../../js/constants/siteTags')
const {STATE_SITES} = require('../../../../../js/constants/stateConstants')
+const bookmarkUtil = require('../../../../../app/common/lib/bookmarkUtil')
require('../../../braveUnit')
describe('bookmarkFoldersReducer unit test', function () {
- let bookmarkFoldersReducer, bookmarkFoldersState, bookmarkToolbarState
+ let bookmarkFoldersReducer, bookmarkFoldersState
const state = Immutable.fromJS({
windows: [
@@ -118,11 +119,6 @@ describe('bookmarkFoldersReducer unit test', function () {
}
})
- const fakeTextCalc = {
- calcText: () => true,
- calcTextList: () => true
- }
-
before(function () {
mockery.enable({
warnOnReplace: false,
@@ -131,10 +127,9 @@ describe('bookmarkFoldersReducer unit test', function () {
})
mockery.registerMock('electron', fakeElectron)
mockery.registerMock('ad-block', fakeAdBlock)
- mockery.registerMock('../../browser/api/textCalc', fakeTextCalc)
+ mockery.registerMock('../../common/lib/bookmarkUtil', bookmarkUtil)
bookmarkFoldersReducer = require('../../../../../app/browser/reducers/bookmarkFoldersReducer')
bookmarkFoldersState = require('../../../../../app/common/state/bookmarkFoldersState')
- bookmarkToolbarState = require('../../../../../app/common/state/bookmarkToolbarState')
})
after(function () {
@@ -142,27 +137,23 @@ describe('bookmarkFoldersReducer unit test', function () {
})
describe('APP_ADD_BOOKMARK_FOLDER', function () {
- let spy, spyCalc
+ let spy
afterEach(function () {
spy.restore()
- spyCalc.restore()
})
it('null case', function () {
spy = sinon.spy(bookmarkFoldersState, 'addFolder')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarkFoldersReducer(state, {
actionType: appConstants.APP_ADD_BOOKMARK_FOLDER
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(state, newState)
})
it('folder data is map (single folder)', function () {
spy = sinon.spy(bookmarkFoldersState, 'addFolder')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarkFoldersReducer(state, {
actionType: appConstants.APP_ADD_BOOKMARK_FOLDER,
folderDetails: {
@@ -193,13 +184,11 @@ describe('bookmarkFoldersReducer unit test', function () {
]
}))
assert.equal(spy.calledOnce, true)
- assert.equal(spyCalc.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
it('folder data is list (multiple folders)', function () {
spy = sinon.spy(bookmarkFoldersState, 'addFolder')
- spyCalc = sinon.spy(fakeTextCalc, 'calcTextList')
const newState = bookmarkFoldersReducer(state, {
actionType: appConstants.APP_ADD_BOOKMARK_FOLDER,
folderDetails: [
@@ -270,45 +259,38 @@ describe('bookmarkFoldersReducer unit test', function () {
]
}))
assert.equal(spy.callCount, 3)
- assert.equal(spyCalc.callCount, 1)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
})
describe('APP_EDIT_BOOKMARK_FOLDER', function () {
- let spy, spyCalc
+ let spy
afterEach(function () {
spy.restore()
- spyCalc.restore()
})
it('null case', function () {
spy = sinon.spy(bookmarkFoldersState, 'editFolder')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarkFoldersReducer(stateWithData, {
actionType: appConstants.APP_EDIT_BOOKMARK_FOLDER
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(stateWithData, newState)
})
it('folder data is missing', function () {
spy = sinon.spy(bookmarkFoldersState, 'editFolder')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarkFoldersReducer(stateWithData, {
actionType: appConstants.APP_EDIT_BOOKMARK_FOLDER,
editKey: '1'
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(stateWithData, newState)
})
it('folder key is missing', function () {
spy = sinon.spy(bookmarkFoldersState, 'editFolder')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarkFoldersReducer(stateWithData, {
actionType: appConstants.APP_EDIT_BOOKMARK_FOLDER,
folderDetails: {
@@ -317,13 +299,11 @@ describe('bookmarkFoldersReducer unit test', function () {
}
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(stateWithData, newState)
})
it('folder data is correct', function () {
spy = sinon.spy(bookmarkFoldersState, 'editFolder')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarkFoldersReducer(stateWithData, {
actionType: appConstants.APP_EDIT_BOOKMARK_FOLDER,
folderDetails: {
@@ -334,33 +314,28 @@ describe('bookmarkFoldersReducer unit test', function () {
})
const expectedState = stateWithData.setIn([STATE_SITES.BOOKMARK_FOLDERS, '1', 'title'], 'folder1 new')
assert.equal(spy.calledOnce, true)
- assert.equal(spyCalc.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
})
describe('APP_MOVE_BOOKMARK_FOLDER', function () {
- let spy, spyToolbar
+ let spy
afterEach(function () {
spy.restore()
- spyToolbar.restore()
})
it('null case', function () {
spy = sinon.spy(bookmarkFoldersState, 'moveFolder')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
const newState = bookmarkFoldersReducer(state, {
actionType: appConstants.APP_MOVE_BOOKMARK_FOLDER
})
assert.equal(spy.notCalled, true)
- assert.equal(spyToolbar.notCalled, true)
assert.deepEqual(state, newState)
})
it('check if move is working', function () {
spy = sinon.spy(bookmarkFoldersState, 'moveFolder')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
const newState = bookmarkFoldersReducer(stateWithData, {
actionType: appConstants.APP_MOVE_BOOKMARK_FOLDER,
folderKey: '1',
@@ -380,58 +355,29 @@ describe('bookmarkFoldersReducer unit test', function () {
type: siteTags.BOOKMARK_FOLDER
}
]))
- .setIn(['windows', 0, 'bookmarksToolbar', 'toolbar'], Immutable.fromJS([
- '69',
- '1'
- ]))
assert.equal(spy.calledOnce, true)
- assert.equal(spyToolbar.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
-
- it('folder is moved from one folder to another', function () {
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- bookmarkFoldersReducer(stateWithData, {
- actionType: appConstants.APP_MOVE_BOOKMARK_FOLDER,
- folderKey: '81',
- destinationKey: '80'
- })
- assert.equal(spyToolbar.notCalled, true)
- })
-
- it('folder is moved from the toolbar into other bookmarks', function () {
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- bookmarkFoldersReducer(stateWithData, {
- actionType: appConstants.APP_MOVE_BOOKMARK_FOLDER,
- folderKey: '1',
- destinationKey: '-1'
- })
- assert.equal(spyToolbar.calledOnce, true)
- })
})
describe('APP_REMOVE_BOOKMARK_FOLDER', function () {
- let spy, spyToolbar
+ let spy
afterEach(function () {
spy.restore()
- spyToolbar.restore()
})
it('null case', function () {
spy = sinon.spy(bookmarkFoldersState, 'removeFolder')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
const newState = bookmarkFoldersReducer(state, {
actionType: appConstants.APP_REMOVE_BOOKMARK_FOLDER
})
assert.equal(spy.notCalled, true)
- assert.equal(spyToolbar.notCalled, true)
assert.deepEqual(state, newState)
})
it('folder key is list (multiple folders)', function () {
spy = sinon.spy(bookmarkFoldersState, 'removeFolder')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
const newState = bookmarkFoldersReducer(stateWithData, {
actionType: appConstants.APP_REMOVE_BOOKMARK_FOLDER,
folderKey: [
@@ -440,13 +386,11 @@ describe('bookmarkFoldersReducer unit test', function () {
]
})
assert.equal(spy.callCount, 4)
- assert.equal(spyToolbar.calledOnce, true)
assert.deepEqual(newState.toJS(), state.toJS())
})
it('folder key is map (single folder)', function () {
spy = sinon.spy(bookmarkFoldersState, 'removeFolder')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
const newState = bookmarkFoldersReducer(stateWithData, {
actionType: appConstants.APP_REMOVE_BOOKMARK_FOLDER,
folderKey: '1'
@@ -462,90 +406,17 @@ describe('bookmarkFoldersReducer unit test', function () {
.deleteIn(['cache', 'bookmarkOrder', '1'])
.deleteIn([STATE_SITES.BOOKMARK_FOLDERS, '1'])
.deleteIn([STATE_SITES.BOOKMARK_FOLDERS, '81'])
- .setIn(['windows', 0, 'bookmarksToolbar', 'toolbar'], Immutable.fromJS([
- '69'
- ]))
assert.equal(spy.calledTwice, true)
- assert.equal(spyToolbar.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
- })
-
- describe('APP_ON_BOOKMARK_FOLDER_WIDTH_CHANGED', function () {
- let spy, spyToolbar
-
- afterEach(function () {
- spy.restore()
- spyToolbar.restore()
- })
- it('null case', function () {
- spy = sinon.spy(bookmarkFoldersState, 'setWidth')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- const newState = bookmarkFoldersReducer(state, {
- actionType: appConstants.APP_ON_BOOKMARK_FOLDER_WIDTH_CHANGED
- })
- assert.equal(spy.notCalled, true)
- assert.equal(spyToolbar.notCalled, true)
- assert.deepEqual(state, newState)
- })
-
- it('we update multiple items', function () {
- spy = sinon.spy(bookmarkFoldersState, 'setWidth')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- const newState = bookmarkFoldersReducer(stateWithData, {
- actionType: appConstants.APP_ON_BOOKMARK_FOLDER_WIDTH_CHANGED,
- folderList: Immutable.fromJS([
- {
- key: '1',
- width: 10,
- parentFolderId: 0
- },
- {
- key: '69',
- width: 15,
- parentFolderId: 0
- },
- {
- key: '80',
- width: 20,
- parentFolderId: 69
- }
- ])
- })
- assert.equal(spy.callCount, 3)
- assert.equal(spyToolbar.calledOnce, true)
- const expectedState = stateWithData
- .setIn([STATE_SITES.BOOKMARK_FOLDERS, '1', 'width'], 10)
- .setIn([STATE_SITES.BOOKMARK_FOLDERS, '69', 'width'], 15)
- .setIn([STATE_SITES.BOOKMARK_FOLDERS, '80', 'width'], 20)
- .setIn(['windows', 0, 'bookmarksToolbar', 'toolbar'], Immutable.fromJS([
- '1'
- ]))
- .setIn(['windows', 0, 'bookmarksToolbar', 'other'], Immutable.fromJS([
- '69'
- ]))
- assert.deepEqual(newState.toJS(), expectedState.toJS())
- })
-
- it('we update one and dont trigger toolbar update (parentFolderId is not 0)', function () {
- spy = sinon.spy(bookmarkFoldersState, 'setWidth')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- const newState = bookmarkFoldersReducer(stateWithData, {
- actionType: appConstants.APP_ON_BOOKMARK_FOLDER_WIDTH_CHANGED,
- folderList: Immutable.fromJS([
- {
- key: '80',
- width: 20,
- parentFolderId: 69
- }
- ])
+ it('calls bookmarkUtil.closeToolbarIfEmpty', function () {
+ spy = sinon.spy(bookmarkUtil, 'closeToolbarIfEmpty')
+ bookmarkFoldersReducer(stateWithData, {
+ actionType: appConstants.APP_REMOVE_BOOKMARK_FOLDER,
+ folderKey: '1'
})
- assert.equal(spy.callCount, 1)
- assert.equal(spyToolbar.notCalled, true)
- const expectedState = stateWithData
- .setIn([STATE_SITES.BOOKMARK_FOLDERS, '80', 'width'], 20)
- assert.deepEqual(newState.toJS(), expectedState.toJS())
+ assert.equal(spy.calledOnce, true)
})
})
})
diff --git a/test/unit/app/browser/reducers/bookmarkToolbarReducerTest.js b/test/unit/app/browser/reducers/bookmarkToolbarReducerTest.js
deleted file mode 100644
index 32330bad97e..00000000000
--- a/test/unit/app/browser/reducers/bookmarkToolbarReducerTest.js
+++ /dev/null
@@ -1,140 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* global describe, it, before, after, afterEach */
-const mockery = require('mockery')
-const Immutable = require('immutable')
-const assert = require('assert')
-const sinon = require('sinon')
-const fakeElectron = require('../../../lib/fakeElectron')
-const fakeAdBlock = require('../../../lib/fakeAdBlock')
-
-const appConstants = require('../../../../../js/constants/appConstants')
-const siteTags = require('../../../../../js/constants/siteTags')
-const {STATE_SITES} = require('../../../../../js/constants/stateConstants')
-require('../../../braveUnit')
-
-describe('bookmarkToolbarReducer unit test', function () {
- let bookmarkToolbarReducer
-
- const fakeTextCalc = {
- calcTextList: () => true
- }
-
- const stateWithData = Immutable.fromJS({
- windows: [],
- bookmarks: {
- 'https://brave.com/|0|0': {
- favicon: undefined,
- title: 'Brave',
- location: 'https://brave.com/',
- key: 'https://brave.com/|0|0',
- parentFolderId: 0,
- partitionNumber: 0,
- objectId: null,
- themeColor: undefined,
- type: siteTags.BOOKMARK
- },
- 'https://brianbondy.com/|0|1': {
- favicon: undefined,
- title: 'Clifton',
- location: 'https://clifton.io/',
- key: 'https://clifton.io/|0|1',
- parentFolderId: 1,
- partitionNumber: 0,
- objectId: null,
- themeColor: undefined,
- type: siteTags.BOOKMARK
- }
- },
- bookmarkFolders: {
- '1': {
- title: 'folder1',
- folderId: 1,
- key: '1',
- parentFolderId: 0,
- partitionNumber: 0,
- objectId: null,
- type: siteTags.BOOKMARK_FOLDER
- }
- },
- cache: {
- bookmarkOrder: {
- '0': [
- {
- key: 'https://brave.com/|0|0',
- order: 0,
- type: siteTags.BOOKMARK
- },
- {
- key: '1',
- order: 1,
- type: siteTags.BOOKMARK_FOLDER
- }
- ],
- '1': [
- {
- key: 'https://brianbondy.com/|0|1',
- order: 0,
- type: siteTags.BOOKMARK
- }
- ]
- },
- bookmarkLocation: {
- 'https://brave.com/': [
- 'https://brave.com/|0|0'
- ],
- 'https://brianbondy.com/': [
- 'https://brianbondy.com/|0|1'
- ]
- }
- },
- historySites: {},
- tabs: []
- })
-
- before(function () {
- mockery.enable({
- warnOnReplace: false,
- warnOnUnregistered: false,
- useCleanCache: true
- })
- mockery.registerMock('electron', fakeElectron)
- mockery.registerMock('ad-block', fakeAdBlock)
- mockery.registerMock('../../browser/api/textCalc', fakeTextCalc)
- bookmarkToolbarReducer = require('../../../../../app/browser/reducers/bookmarkToolbarReducer')
- })
-
- after(function () {
- mockery.disable()
- })
-
- describe('APP_SET_STATE', function () {
- let spyCalc
-
- afterEach(function () {
- spyCalc.restore()
- })
-
- it('we are upgrading from version 0.20 to 0.21', function () {
- spyCalc = sinon.spy(fakeTextCalc, 'calcTextList')
- bookmarkToolbarReducer(stateWithData, {
- actionType: appConstants.APP_SET_STATE
- })
- assert.equal(spyCalc.callCount, 1)
- })
-
- it('we are on version 0.21', function () {
- spyCalc = sinon.spy(fakeTextCalc, 'calcTextList')
- const newState = stateWithData
- .setIn([STATE_SITES.BOOKMARKS, 'https://brave.com/|0|0', 'width'], 10)
- .setIn([STATE_SITES.BOOKMARKS, 'https://brianbondy.com/|0|1', 'width'], 10)
- .setIn([STATE_SITES.BOOKMARK_FOLDERS, '1', 'width'], 10)
- bookmarkToolbarReducer(newState, {
- actionType: appConstants.APP_SET_STATE
- })
- assert.equal(spyCalc.notCalled, true)
- })
- })
-})
diff --git a/test/unit/app/browser/reducers/bookmarksReducerTest.js b/test/unit/app/browser/reducers/bookmarksReducerTest.js
index 3dcb00cc746..21bb994c46c 100644
--- a/test/unit/app/browser/reducers/bookmarksReducerTest.js
+++ b/test/unit/app/browser/reducers/bookmarksReducerTest.js
@@ -2,7 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* global describe, it, before, after, afterEach */
+/* global describe, it, before, after, beforeEach, afterEach */
const mockery = require('mockery')
const Immutable = require('immutable')
const assert = require('assert')
@@ -11,21 +11,19 @@ const fakeElectron = require('../../../lib/fakeElectron')
const fakeAdBlock = require('../../../lib/fakeAdBlock')
const appConstants = require('../../../../../js/constants/appConstants')
+const appActions = require('../../../../../js/actions/appActions')
const siteTags = require('../../../../../js/constants/siteTags')
+const bookmarkUtil = require('../../../../../app/common/lib/bookmarkUtil')
require('../../../braveUnit')
describe('bookmarksReducer unit test', function () {
- let bookmarksReducer, bookmarksState, bookmarkLocationCache, bookmarkToolbarState
+ let bookmarksReducer, bookmarksState, bookmarkLocationCache
const state = Immutable.fromJS({
windows: [
{
windowId: 1,
- width: 100,
- bookmarksToolbar: {
- toolbar: [],
- other: []
- }
+ width: 100
}
],
bookmarks: {},
@@ -42,11 +40,7 @@ describe('bookmarksReducer unit test', function () {
windows: [
{
windowId: 1,
- width: 100,
- bookmarksToolbar: {
- toolbar: [],
- other: []
- }
+ width: 100
}
],
bookmarks: {
@@ -144,11 +138,6 @@ describe('bookmarksReducer unit test', function () {
tabs: []
})
- const fakeTextCalc = {
- calcText: () => true,
- calcTextList: () => true
- }
-
before(function () {
mockery.enable({
warnOnReplace: false,
@@ -157,11 +146,11 @@ describe('bookmarksReducer unit test', function () {
})
mockery.registerMock('electron', fakeElectron)
mockery.registerMock('ad-block', fakeAdBlock)
- mockery.registerMock('../../browser/api/textCalc', fakeTextCalc)
+ mockery.registerMock('../../../js/actions/appActions', appActions)
+ mockery.registerMock('../../common/lib/bookmarkUtil', bookmarkUtil)
bookmarksReducer = require('../../../../../app/browser/reducers/bookmarksReducer')
bookmarksState = require('../../../../../app/common/state/bookmarksState')
bookmarkLocationCache = require('../../../../../app/common/cache/bookmarkLocationCache')
- bookmarkToolbarState = require('../../../../../app/common/state/bookmarkToolbarState')
})
after(function () {
@@ -187,27 +176,23 @@ describe('bookmarksReducer unit test', function () {
})
describe('APP_ADD_BOOKMARK', function () {
- let spy, spyCalc
+ let spy
afterEach(function () {
spy.restore()
- spyCalc.restore()
})
it('null case', function () {
spy = sinon.spy(bookmarksState, 'addBookmark')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarksReducer(state, {
actionType: appConstants.APP_ADD_BOOKMARK
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(state, newState)
})
it('bookmark data is map (single bookmark)', function () {
spy = sinon.spy(bookmarksState, 'addBookmark')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarksReducer(state, {
actionType: appConstants.APP_ADD_BOOKMARK,
siteDetail: {
@@ -228,8 +213,7 @@ describe('bookmarksReducer unit test', function () {
themeColor: undefined,
title: 'Clifton',
type: siteTags.BOOKMARK,
- key: 'https://clifton.io/|0|0',
- width: 0
+ key: 'https://clifton.io/|0|0'
}
}))
.setIn(['cache', 'bookmarkLocation'], Immutable.fromJS({
@@ -247,13 +231,11 @@ describe('bookmarksReducer unit test', function () {
]
}))
assert.equal(spy.calledOnce, true)
- assert.equal(spyCalc.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
it('bookmark data is list (multiple bookmarks)', function () {
spy = sinon.spy(bookmarksState, 'addBookmark')
- spyCalc = sinon.spy(fakeTextCalc, 'calcTextList')
const newState = bookmarksReducer(state, {
actionType: appConstants.APP_ADD_BOOKMARK,
siteDetail: [
@@ -282,8 +264,7 @@ describe('bookmarksReducer unit test', function () {
themeColor: undefined,
title: 'Clifton',
type: siteTags.BOOKMARK,
- key: 'https://clifton.io/|0|0',
- width: 0
+ key: 'https://clifton.io/|0|0'
},
'https://brianbondy.com/|0|0': {
favicon: undefined,
@@ -295,8 +276,7 @@ describe('bookmarksReducer unit test', function () {
themeColor: undefined,
title: 'Bondy',
type: siteTags.BOOKMARK,
- key: 'https://brianbondy.com/|0|0',
- width: 0
+ key: 'https://brianbondy.com/|0|0'
}
}))
.setIn(['cache', 'bookmarkLocation'], Immutable.fromJS({
@@ -322,7 +302,6 @@ describe('bookmarksReducer unit test', function () {
]
}))
assert.equal(spy.callCount, 2)
- assert.equal(spyCalc.callCount, 1)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
@@ -404,8 +383,7 @@ describe('bookmarksReducer unit test', function () {
partitionNumber: 0,
skipSync: null,
themeColor: undefined,
- type: 'bookmark',
- width: 0
+ type: 'bookmark'
},
'https://www.bridiver.io|0|0': {
lastAccessedTime: 0,
@@ -444,39 +422,33 @@ describe('bookmarksReducer unit test', function () {
})
describe('APP_EDIT_BOOKMARK', function () {
- let spy, spyCalc
+ let spy
afterEach(function () {
spy.restore()
- spyCalc.restore()
})
it('null case', function () {
spy = sinon.spy(bookmarksState, 'editBookmark')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarksReducer(state, {
actionType: appConstants.APP_EDIT_BOOKMARK
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(state, newState)
})
it('bookmark data is missing', function () {
spy = sinon.spy(bookmarksState, 'editBookmark')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarksReducer(state, {
actionType: appConstants.APP_EDIT_BOOKMARK,
editKey: 'https://clifton.io|0|0'
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(state, newState)
})
it('bookmark key is missing', function () {
spy = sinon.spy(bookmarksState, 'editBookmark')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarksReducer(state, {
actionType: appConstants.APP_EDIT_BOOKMARK,
siteDetail: {
@@ -485,13 +457,11 @@ describe('bookmarksReducer unit test', function () {
}
})
assert.equal(spy.notCalled, true)
- assert.equal(spyCalc.notCalled, true)
assert.deepEqual(state, newState)
})
it('bookmark data is correct', function () {
spy = sinon.spy(bookmarksState, 'editBookmark')
- spyCalc = sinon.spy(fakeTextCalc, 'calcText')
const newState = bookmarksReducer(stateWithData, {
actionType: appConstants.APP_EDIT_BOOKMARK,
siteDetail: {
@@ -502,33 +472,28 @@ describe('bookmarksReducer unit test', function () {
const expectedState = stateWithData
.setIn(['bookmarks', 'https://clifton.io/|0|0', 'title'], 'Bondy')
assert.equal(spy.calledOnce, true)
- assert.equal(spyCalc.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
})
describe('APP_MOVE_BOOKMARK', function () {
- let spy, spyToolbar
+ let spy
afterEach(function () {
spy.restore()
- spyToolbar.restore()
})
it('null case', function () {
spy = sinon.spy(bookmarksState, 'moveBookmark')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
const newState = bookmarksReducer(state, {
actionType: appConstants.APP_MOVE_BOOKMARK
})
assert.equal(spy.notCalled, true)
- assert.equal(spyToolbar.notCalled, true)
assert.deepEqual(state, newState)
})
it('data is correct', function () {
spy = sinon.spy(bookmarksState, 'moveBookmark')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
const newState = bookmarksReducer(stateWithData, {
actionType: appConstants.APP_MOVE_BOOKMARK,
bookmarkKey: 'https://clifton.io/|0|0',
@@ -548,58 +513,51 @@ describe('bookmarksReducer unit test', function () {
type: siteTags.BOOKMARK
}
]))
- .setIn(['windows', 0, 'bookmarksToolbar', 'toolbar'], Immutable.fromJS([
- 'https://clifton.io/|0|0',
- 'https://brave.com/|0|0'
- ]))
assert.equal(spy.calledOnce, true)
- assert.equal(spyToolbar.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
+ })
- it('bookmark is moved from folder to another folder', function () {
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- bookmarksReducer(stateWithData, {
- actionType: appConstants.APP_MOVE_BOOKMARK,
- bookmarkKey: 'https://brianbondy.com/|0|1',
- destinationKey: 'https://test.com/|0|2'
- })
- assert.equal(spyToolbar.notCalled, true)
+ describe('APP_REMOVE_BOOKMARK', function () {
+ let removeBookmarkSpy
+ let updateActiveTabBookmarkedSpy
+ let closeToolbarIfEmptySpy
+
+ beforeEach(function () {
+ removeBookmarkSpy = sinon.spy(bookmarksState, 'removeBookmark')
+ updateActiveTabBookmarkedSpy = sinon.spy(bookmarkUtil, 'updateActiveTabBookmarked')
+ closeToolbarIfEmptySpy = sinon.spy(bookmarkUtil, 'closeToolbarIfEmpty')
})
- it('bookmark is moved from toolbar to another folder', function () {
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- bookmarksReducer(stateWithData, {
- actionType: appConstants.APP_MOVE_BOOKMARK,
- bookmarkKey: 'https://clifton.io/|0|0',
- destinationKey: 'https://test.com/|0|2'
- })
- assert.equal(spyToolbar.calledOnce, true)
+ afterEach(function () {
+ removeBookmarkSpy.restore()
+ updateActiveTabBookmarkedSpy.restore()
+ closeToolbarIfEmptySpy.restore()
})
- })
- describe('APP_REMOVE_BOOKMARK', function () {
- let spy, spyToolbar
+ describe('when bookmarkKey is null', function () {
+ it('does not call removeBookmark', function () {
+ const newState = bookmarksReducer(state, {
+ actionType: appConstants.APP_REMOVE_BOOKMARK
+ })
+ assert.equal(removeBookmarkSpy.notCalled, true)
+ assert.deepEqual(state, newState)
+ })
+ })
- afterEach(function () {
- spy.restore()
- spyToolbar.restore()
+ describe('when bookmarkKey is a list', function () {
+ // TODO: test that removeBookmark is called multiple times
})
- it('null case', function () {
- spy = sinon.spy(bookmarksState, 'removeBookmark')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- const newState = bookmarksReducer(state, {
- actionType: appConstants.APP_REMOVE_BOOKMARK
+ it('calls bookmarksState.removeBookmark', function () {
+ bookmarksReducer(stateWithData, {
+ actionType: appConstants.APP_REMOVE_BOOKMARK,
+ bookmarkKey: 'https://clifton.io/|0|0'
})
- assert.equal(spy.notCalled, true)
- assert.equal(spyToolbar.notCalled, true)
- assert.deepEqual(state, newState)
+ assert.equal(removeBookmarkSpy.calledOnce, true)
})
- it('check if delete is working', function () {
- spy = sinon.spy(bookmarksState, 'removeBookmark')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
+ it('deletes the entry from bookmarks and cache', function () {
const newState = bookmarksReducer(stateWithData, {
actionType: appConstants.APP_REMOVE_BOOKMARK,
bookmarkKey: 'https://clifton.io/|0|0'
@@ -614,88 +572,23 @@ describe('bookmarksReducer unit test', function () {
]))
.deleteIn(['bookmarks', 'https://clifton.io/|0|0'])
.deleteIn(['cache', 'bookmarkLocation', 'https://clifton.io/'])
- .setIn(['windows', 0, 'bookmarksToolbar', 'toolbar'], Immutable.fromJS([
- 'https://brave.com/|0|0'
- ]))
- assert.equal(spy.calledOnce, true)
- assert.equal(spyToolbar.calledOnce, true)
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
- })
-
- describe('APP_ON_BOOKMARK_WIDTH_CHANGED', function () {
- let spy, spyToolbar
- afterEach(function () {
- spy.restore()
- spyToolbar.restore()
- })
-
- it('null case', function () {
- spy = sinon.spy(bookmarksState, 'setWidth')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- const newState = bookmarksReducer(state, {
- actionType: appConstants.APP_ON_BOOKMARK_WIDTH_CHANGED
- })
- assert.equal(spy.notCalled, true)
- assert.equal(spyToolbar.notCalled, true)
- assert.deepEqual(state, newState)
- })
-
- it('we update multiple items', function () {
- spy = sinon.spy(bookmarksState, 'setWidth')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- const newState = bookmarksReducer(stateWithData, {
- actionType: appConstants.APP_ON_BOOKMARK_WIDTH_CHANGED,
- bookmarkList: Immutable.fromJS([
- {
- key: 'https://brave.com/|0|0',
- width: 10,
- parentFolderId: 0
- },
- {
- key: 'https://clifton.io/|0|0',
- width: 15,
- parentFolderId: 0
- },
- {
- key: 'https://brianbondy.com/|0|1',
- width: 20,
- parentFolderId: 69
- }
- ])
+ it('calls bookmarkUtil.updateActiveTabBookmarked', function () {
+ bookmarksReducer(stateWithData, {
+ actionType: appConstants.APP_REMOVE_BOOKMARK,
+ bookmarkKey: 'https://clifton.io/|0|0'
})
- assert.equal(spy.callCount, 3)
- assert.equal(spyToolbar.calledOnce, true)
- const expectedState = stateWithData
- .setIn(['bookmarks', 'https://brave.com/|0|0', 'width'], 10)
- .setIn(['bookmarks', 'https://clifton.io/|0|0', 'width'], 15)
- .setIn(['bookmarks', 'https://brianbondy.com/|0|1', 'width'], 20)
- .setIn(['windows', 0, 'bookmarksToolbar', 'toolbar'], Immutable.fromJS([
- 'https://brave.com/|0|0',
- 'https://clifton.io/|0|0'
- ]))
- assert.deepEqual(newState.toJS(), expectedState.toJS())
+ assert.equal(updateActiveTabBookmarkedSpy.calledOnce, true)
})
- it('we update one and trigger toolbar update', function () {
- spy = sinon.spy(bookmarksState, 'setWidth')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbars')
- const newState = bookmarksReducer(stateWithData, {
- actionType: appConstants.APP_ON_BOOKMARK_WIDTH_CHANGED,
- bookmarkList: Immutable.fromJS([
- {
- key: 'https://brianbondy.com/|0|1',
- width: 20,
- parentFolderId: 1
- }
- ])
+ it('calls bookmarkUtil.closeToolbarIfEmpty', function () {
+ bookmarksReducer(stateWithData, {
+ actionType: appConstants.APP_REMOVE_BOOKMARK,
+ bookmarkKey: 'https://clifton.io/|0|0'
})
- assert.equal(spy.callCount, 1)
- assert.equal(spyToolbar.notCalled, true)
- const expectedState = stateWithData
- .setIn(['bookmarks', 'https://brianbondy.com/|0|1', 'width'], 20)
- assert.deepEqual(newState.toJS(), expectedState.toJS())
+ assert.equal(closeToolbarIfEmptySpy.calledOnce, true)
})
})
})
diff --git a/test/unit/app/browser/reducers/historyReducerTest.js b/test/unit/app/browser/reducers/historyReducerTest.js
index 2402ffa5394..bfc08e48a60 100644
--- a/test/unit/app/browser/reducers/historyReducerTest.js
+++ b/test/unit/app/browser/reducers/historyReducerTest.js
@@ -86,6 +86,17 @@ describe('historyReducer unit test', function () {
partitionNumber: 0,
themeColor: undefined,
title: 'Brave'
+ },
+ {
+ count: 2,
+ favicon: undefined,
+ key: 'https://brave.com/|1',
+ lastAccessedTime: 0,
+ location: 'https://brave.com/',
+ objectId: null,
+ partitionNumber: 0,
+ themeColor: undefined,
+ title: 'Brave | Another Page'
}
]
}
@@ -350,6 +361,83 @@ describe('historyReducer unit test', function () {
})
})
+ describe('APP_REMOVE_HISTORY_DOMAIN', function () {
+ let spy, spyAbout
+
+ before(function () {
+ spy = sinon.spy(historyState, 'removeSite')
+ spyAbout = sinon.spy(aboutHistoryState, 'setHistory')
+ })
+
+ afterEach(function () {
+ spy.reset()
+ spyAbout.reset()
+ })
+
+ after(function () {
+ spy.restore()
+ spyAbout.restore()
+ })
+
+ it('null case', function () {
+ const newState = historyReducer(state, {
+ actionType: appConstants.APP_REMOVE_HISTORY_DOMAIN
+ })
+ assert.equal(spy.notCalled, true)
+ assert.equal(spyAbout.notCalled, true)
+ assert.deepEqual(newState.toJS(), state.toJS())
+ })
+
+ it('domain is a string', function () {
+ const newState = historyReducer(stateWithData, {
+ actionType: appConstants.APP_REMOVE_HISTORY_DOMAIN,
+ domain: 'https://brave.com'
+ })
+ const expectedState = state
+ .set('historySites', Immutable.fromJS({
+ 'https://clifton.io/|0': {
+ count: 1,
+ favicon: undefined,
+ key: 'https://clifton.io/|0',
+ lastAccessedTime: 0,
+ location: 'https://clifton.io/',
+ objectId: null,
+ partitionNumber: 0,
+ themeColor: undefined,
+ title: 'Clifton'
+ }
+ }))
+ .setIn(['about', 'history'], Immutable.fromJS({
+ entries: [
+ {
+ count: 1,
+ favicon: undefined,
+ key: 'https://clifton.io/|0',
+ lastAccessedTime: 0,
+ location: 'https://clifton.io/',
+ objectId: null,
+ partitionNumber: 0,
+ themeColor: undefined,
+ title: 'Clifton'
+ }
+ ],
+ updatedStamp: 0
+ }))
+
+ it('calls remove for each matching domain', () => {
+ assert.equal(spy.calledTwice, true)
+ })
+
+ it('sets the history with the update site list', () => {
+ assert.equal(spyAbout.calledOnce, true)
+ })
+
+ it('returns the updated state', () => {
+ assert.deepEqual(newState.toJS(), expectedState.toJS())
+ })
+ })
+ })
+
describe('APP_REMOVE_HISTORY_SITE', function () {
let spy, spyAbout
diff --git a/test/unit/app/browser/reducers/ledgerReducerTest.js b/test/unit/app/browser/reducers/ledgerReducerTest.js
index 0f34ff8554a..66843377d8f 100644
--- a/test/unit/app/browser/reducers/ledgerReducerTest.js
+++ b/test/unit/app/browser/reducers/ledgerReducerTest.js
@@ -6,6 +6,8 @@ const sinon = require('sinon')
const appConstants = require('../../../../../js/constants/appConstants')
const settings = require('../../../../../js/constants/settings')
require('../../../braveUnit')
+const ledgerStatuses = require('../../../../../app/common/constants/ledgerStatuses')
+const ledgerState = require('../../../../../app/common/state/ledgerState')
describe('ledgerReducer unit tests', function () {
let ledgerReducer
@@ -15,6 +17,7 @@ describe('ledgerReducer unit tests', function () {
let appState
let paymentsEnabled
let returnedState
+ let fakeAboutPreferencesState
before(function () {
mockery.enable({
@@ -40,7 +43,6 @@ describe('ledgerReducer unit tests', function () {
quit: dummyModifyState,
pageDataChanged: dummyModifyState,
addVisit: dummyModifyState,
- deleteSynopsis: () => {},
boot: () => {},
onBootStateFile: dummyModifyState,
onWalletProperties: dummyModifyState,
@@ -58,25 +60,39 @@ describe('ledgerReducer unit tests', function () {
onPromotionResponse: dummyModifyState,
getPromotion: () => {},
checkReferralActivity: dummyModifyState,
- referralCheck: () => {}
+ referralCheck: () => {},
+ getCaptcha: () => {},
+ onCaptchaResponse: () => {},
+ resetPublishers: () => {},
+ clearPaymentHistory: () => {},
+ deleteWallet: () => {},
+ addNewLocation: dummyModifyState
}
fakeLedgerState = {
- resetSynopsis: dummyModifyState,
+ resetPublishers: dummyModifyState,
setRecoveryStatus: dummyModifyState,
- setInfoProp: dummyModifyState,
+ setRecoveryInProgressStatus: dummyModifyState,
+ setInfoProp: ledgerState.setInfoProp,
saveSynopsis: dummyModifyState,
savePromotion: dummyModifyState,
remindMeLater: dummyModifyState,
- removePromotion: dummyModifyState
+ removePromotion: dummyModifyState,
+ setPromotionProp: dummyModifyState,
+ setAboutProp: ledgerState.setAboutProp
}
fakeLedgerNotifications = {
onPromotionReceived: dummyModifyState,
onInterval: dummyModifyState,
removePromotionNotification: () => {}
}
+ fakeAboutPreferencesState = {
+ setRecoveryStatus: dummyModifyState,
+ setRecoveryInProgress: dummyModifyState
+ }
mockery.registerMock('../../browser/api/ledger', fakeLedgerApi)
mockery.registerMock('../../common/state/ledgerState', fakeLedgerState)
mockery.registerMock('../../browser/api/ledgerNotifications', fakeLedgerNotifications)
+ mockery.registerMock('../../common/state/aboutPreferencesState', fakeAboutPreferencesState)
mockery.registerMock('../../../js/settings', {
getSetting: (settingKey, settingsCollection, value) => {
if (settingKey === settings.PAYMENTS_ENABLED) {
@@ -88,8 +104,7 @@ describe('ledgerReducer unit tests', function () {
ledgerReducer = require('../../../../../app/browser/reducers/ledgerReducer')
appState = Immutable.fromJS({
- ledger: {},
- migrations: {}
+ ledger: {}
})
})
@@ -137,29 +152,69 @@ describe('ledgerReducer unit tests', function () {
it('calls ledgerApi.backupKeys', function () {
assert(backupKeysSpy.withArgs(appState, 'ActionGoesHere').calledOnce)
})
- it('returns an ununmodified state', function () {
- assert.deepEqual(returnedState, appState)
+ it('returns a modified state', function () {
+ assert.notDeepEqual(returnedState, appState)
})
})
describe('APP_RECOVER_WALLET', function () {
let recoverKeysSpy
+ let setRecoveryInProgressSpy
before(function () {
recoverKeysSpy = sinon.spy(fakeLedgerApi, 'recoverKeys')
- returnedState = ledgerReducer(appState, Immutable.fromJS({
- actionType: appConstants.APP_RECOVER_WALLET,
- useRecoveryKeyFile: 'useKeyFile',
- recoveryKey: 'firstKey'
- }))
+ setRecoveryInProgressSpy = sinon.spy(fakeAboutPreferencesState, 'setRecoveryInProgress')
})
after(function () {
recoverKeysSpy.restore()
+ setRecoveryInProgressSpy.restore()
})
- it('calls ledgerApi.recoverKeys', function () {
- assert(recoverKeysSpy.withArgs(appState, 'useKeyFile', 'firstKey').calledOnce)
+
+ describe('with key file', function () {
+ before(function () {
+ returnedState = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_RECOVER_WALLET,
+ useRecoveryKeyFile: 'useKeyFile',
+ recoveryKey: 'firstKey'
+ }))
+ })
+ after(function () {
+ recoverKeysSpy.reset()
+ setRecoveryInProgressSpy.reset()
+ })
+ it('does not call aboutPreferencesState.setRecoveryInProgress if a recovery file is used', function () {
+ assert(setRecoveryInProgressSpy.withArgs(appState, true).notCalled)
+ })
+ it('calls ledgerApi.recoverKeys', function () {
+ assert(recoverKeysSpy.withArgs(appState, 'useKeyFile', 'firstKey').calledOnce)
+ })
+ it('returns a modified state', function () {
+ assert.notDeepEqual(returnedState, appState)
+ })
})
- it('returns a modified state', function () {
- assert.notDeepEqual(returnedState, appState)
+
+ describe('without key file', function () {
+ let modifiedState
+ before(function () {
+ returnedState = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_RECOVER_WALLET,
+ useRecoveryKeyFile: false,
+ recoveryKey: 'firstKey'
+ }))
+ })
+ after(function () {
+ recoverKeysSpy.reset()
+ setRecoveryInProgressSpy.reset()
+ })
+ it('calls aboutPreferencesState.setRecoveryInProgress if a recovery file is not used', function () {
+ assert(setRecoveryInProgressSpy.withArgs(appState, true).calledOnce)
+ })
+ it('calls ledgerApi.recoverKeys', function () {
+ modifiedState = fakeAboutPreferencesState.setRecoveryInProgress(appState, true)
+ assert(recoverKeysSpy.withArgs(modifiedState, false, 'firstKey').calledOnce)
+ })
+ it('returns a modified state', function () {
+ assert.notDeepEqual(returnedState, appState)
+ })
})
})
@@ -182,57 +237,12 @@ describe('ledgerReducer unit tests', function () {
})
})
- describe('APP_ON_CLEAR_BROWSING_DATA', function () {
- let resetSynopsisSpy
- let clearAppState
+ describe('APP_IDLE_STATE_CHANGED', function () {
+ let pageDataChangedSpy
before(function () {
- resetSynopsisSpy = sinon.spy(fakeLedgerState, 'resetSynopsis')
- })
- after(function () {
- resetSynopsisSpy.restore()
+ paymentsEnabled = true
})
- describe('when clearData.browserHistory is true and payments is disabled', function () {
- before(function () {
- resetSynopsisSpy.reset()
- paymentsEnabled = false
- clearAppState = appState.setIn(['settings', settings.PAYMENTS_ENABLED], paymentsEnabled)
- clearAppState = clearAppState.set('clearBrowsingDataDefaults', Immutable.fromJS({
- browserHistory: true
- }))
- returnedState = ledgerReducer(clearAppState, Immutable.fromJS({
- actionType: appConstants.APP_ON_CLEAR_BROWSING_DATA
- }))
- })
- it('calls ledgerState.resetSynopsis', function () {
- assert(resetSynopsisSpy.withArgs(clearAppState).calledOnce)
- })
- it('returns a modified state', function () {
- assert.notDeepEqual(returnedState, clearAppState)
- })
- })
- describe('else', function () {
- before(function () {
- resetSynopsisSpy.reset()
- paymentsEnabled = true
- clearAppState = appState.setIn(['settings', settings.PAYMENTS_ENABLED], paymentsEnabled)
- clearAppState = clearAppState.set('clearBrowsingDataDefaults', Immutable.fromJS({
- browserHistory: true
- }))
- returnedState = ledgerReducer(clearAppState, Immutable.fromJS({
- actionType: appConstants.APP_ON_CLEAR_BROWSING_DATA
- }))
- })
- it('does not call ledgerState.resetSynopsis', function () {
- assert(resetSynopsisSpy.notCalled)
- })
- it('returns an ununmodified state', function () {
- assert.deepEqual(returnedState, clearAppState)
- })
- })
- })
- describe('APP_IDLE_STATE_CHANGED', function () {
- let pageDataChangedSpy
beforeEach(function () {
pageDataChangedSpy = sinon.spy(fakeLedgerApi, 'pageDataChanged')
})
@@ -269,10 +279,6 @@ describe('ledgerReducer unit tests', function () {
})
})
- describe('', function () {
-
- })
-
describe('APP_ON_LEDGER_WALLET_CREATE', function () {
let bootSpy
before(function () {
@@ -287,9 +293,6 @@ describe('ledgerReducer unit tests', function () {
it('calls ledgerApi.boot', function () {
assert(bootSpy.calledOnce)
})
- it('returns a non-modified state, if no transition in progress', function () {
- assert.deepEqual(returnedState, appState)
- })
})
describe('APP_ON_BOOT_STATE_FILE', function () {
@@ -347,9 +350,6 @@ describe('ledgerReducer unit tests', function () {
it('calls ledgerApi.paymentPresent', function () {
assert(paymentPresentSpy.withArgs(appState, 123, true).calledOnce)
})
- it('returns an ununmodified state', function () {
- assert.deepEqual(returnedState, appState)
- })
})
describe('APP_ON_ADD_FUNDS_CLOSED', function () {
@@ -516,7 +516,7 @@ describe('ledgerReducer unit tests', function () {
describe('APP_ON_RESET_RECOVERY_STATUS', function () {
let setRecoveryStatusSpy
before(function () {
- setRecoveryStatusSpy = sinon.spy(fakeLedgerState, 'setRecoveryStatus')
+ setRecoveryStatusSpy = sinon.spy(fakeAboutPreferencesState, 'setRecoveryStatus')
returnedState = ledgerReducer(appState, Immutable.fromJS({
actionType: appConstants.APP_ON_RESET_RECOVERY_STATUS
}))
@@ -524,47 +524,16 @@ describe('ledgerReducer unit tests', function () {
after(function () {
setRecoveryStatusSpy.restore()
})
+ /*
it('calls ledgerApi.setRecoveryStatus', function () {
assert(setRecoveryStatusSpy.withArgs(appState, null).calledOnce)
})
- it('returns a modified state', function () {
- assert.notDeepEqual(returnedState, appState)
- })
- })
-
- describe('APP_ON_BTC_TO_BAT_NOTIFIED', function () {
- before(function () {
- returnedState = ledgerReducer(appState, Immutable.fromJS({
- actionType: appConstants.APP_ON_BTC_TO_BAT_NOTIFIED
- }))
- })
- it('sets the notification timestamp', function () {
- assert.notDeepEqual(returnedState, appState)
- assert(returnedState.getIn(['migrations', 'btc2BatNotifiedTimestamp']))
- })
- })
-
- describe('APP_ON_BTC_TO_BAT_TRANSITIONED', function () {
- before(function () {
- returnedState = ledgerReducer(appState, Immutable.fromJS({
- actionType: appConstants.APP_ON_BTC_TO_BAT_TRANSITIONED
- }))
- })
- it('sets the timestamp', function () {
- assert.notDeepEqual(returnedState, appState)
- assert(returnedState.getIn(['migrations', 'btc2BatTimestamp']))
- })
- })
-
- describe('APP_ON_BTC_TO_BAT_BEGIN_TRANSITION', function () {
- before(function () {
- returnedState = ledgerReducer(appState, Immutable.fromJS({
- actionType: appConstants.APP_ON_BTC_TO_BAT_BEGIN_TRANSITION
- }))
+ */
+ it('calls aboutPreferencesState.setRecoveryStatus', function () {
+ assert(setRecoveryStatusSpy.withArgs(appState, null).calledOnce)
})
- it('sets the state variable', function () {
+ it('returns a modified state', function () {
assert.notDeepEqual(returnedState, appState)
- assert.equal(returnedState.getIn(['migrations', 'btc2BatTransitionPending']), true)
})
})
@@ -640,9 +609,11 @@ describe('ledgerReducer unit tests', function () {
it('execute', function () {
ledgerReducer(appState, Immutable.fromJS({
- actionType: appConstants.APP_ON_PROMOTION_CLAIM
+ actionType: appConstants.APP_ON_PROMOTION_CLAIM,
+ x: 1,
+ y: 2
}))
- assert(claimPromotionSpy.calledOnce)
+ assert(claimPromotionSpy.withArgs(appState, 1, 2).calledOnce)
})
})
@@ -760,4 +731,331 @@ describe('ledgerReducer unit tests', function () {
assert.notDeepEqual(returnedState, appState)
})
})
+
+ describe('APP_ADD_PUBLISHER_TO_LEDGER', function () {
+ let addNewLocationSpy
+ let pageDataChangedSpy
+ const tabIdNone = -1
+ const testTabId = 7
+
+ beforeEach(function () {
+ addNewLocationSpy = sinon.spy(fakeLedgerApi, 'addNewLocation')
+ pageDataChangedSpy = sinon.spy(fakeLedgerApi, 'pageDataChanged')
+ })
+
+ afterEach(function () {
+ addNewLocationSpy.restore()
+ pageDataChangedSpy.restore()
+ })
+
+ it('executes', function () {
+ const newState = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ADD_PUBLISHER_TO_LEDGER,
+ location: 'https://brave.com',
+ tabId: false
+ }))
+ assert(addNewLocationSpy.calledOnce)
+ assert(pageDataChangedSpy.calledOnce)
+ assert.notDeepEqual(newState, appState)
+ })
+
+ it('takes no action with a null location', function () {
+ const newState = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ADD_PUBLISHER_TO_LEDGER,
+ location: null,
+ tabId: false
+ }))
+ assert(addNewLocationSpy.notCalled)
+ assert(pageDataChangedSpy.notCalled)
+ assert.deepEqual(newState, appState)
+ })
+
+ it('tab Id passed is equal to tabState.TAB_ID_NONE when not added via toggle', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ADD_PUBLISHER_TO_LEDGER,
+ location: 'https://brave.com',
+ tabId: false
+ }))
+ assert.equal(tabIdNone, addNewLocationSpy.getCall(0).args[2])
+ })
+
+ it('executes when dispatched with a tab id', function () {
+ const newState = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ADD_PUBLISHER_TO_LEDGER,
+ location: 'https://brave.com',
+ tabId: testTabId
+ }))
+ assert(addNewLocationSpy.calledOnce)
+ assert(pageDataChangedSpy.calledOnce)
+ assert.notDeepEqual(newState, appState)
+ })
+
+ it('tab Id passed to addNewLocation is equal to passed tabId', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ADD_PUBLISHER_TO_LEDGER,
+ location: 'https://brave.com',
+ tabId: testTabId
+ }))
+ assert.equal(testTabId, addNewLocationSpy.getCall(0).args[2])
+ })
+ })
+
+ describe('APP_ON_PUBLISHER_TOGGLE_UPDATE', function () {
+ let pageDataChangedSpy
+
+ beforeEach(function () {
+ pageDataChangedSpy = sinon.spy(fakeLedgerApi, 'pageDataChanged')
+ })
+
+ afterEach(function () {
+ pageDataChangedSpy.restore()
+ })
+
+ it('executes', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_PUBLISHER_TOGGLE_UPDATE,
+ viewData: {
+ location: 'https://brave.com',
+ tabId: 21
+ }
+ }))
+ assert(pageDataChangedSpy.calledTwice)
+ })
+
+ it('modifies state', function () {
+ const newState = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_PUBLISHER_TOGGLE_UPDATE,
+ viewData: {
+ location: 'https://brave.com',
+ tabId: 21
+ }
+ }))
+ assert.notDeepEqual(newState, appState)
+ })
+
+ it('passes in a empty object on first pageDataChanged call', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_PUBLISHER_TOGGLE_UPDATE,
+ viewData: {
+ location: 'https://brave.com',
+ tabId: 21
+ }
+ }))
+ assert.deepEqual({}, pageDataChangedSpy.getCall(0).args[1])
+ })
+
+ it('passes in viewData on second pageDataChanged call', function () {
+ const viewData = {
+ location: 'https://brave.com',
+ tabId: 21
+ }
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_PUBLISHER_TOGGLE_UPDATE,
+ viewData
+ }))
+ assert.deepEqual(viewData, pageDataChangedSpy.getCall(1).args[1])
+ })
+
+ it('keepInfo is set to true for both pageDataChanged calls', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_PUBLISHER_TOGGLE_UPDATE,
+ viewData: {
+ location: 'https://brave.com',
+ tabId: 21
+ }
+ }))
+ assert.equal(true, pageDataChangedSpy.getCall(0).args[2])
+ assert.equal(true, pageDataChangedSpy.getCall(1).args[2])
+ })
+ })
+
+ describe('APP_ON_LEDGER_FUZZING', function () {
+ let newState
+
+ before(() => {
+ newState = appState
+ .setIn(['ledger', 'about', 'status'], ledgerStatuses.FUZZING)
+ })
+
+ it('null case', function () {
+ const result = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_LEDGER_FUZZING
+ }))
+
+ assert.deepEqual(result.toJS(), newState.toJS())
+ })
+
+ it('stamp is string', function () {
+ const result = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_LEDGER_FUZZING,
+ newStamp: 'str'
+ }))
+
+ assert.deepEqual(result.toJS(), newState.toJS())
+ })
+
+ it('stamp is negative', function () {
+ const result = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_LEDGER_FUZZING,
+ newStamp: -10
+ }))
+
+ assert.deepEqual(result.toJS(), newState.toJS())
+ })
+
+ it('stamp is number (string)', function () {
+ const result = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_LEDGER_FUZZING,
+ newStamp: '10'
+ }))
+
+ const expectedState = newState
+ .setIn(['ledger', 'info', 'reconcileStamp'], 10)
+
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+
+ it('reconcile stamp is set', function () {
+ const result = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_LEDGER_FUZZING,
+ newStamp: 10
+ }))
+
+ const expectedState = newState
+ .setIn(['ledger', 'info', 'reconcileStamp'], 10)
+
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('APP_ON_PROMOTION_CLICK', function () {
+ let getCaptchaSpy
+
+ before(function () {
+ getCaptchaSpy = sinon.spy(fakeLedgerApi, 'getCaptcha')
+ })
+
+ afterEach(function () {
+ getCaptchaSpy.reset()
+ })
+
+ after(function () {
+ getCaptchaSpy.restore()
+ })
+
+ it('execute', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_PROMOTION_CLICK
+ }))
+ assert(getCaptchaSpy.calledOnce)
+ })
+ })
+
+ describe('APP_ON_CAPTCHA_RESPONSE', function () {
+ let onCaptchaResponseSpy
+
+ before(function () {
+ onCaptchaResponseSpy = sinon.spy(fakeLedgerApi, 'onCaptchaResponse')
+ })
+
+ afterEach(function () {
+ onCaptchaResponseSpy.reset()
+ })
+
+ after(function () {
+ onCaptchaResponseSpy.restore()
+ })
+
+ it('execute', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_CAPTCHA_RESPONSE,
+ body: 1
+ }))
+ assert(onCaptchaResponseSpy.withArgs(sinon.match.any, 1).calledOnce)
+ })
+ })
+
+ describe('APP_ON_CAPTCHA_CLOSE', function () {
+ it('execute', function () {
+ const result = ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_CAPTCHA_CLOSE
+ }))
+ assert.notDeepEqual(result.toJS(), appState.toJS())
+ })
+ })
+
+ describe('APP_ON_CLEAR_BROWSING_DATA', function () {
+ let resetPublishersSpy, clearPaymentHistorySpy
+
+ before(function () {
+ resetPublishersSpy = sinon.spy(fakeLedgerApi, 'resetPublishers')
+ clearPaymentHistorySpy = sinon.spy(fakeLedgerApi, 'clearPaymentHistory')
+ })
+
+ afterEach(function () {
+ resetPublishersSpy.reset()
+ clearPaymentHistorySpy.reset()
+ })
+
+ after(function () {
+ resetPublishersSpy.restore()
+ clearPaymentHistorySpy.restore()
+ })
+
+ it('only defaults', function () {
+ const state = appState
+ .set('clearBrowsingDataDefaults', Immutable.fromJS({
+ publishersClear: true,
+ paymentHistory: true
+ }))
+
+ ledgerReducer(state, Immutable.fromJS({
+ actionType: appConstants.APP_ON_CLEAR_BROWSING_DATA
+ }))
+
+ assert(clearPaymentHistorySpy.calledOnce)
+ assert(resetPublishersSpy.calledOnce)
+ })
+
+ it('we have some temp data', function () {
+ const state = appState
+ .set('clearBrowsingDataDefaults', Immutable.fromJS({
+ publishersClear: false,
+ paymentHistory: false
+ }))
+ .set('tempClearBrowsingData', Immutable.fromJS({
+ paymentHistory: true
+ }))
+
+ ledgerReducer(state, Immutable.fromJS({
+ actionType: appConstants.APP_ON_CLEAR_BROWSING_DATA
+ }))
+
+ assert(clearPaymentHistorySpy.calledOnce)
+ assert(resetPublishersSpy.notCalled)
+ })
+ })
+
+ describe('APP_ON_WALLET_DELETE', function () {
+ let deleteWalletSpy
+
+ before(function () {
+ deleteWalletSpy = sinon.spy(fakeLedgerApi, 'deleteWallet')
+ })
+
+ afterEach(function () {
+ deleteWalletSpy.reset()
+ })
+
+ after(function () {
+ deleteWalletSpy.restore()
+ })
+
+ it('execute', function () {
+ ledgerReducer(appState, Immutable.fromJS({
+ actionType: appConstants.APP_ON_WALLET_DELETE
+ }))
+ assert(deleteWalletSpy.calledOnce)
+ })
+ })
})
diff --git a/test/unit/app/browser/reducers/passwordManagerReducerTest.js b/test/unit/app/browser/reducers/passwordManagerReducerTest.js
new file mode 100644
index 00000000000..bc2398126dc
--- /dev/null
+++ b/test/unit/app/browser/reducers/passwordManagerReducerTest.js
@@ -0,0 +1,163 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at https://mozilla.org/MPL/2.0/. */
+
+/* global describe, it, before, beforeEach, after */
+const mockery = require('mockery')
+const Immutable = require('immutable')
+const assert = require('assert')
+const sinon = require('sinon')
+const appActions = require('../../../../../js/actions/appActions')
+const appConstants = require('../../../../../js/constants/appConstants')
+const messages = require('../../../../../js/constants/messages')
+const fakeElectron = require('../../../lib/fakeElectron')
+
+describe('passwordManagerReducer unit tests', function () {
+ let passwordManagerReducer
+ let fakeWebContents, fakeWebContentsCache
+ let showNotificationSpy, hideNotificationSpy
+ let neverSavePasswordSpy, savePasswordSpy
+ let spyList = []
+ let savePasswordParams
+
+ let state = Immutable.fromJS({
+ })
+
+ before(function () {
+ mockery.enable({
+ warnOnReplace: false,
+ warnOnUnregistered: false,
+ useCleanCache: true
+ })
+ mockery.registerMock('electron', fakeElectron)
+ mockery.registerMock('../../../js/actions/appActions', appActions)
+ mockery.registerMock('../../locale', {
+ translation: (msg, arg) => {
+ return msg
+ }
+ })
+ fakeWebContents = {
+ destroyed: false,
+ isDestroyed: () => fakeWebContents.destroyed,
+ neverSavePassword: () => { if (fakeWebContents.isDestroyed()) throw new Error('OOPS - neverSavePassword') },
+ savePassword: () => { if (fakeWebContents.isDestroyed()) throw new Error('OOPS - savePassword') },
+ updatePassword: () => { if (fakeWebContents.isDestroyed()) throw new Error('OOPS - updatePassword') },
+ noUpdatePassword: () => { if (fakeWebContents.isDestroyed()) throw new Error('OOPS - noUpdatePassword') }
+ }
+ fakeWebContentsCache = {
+ getWebContents: (tabId) => {
+ if (tabId === 1) {
+ return fakeWebContents
+ }
+ }
+ }
+ spyList.push(neverSavePasswordSpy = sinon.spy(fakeWebContents, 'neverSavePassword'))
+ spyList.push(savePasswordSpy = sinon.spy(fakeWebContents, 'savePassword'))
+ mockery.registerMock('../webContentsCache', fakeWebContentsCache)
+ spyList.push(showNotificationSpy = sinon.spy(appActions, 'showNotification'))
+ spyList.push(hideNotificationSpy = sinon.spy(appActions, 'hideNotification'))
+ passwordManagerReducer = require('../../../../../app/browser/reducers/passwordManagerReducer')
+ state = passwordManagerReducer(state, {
+ actionType: appConstants.APP_SET_STATE
+ })
+
+ savePasswordParams = {
+ actionType: appConstants.APP_SAVE_PASSWORD,
+ username: 'username',
+ origin: 'brave.com',
+ tabId: 1
+ }
+ })
+
+ beforeEach(function () {
+ fakeWebContents.destroyed = false
+ spyList.forEach((spy) => spy.reset())
+ })
+
+ after(function () {
+ spyList.forEach((spy) => spy.restore())
+ spyList = []
+ mockery.deregisterAll()
+ mockery.disable()
+ })
+
+ describe('savePassword', function () {
+ it('does not call showNotification if origin is falsey', function () {
+ passwordManagerReducer(state, {
+ actionType: appConstants.APP_SAVE_PASSWORD,
+ username: 'username',
+ origin: undefined,
+ tabId: 1
+ })
+ assert.equal(showNotificationSpy.notCalled, true)
+ })
+
+ it('shows the notification', function () {
+ passwordManagerReducer(state, savePasswordParams)
+ assert.equal(showNotificationSpy.calledOnce, true)
+ })
+
+ describe('password callbacks', function () {
+ const assertCalled = (spy, buttonIndex, shouldBeCalledOnce) => {
+ passwordManagerReducer(state, savePasswordParams)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, 'notificationPasswordWithUserName', buttonIndex, true)
+ assert.equal((shouldBeCalledOnce ? spy.calledOnce : spy.notCalled), true)
+ }
+ const assertSaveCalled = (buttonIndex, shouldBeCalledOnce) => assertCalled(savePasswordSpy, buttonIndex, shouldBeCalledOnce)
+ const assertNeverSaveCalled = (buttonIndex, shouldBeCalledOnce) => assertCalled(neverSavePasswordSpy, buttonIndex, shouldBeCalledOnce)
+
+ it('hides the notification', function () {
+ passwordManagerReducer(state, savePasswordParams)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, 'notificationPasswordWithUserName', 0, true)
+ assert.equal(hideNotificationSpy.withArgs('notificationPasswordWithUserName').calledOnce, true)
+ })
+ it('removes the entry from passwordCallbacks', function () {
+ passwordManagerReducer(state, savePasswordParams)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, 'notificationPasswordWithUserName', 0, true)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, 'notificationPasswordWithUserName', 0, true)
+ assert.equal(hideNotificationSpy.withArgs('notificationPasswordWithUserName').calledOnce, true)
+ })
+ it('does not throw an exception when webContents is null/undefined', function () {
+ passwordManagerReducer(state, {
+ actionType: appConstants.APP_SAVE_PASSWORD,
+ username: 'username',
+ origin: 'brave.com',
+ tabId: 2
+ })
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, 'notificationPasswordWithUserName', 0, true)
+ })
+ it('does not throw an exception when webContents is destroyed', function () {
+ fakeWebContents.destroyed = true
+ passwordManagerReducer(state, savePasswordParams)
+ fakeElectron.ipcMain.send(messages.NOTIFICATION_RESPONSE, {}, 'notificationPasswordWithUserName', 0, true)
+ })
+
+ describe('when buttonIndex is 0', function () {
+ it('calls webContents.savePassword', function () {
+ assertSaveCalled(0, true)
+ })
+ it('does not call webContents.neverSavePassword', function () {
+ assertNeverSaveCalled(0, false)
+ })
+ })
+
+ describe('when buttonIndex is 1', function () {
+ it('does not call webContents.neverSavePassword', function () {
+ assertNeverSaveCalled(1, false)
+ })
+ it('does not call webContents.savePassword', function () {
+ assertSaveCalled(1, false)
+ })
+ })
+
+ describe('when buttonIndex is 2', function () {
+ it('calls webContents.neverSavePassword', function () {
+ assertNeverSaveCalled(2, true)
+ })
+ it('does not call webContents.savePassword', function () {
+ assertSaveCalled(2, false)
+ })
+ })
+ })
+ })
+})
diff --git a/test/unit/app/browser/reducers/pinnedSitesReducerTest.js b/test/unit/app/browser/reducers/pinnedSitesReducerTest.js
index 89dd49ac93c..b34fba742d5 100644
--- a/test/unit/app/browser/reducers/pinnedSitesReducerTest.js
+++ b/test/unit/app/browser/reducers/pinnedSitesReducerTest.js
@@ -7,8 +7,10 @@ const mockery = require('mockery')
const Immutable = require('immutable')
const assert = require('assert')
const sinon = require('sinon')
-
+const fakeElectron = require('../../../lib/fakeElectron')
+const fakeAdBlock = require('../../../lib/fakeAdBlock')
const appConstants = require('../../../../../js/constants/appConstants')
+
require('../../../braveUnit')
describe('pinnedSitesReducer unit test', function () {
@@ -40,25 +42,54 @@ describe('pinnedSitesReducer unit test', function () {
windowId: 1,
windowUUID: 'uuid',
url: 'https://brave.com/',
- title: 'Brave'
+ title: 'Brave',
+ partitionNumber: 0,
+ pinned: true,
+ index: 0
+ }, {
+ tabId: 2,
+ windowId: 1,
+ windowUUID: 'uuid',
+ url: 'https://petemill.com/',
+ title: 'Brave',
+ partitionNumber: 0,
+ pinned: true,
+ index: 1
+ }, {
+ tabId: 3,
+ windowId: 1,
+ windowUUID: 'uuid',
+ url: 'https://clifton.io/',
+ title: 'Brave',
+ partitionNumber: 0,
+ pinned: true,
+ index: 2
}],
tabsInternal: {
index: {
+ 3: 2,
+ 2: 1,
1: 0
}
},
pinnedSites: {
'https://brave.com/|0': {
location: 'https://brave.com/',
- order: 0,
+ order: 2, // changed to 0
title: 'Brave',
partitionNumber: 0
},
'https://clifton.io/|0': {
location: 'https://clifton.io/',
- order: 1,
+ order: 0, // changed to 1
title: 'Clifton',
partitionNumber: 0
+ },
+ 'https://petemill.com/|0': {
+ location: 'https://petemill.com/',
+ order: 1, // changed to 2
+ title: 'Pete',
+ partitionNumber: 0
}
}
})
@@ -69,6 +100,8 @@ describe('pinnedSitesReducer unit test', function () {
warnOnUnregistered: false,
useCleanCache: true
})
+ mockery.registerMock('electron', fakeElectron)
+ mockery.registerMock('ad-block', fakeAdBlock)
pinnedSitesReducer = require('../../../../../app/browser/reducers/pinnedSitesReducer')
pinnedSitesState = require('../../../../../app/common/state/pinnedSitesState')
})
@@ -151,6 +184,44 @@ describe('pinnedSitesReducer unit test', function () {
assert.equal(spyRemove.calledOnce, true)
assert.deepEqual(newState.toJS(), state.toJS())
})
+
+ it('reorder pinned site', function () {
+ // for this test there are three tabs, in completely different
+ // order than the 'pinned sites' state, but we only learn
+ // about each tab index change one at a time
+ // i.e. tabs are at b:0 p:1 c:2 but pinned state has c:0 p:1 b:2
+ // and we learn about b moving to 0 first, then c moving to 2
+ // first tab
+ const actualFirst = pinnedSitesReducer(stateWithData, {
+ actionType: appConstants.APP_TAB_UPDATED,
+ changeInfo: {
+ index: 1 // irrelevant
+ },
+ tabValue: {
+ tabId: 1 // b
+ }
+ })
+ let expectedFirstState = stateWithData
+ .setIn(['pinnedSites', 'https://clifton.io/|0', 'order'], 1)
+ .setIn(['pinnedSites', 'https://brave.com/|0', 'order'], 0)
+ .setIn(['pinnedSites', 'https://petemill.com/|0', 'order'], 2)
+ assert.deepEqual(actualFirst.toJS(), expectedFirstState.toJS())
+ // second tab (it was swapped with)
+ const actualSecond = pinnedSitesReducer(actualFirst, {
+ actionType: appConstants.APP_TAB_UPDATED,
+ changeInfo: {
+ index: 1 // irrelevant
+ },
+ tabValue: {
+ tabId: 3 // c
+ }
+ })
+ let expectedSecondState = stateWithData
+ .setIn(['pinnedSites', 'https://clifton.io/|0', 'order'], 2)
+ .setIn(['pinnedSites', 'https://brave.com/|0', 'order'], 0)
+ .setIn(['pinnedSites', 'https://petemill.com/|0', 'order'], 1)
+ assert.deepEqual(actualSecond.toJS(), expectedSecondState.toJS())
+ })
})
describe('APP_CREATE_TAB_REQUESTED', function () {
@@ -186,47 +257,4 @@ describe('pinnedSitesReducer unit test', function () {
assert.deepEqual(newState.toJS(), expectedState.toJS())
})
})
-
- describe('APP_ON_PINNED_TAB_REORDER', function () {
- let spy
-
- afterEach(function () {
- spy.restore()
- })
-
- it('null case', function () {
- spy = sinon.spy(pinnedSitesState, 'reOrderSite')
- const newState = pinnedSitesReducer(state, {
- actionType: appConstants.APP_ON_PINNED_TAB_REORDER
- })
- assert.equal(spy.notCalled, true)
- assert.deepEqual(newState.toJS(), state.toJS())
- })
-
- it('check if works', function () {
- spy = sinon.spy(pinnedSitesState, 'reOrderSite')
- const newState = pinnedSitesReducer(stateWithData, {
- actionType: appConstants.APP_ON_PINNED_TAB_REORDER,
- siteKey: 'https://clifton.io/|0',
- destinationKey: 'https://brave.com/|0',
- prepend: true
- })
- const expectedState = state.setIn(['pinnedSites'], Immutable.fromJS({
- 'https://clifton.io/|0': {
- location: 'https://clifton.io/',
- order: 0,
- title: 'Clifton',
- partitionNumber: 0
- },
- 'https://brave.com/|0': {
- location: 'https://brave.com/',
- order: 1,
- title: 'Brave',
- partitionNumber: 0
- }
- }))
- assert.equal(spy.calledOnce, true)
- assert.deepEqual(newState.toJS(), expectedState.toJS())
- })
- })
})
diff --git a/test/unit/app/browser/reducers/siteSettingsReducerTest.js b/test/unit/app/browser/reducers/siteSettingsReducerTest.js
index a590810e991..802eb1485e2 100644
--- a/test/unit/app/browser/reducers/siteSettingsReducerTest.js
+++ b/test/unit/app/browser/reducers/siteSettingsReducerTest.js
@@ -269,6 +269,30 @@ describe('siteSettingsReducer unit tests', function () {
assert.equal(newState.getIn(['siteSettings', 'https://example.com', 'skipSync']), undefined)
})
})
+
+ it('ledger delete flag is cleared', function () {
+ const beforeState = fakeAppState.setIn(['siteSettings'], Immutable.fromJS({
+ 'https://example.com': {
+ ledgerPaymentsShown: false,
+ ledgerPayments: true
+ },
+ 'https://example1.com': {
+ keyNameHere: 'keyValueHere'
+ },
+ 'https://example2.com': {
+ ledgerPayments: true
+ }
+ }))
+ const afterState = siteSettingsReducer(beforeState, Immutable.fromJS({
+ actionType: appConstants.APP_CLEAR_SITE_SETTINGS,
+ key: 'ledgerPaymentsShown'
+ }))
+
+ const expectedState = afterState
+ .setIn(['siteSettings', 'https://example.com'], Immutable.Map())
+
+ assert.deepEqual(afterState.toJS(), expectedState.toJS())
+ })
})
describe('APP_ADD_NOSCRIPT_EXCEPTIONS', function () {
diff --git a/test/unit/app/browser/reducers/tabsReducerTest.js b/test/unit/app/browser/reducers/tabsReducerTest.js
index e61f3303373..5a886f75c4f 100644
--- a/test/unit/app/browser/reducers/tabsReducerTest.js
+++ b/test/unit/app/browser/reducers/tabsReducerTest.js
@@ -20,7 +20,9 @@ describe('tabsReducer unit tests', function () {
useCleanCache: true
})
this.state = Immutable.fromJS({
- settings: [],
+ settings: {
+ 'advanced.webrtc.policy': 'disable_non_proxied_udp'
+ },
tabs: [{
tabId: 1,
index: 0,
@@ -80,12 +82,12 @@ describe('tabsReducer unit tests', function () {
isDevToolsFocused: (tabId) => {
return tabId === 1
},
- setWebRTCIPHandlingPolicy: sinon.mock(),
+ setWebRTCIPHandlingPolicy: sinon.spy(),
toggleDevTools: sinon.mock(),
closeTab: sinon.mock(),
moveTo: sinon.mock(),
reload: sinon.mock(),
- updateTabsStateForWindow: sinon.mock(),
+ updateTabIndexesForWindow: sinon.mock(),
create: sinon.mock(),
forgetTab: sinon.spy()
}
@@ -158,7 +160,9 @@ describe('tabsReducer unit tests', function () {
})
it('updates the setWebRTCIPHandlingPolicy', function () {
- assert(this.tabsAPI.setWebRTCIPHandlingPolicy.calledOnce)
+ assert.deepEqual(this.tabsAPI.setWebRTCIPHandlingPolicy.args, [
+ [1, 'disable_non_proxied_udp']
+ ])
})
})
@@ -259,13 +263,13 @@ describe('tabsReducer unit tests', function () {
afterEach(function () {
this.removeTabByTabIdSpy.restore()
- this.tabsAPI.updateTabsStateForWindow.reset()
+ this.tabsAPI.updateTabIndexesForWindow.reset()
})
it('calls tabState.removeTabByTabId', function () {
tabsReducer(this.state, action)
assert.equal(this.tabStateAPI.removeTabByTabId.getCall(0).args[1], action.tabId)
- assert.equal(this.tabsAPI.updateTabsStateForWindow.getCall(0).args[1], 2)
+ assert.equal(this.tabsAPI.updateTabIndexesForWindow.getCall(0).args[1], 2)
assert(this.tabsAPI.forgetTab.withArgs(5).calledOnce)
})
@@ -592,10 +596,12 @@ describe('tabsReducer unit tests', function () {
assert.equal(args[0], state) // State is passed in as first arg
assert.equal(args[1], 1) // tabId is 1 for first tab
// frameOpts being dragged is for the first tab
- assert.deepEqual(args[2].toJS(), { tabId: 1,
+ assert.deepEqual(args[2].toJS(), {
+ tabId: 1,
windowId: 1,
pinned: false,
- active: true
+ active: true,
+ index: -1 // -1 specifies should go at end of tab strip
})
// Passes browser options for position by mouse cursor
assert.deepEqual(args[3], {
diff --git a/test/unit/app/browser/reducers/windowReducerTest.js b/test/unit/app/browser/reducers/windowReducerTest.js
index a50751484bf..055fa978e30 100644
--- a/test/unit/app/browser/reducers/windowReducerTest.js
+++ b/test/unit/app/browser/reducers/windowReducerTest.js
@@ -13,7 +13,7 @@ const appConstants = require('../../../../../js/constants/appConstants')
require('../../../braveUnit')
describe('windowsReducer unit test', function () {
- let windowsReducer, bookmarkToolbarState
+ let windowsReducer
const fakeElectron = Object.assign({}, require('../../../lib/fakeElectron'))
const fakeWindowState = {
@@ -22,8 +22,7 @@ describe('windowsReducer unit test', function () {
const state = Immutable.fromJS({
windows: [],
- defaultWindowParams: {},
- bookmarks: {}
+ defaultWindowParams: {}
})
before(function () {
@@ -36,7 +35,6 @@ describe('windowsReducer unit test', function () {
mockery.registerMock('ad-block', fakeAdBlock)
mockery.registerMock('../../common/state/windowState', fakeWindowState)
windowsReducer = require('../../../../../app/browser/reducers/windowsReducer')
- bookmarkToolbarState = require('../../../../../app/common/state/bookmarkToolbarState')
})
after(function () {
@@ -44,16 +42,14 @@ describe('windowsReducer unit test', function () {
})
describe('APP_WINDOW_CREATED', function () {
- let spy, spyToolbar
+ let spy
afterEach(function () {
spy.restore()
- spyToolbar.restore()
})
it('check if functions are called', function () {
spy = sinon.spy(fakeWindowState, 'maybeCreateWindow')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbar')
windowsReducer(state, {
actionType: appConstants.APP_WINDOW_CREATED,
windowValue: Immutable.fromJS({
@@ -61,21 +57,18 @@ describe('windowsReducer unit test', function () {
})
})
assert.equal(spy.calledOnce, true)
- assert.equal(spyToolbar.calledOnce, true)
})
})
describe('APP_WINDOW_RESIZED', function () {
- let spy, spyToolbar
+ let spy
afterEach(function () {
spy.restore()
- spyToolbar.restore()
})
it('check if functions are called', function () {
spy = sinon.spy(fakeWindowState, 'maybeCreateWindow')
- spyToolbar = sinon.spy(bookmarkToolbarState, 'setToolbar')
windowsReducer(state, {
actionType: appConstants.APP_WINDOW_RESIZED,
windowValue: Immutable.fromJS({
@@ -83,7 +76,6 @@ describe('windowsReducer unit test', function () {
})
})
assert.equal(spy.calledOnce, true)
- assert.equal(spyToolbar.calledOnce, true)
})
})
})
diff --git a/test/unit/app/browser/tabMessageBoxTest.js b/test/unit/app/browser/tabMessageBoxTest.js
index 17d405c8842..d9b704d71ed 100644
--- a/test/unit/app/browser/tabMessageBoxTest.js
+++ b/test/unit/app/browser/tabMessageBoxTest.js
@@ -38,8 +38,13 @@ describe('tabMessageBox unit tests', function () {
useCleanCache: true
})
+ const fakeLocale = {
+ translation: (token) => { return token }
+ }
+
mockery.registerMock('electron', require('../../lib/fakeElectron'))
mockery.registerMock('../common/state/tabMessageBoxState', fakeMessageBoxState)
+ mockery.registerMock('../../../js/l10n', fakeLocale)
tabMessageBox = require('../../../../app/browser/tabMessageBox')
appActions = require('../../../../js/actions/appActions')
@@ -224,4 +229,47 @@ describe('tabMessageBox unit tests', function () {
})
})
})
+
+ describe('onWindowPrompt', () => {
+ const tabId = '123'
+ const webContents = {
+ getId: () => tabId
+ }
+ const extraData = undefined
+ const title = 'some title'
+ const message = 'some message'
+ const defaultPromptText = 'some prompt text'
+ const shouldDisplaySuppressCheckbox = true
+ const isBeforeUnloadDialog = undefined
+ const isReload = undefined
+ const muonCb = 'muonCb'
+
+ it('calls tabMessageBox.show', () => {
+ const mockShow = sinon.stub()
+ const expectecDetail = {
+ message,
+ title,
+ buttons: ['MESSAGEBOXOK', 'MESSAGEBOXCANCEL'],
+ cancelId: 1,
+ suppress: false,
+ allowInput: true,
+ defaultPromptText,
+ showSuppress: shouldDisplaySuppressCheckbox
+ }
+
+ tabMessageBox.onWindowPrompt(mockShow)(
+ webContents,
+ extraData,
+ title,
+ message,
+ defaultPromptText,
+ shouldDisplaySuppressCheckbox,
+ isBeforeUnloadDialog,
+ isReload,
+ muonCb
+ )
+
+ assert.equal(mockShow.withArgs(tabId, expectecDetail, muonCb).calledOnce, true)
+ })
+ })
})
diff --git a/test/unit/app/browser/tabsTest.js b/test/unit/app/browser/tabsTest.js
index 3eb5c571fb3..4077193a568 100644
--- a/test/unit/app/browser/tabsTest.js
+++ b/test/unit/app/browser/tabsTest.js
@@ -13,7 +13,7 @@ const fakeAdBlock = require('../../lib/fakeAdBlock')
require('../../braveUnit')
describe('tabs API unit tests', function () {
- let tabs, appActions
+ let tabs, appActions, windows
before(function () {
mockery.enable({
warnOnReplace: false,
@@ -80,7 +80,9 @@ describe('tabs API unit tests', function () {
detach: (cb) => cb(),
once: (event, cb) => {
setImmediate(cb)
- }
+ },
+ getZoomPercent: () => 100,
+ isPlaceholder: () => false
}
if (tabId === 1) {
Object.assign(webContents, this.tabWithDevToolsClosed)
@@ -102,8 +104,11 @@ describe('tabs API unit tests', function () {
this.actualActiveTabHistory = require('../../../../app/browser/activeTabHistory')
this.actualWebContentsCache = require('../../../../app/browser/webContentsCache')
this.settings = require('../../../../js/settings')
- tabs = require('../../../../app/browser/tabs')
+
appActions = require('../../../../js/actions/appActions')
+ windows = require('../../../../app/browser/windows')
+ mockery.registerMock('./windows', windows)
+ tabs = require('../../../../app/browser/tabs')
})
after(function () {
@@ -187,12 +192,12 @@ describe('tabs API unit tests', function () {
beforeEach(function () {
this.newWindowSpy = sinon.spy(appActions, 'newWindow')
- this.newWebContentsAddedSpy = sinon.spy(appActions, 'newWebContentsAdded')
+ // this.notifyWindowWebContentsAddedSpy = sinon.spy(windows, 'notifyWindowWebContentsAdded')
})
afterEach(function () {
this.newWindowSpy.restore()
- this.newWebContentsAddedSpy.restore()
+ // this.notifyWindowWebContentsAddedSpy.restore()
})
it('moves tab to a new window', function () {
@@ -212,7 +217,7 @@ describe('tabs API unit tests', function () {
}
tabs.moveTo(state, frameOpts.tabId, frameOpts, this.browserOpts, state.getIn(['dragData', 'dropWindowId']))
assert.equal(this.newWindowSpy.calledOnce, true)
- assert.equal(this.newWebContentsAddedSpy.notCalled, true)
+ // assert.equal(this.notifyWindowWebContentsAddedSpy.notCalled, true)
})
it('moves tab to an existing window', function () {
const state = this.state.set('dragData', Immutable.fromJS({
@@ -231,7 +236,7 @@ describe('tabs API unit tests', function () {
}
tabs.moveTo(state, frameOpts.tabId, frameOpts, this.browserOpts, state.getIn(['dragData', 'dropWindowId']))
assert.equal(this.newWindowSpy.notCalled, true)
- assert.equal(this.newWebContentsAddedSpy.calledOnce, true)
+ // assert.equal(this.notifyWindowWebContentsAddedSpy.calledOnce, true)
})
it('does not move pinned tabs', function () {
const state = this.state.set('dragData', Immutable.fromJS({
@@ -250,7 +255,6 @@ describe('tabs API unit tests', function () {
}
tabs.moveTo(state, frameOpts.tabId, frameOpts, this.browserOpts, state.getIn(['dragData', 'dropWindowId']))
assert.equal(this.newWindowSpy.notCalled, true)
- assert.equal(this.newWebContentsAddedSpy.notCalled, true)
})
it('does not move pinned tabs to alt window', function () {
const state = this.state.set('dragData', Immutable.fromJS({
@@ -269,7 +273,6 @@ describe('tabs API unit tests', function () {
}
tabs.moveTo(state, frameOpts.tabId, frameOpts, this.browserOpts, state.getIn(['dragData', 'dropWindowId']))
assert.equal(this.newWindowSpy.notCalled, true)
- assert.equal(this.newWebContentsAddedSpy.notCalled, true)
})
it('does not move single tab windows into new window', function () {
const state = this.state.set('dragData', Immutable.fromJS({
@@ -288,7 +291,6 @@ describe('tabs API unit tests', function () {
}
tabs.moveTo(state, frameOpts.tabId, frameOpts, this.browserOpts, state.getIn(['dragData', 'dropWindowId']))
assert.equal(this.newWindowSpy.notCalled, true)
- assert.equal(this.newWebContentsAddedSpy.notCalled, true)
})
it('allows combining single tab into alt window', function () {
const state = this.state.set('dragData', Immutable.fromJS({
@@ -307,7 +309,6 @@ describe('tabs API unit tests', function () {
}
tabs.moveTo(state, frameOpts.tabId, frameOpts, this.browserOpts, state.getIn(['dragData', 'dropWindowId']))
assert.equal(this.newWindowSpy.notCalled, true)
- assert.equal(this.newWebContentsAddedSpy.calledOnce, true)
})
})
diff --git a/test/unit/app/cmdLineTest.js b/test/unit/app/cmdLineTest.js
index e99e3fc5c92..2d6ba175598 100644
--- a/test/unit/app/cmdLineTest.js
+++ b/test/unit/app/cmdLineTest.js
@@ -52,6 +52,31 @@ describe('cmdLine', function () {
const result = this.cmdLine.getFirstRunPromoCode(args)
assert.equal(result, promoCode)
})
+
+ it('finds and parses promo code when we have multiple downloads', function () {
+ const promoCode = 'pem001 (1)'
+ const validPromoCodeInstallerPath = `d:\\my\\location\\on-disk\\in-a-folder-tes301\\Setup-Brave-x64-${promoCode}.exe`
+ const args = [...initialArgs, key, validPromoCodeInstallerPath, '--other', 'arg', '--and-another']
+ const result = this.cmdLine.getFirstRunPromoCode(args)
+ assert.equal(result, 'pem001')
+ })
+
+ it('finds and parses promo code 2', function () {
+ const promoCode = 'org-name'
+ const validPromoCodeInstallerPath = `d:\\my\\location\\on-disk\\in-a-folder-tes301\\Setup-Brave-x64-${promoCode}.exe`
+ const args = [...initialArgs, key, validPromoCodeInstallerPath, '--other', 'arg', '--and-another']
+ const result = this.cmdLine.getFirstRunPromoCode(args)
+ assert.equal(result, promoCode)
+ })
+
+ it('finds and parses promo code 2 when we have multiple downloads', function () {
+ const promoCode = 'org-name (1)'
+ const validPromoCodeInstallerPath = `d:\\my\\location\\on-disk\\in-a-folder-tes301\\Setup-Brave-x64-${promoCode}.exe`
+ const args = [...initialArgs, key, validPromoCodeInstallerPath, '--other', 'arg', '--and-another']
+ const result = this.cmdLine.getFirstRunPromoCode(args)
+ assert.equal(result, 'org-name')
+ })
+
it(`does not find promo code when there isn't one`, function () {
const noPromoCodeInstallerPath = `d:\\my\\location\\on-disk\\in-a-folder-tes301\\Setup-Brave-x64.exe`
const args = [...initialArgs, key, noPromoCodeInstallerPath, '--other', 'arg', '--and-another']
diff --git a/test/unit/app/common/cache/ledgerVideoCacheTest.js b/test/unit/app/common/cache/ledgerVideoCacheTest.js
index feadd27153c..71b4cd6907c 100644
--- a/test/unit/app/common/cache/ledgerVideoCacheTest.js
+++ b/test/unit/app/common/cache/ledgerVideoCacheTest.js
@@ -17,6 +17,10 @@ const stateWithData = Immutable.fromJS({
ledgerVideos: {
'youtube_kLiLOkzLetE': {
publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg'
+ },
+ 'twitch_test': {
+ publisher: 'twitch#author:test',
+ time: 1234
}
}
}
@@ -52,9 +56,40 @@ describe('ledgerVideoCache unit test', function () {
const state = ledgerVideoCache.setCacheByVideoId(baseState, 'youtube_kLiLOkzLetE', Immutable.fromJS({
publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg'
}))
- const expectedState = state.setIn(['cache', 'ledgerVideos', 'youtube_kLiLOkzLetE'], Immutable.fromJS({
- publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg'
- }))
+ const expectedState = state
+ .setIn(['cache', 'ledgerVideos', 'youtube_kLiLOkzLetE'], Immutable.fromJS({
+ publisher: 'youtube#channel:UCFNTTISby1c_H-rm5Ww5rZg'
+ }))
+ assert.deepEqual(state.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('mergeCacheByVideoId', function () {
+ it('null case', function () {
+ const state = ledgerVideoCache.mergeCacheByVideoId(baseState)
+ assert.deepEqual(state.toJS(), baseState.toJS())
+ })
+
+ it('old data is missing', function () {
+ const state = ledgerVideoCache.mergeCacheByVideoId(baseState, 'twitch_test', {someData: 'test'})
+ const expectedState = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({someData: 'test'}))
+ assert.deepEqual(state.toJS(), expectedState.toJS())
+ })
+
+ it('new data is null', function () {
+ const state = ledgerVideoCache.mergeCacheByVideoId(stateWithData, 'twitch_test')
+ assert.deepEqual(state.toJS(), stateWithData.toJS())
+ })
+
+ it('old and new data are present', function () {
+ const state = ledgerVideoCache.mergeCacheByVideoId(stateWithData, 'twitch_test', {someData: 'test'})
+ const expectedState = stateWithData
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ publisher: 'twitch#author:test',
+ time: 1234,
+ someData: 'test'
+ }))
assert.deepEqual(state.toJS(), expectedState.toJS())
})
})
diff --git a/test/unit/app/common/lib/bookmarkToolbarUtilTest.js b/test/unit/app/common/lib/bookmarkToolbarUtilTest.js
deleted file mode 100644
index a0750357f1f..00000000000
--- a/test/unit/app/common/lib/bookmarkToolbarUtilTest.js
+++ /dev/null
@@ -1,94 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* global describe, it, before, after */
-const assert = require('assert')
-const mockery = require('mockery')
-const sinon = require('sinon')
-const Immutable = require('immutable')
-const siteTags = require('../../../../../js/constants/siteTags')
-
-require('../../../braveUnit')
-
-describe('bookmarkToolbarUtil unit test', function () {
- let bookmarkToolbarUtil, bookmarkUtil
-
- const generateBookmarks = (num) => {
- return Immutable.fromJS(new Array(num).fill().map((_, i) => {
- return {
- type: siteTags.BOOKMARK,
- title: `Bookmark ${i}`,
- key: `bookmark-${i}|0|0`,
- width: 10 * i
- }
- }))
- }
-
- const generateBookmarksKeys = (num, skip = 0) => {
- return Immutable.fromJS(new Array(num).fill().map((_, i) => {
- const id = skip + i
- return `bookmark-${id}|0|0`
- }))
- }
-
- before(function () {
- mockery.enable({
- warnOnReplace: false,
- warnOnUnregistered: false,
- useCleanCache: true
- })
- bookmarkToolbarUtil = require('../../../../../app/common/lib/bookmarkToolbarUtil')
- bookmarkUtil = require('../../../../../app/common/lib/bookmarkUtil')
- })
-
- after(function () {
- mockery.disable()
- })
-
- describe('getToolbarBookmarks', function () {
- let showOnlyText
-
- before(function () {
- showOnlyText = sinon.stub(bookmarkUtil, 'showOnlyText', () => true)
- })
-
- after(function () {
- showOnlyText.restore()
- })
-
- it('null scenario', function () {
- assert.deepEqual(bookmarkToolbarUtil.getBookmarkKeys(), {
- toolbar: Immutable.List(),
- other: Immutable.List()
- })
- })
-
- it('we only have bookmark for the toolbar', function () {
- const bookmarks = generateBookmarks(5)
-
- assert.deepEqual(bookmarkToolbarUtil.getBookmarkKeys(500, bookmarks), {
- toolbar: generateBookmarksKeys(5),
- other: Immutable.List()
- })
- })
-
- it('we have bookmarks for toolbar and other', function () {
- const bookmarks = generateBookmarks(50)
-
- assert.deepEqual(bookmarkToolbarUtil.getBookmarkKeys(500, bookmarks), {
- toolbar: generateBookmarksKeys(8),
- other: generateBookmarksKeys(42, 8)
- })
- })
-
- it('other limit is set to 100', function () {
- const bookmarks = generateBookmarks(500)
-
- assert.deepEqual(bookmarkToolbarUtil.getBookmarkKeys(500, bookmarks), {
- toolbar: generateBookmarksKeys(8),
- other: generateBookmarksKeys(100, 8)
- })
- })
- })
-})
diff --git a/test/unit/app/common/lib/bookmarkUtilTest.js b/test/unit/app/common/lib/bookmarkUtilTest.js
index f5fde0be313..b38860836a8 100644
--- a/test/unit/app/common/lib/bookmarkUtilTest.js
+++ b/test/unit/app/common/lib/bookmarkUtilTest.js
@@ -9,8 +9,11 @@ const Immutable = require('immutable')
const {makeImmutable} = require('../../../../../app/common/state/immutableUtil')
const {bookmarksToolbarMode} = require('../../../../../app/common/constants/settingsEnums')
const dragTypes = require('../../../../../js/constants/dragTypes')
+const appActions = require('../../../../../js/actions/appActions')
+const settingsConstants = require('../../../../../js/constants/settings')
const siteTags = require('../../../../../js/constants/siteTags')
const tabState = require('../../../../../app/common/state/tabState')
+const bookmarksState = require('../../../../../app/common/state/bookmarksState')
const sinon = require('sinon')
require('../../../braveUnit')
@@ -121,6 +124,8 @@ describe('bookmarkUtil unit test', function () {
useCleanCache: true
})
mockery.registerMock('../state/tabState', tabState)
+ mockery.registerMock('../../../js/actions/appActions', appActions)
+ // kind of a sloppy hack; set `settingDefaultValue` to value you'd like returned
mockery.registerMock('../../../js/settings', {
getSetting: () => {
return settingDefaultValue
@@ -171,20 +176,6 @@ describe('bookmarkUtil unit test', function () {
})
})
- describe('showOnlyFavicon', function () {
- it('BOOKMARKS_TOOLBAR_MODE is FAVICONS_ONLY', function () {
- settingDefaultValue = bookmarksToolbarMode.FAVICONS_ONLY
- const result = bookmarkUtil.showOnlyFavicon()
- assert.equal(result, true)
- })
-
- it('BOOKMARKS_TOOLBAR_MODE is not FAVICONS_ONLY', function () {
- settingDefaultValue = bookmarksToolbarMode.TEXT_ONLY
- const result = bookmarkUtil.showOnlyFavicon()
- assert.equal(result, false)
- })
- })
-
describe('showFavicon', function () {
it('BOOKMARKS_TOOLBAR_MODE is FAVICONS_ONLY', function () {
settingDefaultValue = bookmarksToolbarMode.FAVICONS_ONLY
@@ -205,34 +196,6 @@ describe('bookmarkUtil unit test', function () {
})
})
- describe('showOnlyText', function () {
- it('BOOKMARKS_TOOLBAR_MODE is TEXT_ONLY', function () {
- settingDefaultValue = bookmarksToolbarMode.TEXT_ONLY
- const result = bookmarkUtil.showOnlyText()
- assert.equal(result, true)
- })
-
- it('BOOKMARKS_TOOLBAR_MODE is not TEXT_ONLY', function () {
- settingDefaultValue = bookmarksToolbarMode.FAVICONS_ONLY
- const result = bookmarkUtil.showOnlyText()
- assert.equal(result, false)
- })
- })
-
- describe('showTextAndFavicon', function () {
- it('BOOKMARKS_TOOLBAR_MODE is TEXT_AND_FAVICONS', function () {
- settingDefaultValue = bookmarksToolbarMode.TEXT_AND_FAVICONS
- const result = bookmarkUtil.showTextAndFavicon()
- assert.equal(result, true)
- })
-
- it('BOOKMARKS_TOOLBAR_MODE is not TEXT_AND_FAVICONS', function () {
- settingDefaultValue = bookmarksToolbarMode.TEXT_ONLY
- const result = bookmarkUtil.showTextAndFavicon()
- assert.equal(result, false)
- })
- })
-
describe('getDNDBookmarkData', function () {
it('dragOverData is missing', function () {
const state = makeImmutable({
@@ -497,8 +460,7 @@ describe('bookmarkUtil unit test', function () {
themeColor: undefined,
type: siteTags.BOOKMARK,
key: 'https://brave.com|0|0',
- skipSync: null,
- width: 0
+ skipSync: null
}
assert.deepEqual(bookmarkUtil.buildBookmark(state, bookmark).toJS(), expectedResult)
@@ -527,8 +489,7 @@ describe('bookmarkUtil unit test', function () {
themeColor: '#000',
type: siteTags.BOOKMARK,
key: 'https://brave.com|0|0',
- skipSync: null,
- width: 0
+ skipSync: null
}
assert.deepEqual(bookmarkUtil.buildBookmark(newState, bookmark).toJS(), expectedResult)
@@ -550,8 +511,7 @@ describe('bookmarkUtil unit test', function () {
themeColor: '#FFF',
type: siteTags.BOOKMARK,
key: 'https://brave.com/|0|0',
- skipSync: null,
- width: 0
+ skipSync: null
}
assert.deepEqual(bookmarkUtil.buildBookmark(stateWithData, bookmark).toJS(), expectedResult)
@@ -559,22 +519,21 @@ describe('bookmarkUtil unit test', function () {
it('bookmark data is in topSites', function () {
const bookmark = Immutable.fromJS({
- title: 'Brave',
- location: 'https://www.facebook.com/BraveSoftware/'
+ title: 'Brave Software | GitHub',
+ location: 'https://github.com/brave/'
})
const expectedResult = {
- title: 'Brave',
- location: 'https://www.facebook.com/BraveSoftware/',
+ title: 'Brave Software | GitHub',
+ location: 'https://github.com/brave/',
parentFolderId: 0,
partitionNumber: 0,
objectId: null,
- favicon: 'chrome-extension://mnojpmjdmbbfmejpflffifhffcmidifd/img/newtab/defaultTopSitesIcon/facebook.png',
- themeColor: 'rgb(59, 89, 152)',
+ favicon: 'chrome-extension://mnojpmjdmbbfmejpflffifhffcmidifd/img/newtab/defaultTopSitesIcon/github.png',
+ themeColor: 'rgb(255, 255, 255)',
type: siteTags.BOOKMARK,
- key: 'https://www.facebook.com/BraveSoftware/|0|0',
- skipSync: null,
- width: 0
+ key: 'https://github.com/brave/|0|0',
+ skipSync: null
}
assert.deepEqual(bookmarkUtil.buildBookmark(stateWithData, bookmark).toJS(), expectedResult)
@@ -629,4 +588,49 @@ describe('bookmarkUtil unit test', function () {
assert.deepEqual(bookmarkUtil.buildEditBookmark(oldBookmark, newBookmark).toJS(), expectedBookmark.toJS())
})
})
+
+ describe('closeToolbarIfEmpty', function () {
+ let onChangeSettingSpy
+
+ const removeAllBookmarks = (stateWithBookmarks) => {
+ let newState = stateWithBookmarks
+ for (const bookmarkKey of stateWithBookmarks.get('bookmarks').keys()) {
+ newState = bookmarksState.removeBookmark(newState, bookmarkKey)
+ }
+ return newState
+ }
+
+ beforeEach(function () {
+ onChangeSettingSpy = sinon.spy(appActions, 'changeSetting')
+ settingDefaultValue = true
+ })
+
+ afterEach(function () {
+ onChangeSettingSpy.restore()
+ })
+
+ describe('when SHOW_BOOKMARKS_TOOLBAR is false', function () {
+ beforeEach(function () {
+ settingDefaultValue = false
+ })
+
+ it('does not call appActions.changeSetting if bookmarks toolbar is hidden', function () {
+ let newState = removeAllBookmarks(stateWithData)
+ bookmarkUtil.closeToolbarIfEmpty(newState)
+ assert.equal(onChangeSettingSpy.notCalled, true)
+ })
+ })
+
+ it('does not hide bookmarks toolbar if bookmarks still exist', function () {
+ let newState = bookmarksState.removeBookmark(stateWithData, 'https://brave.com/|0|0')
+ bookmarkUtil.closeToolbarIfEmpty(newState)
+ assert.equal(onChangeSettingSpy.notCalled, true)
+ })
+
+ it('hides bookmarks toolbar when all toolbar bookmarks are removed', function () {
+ let newState = removeAllBookmarks(stateWithData)
+ bookmarkUtil.closeToolbarIfEmpty(newState)
+ assert.ok(onChangeSettingSpy.calledWith(settingsConstants.SHOW_BOOKMARKS_TOOLBAR, false))
+ })
+ })
})
diff --git a/test/unit/app/common/lib/historyUtilTest.js b/test/unit/app/common/lib/historyUtilTest.js
index 646b9c90d24..e1b5855187e 100644
--- a/test/unit/app/common/lib/historyUtilTest.js
+++ b/test/unit/app/common/lib/historyUtilTest.js
@@ -297,7 +297,13 @@ describe('historyUtil unit tests', function () {
describe('getDetailFromFrame', function () {
it('null case', function () {
const result = historyUtil.getDetailFromFrame()
- assert.deepEqual(result, Immutable.Map())
+ assert.deepEqual(result, null)
+ })
+
+ it('no location case', function () {
+ const badFrame = Immutable.Map().set('partitionNumber', 0)
+ const result = historyUtil.getDetailFromFrame(badFrame)
+ assert.deepEqual(result, null)
})
it('returns details', function () {
@@ -308,7 +314,6 @@ describe('historyUtil unit tests', function () {
isFullScreen: false,
isPrivate: false,
key: 1,
- lastZoomPercentage: 1,
loading: true,
location: 'https://brave.com',
title: 'Brave'
diff --git a/test/unit/app/common/lib/ledgerUtilTest.js b/test/unit/app/common/lib/ledgerUtilTest.js
index 8adfd00266d..e1a332fbe74 100644
--- a/test/unit/app/common/lib/ledgerUtilTest.js
+++ b/test/unit/app/common/lib/ledgerUtilTest.js
@@ -5,6 +5,29 @@ const Immutable = require('immutable')
require('../../../braveUnit')
const settings = require('../../../../../js/constants/settings')
const ledgerMediaProviders = require('../../../../../app/common/constants/ledgerMediaProviders')
+const twitchEvents = require('../../../../../app/common/constants/twitchEvents')
+const urlUtil = require('../../../../../js/lib/urlutil')
+const ledgerStatuses = require('../../../../../app/common/constants/ledgerStatuses')
+
+const defaultState = Immutable.fromJS({
+ ledger: {}
+})
+const baseState = Immutable.fromJS({
+ cache: {
+ ledgerVideos: {}
+ }
+})
+const stateWithData = Immutable.fromJS({
+ cache: {
+ ledgerVideos: {
+ 'twitch_test': {
+ publisher: 'twitch#author:test',
+ event: twitchEvents.START,
+ time: 1519279886
+ }
+ }
+ }
+})
describe('ledgerUtil unit test', function () {
let ledgerUtil
@@ -13,6 +36,8 @@ describe('ledgerUtil unit test', function () {
const fakeAdBlock = require('../../../lib/fakeAdBlock')
// settings
+ let paymentsMinVisits
+ let paymentsMinVisitTime
let paymentsContributionAmount = 25
before(function () {
@@ -28,10 +53,16 @@ describe('ledgerUtil unit test', function () {
mockery.registerMock('electron', fakeElectron)
mockery.registerMock('ad-block', fakeAdBlock)
mockery.registerMock('level', fakeLevel)
+ mockery.registerMock('../../../img/mediaProviders/youtube.png', 'youtube.png')
+ mockery.registerMock('../../../img/mediaProviders/twitch.svg', 'twitch.svg')
mockery.registerMock('../../../js/settings', {
getSetting: (settingKey) => {
switch (settingKey) {
+ case settings.PAYMENTS_MINIMUM_VISITS:
+ return paymentsMinVisits
+ case settings.PAYMENTS_MINIMUM_VISIT_TIME:
+ return paymentsMinVisitTime
case settings.PAYMENTS_CONTRIBUTION_AMOUNT:
return paymentsContributionAmount
}
@@ -192,12 +223,12 @@ describe('ledgerUtil unit test', function () {
it('defaults to 0 as balance when rate is not present', function () {
const data = ledgerData.delete('rates')
- const result = ledgerUtil.formatCurrentBalance(data)
+ const result = ledgerUtil.formatCurrentBalance(data, ledgerData.get('balance'))
assert.equal(result, '5.00 BAT')
})
it('formats `balance` and `converted` values to two decimal places', function () {
- const result = ledgerUtil.formatCurrentBalance(ledgerData)
+ const result = ledgerUtil.formatCurrentBalance(ledgerData, ledgerData.get('balance'))
assert.equal(result, '5.00 BAT (1.12 USD)')
})
@@ -207,23 +238,28 @@ describe('ledgerUtil unit test', function () {
})
it('defaults `converted` to 0 if not found', function () {
- const result = ledgerUtil.formatCurrentBalance(ledgerData.delete('converted'))
+ const result = ledgerUtil.formatCurrentBalance(ledgerData.delete('converted'), ledgerData.get('balance'))
assert.equal(result, '5.00 BAT (0.00 USD)')
})
it('handles `balance` being a string', function () {
- const result = ledgerUtil.formatCurrentBalance(ledgerData.set('balance', '5'))
+ const result = ledgerUtil.formatCurrentBalance(ledgerData, 5)
assert.equal(result, '5.00 BAT (1.12 USD)')
})
it('handles `converted` being a string', function () {
- const result = ledgerUtil.formatCurrentBalance(ledgerData.set('converted', '1.1234'))
+ const result = ledgerUtil.formatCurrentBalance(ledgerData.set('converted', '1.1234'), ledgerData.get('balance'))
assert.equal(result, '5.00 BAT (1.12 USD)')
})
it('custom format for amount lower then 0.01', function () {
- const result = ledgerUtil.formatCurrentBalance(ledgerData.set('converted', '0.004'))
- assert.equal(result, '5.00 BAT (<.01 USD)')
+ const result = ledgerUtil.formatCurrentBalance(ledgerData.set('converted', '0.004'), ledgerData.get('balance'))
+ assert.equal(result, '5.00 BAT (< 0.01 USD)')
+ })
+
+ it('formats only `balance` when alt is excluded', function () {
+ const result = ledgerUtil.formatCurrentBalance(ledgerData, ledgerData.get('balance'), false)
+ assert.equal(result, '5.00 BAT')
})
})
@@ -235,12 +271,21 @@ describe('ledgerUtil unit test', function () {
describe('walletStatus', function () {
it('null case', function () {
- const result = ledgerUtil.walletStatus()
+ const result = ledgerUtil.walletStatus(Immutable.Map())
assert.deepEqual(result, {
id: 'createWalletStatus'
})
})
+ it('on fuzzing', function () {
+ const result = ledgerUtil.walletStatus(Immutable.fromJS({
+ status: ledgerStatuses.FUZZING
+ }))
+ assert.deepEqual(result, {
+ id: 'ledgerFuzzed'
+ })
+ })
+
it('on error', function () {
const state = Immutable.fromJS({
error: {
@@ -373,6 +418,77 @@ describe('ledgerUtil unit test', function () {
})
})
+ describe('shouldShowMenuOption', function () {
+ let ledgerState
+
+ before(function () {
+ ledgerState = Immutable.fromJS({
+ ledger: {},
+ siteSettings: {}
+ })
+ })
+
+ it('null location', function () {
+ const result = ledgerUtil.shouldShowMenuOption(ledgerState, null)
+ assert.equal(result, false)
+ })
+
+ it('false when location is an invalid url', function () {
+ const result = ledgerUtil.shouldShowMenuOption(ledgerState, 'brave')
+ assert.equal(result, false)
+ })
+
+ it('false if url contains a bad domain', function () {
+ const result = ledgerUtil.shouldShowMenuOption(ledgerState, 'https://foobar.bananas')
+ assert.equal(result, false)
+ })
+
+ it('false if a publisher key can not be deduced', function () {
+ const result = ledgerUtil.shouldShowMenuOption(ledgerState, 'bravecom/about')
+ assert.equal(result, false)
+ })
+
+ it('false when the publisher has been deleted from the ledger', function () {
+ const publisherKey = 'brave.com'
+ const hostPattern = urlUtil.getHostPattern(publisherKey)
+ const modifiedState = ledgerState
+ .setIn(['siteSettings', hostPattern, 'ledgerPaymentsShown'], false)
+ const result = ledgerUtil.shouldShowMenuOption(modifiedState, 'https://brave.com')
+ assert.equal(result, false)
+ })
+
+ it('true if the publisher has not been deleted from the ledger', function () {
+ const publisherKey = 'foo.com'
+ const hostPattern = urlUtil.getHostPattern(publisherKey)
+ const modifiedState = ledgerState
+ .setIn(['siteSettings', hostPattern, 'ledgerPaymentsShown'], false)
+ const result = ledgerUtil.shouldShowMenuOption(modifiedState, 'https://brave.com')
+ assert.equal(result, true)
+ })
+
+ it('true when location has protocol and is a valid url', function () {
+ const result = ledgerUtil.shouldShowMenuOption(ledgerState, 'https://brave.com')
+ assert.equal(result, true)
+ })
+
+ it('true when location has protocol and is a valid url', function () {
+ const result = ledgerUtil.shouldShowMenuOption(ledgerState, 'http://www.brave.com')
+ assert.equal(result, true)
+ })
+
+ it('true when location is valid and is not present in the ledger', function () {
+ const stateWithLocations = Immutable.fromJS({
+ ledger: {
+ locations: [
+ 'ebay.com'
+ ]
+ }
+ })
+ const result = ledgerUtil.shouldShowMenuOption(stateWithLocations, 'https://brave.com')
+ assert.equal(result, true)
+ })
+ })
+
describe('getMediaId', function () {
it('null case', function () {
const result = ledgerUtil.getMediaId()
@@ -380,7 +496,7 @@ describe('ledgerUtil unit test', function () {
})
it('unknown type', function () {
- const result = ledgerUtil.getMediaData({}, 'test')
+ const result = ledgerUtil.getMediaId({}, 'test')
assert.equal(result, null)
})
@@ -395,6 +511,48 @@ describe('ledgerUtil unit test', function () {
assert.equal(result, 'kLiLOkzLetE')
})
})
+
+ describe('Twitch', function () {
+ it('null case', function () {
+ const result = ledgerUtil.getMediaId(null, ledgerMediaProviders.TWITCH)
+ assert.equal(result, null)
+ })
+
+ it('event is not correct', function () {
+ const result = ledgerUtil.getMediaId({
+ event: 'wrong'
+ }, ledgerMediaProviders.TWITCH)
+ assert.equal(result, null)
+ })
+
+ it('properties are missing', function () {
+ const result = ledgerUtil.getMediaId({
+ event: twitchEvents.MINUTE_WATCHED
+ }, ledgerMediaProviders.TWITCH)
+ assert.equal(result, null)
+ })
+
+ it('content is a live stream', function () {
+ const result = ledgerUtil.getMediaId({
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ channel: 'tchannel'
+ }
+ }, ledgerMediaProviders.TWITCH)
+ assert.equal(result, 'tchannel')
+ })
+
+ it('content is a vod', function () {
+ const result = ledgerUtil.getMediaId({
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ channel: 'tchannel',
+ vod: 'v12343234'
+ }
+ }, ledgerMediaProviders.TWITCH)
+ assert.equal(result, 'tchannel_vod_12343234')
+ })
+ })
})
describe('getMediaKey', function () {
@@ -408,14 +566,16 @@ describe('ledgerUtil unit test', function () {
assert.equal(result, null)
})
- it('id is null', function () {
- const result = ledgerUtil.getMediaKey(null, ledgerMediaProviders.YOUTUBE)
- assert.equal(result, null)
- })
+ describe('YouTube', function () {
+ it('id is null', function () {
+ const result = ledgerUtil.getMediaKey(null, ledgerMediaProviders.YOUTUBE)
+ assert.equal(result, null)
+ })
- it('data is ok', function () {
- const result = ledgerUtil.getMediaKey('kLiLOkzLetE', ledgerMediaProviders.YOUTUBE)
- assert.equal(result, 'youtube_kLiLOkzLetE')
+ it('data is ok', function () {
+ const result = ledgerUtil.getMediaKey('kLiLOkzLetE', ledgerMediaProviders.YOUTUBE)
+ assert.equal(result, 'youtube_kLiLOkzLetE')
+ })
})
})
@@ -430,17 +590,17 @@ describe('ledgerUtil unit test', function () {
assert.equal(result, null)
})
+ it('query is not present', function () {
+ const result = ledgerUtil.getMediaData('https://youtube.com', ledgerMediaProviders.YOUTUBE)
+ assert.equal(result, null)
+ })
+
describe('Youtube', function () {
it('null case', function () {
const result = ledgerUtil.getMediaData(null, ledgerMediaProviders.YOUTUBE)
assert.equal(result, null)
})
- it('query is not present', function () {
- const result = ledgerUtil.getMediaData('https://youtube.com', ledgerMediaProviders.YOUTUBE)
- assert.equal(result, null)
- })
-
it('query is present', function () {
const result = ledgerUtil.getMediaData('https://www.youtube.com/api/stats/watchtime?docid=kLiLOkzLetE&st=11.338&et=21.339', ledgerMediaProviders.YOUTUBE)
assert.deepEqual(result, {
@@ -450,6 +610,133 @@ describe('ledgerUtil unit test', function () {
})
})
})
+
+ describe('Twitch', function () {
+ const url = 'https://video-edge-f0f586.sjc01.hls.ttvnw.net/v1/segment/CuDNI7xCy5CGJ8g7G3thdHT26OW_DhnEuVw0tRGN-DKhJxrRTeGe...'
+
+ it('null case', function () {
+ const result = ledgerUtil.getMediaData(null, ledgerMediaProviders.TWITCH)
+ assert.equal(result, null)
+ })
+
+ it('uploadData is missing', function () {
+ const result = ledgerUtil.getMediaData(url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348'
+ }))
+ assert.equal(result, null)
+ })
+
+ it('bytes is missing', function () {
+ const result = ledgerUtil.getMediaData(url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: []
+ }))
+ assert.equal(result, null)
+ })
+
+ it('data is missing', function () {
+ const result = ledgerUtil.getMediaData(url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [{
+ bytes: new Uint8Array([116, 101, 115, 116])
+ }]
+ }))
+ assert.equal(result, null)
+ })
+
+ it('data is empty string', function () {
+ const result = ledgerUtil.getMediaData(url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [{
+ bytes: new Uint8Array([100, 97, 116, 97, 61])
+ }]
+ }))
+ assert.equal(result, null)
+ })
+
+ it('single event is parsed correctly', function () {
+ const result = ledgerUtil.getMediaData(url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [{
+ bytes: new Uint8Array([
+ 100, 97, 116, 97, 61, 87, 51, 115, 105, 90, 88, 90, 108, 98, 110, 81, 105, 79, 105,
+ 74, 116, 97, 87, 53, 49, 100, 71, 85, 116, 100, 50, 70, 48, 89, 50, 104, 108, 90, 67, 73, 115, 73, 110,
+ 66, 121, 98, 51, 66, 108, 99, 110, 82, 112, 90, 88, 77, 105, 79, 110, 115, 105, 89, 50, 104, 104, 98,
+ 109, 53, 108, 98, 67, 73, 54, 73, 110, 82, 51, 73, 110, 49, 57, 88, 81, 61, 61
+ ])
+ }]
+ }))
+ assert.deepEqual(result, [{
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ channel: 'tw'
+ }
+ }])
+ })
+
+ it('multiple events are parsed correctly', function () {
+ const result = ledgerUtil.getMediaData(url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [{
+ bytes: new Uint8Array([
+ 100, 97, 116, 97, 61, 87, 51, 115, 105, 90, 88, 90, 108, 98, 110, 81, 105, 79, 105,
+ 74, 50, 97, 87, 82, 108, 98, 121, 49, 119, 98, 71, 70, 53, 73, 105, 119, 105, 99, 72, 74, 118, 99, 71,
+ 86, 121, 100, 71, 108, 108, 99, 121, 73, 54, 101, 121, 74, 106, 97, 71, 70, 117, 98, 109, 86, 115, 73,
+ 106, 111, 105, 100, 72, 99, 105, 102, 88, 48, 115, 101, 121, 74, 108, 100, 109, 86, 117, 100, 67, 73, 54,
+ 73, 110, 90, 112, 90, 71, 86, 118, 88, 50, 86, 121, 99, 109, 57, 121, 73, 105, 119, 105, 99, 72, 74, 118,
+ 99, 71, 86, 121, 100, 71, 108, 108, 99, 121, 73, 54, 101, 121, 74, 106, 97, 71, 70, 117, 98, 109, 86,
+ 115, 73, 106, 111, 105, 100, 72, 99, 105, 102, 88, 49, 100
+ ])
+ }]
+ }))
+ assert.deepEqual(result, [{
+ event: twitchEvents.START,
+ properties: {
+ channel: 'tw'
+ }
+ }, {
+ event: twitchEvents.VIDEO_ERROR,
+ properties: {
+ channel: 'tw'
+ }
+ }])
+ })
+
+ it('multiple upload data', function () {
+ const result = ledgerUtil.getMediaData(url, ledgerMediaProviders.TWITCH, Immutable.fromJS({
+ firstPartyUrl: 'https://www.twitch.tv/videos/241926348',
+ uploadData: [
+ {
+ bytes: new Uint8Array([
+ 100, 97, 116, 97, 61, 87, 51, 115, 105, 90, 88, 90, 108, 98, 110, 81, 105, 79, 105, 74, 50, 97, 87,
+ 82, 108, 98, 121, 49, 119, 98, 71, 70, 53, 73, 105, 119, 105, 99
+ ])
+ },
+ {
+ bytes: new Uint8Array([
+ 72, 74, 118, 99, 71, 86, 121, 100, 71, 108, 108, 99, 121, 73, 54, 101, 121, 74,
+ 106, 97, 71, 70, 117, 98, 109, 86, 115, 73, 106, 111, 105, 100, 72, 99, 105, 102, 88, 48, 115, 101,
+ 121, 74, 108, 100, 109, 86, 117, 100, 67, 73, 54, 73, 110, 90, 112, 90, 71, 86, 118, 88, 50, 86, 121,
+ 99, 109, 57, 121, 73, 105, 119, 105, 99, 72, 74, 118, 99, 71, 86, 121, 100, 71, 108, 108, 99, 121,
+ 73, 54, 101, 121, 74, 106, 97, 71, 70, 117, 98, 109, 86, 115, 73, 106, 111, 105, 100, 72, 99, 105,
+ 102, 88, 49, 100
+ ])
+ }
+ ]
+ }))
+ assert.deepEqual(result, [{
+ event: twitchEvents.START,
+ properties: {
+ channel: 'tw'
+ }
+ }, {
+ event: twitchEvents.VIDEO_ERROR,
+ properties: {
+ channel: 'tw'
+ }
+ }])
+ })
+ })
})
describe('getYouTubeDuration', function () {
@@ -490,6 +777,30 @@ describe('ledgerUtil unit test', function () {
const result = ledgerUtil.getMediaProvider('https://www.youtube.com/api/stats/watchtime?docid=kLiLOkzLetE&st=11.338&et=21.339')
assert.equal(result, ledgerMediaProviders.YOUTUBE)
})
+
+ describe('twitch', function () {
+ it('we only have url', function () {
+ const result = ledgerUtil.getMediaProvider('https://ttvnw.net/v1/segment/sdfsdfsdfdsf')
+ assert.equal(result, null)
+ })
+
+ it('video is on twitch.tv', function () {
+ const result = ledgerUtil.getMediaProvider(
+ 'https://ttvnw.net/v1/segment/sdfsdfsdfdsf',
+ 'https://www.twitch.tv/'
+ )
+ assert.equal(result, ledgerMediaProviders.TWITCH)
+ })
+
+ it('video is embeded', function () {
+ const result = ledgerUtil.getMediaProvider(
+ 'https://ttvnw.net/v1/segment/sdfsdfsdfdsf',
+ 'https://www.site.tv/',
+ 'https://player.twitch.tv/'
+ )
+ assert.equal(result, ledgerMediaProviders.TWITCH)
+ })
+ })
})
describe('milliseconds', function () {
@@ -529,4 +840,400 @@ describe('ledgerUtil unit test', function () {
assert.deepEqual(ledgerUtil.defaultMonthlyAmounts.toJS(), [5.0, 7.5, 10.0, 17.5, 25.0, 50.0, 75.0, 100.0])
})
})
+
+ describe('getDefaultMediaFavicon', function () {
+ it('null case', function () {
+ const result = ledgerUtil.getDefaultMediaFavicon()
+ assert.equal(result, null)
+ })
+
+ it('youtube', function () {
+ const result = ledgerUtil.getDefaultMediaFavicon('YouTube')
+ assert.equal(result, 'youtube.png')
+ })
+
+ it('twitch', function () {
+ const result = ledgerUtil.getDefaultMediaFavicon('Twitch')
+ assert.equal(result, 'twitch.svg')
+ })
+ })
+
+ describe('generateTwitchCacheData', function () {
+ it('null check', function () {
+ const result = ledgerUtil.generateTwitchCacheData()
+ assert.deepEqual(result.toJS(), {})
+ })
+
+ it('properties are missing', function () {
+ const result = ledgerUtil.generateTwitchCacheData(baseState, {
+ event: twitchEvents.START,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.START,
+ status: 'playing'
+ })
+ })
+
+ it('properties are present', function () {
+ const result = ledgerUtil.generateTwitchCacheData(baseState, {
+ event: twitchEvents.START,
+ properties: {
+ time: 100,
+ minute_logged: 1
+ },
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.START,
+ time: 100,
+ status: 'playing'
+ })
+ })
+
+ describe('user actions: ', function () {
+ it('start -> pause', function () {
+ const state = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ event: twitchEvents.START,
+ status: 'playing'
+ }))
+
+ const result = ledgerUtil.generateTwitchCacheData(state, {
+ event: twitchEvents.PLAY_PAUSE,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'paused'
+ })
+ })
+
+ it('start -> seek', function () {
+ const state = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ event: twitchEvents.START,
+ status: 'playing'
+ }))
+
+ const result = ledgerUtil.generateTwitchCacheData(state, {
+ event: twitchEvents.SEEK,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.SEEK,
+ status: 'playing'
+ })
+ })
+
+ it('play -> pause -> play', function () {
+ const state = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'paused'
+ }))
+
+ const result = ledgerUtil.generateTwitchCacheData(state, {
+ event: twitchEvents.PLAY_PAUSE,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'playing'
+ })
+ })
+
+ it('pause -> play -> pause', function () {
+ const state = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'playing'
+ }))
+
+ const result = ledgerUtil.generateTwitchCacheData(state, {
+ event: twitchEvents.PLAY_PAUSE,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'paused'
+ })
+ })
+
+ it('play -> pause -> seek', function () {
+ const state = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'paused'
+ }))
+
+ const result = ledgerUtil.generateTwitchCacheData(state, {
+ event: twitchEvents.SEEK,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.SEEK,
+ status: 'paused'
+ })
+ })
+
+ it('pause -> seek -> play', function () {
+ const state = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ event: twitchEvents.SEEK,
+ status: 'paused'
+ }))
+
+ const result = ledgerUtil.generateTwitchCacheData(state, {
+ event: twitchEvents.PLAY_PAUSE,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'playing'
+ })
+ })
+
+ it('play -> seek -> pause', function () {
+ const state = baseState
+ .setIn(['cache', 'ledgerVideos', 'twitch_test'], Immutable.fromJS({
+ event: twitchEvents.SEEK,
+ status: 'playing'
+ }))
+
+ const result = ledgerUtil.generateTwitchCacheData(state, {
+ event: twitchEvents.PLAY_PAUSE,
+ channel: 'test'
+ }, 'twitch_test')
+
+ assert.deepEqual(result.toJS(), {
+ event: twitchEvents.PLAY_PAUSE,
+ status: 'paused'
+ })
+ })
+ })
+ })
+
+ describe('getTwitchDuration', function () {
+ it('null case', function () {
+ const result = ledgerUtil.getTwitchDuration()
+ assert.deepEqual(result, 0)
+ })
+
+ it('we just video playing', function () {
+ const result = ledgerUtil.getTwitchDuration(baseState, {
+ event: twitchEvents.START,
+ properties: {
+ time: '1223fa'
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 10000)
+ })
+
+ it('properties are missing', function () {
+ const result = ledgerUtil.getTwitchDuration(baseState, {
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ time: '1223fa'
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 0)
+ })
+
+ it('current time is not a number', function () {
+ const result = ledgerUtil.getTwitchDuration(stateWithData, {
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ time: '1223fa'
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 0)
+ })
+
+ it('user paused a video', function () {
+ const result = ledgerUtil.getTwitchDuration(stateWithData, {
+ event: twitchEvents.PLAY_PAUSE,
+ properties: {
+ time: 1519279926
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 30000)
+ })
+
+ it('first minute watched', function () {
+ const result = ledgerUtil.getTwitchDuration(stateWithData, {
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ time: 1519279926
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 30000)
+ })
+
+ it('second minute watched', function () {
+ const state = stateWithData
+ .setIn(['cache', 'ledgerVideos', 'twitch_test', 'event'], twitchEvents.MINUTE_WATCHED)
+
+ const result = ledgerUtil.getTwitchDuration(state, {
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ time: 1519279926
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 40000)
+ })
+
+ it('vod seeked', function () {
+ const state = stateWithData
+ .setIn(['cache', 'ledgerVideos', 'twitch_test', 'event'], twitchEvents.MINUTE_WATCHED)
+
+ const result = ledgerUtil.getTwitchDuration(state, {
+ event: twitchEvents.SEEK,
+ properties: {
+ time: 1519279926
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 40000)
+ })
+
+ it('end time is negative', function () {
+ const result = ledgerUtil.getTwitchDuration(stateWithData, {
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ time: 1519249926
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 0)
+ })
+
+ it('end time is more then 2 minutes', function () {
+ const result = ledgerUtil.getTwitchDuration(stateWithData, {
+ event: twitchEvents.MINUTE_WATCHED,
+ properties: {
+ time: 1519449926
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 120000)
+ })
+
+ it('start event is send twice', function () {
+ const state = stateWithData
+ .setIn(['cache', 'ledgerVideos', 'twitch_test', 'event'], twitchEvents.START)
+
+ const result = ledgerUtil.getTwitchDuration(state, {
+ event: twitchEvents.START,
+ properties: {
+ time: 1519279926
+ }
+ }, 'twitch_test')
+ assert.deepEqual(result, 0)
+ })
+ })
+
+ describe('hasRequiredVisits', function () {
+ it('null case', function () {
+ paymentsMinVisits = 1
+
+ const result = ledgerUtil.hasRequiredVisits(defaultState)
+ assert.equal(result, false)
+ })
+
+ it('returns true if minimum visits is set to 1', function () {
+ paymentsMinVisits = 1
+ const publisherKey = 'brave.com'
+
+ const result = ledgerUtil.hasRequiredVisits(defaultState, publisherKey)
+ assert(result)
+ })
+
+ it('returns false if the publisher is new and minimum visits is set to > 1', function () {
+ paymentsMinVisits = 5
+ const publisherKey = 'new.com'
+
+ const result = ledgerUtil.hasRequiredVisits(defaultState, publisherKey)
+ assert.equal(result, false)
+ })
+
+ it('returns true if the publisher is new and minimum visits is set to 1', function () {
+ paymentsMinVisits = 1
+ const publisherKey = 'new.com'
+
+ const result = ledgerUtil.hasRequiredVisits(defaultState, publisherKey)
+ assert.equal(result, true)
+ })
+
+ it('returns false if the publisher is > 1 visit away from minimum visits', function () {
+ paymentsMinVisits = 5
+ const publisherVisits = 3
+ const publisherKey = 'brave.com'
+
+ const state = defaultState
+ .setIn(['ledger', 'synopsis', 'publishers', publisherKey, 'visits'], publisherVisits)
+
+ const result = ledgerUtil.hasRequiredVisits(state, publisherKey)
+ assert.equal(result, false)
+ })
+
+ it('returns true if the publisher is 1 visit away from minimum visits', function () {
+ paymentsMinVisits = 5
+ const publisherVisits = 4
+ const publisherKey = 'brave.com'
+
+ const state = defaultState
+ .setIn(['ledger', 'synopsis', 'publishers', publisherKey, 'visits'], publisherVisits)
+
+ const result = ledgerUtil.hasRequiredVisits(state, publisherKey)
+ assert.equal(result, true)
+ })
+ })
+
+ describe('getRemainingRequiredTime', function () {
+ it('null case', function () {
+ paymentsMinVisitTime = 8000
+
+ const result = ledgerUtil.getRemainingRequiredTime(defaultState)
+ assert.equal(result, paymentsMinVisitTime)
+ })
+
+ it('returns the minimum visit time if the publisher is new', function () {
+ paymentsMinVisitTime = 8000
+ const publisherKey = 'brave.com'
+
+ const result = ledgerUtil.getRemainingRequiredTime(defaultState, publisherKey)
+ assert.equal(result, paymentsMinVisitTime)
+ })
+
+ it('returns the minimum visit time if the publisher has duration >= minimum visit time', function () {
+ paymentsMinVisitTime = 8000
+ const publisherDuration = 8888
+ const publisherKey = 'brave.com'
+
+ const state = defaultState
+ .setIn(['ledger', 'synopsis', 'publishers', publisherKey, 'duration'], publisherDuration)
+
+ const result = ledgerUtil.getRemainingRequiredTime(state, publisherKey)
+ assert.equal(result, paymentsMinVisitTime)
+ })
+
+ it('returns the difference in time if the publisher has duration < minimum visit time', function () {
+ paymentsMinVisitTime = 8000
+ const expectedResult = 1500
+ const publisherDuration = 6500
+ const publisherKey = 'brave.com'
+
+ const state = defaultState
+ .setIn(['ledger', 'synopsis', 'publishers', publisherKey, 'duration'], publisherDuration)
+
+ const result = ledgerUtil.getRemainingRequiredTime(state, publisherKey)
+ assert.equal(result, expectedResult)
+ })
+ })
})
diff --git a/test/unit/app/common/lib/menuUtilTest.js b/test/unit/app/common/lib/menuUtilTest.js
index cce7b0475f6..b445a34a8c0 100644
--- a/test/unit/app/common/lib/menuUtilTest.js
+++ b/test/unit/app/common/lib/menuUtilTest.js
@@ -86,7 +86,7 @@ describe('menuUtil tests', function () {
})
})
- describe('setTemplateItemChecked', function () {
+ describe('setTemplateItemAttribute', function () {
const defaultTemplate = Immutable.fromJS([
{
'label': 'Bookmarks',
@@ -113,11 +113,11 @@ describe('menuUtil tests', function () {
]
}
])
- const newTemplate = menuUtil.setTemplateItemChecked(defaultTemplate, 'Bookmarks Toolbar', true)
+ const newTemplate = menuUtil.setTemplateItemAttribute(defaultTemplate, 'Bookmarks Toolbar', 'checked', true)
assert.deepEqual(newTemplate.toJS(), expectedTemplate.toJS())
})
it('returns null when no change is made', function () {
- const newTemplate = menuUtil.setTemplateItemChecked(defaultTemplate, 'Bookmarks Toolbar', false)
+ const newTemplate = menuUtil.setTemplateItemAttribute(defaultTemplate, 'Bookmarks Toolbar', 'checked', false)
assert.equal(newTemplate, null)
})
})
diff --git a/test/unit/app/common/lib/publisherUtilTest.js b/test/unit/app/common/lib/publisherUtilTest.js
index c3f3178d113..e279ca95c6c 100644
--- a/test/unit/app/common/lib/publisherUtilTest.js
+++ b/test/unit/app/common/lib/publisherUtilTest.js
@@ -67,5 +67,10 @@ describe('publisherUtil test', function () {
const result = publisherUtil.shouldShowAddPublisherButton(state, 'https://brave.com', 'brave.com')
assert.equal(result, true)
})
+
+ it('location is pdf', function () {
+ const result = publisherUtil.shouldShowAddPublisherButton(state, 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/http://orimi.com/pdf-test.pdf', 'orimi.com')
+ assert.equal(result, true)
+ })
})
})
diff --git a/test/unit/app/common/lib/siteSuggestionsTest.js b/test/unit/app/common/lib/siteSuggestionsTest.js
index 39593a8db00..8846be53ef1 100644
--- a/test/unit/app/common/lib/siteSuggestionsTest.js
+++ b/test/unit/app/common/lib/siteSuggestionsTest.js
@@ -1,55 +1,10 @@
-/* global describe, before, after, it */
-const {tokenizeInput, init, query, add} = require('../../../../../app/common/lib/siteSuggestions')
-const assert = require('assert')
-const Immutable = require('immutable')
-const sinon = require('sinon')
+/* global describe, before, after */
+
+const runMuonCompatibleTests = require('../../../runMuonCompatibleTests')
+const components = require('./siteSuggestionsTestComponents')
const fakeElectron = require('../../../lib/fakeElectron')
const mockery = require('mockery')
-const site1 = {
- location: 'https://www.bradrichter.co/bad_numbers/3',
- title: 'Do not use 3 for items because it is prime'
-}
-const site2 = {
- location: 'https://www.brave.com',
- title: 'No really, take back the web'
-}
-const site3 = {
- location: 'https://www.bradrichter.co/bad_numbers/5',
- title: 'Do not use 5 it is so bad, try 6 instead. Much better.'
-}
-
-const site4 = {
- location: 'https://www.designers.com/brad',
- title: 'Brad Saves The World!',
- count: 50
-}
-
-// Same as site4 but added after in init, should be ignored.
-const site5 = {
- location: 'https://www.designers.com/brad',
- title: 'Brad Saves The World!'
-}
-
-// Compares 2 sites via deepEqual while first clearing out cached data
-const siteEqual = (actual, expected) => {
- assert.equal(actual.constructor, expected.constructor)
- if (expected.constructor === Array) {
- assert.equal(actual.length, expected.length)
- for (let i = 0; i < actual.length; i++) {
- assert.deepEqual(actual[i].delete('parsedUrl').toJS(), expected[i].delete('parsedUrl').toJS())
- }
- } else {
- const a = Object.assign({}, actual)
- delete a.parsedUrl
- const e = Object.assign({}, expected)
- delete e.parsedUrl
- assert.deepEqual(a, e)
- }
-}
-
-require('../../../braveUnit')
-
describe('siteSuggestions lib', function () {
before(function () {
mockery.enable({
@@ -62,304 +17,6 @@ describe('siteSuggestions lib', function () {
after(function () {
mockery.disable()
})
- describe('tokenizeInput', function () {
- it('empty string has no tokens', function () {
- assert.deepEqual(tokenizeInput(''), [])
- })
- it('undefined has no tokens', function () {
- assert.deepEqual(tokenizeInput(null), [])
- })
- it('null has no tokens', function () {
- assert.deepEqual(tokenizeInput(undefined), [])
- })
- it('lowercases tokens', function () {
- assert.deepEqual(tokenizeInput('BRaD HaTES PRIMES'), ['brad', 'hates', 'primes'])
- })
- it('includes protocol', function () {
- assert.deepEqual(tokenizeInput('https://bradrichter.co/I/hate/primes.html'), ['bradrichter', 'co', 'i', 'hate', 'primes', 'html', 'https:'])
- })
- it('includes query', function () {
- assert.deepEqual(tokenizeInput('https://bradrichter.co/I/hate/primes.html?test=abc&test2=abcd'), ['bradrichter', 'co', 'i', 'hate', 'primes', 'html', 'test', 'abc', 'test2', 'abcd', 'https:'])
- })
- it('does not include hash', function () {
- assert.deepEqual(tokenizeInput('https://bradrichter.co/I/hate/primes.html?test=abc#testing'), ['testing', 'bradrichter', 'co', 'i', 'hate', 'primes', 'html', 'test', 'abc', 'https:'])
- })
- it('spaces get tokenized', function () {
- assert.deepEqual(tokenizeInput('brad\thates primes'), ['brad', 'hates', 'primes'])
- })
- it('periods get tokenized', function () {
- assert.deepEqual(tokenizeInput('brad.hates.primes'), ['brad', 'hates', 'primes'])
- })
- it('/ gets tokenized', function () {
- assert.deepEqual(tokenizeInput('brad/hates/primes'), ['brad', 'hates', 'primes'])
- })
- it('\\ gets tokenized', function () {
- assert.deepEqual(tokenizeInput('brad\\hates\\primes'), ['brad', 'hates', 'primes'])
- })
- it('can tokenize site objects', function () {
- assert.deepEqual(tokenizeInput(Immutable.fromJS(site1)), ['do', 'not', 'use', '3', 'for', 'items', 'because', 'it', 'is', 'prime', 'www', 'bradrichter', 'co', 'bad_numbers', '3', 'https:'])
- })
- it('non URLs get tokenized', function () {
- assert.deepEqual(tokenizeInput('hello world Greatest...Boss...Ever'), ['hello', 'world', 'greatest', 'boss', 'ever'])
- })
- })
-
- const checkResult = (inputQuery, expectedResults, cb) => {
- query(inputQuery).then((results) => {
- siteEqual(results, expectedResults)
- cb()
- })
- }
-
- describe('not initialized query', function () {
- it('returns no results if not initialized', function (cb) {
- checkResult('hello', [], cb)
- })
- })
-
- describe('query', function () {
- let sites
- before(function (cb) {
- sites = Immutable.fromJS([site1, site2, site3, site4, site5])
- this.clock = sinon.useFakeTimers()
- init(sites).then(cb.bind(null, null))
- this.clock.tick(1510)
- })
- after(function () {
- this.clock.restore()
- })
- it('can query with empty string', function (cb) {
- checkResult('', [], cb)
- })
- it('can query with null', function (cb) {
- checkResult(null, [], cb)
- })
- it('can query with undefined', function (cb) {
- checkResult(undefined, [], cb)
- })
- it('returns an empty array when there are no matches', function (cb) {
- checkResult('hello', [], cb)
- })
- it('returns matched result on an exact token', function (cb) {
- checkResult('bradrichter', [sites.get(0), sites.get(2)], cb)
- })
- it('returns matched result on a token prefix', function (cb) {
- checkResult('brad', [sites.get(0), sites.get(2), sites.get(3).delete('count')], cb)
- })
- it('returns no results on input that has a token as a prefix', function (cb) {
- checkResult('bradrichterhatesprimes.com', [], cb)
- })
- it('can query on title', function (cb) {
- checkResult('back', [sites.get(1)], cb)
- })
- it('can query on multiple tokens in different order', function (cb) {
- checkResult('back really', [sites.get(1)], cb)
- })
- it('all tokens must match, not just some', function (cb) {
- checkResult('brave brad', [], cb)
- })
- })
-
- describe('query', function () {
- describe('sorts results by location', function () {
- before(function (cb) {
- const sites = Immutable.fromJS([{
- location: 'https://brave.com/twi'
- }, {
- location: 'https://twitter.com/brave'
- }, {
- location: 'https://twitter.com/brianbondy'
- }, {
- location: 'https://twitter.com/_brianclif'
- }, {
- location: 'https://twitter.com/cezaraugusto'
- }, {
- location: 'https://bbondy.com/twitter'
- }, {
- location: 'https://twitter.com'
- }, {
- location: 'https://twitter.com/i/moments'
- }])
- init(sites).then(cb.bind(null, null))
- })
- it('orders shortest match first', function (cb) {
- query('twitter.com').then((results) => {
- siteEqual(results[0], Immutable.fromJS({ location: 'https://twitter.com' }))
- cb()
- })
- })
- it('matches prefixes first', function (cb) {
- query('twi').then((results) => {
- siteEqual(results[0], Immutable.fromJS({ location: 'https://twitter.com' }))
- cb()
- })
- })
- it('closest to the left match wins', function (cb) {
- query('twitter.com brian').then((results) => {
- siteEqual(results[0], Immutable.fromJS({ location: 'https://twitter.com/brianbondy' }))
- cb()
- })
- })
- it('matches based on tokens and not exactly', function (cb) {
- query('twitter.com/moments').then((results) => {
- siteEqual(results[0], Immutable.fromJS({ location: 'https://twitter.com/i/moments' }))
- cb()
- })
- })
- })
- describe('sorts results by count', function () {
- describe('with lastAccessedTime', function () {
- before(function (cb) {
- const lastAccessedTime = 1494958046427
- this.page2 = {
- location: 'https://brave.com/page2',
- lastAccessedTime,
- count: 20
- }
- const sites = Immutable.fromJS([{
- location: 'https://brave.com/page1',
- lastAccessedTime,
- count: 5
- }, this.page2, {
- location: 'https://brave.com/page3',
- lastAccessedTime,
- count: 2
- }])
- init(sites).then(cb.bind(null, null))
- })
- it('highest count first', function (cb) {
- query('https://brave.com/page').then((results) => {
- siteEqual(results[0], Immutable.fromJS(this.page2))
- cb()
- })
- })
- })
- describe('without last access time', function () {
- before(function (cb) {
- this.page2 = {
- location: 'https://brave.com/page2',
- count: 20
- }
- const sites = Immutable.fromJS([{
- location: 'https://brave.com/page1',
- count: 5
- }, this.page2, {
- location: 'https://brave.com/page3',
- count: 2
- }])
- init(sites).then(cb.bind(null, null))
- })
- it('highest count first', function (cb) {
- query('https://brave.com/page').then((results) => {
- siteEqual(results[0], Immutable.fromJS(this.page2))
- cb()
- })
- })
- })
- })
- describe('sorts results by lastAccessTime', function () {
- describe('with counts', function () {
- before(function (cb) {
- this.site = {
- location: 'https://bravebrowser.com/page2',
- lastAccessedTime: 1494958046427, // most recent
- count: 1
- }
- const sites = Immutable.fromJS([{
- location: 'https://bravez.com/page1',
- lastAccessedTime: 1,
- count: 1
- }, {
- location: 'https://bravebrowser.com/page1',
- lastAccessedTime: 1494957046426,
- count: 1
- }, this.site, {
- location: 'https://bravebrowser.com/page3',
- lastAccessedTime: 1494957046437,
- count: 1
- }])
- init(sites).then(cb.bind(null, null))
- })
- it('items with lastAccessTime of 1 get ignored (signifies preloaded default)', function (cb) {
- query('https://bravez.com/page').then((results) => {
- assert.equal(results.length, 0)
- cb()
- })
- })
- it('most recently accessed get sorted first', function (cb) {
- query('bravebrowser').then((results) => {
- siteEqual(results[0], Immutable.fromJS(this.site))
- cb()
- })
- })
- })
- describe('without counts', function () {
- before(function (cb) {
- this.site = {
- location: 'https://bravebrowser.com/page2',
- lastAccessedTime: 1494958046427 // most recent
- }
- const sites = Immutable.fromJS([{
- location: 'https://bravez.com/page1',
- lastAccessedTime: 1
- }, {
- location: 'https://bravebrowser.com/page1',
- lastAccessedTime: 1494957046426
- }, this.site, {
- location: 'https://bravebrowser.com/page3',
- lastAccessedTime: 1494957046437
- }])
- init(sites).then(cb.bind(null, null))
- })
- it('items with lastAccessTime of 1 get ignored (signifies preloaded default)', function (cb) {
- query('https://bravez.com/page').then((results) => {
- assert.equal(results.length, 0)
- cb()
- })
- })
- it('most recently accessed get sorted first', function (cb) {
- query('bravebrowser').then((results) => {
- siteEqual(results[0], Immutable.fromJS(this.site))
- cb()
- })
- })
- })
- })
- })
-
- describe('add sites after init', function () {
- before(function (cb) {
- const sites = [site1, site2, site3, site4]
- init(sites).then(() => {
- add({
- location: 'https://slack.com'
- })
- }).then(cb.bind(null, null))
- })
- it('can be found', function (cb) {
- checkResult('slack', [Immutable.fromJS({ location: 'https://slack.com' })], cb)
- })
- it('adding twice results in 1 result only with latest results', function (cb) {
- const newSite = {
- location: 'https://slack.com',
- count: 30,
- title: 'SlickSlack'
- }
- add(newSite)
- checkResult('slack', [Immutable.fromJS(newSite)], cb)
- })
- it('can add simple strings', function (cb) {
- add({
- location: 'https://slashdot.org'
- })
- checkResult('slash', [Immutable.fromJS({ location: 'https://slashdot.org' })], cb)
- })
- it('can add Immutable objects', function (cb) {
- add(Immutable.fromJS({
- location: 'https://microsoft.com'
- }))
- checkResult('micro', [Immutable.fromJS({ location: 'https://microsoft.com' })], cb)
- })
- })
+ runMuonCompatibleTests('urlutil', components)
})
diff --git a/test/unit/app/common/lib/siteSuggestionsTestComponents.js b/test/unit/app/common/lib/siteSuggestionsTestComponents.js
new file mode 100644
index 00000000000..76591ae4df0
--- /dev/null
+++ b/test/unit/app/common/lib/siteSuggestionsTestComponents.js
@@ -0,0 +1,338 @@
+const {tokenizeInput, init, query, add} = require('../../../../../app/common/lib/siteSuggestions')
+const Immutable = require('immutable')
+const lolex = require('lolex')
+
+const site1 = {
+ location: 'https://www.bradrichter.co/bad_numbers/3',
+ title: 'Do not use 3 for items because it is prime'
+}
+const site2 = {
+ location: 'https://www.brave.com',
+ title: 'No really, take back the web'
+}
+const site3 = {
+ location: 'https://www.bradrichter.co/bad_numbers/5',
+ title: 'Do not use 5 it is so bad, try 6 instead. Much better.'
+}
+const site4 = {
+ location: 'https://www.designers.com/brad',
+ title: 'Brad Saves The World!',
+ count: 50
+}
+// Same as site4 but added after in init, should be ignored.
+const site5 = {
+ location: 'https://www.designers.com/brad',
+ title: 'Brad Saves The World!'
+}
+const sites = Immutable.fromJS([site1, site2, site3, site4, site5])
+
+// Compares 2 sites via deepEqual while first clearing out cached data
+const siteEqual = (test, actual, expected) => {
+ test.equal(actual.constructor, expected.constructor)
+ if (expected.constructor === Array) {
+ test.equal(actual.length, expected.length)
+ for (let i = 0; i < actual.length; i++) {
+ test.deepEqual(actual[i].delete('parsedUrl').toJS(), expected[i].delete('parsedUrl').toJS())
+ }
+ } else {
+ const a = Object.assign({}, actual)
+ delete a.parsedUrl
+ const e = Object.assign({}, expected)
+ delete e.parsedUrl
+ test.deepEqual(a, e)
+ }
+}
+
+const checkResult = (test, inputQuery, expectedResults, cb) => {
+ return query(inputQuery).then((results) => {
+ siteEqual(test, results, expectedResults)
+ cb()
+ })
+}
+
+module.exports = {
+ 'tokenizeInput': {
+ 'empty string has no tokens': (test) => {
+ test.deepEqual(tokenizeInput(''), [])
+ },
+ 'undefined has no tokens': (test) => {
+ test.deepEqual(tokenizeInput(null), [])
+ },
+ 'null has no tokens': (test) => {
+ test.deepEqual(tokenizeInput(undefined), [])
+ },
+ 'lowercases tokens': (test) => {
+ test.deepEqual(tokenizeInput('BRaD HaTES PRIMES'), ['brad', 'hates', 'primes'])
+ },
+ 'includes protocol': (test) => {
+ test.deepEqual(tokenizeInput('https://bradrichter.co/I/hate/primes.html'), ['bradrichter', 'co', 'i', 'hate', 'primes', 'html', 'https:'])
+ },
+ 'includes query': (test) => {
+ test.deepEqual(tokenizeInput('https://bradrichter.co/I/hate/primes.html?test=abc&test2=abcd'), ['bradrichter', 'co', 'i', 'hate', 'primes', 'html', 'test', 'abc', 'test2', 'abcd', 'https:'])
+ },
+ 'does not include hash': (test) => {
+ test.deepEqual(tokenizeInput('https://bradrichter.co/I/hate/primes.html?test=abc#testing'), ['testing', 'bradrichter', 'co', 'i', 'hate', 'primes', 'html', 'test', 'abc', 'https:'])
+ },
+ 'spaces get tokenized': (test) => {
+ test.deepEqual(tokenizeInput('brad\thates primes'), ['brad', 'hates', 'primes'])
+ },
+ 'periods get tokenized': (test) => {
+ test.deepEqual(tokenizeInput('brad.hates.primes'), ['brad', 'hates', 'primes'])
+ },
+ 'forward slash gets tokenized': (test) => {
+ test.deepEqual(tokenizeInput('brad/hates/primes'), ['brad', 'hates', 'primes'])
+ },
+ 'backslash gets tokenized': (test) => {
+ test.deepEqual(tokenizeInput('brad\\hates\\primes'), ['brad', 'hates', 'primes'])
+ },
+ 'can tokenize site objects': (test) => {
+ test.deepEqual(tokenizeInput(Immutable.fromJS(site1)), ['do', 'not', 'use', '3', 'for', 'items', 'because', 'it', 'is', 'prime', 'www', 'bradrichter', 'co', 'bad_numbers', '3', 'https:'])
+ },
+ 'non URLs get tokenized': (test) => {
+ test.deepEqual(tokenizeInput('hello world Greatest...Boss...Ever'), ['hello', 'world', 'greatest', 'boss', 'ever'])
+ }
+ },
+
+ 'not initialized query': {
+ 'returns no results if not initialized': (test, cb) => {
+ checkResult(test, 'hello', [], cb).catch(cb)
+ }
+ },
+
+ 'basic query': {
+ before: function (cb) {
+ this.clock = lolex.install()
+ init(sites).then(cb.bind(null, null))
+ this.clock.tick(1510)
+ },
+ after: function () {
+ this.clock.uninstall()
+ },
+ 'can query with empty string': (test, cb) => {
+ checkResult(test, '', [], cb).catch(cb)
+ },
+ 'can query with null': (test, cb) => {
+ checkResult(test, null, [], cb).catch(cb)
+ },
+ 'can query with undefined': (test, cb) => {
+ checkResult(test, undefined, [], cb).catch(cb)
+ },
+ 'returns an empty array when there are no matches': (test, cb) => {
+ checkResult(test, 'hello', [], cb).catch(cb)
+ },
+ 'returns matched result on an exact token': (test, cb) => {
+ checkResult(test, 'bradrichter', [sites.get(0), sites.get(2)], cb).catch(cb)
+ },
+ 'returns matched result on a token prefix': (test, cb) => {
+ checkResult(test, 'brad', [sites.get(0), sites.get(2), sites.get(3).delete('count')], cb).catch(cb)
+ },
+ 'returns no results on input that has a token as a prefix': (test, cb) => {
+ checkResult(test, 'bradrichterhatesprimes.com', [], cb).catch(cb)
+ },
+ 'can query on title': (test, cb) => {
+ checkResult(test, 'back', [sites.get(1)], cb).catch(cb)
+ },
+ 'can query on multiple tokens in different order': (test, cb) => {
+ checkResult(test, 'back really', [sites.get(1)], cb).catch(cb)
+ },
+ 'all tokens must match, not just some': (test, cb) => {
+ checkResult(test, 'brave brad', [], cb).catch(cb)
+ }
+ },
+
+ 'query': {
+ 'sorts results by location': {
+ before: (cb) => {
+ const sites = Immutable.fromJS([{
+ location: 'https://brave.com/twi'
+ }, {
+ location: 'https://twitter.com/brave'
+ }, {
+ location: 'https://twitter.com/brianbondy'
+ }, {
+ location: 'https://twitter.com/_brianclif'
+ }, {
+ location: 'https://twitter.com/cezaraugusto'
+ }, {
+ location: 'https://bbondy.com/twitter'
+ }, {
+ location: 'https://twitter.com'
+ }, {
+ location: 'https://twitter.com/i/moments'
+ }])
+ init(sites).then(cb.bind(null, null))
+ },
+ 'orders shortest match first': (test, cb) => {
+ query('twitter.com').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS({ location: 'https://twitter.com' }))
+ cb()
+ }).catch(cb)
+ },
+ 'matches prefixes first': (test, cb) => {
+ query('twi').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS({ location: 'https://twitter.com' }))
+ cb()
+ }).catch(cb)
+ },
+ 'closest to the left match wins': (test, cb) => {
+ query('twitter.com brian').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS({ location: 'https://twitter.com/brianbondy' }))
+ cb()
+ }).catch(cb)
+ },
+ 'matches based on tokens and not exactly': (test, cb) => {
+ query('twitter.com/moments').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS({ location: 'https://twitter.com/i/moments' }))
+ cb()
+ }).catch(cb)
+ }
+ },
+ 'sorts results by count': {
+ 'with lastAccessedTime': {
+ before: function (cb) {
+ const lastAccessedTime = 1494958046427
+ this.page2 = {
+ location: 'https://brave.com/page2',
+ lastAccessedTime,
+ count: 20
+ }
+ const sites = Immutable.fromJS([{
+ location: 'https://brave.com/page1',
+ lastAccessedTime,
+ count: 5
+ }, this.page2, {
+ location: 'https://brave.com/page3',
+ lastAccessedTime,
+ count: 2
+ }])
+ init(sites).then(cb.bind(null, null))
+ },
+ 'highest count first': function (test, cb) {
+ query('https://brave.com/page').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS(this.page2))
+ cb()
+ }).catch(cb)
+ }
+ },
+ 'without last access time': {
+ before: function (cb) {
+ this.page2 = {
+ location: 'https://brave.com/page2',
+ count: 20
+ }
+ const sites = Immutable.fromJS([{
+ location: 'https://brave.com/page1',
+ count: 5
+ }, this.page2, {
+ location: 'https://brave.com/page3',
+ count: 2
+ }])
+ init(sites).then(cb.bind(null, null))
+ },
+ 'highest count first': function (test, cb) {
+ query('https://brave.com/page').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS(this.page2))
+ cb()
+ }).catch(cb)
+ }
+ }
+ },
+ 'sorts results by lastAccessTime': {
+ 'with counts': {
+ before: function (cb) {
+ this.site = {
+ location: 'https://bravebrowser.com/page2',
+ lastAccessedTime: 1494958046427, // most recent
+ count: 1
+ }
+ const sites = Immutable.fromJS([{
+ location: 'https://bravez.com/page1',
+ lastAccessedTime: 1,
+ count: 1
+ }, {
+ location: 'https://bravebrowser.com/page1',
+ lastAccessedTime: 1494957046426,
+ count: 1
+ }, this.site, {
+ location: 'https://bravebrowser.com/page3',
+ lastAccessedTime: 1494957046437,
+ count: 1
+ }])
+ init(sites).then(cb.bind(null, null))
+ },
+ 'items with lastAccessTime of 1 get ignored (signifies preloaded default)': (test, cb) => {
+ query('https://bravez.com/page').then((results) => {
+ test.equal(results.length, 0)
+ cb()
+ }).catch(cb)
+ },
+ 'most recently accessed get sorted first': function (test, cb) {
+ query('bravebrowser').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS(this.site))
+ cb()
+ }).catch(cb)
+ }
+ },
+ 'without counts': {
+ before: function (cb) {
+ this.site = {
+ location: 'https://bravebrowser.com/page2',
+ lastAccessedTime: 1494958046427 // most recent
+ }
+ const sites = Immutable.fromJS([{
+ location: 'https://bravez.com/page1',
+ lastAccessedTime: 1
+ }, {
+ location: 'https://bravebrowser.com/page1',
+ lastAccessedTime: 1494957046426
+ }, this.site, {
+ location: 'https://bravebrowser.com/page3',
+ lastAccessedTime: 1494957046437
+ }])
+ init(sites).then(cb.bind(null, null))
+ },
+ 'items with lastAccessTime of 1 get ignored (signifies preloaded default)': (test, cb) => {
+ query('https://bravez.com/page').then((results) => {
+ test.equal(results.length, 0)
+ cb()
+ }).catch(cb)
+ },
+ 'most recently accessed get sorted first': function (test, cb) {
+ query('bravebrowser').then((results) => {
+ siteEqual(test, results[0], Immutable.fromJS(this.site))
+ cb()
+ }).catch(cb)
+ }
+ }
+ }
+ },
+
+ 'add sites after init': {
+ before: (cb) => {
+ const sites = [site1, site2, site3, site4]
+ init(sites).then(() => {
+ add({ location: 'https://slack.com' })
+ }).then(cb.bind(null, null))
+ },
+ 'can be found': (test, cb) => {
+ checkResult(test, 'slack', [Immutable.fromJS({ location: 'https://slack.com' })], cb).catch(cb)
+ },
+ 'adding twice results in 1 result only with latest results': (test, cb) => {
+ const newSite = {
+ location: 'https://slack.com',
+ count: 30,
+ title: 'SlickSlack'
+ }
+ add(newSite)
+ checkResult(test, 'slack', [Immutable.fromJS(newSite)], cb).catch(cb)
+ },
+ 'can add simple strings': (test, cb) => {
+ add({ location: 'https://slashdot.org' })
+ checkResult(test, 'slash', [Immutable.fromJS({ location: 'https://slashdot.org' })], cb).catch(cb)
+ },
+ 'can add Immutable objects': (test, cb) => {
+ add(Immutable.fromJS({ location: 'https://microsoft.com' }))
+ checkResult(test, 'micro', [Immutable.fromJS({ location: 'https://microsoft.com' })], cb).catch(cb)
+ }
+ }
+}
diff --git a/test/unit/app/common/lib/suggestionTest.js b/test/unit/app/common/lib/suggestionTest.js
index 5318d5af531..de3f811bbba 100644
--- a/test/unit/app/common/lib/suggestionTest.js
+++ b/test/unit/app/common/lib/suggestionTest.js
@@ -58,6 +58,12 @@ describe('suggestion unit tests', function () {
it('normalizes location', function () {
assert.ok(suggestion.normalizeLocation('https://www.site.com') === 'site.com', 'www. prefix removed')
assert.ok(suggestion.normalizeLocation('http://site.com') === 'site.com', 'location not modified')
+ assert.ok(suggestion.normalizeLocation('http://wowww.com') === 'wowww.com', 'location not modified')
+ assert.ok(suggestion.normalizeLocation('https://wowww.com') === 'wowww.com', 'location not modified')
+ assert.ok(suggestion.normalizeLocation('wowww.com') === 'wowww.com', 'location not modified')
+ assert.ok(suggestion.normalizeLocation('http://www.wowww.com') === 'wowww.com', 'www. prefix removed')
+ assert.ok(suggestion.normalizeLocation('https://www.wowww.com') === 'wowww.com', 'www. prefix removed')
+ assert.ok(suggestion.normalizeLocation('www.wowww.com') === 'wowww.com', 'www. prefix removed')
})
})
diff --git a/test/unit/app/common/state/aboutPreferencesStateTest.js b/test/unit/app/common/state/aboutPreferencesStateTest.js
new file mode 100644
index 00000000000..6235968659f
--- /dev/null
+++ b/test/unit/app/common/state/aboutPreferencesStateTest.js
@@ -0,0 +1,126 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+* License, v. 2.0. If a copy of the MPL was not distributed with this file,
+* You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* global describe, it */
+const assert = require('assert')
+const Immutable = require('immutable')
+const aboutPreferencesState = require('../../../../../app/common/state/aboutPreferencesState')
+
+describe('aboutPreferencesState unit test', function () {
+ // State
+ const defaultState = Immutable.fromJS({
+ about: {
+ preferences: {}
+ },
+ ledger: {}
+ })
+ describe('setBackupStatus', function () {
+ it('null case', function () {
+ const result = aboutPreferencesState.setBackupStatus(defaultState)
+ assert.deepEqual(result.toJS(), defaultState.toJS())
+ })
+ it('set backup succeeded', function () {
+ const result = aboutPreferencesState.setBackupStatus(defaultState, true)
+ const expectedDate = result.getIn(['about', 'preferences', 'updatedStamp']) // ignore date
+ const expectedState = defaultState
+ .setIn(['about', 'preferences', 'backupSucceeded'], true)
+ .setIn(['about', 'preferences', 'updatedStamp'], expectedDate)
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ it('set backup failed', function () {
+ const result = aboutPreferencesState.setBackupStatus(defaultState, false)
+ const expectedDate = result.getIn(['about', 'preferences', 'updatedStamp']) // ignore date
+ const expectedState = defaultState
+ .setIn(['about', 'preferences', 'backupSucceeded'], false)
+ .setIn(['about', 'preferences', 'updatedStamp'], expectedDate)
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('hasBeenBackedUp', function () {
+ it('no backup or recovery bit', function () {
+ const result = aboutPreferencesState.hasBeenBackedUp(defaultState)
+ assert.equal(result, false)
+ })
+ it('has backup and recovery bit', function () {
+ const state = defaultState
+ .setIn(['about', 'preferences', 'backupSucceeded'], true)
+ .setIn(['about', 'preferences', 'recoverySucceeded'], true)
+ const result = aboutPreferencesState.hasBeenBackedUp(state)
+ assert.equal(result, true)
+ })
+ it('has backup bit but not recovery', function () {
+ const state = defaultState.setIn(['about', 'preferences', 'backupSucceeded'], true)
+ const result = aboutPreferencesState.hasBeenBackedUp(state)
+ assert.equal(result, true)
+ })
+ it('has recovery bit but not backup', function () {
+ const state = defaultState.setIn(['about', 'preferences', 'recoverySucceeded'], new Date().getTime())
+ const result = aboutPreferencesState.hasBeenBackedUp(state)
+ assert.notEqual(result, null)
+ })
+ })
+
+ describe('setRecoveryBalanceRecalculated', function () {
+ it('null case', function () {
+ const state = aboutPreferencesState.setRecoveryBalanceRecalculated(defaultState, null)
+ assert.equal(aboutPreferencesState.getPreferencesProp(state, 'recoveryBalanceRecalculated'), null)
+ })
+
+ it('sets true', function () {
+ const state = aboutPreferencesState.setRecoveryBalanceRecalculated(defaultState, true)
+ assert.equal(aboutPreferencesState.getPreferencesProp(state, 'recoveryBalanceRecalculated'), true)
+ })
+
+ it('sets false', function () {
+ const state = aboutPreferencesState.setRecoveryBalanceRecalculated(defaultState, false)
+ assert.equal(aboutPreferencesState.getPreferencesProp(state, 'recoveryBalanceRecalculated'), false)
+ })
+ })
+
+ describe('getRecoveryBalanceRecalculated', function () {
+ it('null case returns false', function () {
+ const state = aboutPreferencesState.setRecoveryBalanceRecalculated(defaultState, null)
+ const result = aboutPreferencesState.getRecoveryBalanceRecalulated(state)
+ assert.equal(result, false)
+ })
+
+ it('returns false', function () {
+ const state = aboutPreferencesState.setRecoveryBalanceRecalculated(defaultState, false)
+ const result = aboutPreferencesState.getRecoveryBalanceRecalulated(state)
+ assert.equal(result, false)
+ })
+
+ it('returns true', function () {
+ const state = aboutPreferencesState.setRecoveryBalanceRecalculated(defaultState, true)
+ const result = aboutPreferencesState.getRecoveryBalanceRecalulated(state)
+ assert.equal(result, true)
+ })
+ })
+
+ describe('setRecoveryStatus', function () {
+ it('updates recoverySucceeded', function () {
+ const result = aboutPreferencesState.setRecoveryStatus(defaultState, true)
+ assert.equal(aboutPreferencesState.getPreferencesProp(result, 'recoverySucceeded'), true)
+ })
+ it('recoveryInProgress is false when recovery is successful', function () {
+ const result = aboutPreferencesState.setRecoveryStatus(defaultState, true)
+ assert.equal(aboutPreferencesState.getPreferencesProp(result, 'recoveryInProgress'), false)
+ })
+ it('recoveryInProgress is false when recovery is not successful', function () {
+ const result = aboutPreferencesState.setRecoveryStatus(defaultState, false)
+ assert.equal(aboutPreferencesState.getPreferencesProp(result, 'recoveryInProgress'), false)
+ })
+ })
+
+ describe('setRecoveryInProgress', function () {
+ it('updates recoveryInProgress', function () {
+ const result = aboutPreferencesState.setRecoveryInProgress(defaultState, true)
+ assert.equal(aboutPreferencesState.getPreferencesProp(result, 'recoveryInProgress'), true)
+
+ const nextResult = aboutPreferencesState.setRecoveryInProgress(defaultState, false)
+ assert.equal(aboutPreferencesState.getPreferencesProp(nextResult, 'recoveryInProgress'), false)
+ })
+ })
+})
diff --git a/test/unit/app/common/state/bookmarkFoldersStateTest.js b/test/unit/app/common/state/bookmarkFoldersStateTest.js
index 7c5dcf36421..d68088bd663 100644
--- a/test/unit/app/common/state/bookmarkFoldersStateTest.js
+++ b/test/unit/app/common/state/bookmarkFoldersStateTest.js
@@ -788,22 +788,4 @@ describe('bookmarkFoldersState unit test', function () {
assert(findBookmarkSpy.calledOnce)
})
})
-
- describe('setWidth', function () {
- it('null case', function () {
- const result = bookmarkFoldersState.setWidth(stateWithData)
- assert.deepEqual(result.toJS(), stateWithData.toJS())
- })
-
- it('parse width', function () {
- const result = bookmarkFoldersState.setWidth(stateWithData, '1', 'dsfsdfds')
- assert.deepEqual(result.toJS(), stateWithData.toJS())
- })
-
- it('set width', function () {
- const result = bookmarkFoldersState.setWidth(stateWithData, '1', 100)
- const expectedResult = stateWithData.setIn(['bookmarkFolders', '1', 'width'], 100)
- assert.deepEqual(result.toJS(), expectedResult.toJS())
- })
- })
})
diff --git a/test/unit/app/common/state/bookmarkToolbarStateTest.js b/test/unit/app/common/state/bookmarkToolbarStateTest.js
deleted file mode 100644
index 7e31463bfd2..00000000000
--- a/test/unit/app/common/state/bookmarkToolbarStateTest.js
+++ /dev/null
@@ -1,158 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this file,
- * You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-/* global before, after, describe, it */
-const Immutable = require('immutable')
-const assert = require('assert')
-const mockery = require('mockery')
-
-describe('bookmarkToolbarState unit test', function () {
- let bookmarkToolbarState
-
- const state = Immutable.fromJS({
- windows: [],
- bookmarks: {},
- bookmarkFolders: {},
- cache: {
- bookmarkOrder: {},
- bookmarkLocation: {}
- },
- historySites: {},
- tabs: []
- })
-
- const stateWithData = Immutable.fromJS({
- windows: [
- {
- windowId: 1
- },
- {
- windowId: 2
- }
- ],
- bookmarks: {},
- bookmarkFolders: {},
- cache: {
- bookmarkOrder: {},
- bookmarkLocation: {}
- },
- historySites: {},
- tabs: []
- })
-
- const stateWithToolbar = Immutable.fromJS({
- windows: [
- {
- windowId: 1,
- bookmarksToolbar: {
- toolbar: ['1'],
- other: ['2']
- }
- }
- ],
- bookmarks: {},
- bookmarkFolders: {},
- cache: {
- bookmarkOrder: {},
- bookmarkLocation: {}
- },
- historySites: {},
- tabs: []
- })
-
- before(function () {
- mockery.enable({
- warnOnReplace: false,
- warnOnUnregistered: false,
- useCleanCache: true
- })
- mockery.registerMock('../lib/bookmarkToolbarUtil', {
- getBookmarkKeys: () => {
- return {
- toolbar: Immutable.fromJS(['1']),
- other: Immutable.fromJS(['2'])
- }
- }
- })
- bookmarkToolbarState = require('../../../../../app/common/state/bookmarkToolbarState')
- })
-
- after(function () {
- mockery.disable()
- })
-
- describe('setToolbars', function () {
- it('null case', function () {
- const newState = bookmarkToolbarState.setToolbars(state)
- assert.deepEqual(newState, state)
- })
-
- it('set data', function () {
- const newState = bookmarkToolbarState.setToolbars(stateWithData)
- const expectedState = stateWithData
- .setIn(['windows', 0, 'bookmarksToolbar'], Immutable.fromJS({
- 'other': [
- '2'
- ],
- 'toolbar': [
- '1'
- ]
- }))
- .setIn(['windows', 1, 'bookmarksToolbar'], Immutable.fromJS({
- 'other': [
- '2'
- ],
- 'toolbar': [
- '1'
- ]
- }))
- assert.deepEqual(newState.toJS(), expectedState.toJS())
- })
- })
-
- describe('setToolbar', function () {
- it('null case', function () {
- const newState = bookmarkToolbarState.setToolbar(state, 1)
- assert.deepEqual(newState.toJS(), state.toJS())
- })
-
- it('set data', function () {
- const newState = bookmarkToolbarState.setToolbar(stateWithData, 2)
- const expectedState = stateWithData
- .setIn(['windows', 1, 'bookmarksToolbar'], Immutable.fromJS({
- 'other': [
- '2'
- ],
- 'toolbar': [
- '1'
- ]
- }))
- assert.deepEqual(newState.toJS(), expectedState.toJS())
- })
- })
-
- describe('getToolbar', function () {
- it('null case', function () {
- const newState = bookmarkToolbarState.getToolbar(state, 1)
- assert.deepEqual(newState, Immutable.List())
- })
-
- it('return data', function () {
- const newState = bookmarkToolbarState.getToolbar(stateWithToolbar, 1)
- assert.deepEqual(newState, Immutable.fromJS(['1']))
- })
- })
-
- describe('getOther', function () {
- it('null case', function () {
- const newState = bookmarkToolbarState.getOther(state, 1)
- assert.deepEqual(newState, Immutable.List())
- })
-
- it('return data', function () {
- const newState = bookmarkToolbarState.getOther(stateWithToolbar, 1)
- assert.deepEqual(newState, Immutable.fromJS(['2']))
- })
- })
-})
diff --git a/test/unit/app/common/state/bookmarksStateTest.js b/test/unit/app/common/state/bookmarksStateTest.js
index 7016cbb8e06..297c13d0f29 100644
--- a/test/unit/app/common/state/bookmarksStateTest.js
+++ b/test/unit/app/common/state/bookmarksStateTest.js
@@ -164,6 +164,11 @@ describe('bookmarkState unit test', function () {
bookmarksState = require('../../../../../app/common/state/bookmarksState')
})
+ after(function () {
+ mockery.deregisterAll()
+ mockery.disable()
+ })
+
describe('updateFavicon', function () {
it('updates the favicon for all matching entries', function () {
const processedState = bookmarksState.updateFavicon(stateWithData, 'https://brave.com/', 'https://brave.com/favicon.ico')
@@ -309,24 +314,6 @@ describe('bookmarkState unit test', function () {
})
})
- describe('setWidth', function () {
- it('null case', function () {
- const result = bookmarksState.setWidth(stateWithData)
- assert.deepEqual(result.toJS(), stateWithData.toJS())
- })
-
- it('parse width', function () {
- const result = bookmarksState.setWidth(stateWithData, '1', 'dsfsdfds')
- assert.deepEqual(result.toJS(), stateWithData.toJS())
- })
-
- it('set width', function () {
- const result = bookmarksState.setWidth(stateWithData, '1', 100)
- const expectedResult = stateWithData.setIn(['bookmarks', '1', 'width'], 100)
- assert.deepEqual(result.toJS(), expectedResult.toJS())
- })
- })
-
describe('getBookmarksWithFolders', function () {
let getBookmarksWithFoldersSpy
before(function () {
diff --git a/test/unit/app/common/state/extensionStateTest.js b/test/unit/app/common/state/extensionStateTest.js
index 15195749e54..bd13cbca024 100644
--- a/test/unit/app/common/state/extensionStateTest.js
+++ b/test/unit/app/common/state/extensionStateTest.js
@@ -1,5 +1,6 @@
/* global describe, it, before */
const extensionState = require('../../../../../app/common/state/extensionState')
+const settings = require('../../../../../js/constants/settings')
const Immutable = require('immutable')
const assert = require('assert')
@@ -682,4 +683,30 @@ describe('extensionState', function () {
commonTests()
})
})
+
+ describe('isWebTorrentEnabled', function () {
+ it('null case', function () {
+ const result = extensionState.isWebTorrentEnabled()
+ assert.equal(result, false)
+ })
+
+ it('torrent is enabled by default', function () {
+ const result = extensionState.isWebTorrentEnabled(defaultAppState)
+ assert.equal(result, true)
+ })
+
+ it('torrent is disabled', function () {
+ const state = defaultAppState
+ .setIn(['settings', settings.TORRENT_VIEWER_ENABLED], false)
+ const result = extensionState.isWebTorrentEnabled(state)
+ assert.equal(result, false)
+ })
+
+ it('torrent is enabled', function () {
+ const state = defaultAppState
+ .setIn(['settings', settings.TORRENT_VIEWER_ENABLED], true)
+ const result = extensionState.isWebTorrentEnabled(state)
+ assert.equal(result, true)
+ })
+ })
})
diff --git a/test/unit/app/common/state/immutableUtilTest.js b/test/unit/app/common/state/immutableUtilTest.js
index 5f55ff48f5f..05ec1361efe 100644
--- a/test/unit/app/common/state/immutableUtilTest.js
+++ b/test/unit/app/common/state/immutableUtilTest.js
@@ -148,4 +148,32 @@ describe('immutableUtil unit test', function () {
assert.deepEqual(immutableUtil.deleteImmutablePaths(data, [['a', 'a1'], 'c']).toJS(), {a: {a2: 8}, d: 5})
})
})
+ describe('findNullKeyPaths', function () {
+ it('finds maps which have a null key', function () {
+ const data = Immutable.fromJS({
+ normal: {
+ key1: 'value'
+ },
+ bad: { },
+ anotherBad: {
+ deeper: { }
+ },
+ null: {
+ badParent: 'value4'
+ },
+ nullValue: null
+ })
+ .setIn(['bad', null], 'value2')
+ .setIn(['anotherBad', 'deeper', null], 'value3')
+ .set(null, Immutable.fromJS({badParent: 'value4'}))
+
+ const expectedNullPaths = [
+ ['bad', null],
+ ['anotherBad', 'deeper', null],
+ [null]
+ ]
+ const actualNullPaths = immutableUtil.findNullKeyPaths(data)
+ assert.deepEqual(actualNullPaths, expectedNullPaths)
+ })
+ })
})
diff --git a/test/unit/app/common/state/ledgerStateTest.js b/test/unit/app/common/state/ledgerStateTest.js
index 493a28183a2..b73ea609449 100644
--- a/test/unit/app/common/state/ledgerStateTest.js
+++ b/test/unit/app/common/state/ledgerStateTest.js
@@ -24,6 +24,98 @@ describe('ledgerState unit test', function () {
}
})
+ const stateWithPublisher = defaultState
+ .setIn(['cache', 'ledgerVideos'], Immutable.fromJS({
+ 'youtube_Ece3i74Wces': 'youtube#channel:radio1slovenia'
+ }))
+ .setIn(['settings', 'payments.enabled'], true)
+ .set('pageData', Immutable.fromJS({
+ info: {
+ 'https://www.youtube.com/user/radio1slovenia/videos': {
+ faviconURL: 'https://s.ytimg.com/yts/img/favicon_32-vflOogEID.png',
+ key: 'https://www.youtube.com/user/radio1slovenia/videos',
+ protocol: 'https:',
+ publisher: 'youtube.com',
+ timestamp: 1526367684155,
+ url: 'https://www.youtube.com/user/radio1slovenia/videos'
+ }
+ },
+ last: {
+ closedTabValue: {
+ audible: false,
+ width: 2560,
+ active: true
+ },
+ info: '',
+ tabId: '7'
+ }
+ }))
+ .set('ledger', Immutable.fromJS({
+ about: {
+ synopsis: [
+ {
+ daysSpent: 0,
+ duration: 166431,
+ exclude: false,
+ faviconURL: 'data:image/jpeg;base64',
+ hoursSpent: 0,
+ minutesSpent: 2,
+ percentage: 38,
+ pinPercentage: undefined,
+ providerName: 'YouTube',
+ publisherKey: 'youtube#channel:radio1slovenia',
+ publisherURL: 'https://www.youtube.com/user/radio1slovenia/videos',
+ score: 14.588460435541956,
+ secondsSpent: 46,
+ siteName: 'radio1slovenia on YouTube',
+ verified: false,
+ views: 2,
+ weight: 38.244594657485045
+ }
+ ],
+ synopsisOptions: {
+ _a: 7000,
+ _b: 1000,
+ scorekeeper: 'concave',
+ _d: 0.000033333333333333335
+ }
+ },
+ info: {
+ balance: 0,
+ paymentId: 'ladasda'
+ },
+ locations: {
+ 'https://www.youtube.com/user/radio1slovenia/videos': {
+ publisher: 'youtube.com'
+ }
+ },
+ synopsis: {
+ options: {
+ _a: 7000,
+ _b: 1000,
+ scorekeeper: 'concave',
+ _d: 0.000033333333333333335
+ },
+ publishers: {
+ 'youtube#channel:radio1slovenia': {
+ duration: 166431,
+ options: {
+ exclude: false
+ },
+ pinPercentage: 20,
+ scores: {
+ concave: 3.249426617127623,
+ visits: 2
+ },
+ views: 2,
+ weight: 20
+ }
+ }
+ },
+ promotion: {},
+ publisherTimestamp: 123
+ }))
+
// settings
let paymentsEnabled = true
let paymentsAmount = 5
@@ -36,7 +128,6 @@ describe('ledgerState unit test', function () {
warnOnUnregistered: false,
useCleanCache: true
})
-
mockery.registerMock('../../../js/settings', {
getSetting: (settingKey) => {
switch (settingKey) {
@@ -51,10 +142,15 @@ describe('ledgerState unit test', function () {
return false
}
})
-
+ mockery.registerMock('../../../js/actions/appActions', appActions)
ledgerState = require('../../../../../app/common/state/ledgerState')
})
+ after(function () {
+ mockery.deregisterAll()
+ mockery.disable()
+ })
+
describe('setLedgerValue', function () {
it('null case', function () {
const result = ledgerState.setLedgerValue(defaultState)
@@ -161,6 +257,9 @@ describe('ledgerState unit test', function () {
before(function () {
hideNotificationSpy = sinon.spy(appActions, 'hideNotification')
})
+ after(function () {
+ hideNotificationSpy.restore()
+ })
it('we have existing promotion, but is empty', function () {
const state = defaultState
@@ -486,6 +585,21 @@ describe('ledgerState unit test', function () {
const expectedPromo = promo.set('claimedTimestamp', 10000)
assert.deepEqual(result.toJS(), expectedPromo.toJS())
})
+
+ it('with captcha', function () {
+ const promo = Immutable.fromJS({
+ notification: {
+ message: 'Hello'
+ }
+ })
+ const state = defaultState
+ .setIn(['ledger', 'promotion', 'activeState'], 'emptyWallet')
+ .setIn(['ledger', 'promotion', 'captcha'], 'base64....')
+ .setIn(['ledger', 'promotion', 'stateWallet', 'emptyWallet'], promo)
+ const result = ledgerState.getAboutPromotion(state)
+ const expectedPromo = promo.set('captcha', 'base64....')
+ assert.deepEqual(result.toJS(), expectedPromo.toJS())
+ })
})
describe('resetInfo', function () {
@@ -499,7 +613,7 @@ describe('ledgerState unit test', function () {
assert.deepEqual(result.toJS(), expectedState.toJS())
})
- it('keep is on, but paymentId is not there', function () {
+ it('keep is on, but paymentId and transactions are not there', function () {
const state = defaultState.setIn(['ledger', 'info'], Immutable.fromJS({
balance: 10.00
}))
@@ -511,11 +625,21 @@ describe('ledgerState unit test', function () {
it('keep it', function () {
const state = defaultState.setIn(['ledger', 'info'], Immutable.fromJS({
paymentId: 'a-1-a',
+ transactions: [
+ {
+ votes: 15
+ }
+ ],
balance: 10.00
}))
const result = ledgerState.resetInfo(state, true)
const expectedState = defaultState.setIn(['ledger', 'info'], Immutable.fromJS({
- paymentId: 'a-1-a'
+ paymentId: 'a-1-a',
+ transactions: [
+ {
+ votes: 15
+ }
+ ]
}))
assert.deepEqual(result.toJS(), expectedState.toJS())
})
@@ -579,4 +703,142 @@ describe('ledgerState unit test', function () {
})
})
})
+
+ describe('setAboutProp', function () {
+ it('null case', function () {
+ const result = ledgerState.setAboutProp(defaultState)
+ assert.deepEqual(result.toJS(), defaultState.toJS())
+ })
+
+ it('prop is set', function () {
+ const result = ledgerState.setAboutProp(defaultState, 'status', 'ok')
+ const expectedState = defaultState.setIn(['ledger', 'about', 'status'], 'ok')
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('getAboutProp', function () {
+ it('null case', function () {
+ const result = ledgerState.getAboutProp(defaultState)
+ assert.equal(result, null)
+ })
+
+ it('prop is set', function () {
+ const state = defaultState.setIn(['ledger', 'about', 'status'], 'corrupted')
+ const result = ledgerState.getAboutProp(state, 'status')
+ assert.equal(result, 'corrupted')
+ })
+ })
+
+ describe('getVerifiedPublisherLocation', function () {
+ it('null case', function () {
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState)
+ assert.equal(result, null)
+ })
+ it('empty string', function () {
+ const url = ''
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, null)
+ })
+ it('url shortener', function () {
+ const url = 'https://www.duckduckgo.com'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'duckduckgo.com')
+ })
+ it('url shortner with sub levels', function () {
+ const url = 'https://brianbondywww.com/projects/'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'brianbondywww.com')
+ })
+ it('url shortner with sub levels', function () {
+ const url = 'https://www.brianbondywww.com/projects/'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'brianbondywww.com')
+ })
+ it('url shortner with sub levels', function () {
+ const url = 'https://www2.brianbondy.com/projects/'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'brianbondy.com')
+ })
+ it('url shortner with sub levels', function () {
+ const url = 'https://subdomain.brianbondy.com/projects/'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'brianbondy.com')
+ })
+ it('url shortener with multi sublevels', function () {
+ const url = 'https://www.coindesk.com/market-center/ethereum'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'coindesk.com')
+ })
+ it('url shortener with any protocol', function () {
+ const url = 'anything://www.this.any.site.com'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'site.com')
+ })
+ it('url shortener with any protocol [ccTLD]', function () {
+ const url = 'anything://www.this.any.site.co.jp'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'site.co.jp')
+ })
+ it('url shortener with any protocol with sublevels', function () {
+ const url = 'anything://www.this.any.site.co.jp/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'site.co.jp')
+ })
+ it('url shortener with any protocol with sublevels ultra log', function () {
+ const url = 'anything://www.this.any.site.co.jp/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v/a/b/c/d/e/f/g/h/i/j/k/l/m/n/o/p/q/r/s/.com/r/s/t/u/v'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'site.co.jp')
+ })
+ it('url shortener with any protocol confusion', function () {
+ const url = 'anything://www.2.www.ww.www.this.any.site.com.org.com'
+ const result = ledgerState.getVerifiedPublisherLocation(defaultState, url)
+ assert.equal(result, 'org.com')
+ })
+ })
+
+ describe('deleteSynopsis', function () {
+ it('data is cleared', function () {
+ const result = ledgerState.deleteSynopsis(stateWithPublisher)
+ const expectedState = stateWithPublisher
+ .set('ledger', Immutable.fromJS({
+ about: {
+ synopsis: [],
+ synopsisOptions: {}
+ },
+ info: {},
+ locations: {},
+ synopsis: {
+ options: {},
+ publishers: {}
+ },
+ promotion: {}
+ }))
+ .setIn(['cache', 'ledgerVideos'], Immutable.Map())
+ .setIn(['pageData', 'info'], Immutable.Map())
+ .setIn(['pageData', 'last', 'info'], null)
+ .setIn(['pageData', 'last', 'tabId'], null)
+ .setIn(['pageData', 'last', 'closedTabValue'], null)
+
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
+
+ describe('resetPublishers', function () {
+ it('data is cleared', function () {
+ const result = ledgerState.resetPublishers(stateWithPublisher)
+ const expectedState = stateWithPublisher
+ .setIn(['ledger', 'synopsis', 'publishers'], Immutable.Map())
+ .setIn(['ledger', 'locations'], Immutable.Map())
+ .setIn(['ledger', 'about', 'synopsis'], Immutable.List())
+ .setIn(['ledger', 'publisherTimestamp'], 0)
+ .setIn(['cache', 'ledgerVideos'], Immutable.Map())
+ .setIn(['pageData', 'info'], Immutable.Map())
+ .setIn(['pageData', 'last', 'info'], null)
+ .setIn(['pageData', 'last', 'tabId'], null)
+ .setIn(['pageData', 'last', 'closedTabValue'], null)
+
+ assert.deepEqual(result.toJS(), expectedState.toJS())
+ })
+ })
})
diff --git a/test/unit/app/common/state/tabContentStateTest/audioStateTest.js b/test/unit/app/common/state/tabContentStateTest/audioStateTest.js
index 19aec879344..20a005721ff 100644
--- a/test/unit/app/common/state/tabContentStateTest/audioStateTest.js
+++ b/test/unit/app/common/state/tabContentStateTest/audioStateTest.js
@@ -156,7 +156,15 @@ describe('audioState unit tests', function () {
const state = defaultState
.setIn(['frames', index, 'audioPlaybackActive'], false)
.setIn(['frames', index, 'audioMuted'], false)
- .setIn(['ui', 'tabs', 'intersectionRatio'], intersection.at45)
+ .setIn(['ui', 'tabs', 'intersectionRatio'], intersection.at46)
+ const result = audioState.showAudioTopBorder(state, frameKey, false)
+ assert.equal(result, false)
+ })
+
+ it('return false if tab audio is mute and not pinned', function * () {
+ const state = defaultState
+ .setIn(['frames', index, 'audioPlayback'], true)
+ .setIn(['frames', index, 'audioMuted'], true)
const result = audioState.showAudioTopBorder(state, frameKey, false)
assert.equal(result, false)
})
diff --git a/test/unit/app/common/state/tabContentStateTest/closeStateTest.js b/test/unit/app/common/state/tabContentStateTest/closeStateTest.js
index 32f44f565c4..bd9619a6fb7 100644
--- a/test/unit/app/common/state/tabContentStateTest/closeStateTest.js
+++ b/test/unit/app/common/state/tabContentStateTest/closeStateTest.js
@@ -150,7 +150,7 @@ describe('closeState unit tests', function () {
it('returns false if tab is intersected and not active', function * () {
const state = defaultState
.set('activeFrameKey', 1337)
- .setIn(['ui', 'tabs', 'intersectionRatio', intersection.at45])
+ .setIn(['ui', 'tabs', 'intersectionRatio', intersection.at46])
const result = closeState.showCloseTabIcon(state, frameKey)
assert.equal(result, false)
})
diff --git a/test/unit/app/common/state/tabStateTest.js b/test/unit/app/common/state/tabStateTest.js
index 84f56fa5b98..e5be82348ee 100644
--- a/test/unit/app/common/state/tabStateTest.js
+++ b/test/unit/app/common/state/tabStateTest.js
@@ -236,7 +236,7 @@ describe('tabState unit tests', function () {
})
it('returns a new immutable state with the tab for `tabId` removed if it exists', function () {
- assert.deepEqual(tabState.removeTabByTabId(this.appState, 2).get('tabs').toJS(), [twoTabsAppState.getIn(['tabs', 0]).toJS()])
+ assert.deepEqual(tabState.removeTabByTabId(this.appState, 2).get('tabs').toJS(), [twoTabsAppState.getIn(['tabs', 0]).toJS(), {}])
})
it('returns the state unmodified if the tab for `tabId` does not exist', function () {
@@ -258,7 +258,7 @@ describe('tabState unit tests', function () {
})
it('returns a new immutable state with the tab at `index` removed if it exists', function () {
- assert.deepEqual(tabState.removeTabByIndex(this.appState, 1).get('tabs').toJS(), [ twoTabsAppState.getIn(['tabs', 0]).toJS() ])
+ assert.deepEqual(tabState.removeTabByIndex(this.appState, 1).get('tabs').toJS(), [ twoTabsAppState.getIn(['tabs', 0]).toJS(), {} ])
})
it('returns the state unmodified if `index` is out of bounds', function () {
diff --git a/test/unit/app/common/state/tabUIStateTest.js b/test/unit/app/common/state/tabUIStateTest.js
index 58a11a189bb..25de62604f2 100644
--- a/test/unit/app/common/state/tabUIStateTest.js
+++ b/test/unit/app/common/state/tabUIStateTest.js
@@ -8,7 +8,6 @@ const assert = require('assert')
const Immutable = require('immutable')
const mockery = require('mockery')
const fakeElectron = require('../../../lib/fakeElectron')
-const {theme} = require('../../../../../app/renderer/components/styles/theme')
const {intersection} = require('../../../../../app/renderer/components/styles/global')
const frameKey = 1
@@ -307,95 +306,4 @@ describe('tabUIState unit tests', function () {
assert.equal(result, true)
})
})
-
- describe('getTabEndIconBackgroundColor', function () {
- before(function () {
- // just a helper for results
- this.defaultResult = (bgColor, color1Size, color2Size) =>
- `linear-gradient(to left, ${bgColor} ${color1Size}, transparent ${color2Size})`
- })
-
- describe('when tab is private', function () {
- it('returns `tab.private.background` color if not active', function * () {
- const state = defaultState
- .set('activeFrameKey', 1337)
- .mergeIn(['frames', index], {
- themeColor: '#c0ff33',
- isPrivate: true
- })
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult(theme.tab.private.background, '10px', '40px')
- assert.equal(result, expected)
- })
-
- it('returns `tab.active.private.background` if tab is active', function * () {
- const state = defaultState
- .mergeIn(['frames', index], {
- themeColor: '#c0ff33',
- isPrivate: true
- })
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult(theme.tab.active.private.background, '10px', '40px')
- assert.equal(result, expected)
- })
-
- it('retuns active private color if tab is being hovered', function * () {
- const state = defaultState
- .mergeIn(['frames', index], {
- themeColor: '#c0ff33',
- isPrivate: true
- })
- .setIn(['ui', 'tabs', 'hoverTabIndex'], index)
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult(theme.tab.active.private.background, '10px', '40px')
- assert.equal(result, expected)
- })
- })
-
- describe('when tab is not private', function () {
- it('returns the themeColor if tab is active', function * () {
- const state = defaultState
- .setIn(['frames', index, 'themeColor'], '#c0ff33')
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult('#c0ff33', '0', '12px')
- assert.equal(result, expected)
- })
- it('returns `theme.tab.background` if tab is not active', function * () {
- const state = defaultState
- .set('activeFrameKey', 1337)
- .setIn(['frames', index, 'themeColor'], '#c0ff33')
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult(theme.tab.background, '0', '12px')
- assert.equal(result, expected)
- })
- })
-
- describe('returns `linear gradient` size', function () {
- it('at 10px/40px if tab is partitioned', function * () {
- const state = defaultState
- .mergeIn(['frames', index], {
- partitionNumber: 1337,
- themeColor: '#c0ff33'
- })
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult('#c0ff33', '10px', '40px')
- assert.equal(result, expected)
- })
- it('at 10px/40px gradient size if tab has a visible close icon', function * () {
- const state = defaultState
- .setIn(['frames', index, 'themeColor'], '#c0ff33')
- .setIn(['ui', 'tabs', 'hoverTabIndex'], index)
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult('#c0ff33', '10px', '40px')
- assert.equal(result, expected)
- })
- it('at 0/12px gradient size if is neither private, partition or has close icon visible', function * () {
- const state = defaultState
- .setIn(['frames', index, 'themeColor'], '#c0ff33')
- const result = tabUIState.getTabEndIconBackgroundColor(state, frameKey)
- const expected = this.defaultResult('#c0ff33', '0', '12px')
- assert.equal(result, expected)
- })
- })
- })
})
diff --git a/test/unit/app/extensions/brave/content/scripts/requestHandlerTest.js b/test/unit/app/extensions/brave/content/scripts/requestHandlerTest.js
new file mode 100644
index 00000000000..df7530a0f34
--- /dev/null
+++ b/test/unit/app/extensions/brave/content/scripts/requestHandlerTest.js
@@ -0,0 +1,619 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* global describe, it, before */
+const assert = require('assert')
+
+const fakeElectron = require('../../../../../lib/fakeElectron')
+require('../../../../../braveUnit')
+
+describe('requestHandler unit test', function () {
+ let requestHandler, parseFromStringHTML
+
+ before(() => {
+ global.chrome = {
+ ipcRenderer: fakeElectron.ipcRenderer
+ }
+
+ global.DOMParser = class {
+ parseFromString () {
+ return parseFromStringHTML
+ }
+ }
+
+ global.XMLSerializer = class {
+ serializeToString () {
+ return ''
+ }
+ }
+
+ requestHandler = require('../../../../../../../app/extensions/brave/content/scripts/requestHandler')
+ })
+
+ describe('getText', function () {
+ it('null case', function () {
+ const result = requestHandler.getText()
+ assert.equal(result, '')
+ })
+
+ it('node is actually number', function () {
+ const result = requestHandler.getText(123)
+ assert.equal(result, '')
+ })
+
+ it('span is provided', function () {
+ let span = document.createElement('span')
+ span.innerHTML = ('Span hello')
+ const result = requestHandler.getText(span)
+ assert.equal(result, ' Span hello ')
+ })
+ })
+
+ describe('urlCheck', function () {
+ it('null case', function () {
+ const result = requestHandler.urlCheck()
+ assert.equal(result, false)
+ })
+
+ it('is not url', function () {
+ const result = requestHandler.urlCheck(123)
+ assert.equal(result, false)
+ })
+
+ it('is http url', function () {
+ const result = requestHandler.urlCheck('http://test.com')
+ assert.equal(result, true)
+ })
+ })
+
+ describe('getContent', function () {
+ it('null case', function () {
+ const result = requestHandler.getContent()
+ assert.equal(result, null)
+ })
+
+ it('empty object', function () {
+ const result = requestHandler.getContent({})
+ assert.equal(result, null)
+ })
+
+ it('src is provided', function () {
+ const result = requestHandler.getContent({content: 'some text'})
+ assert.equal(result, 'some text')
+ })
+ })
+
+ describe('getSrc', function () {
+ it('null case', function () {
+ const result = requestHandler.getSrc()
+ assert.equal(result, null)
+ })
+
+ it('empty object', function () {
+ const result = requestHandler.getSrc({})
+ assert.equal(result, null)
+ })
+
+ it('src is provided', function () {
+ const result = requestHandler.getSrc({src: 'url'})
+ assert.equal(result, 'url')
+ })
+ })
+
+ describe('urlTest', function () {
+ it('null case', function () {
+ const result = requestHandler.urlTest()
+ assert.equal(result, false)
+ })
+
+ it('is not url', function () {
+ const result = requestHandler.urlTest(123)
+ assert.equal(result, false)
+ })
+
+ it('is simple url', function () {
+ const result = requestHandler.urlTest('test.com')
+ assert.equal(result, true)
+ })
+
+ it('is http url', function () {
+ const result = requestHandler.urlTest('http://test.com')
+ assert.equal(result, true)
+ })
+
+ it('is file url', function () {
+ const result = requestHandler.urlTest('file://test.png')
+ assert.equal(result, true)
+ })
+
+ it('relative url', function () {
+ const result = requestHandler.urlTest('/page', {relative: true})
+ assert.equal(result, true)
+ })
+
+ it('do not allow relative url', function () {
+ const result = requestHandler.urlTest('/page', {relative: false})
+ assert.equal(result, false)
+ })
+ })
+
+ describe('isEmpty', function () {
+ it('null case', function () {
+ const result = requestHandler.isEmpty()
+ assert.equal(result, true)
+ })
+
+ it('empty string', function () {
+ const result = requestHandler.isEmpty('')
+ assert.equal(result, true)
+ })
+
+ it('string is provided', function () {
+ const result = requestHandler.isEmpty('test.com')
+ assert.equal(result, false)
+ })
+ })
+
+ describe('isUrl', function () {
+ it('null case', function () {
+ const result = requestHandler.isUrl()
+ assert.equal(result, false)
+ })
+
+ it('emtpy string', function () {
+ const result = requestHandler.isUrl('')
+ assert.equal(result, false)
+ })
+
+ it('is not url', function () {
+ const result = requestHandler.isUrl(123)
+ assert.equal(result, false)
+ })
+
+ it('is simple url', function () {
+ const result = requestHandler.isUrl('test.com')
+ assert.equal(result, true)
+ })
+
+ it('is http url', function () {
+ const result = requestHandler.isUrl('http://test.com')
+ assert.equal(result, true)
+ })
+
+ it('is file url', function () {
+ const result = requestHandler.isUrl('file://test.png')
+ assert.equal(result, true)
+ })
+
+ it('relative url', function () {
+ const result = requestHandler.isUrl('/page', {relative: true})
+ assert.equal(result, true)
+ })
+
+ it('do not allow relative url', function () {
+ const result = requestHandler.isUrl('/page', {relative: false})
+ assert.equal(result, false)
+ })
+ })
+
+ describe('getUrl', function () {
+ it('null case', function () {
+ const result = requestHandler.getUrl()
+ assert.equal(result, undefined)
+ })
+
+ it('relative path is absolute link', function () {
+ const result = requestHandler.getUrl('https://youtube.com', '/page')
+ assert.equal(result, 'https://youtube.com/page')
+ })
+
+ it('relative path is relative link', function () {
+ const result = requestHandler.getUrl('https://youtube.com', '/page')
+ assert.equal(result, 'https://youtube.com/page')
+ })
+
+ it('relative path is absolute link', function () {
+ const result = requestHandler.getUrl('https://youtube.com', 'https://youtube.com/page')
+ assert.equal(result, 'https://youtube.com/page')
+ })
+ })
+
+ describe('isStrictString', function () {
+ it('null case', function () {
+ const result = requestHandler.isStrictString()
+ assert.equal(result, false)
+ })
+
+ it('value is no in correct format', function () {
+ const result = requestHandler.isStrictString('firstlast')
+ assert.equal(result, false)
+ })
+
+ it('value is in correct format', function () {
+ const result = requestHandler.isStrictString('first last')
+ assert.equal(result, 'first last')
+ })
+ })
+
+ describe('titleize', function () {
+ it('null case', function () {
+ const result = requestHandler.titleize()
+ assert.equal(result, '')
+ })
+
+ it('remove multiple spaces', function () {
+ const result = requestHandler.titleize('this is long title')
+ assert.equal(result, 'this is long title')
+ })
+
+ it('keep by by default', function () {
+ const result = requestHandler.titleize('by Author')
+ assert.equal(result, 'by Author')
+ })
+
+ it('keep by by default', function () {
+ const result = requestHandler.titleize('by Author', {removeBy: true})
+ assert.equal(result, 'Author')
+ })
+ })
+
+ describe('defaultFn', function () {
+ it('null case', function () {
+ const result = requestHandler.defaultFn()
+ assert.equal(result, '')
+ })
+
+ it('parameter is not HTML element', function () {
+ const result = requestHandler.defaultFn('something')
+ assert.equal(result, '')
+ })
+
+ it('text is trimmed', function () {
+ let span = document.createElement('span')
+ span.innerHTML = (' Span as a child ')
+
+ const result = requestHandler.defaultFn(span)
+ assert.equal(result, 'Span as a child')
+ })
+ })
+
+ describe('getValue', function () {
+ it('null case', function () {
+ const result = requestHandler.getValue()
+ assert.equal(result, null)
+ })
+
+ it('collection has only one element', function () {
+ let wrap = document.createElement('div')
+ let span = document.createElement('span')
+ span.innerHTML = ('Span as a child')
+ wrap.appendChild(span)
+ const result = requestHandler.getValue(wrap.querySelector('span'))
+ assert.equal(result, 'Span as a child')
+ })
+
+ it('collection has multiple elements', function () {
+ let wrap = document.createElement('div')
+ let span = document.createElement('span')
+ span.innerHTML = ('Span as a first child')
+ wrap.appendChild(span)
+ let span2 = document.createElement('span')
+ span2.innerHTML = ('Span as a second child')
+ wrap.appendChild(span2)
+ const result = requestHandler.getValue(wrap.querySelectorAll('span'))
+ assert.equal(result, 'Span as a first child')
+ })
+
+ it('first element has empty span', function () {
+ let wrap = document.createElement('div')
+ let span = document.createElement('span')
+ span.innerHTML = ('')
+ wrap.appendChild(span)
+ let span2 = document.createElement('span')
+ span2.innerHTML = ('Span as a second child')
+ wrap.appendChild(span2)
+ const result = requestHandler.getValue(wrap.querySelectorAll('span'))
+ assert.equal(result, 'Span as a second child')
+ })
+ })
+
+ describe('getThumbnailUrl', function () {
+ it('null case', function () {
+ const result = requestHandler.getThumbnailUrl()
+ assert.equal(result, null)
+ })
+
+ it('id is passed in', function () {
+ const result = requestHandler.getThumbnailUrl('ABC12302')
+ assert.equal(result, `https://img.youtube.com/vi/ABC12302/sddefault.jpg`)
+ })
+ })
+
+ describe('getVideoId', function () {
+ it('null case', function () {
+ const result = requestHandler.getVideoId()
+ assert.deepEqual(result, {})
+ })
+
+ it('strip white space', function () {
+ const result = requestHandler.getVideoId(' https://youtu.be/ABC12302 ')
+ assert.deepEqual(result, {
+ id: 'ABC12302',
+ service: 'youtube'
+ })
+ })
+
+ it('strip white space', function () {
+ const result = requestHandler.getVideoId(' https://youtu.be/ABC12302 ')
+ assert.deepEqual(result, {
+ id: 'ABC12302',
+ service: 'youtube'
+ })
+ })
+
+ it('nocookie ', function () {
+ const result = requestHandler.getVideoId('http://www.youtube-nocookie.com/ytscreeningroom?v=ABC12300')
+ assert.deepEqual(result, {
+ id: 'ABC12300',
+ service: 'youtube'
+ })
+ })
+
+ it('removes www', function () {
+ const result = requestHandler.getVideoId('https://www.youtu.be/ABC12302')
+ assert.deepEqual(result, {
+ id: 'ABC12302',
+ service: 'youtube'
+ })
+ })
+ })
+
+ // source https://github.com/radiovisual/get-video-id/blob/master/test.js
+ describe('getYouTubeId', function () {
+ it('null case', function () {
+ const result = requestHandler.getYouTubeId()
+ assert.equal(result, '')
+ })
+
+ it('gets metadata from youtube short code formats', () => {
+ assert.equal(requestHandler.getYouTubeId('youtube://ABC12301'), 'ABC12301')
+ assert.equal(requestHandler.getYouTubeId('https://youtu.be/ABC12302'), 'ABC12302')
+ assert.equal(requestHandler.getYouTubeId('http://youtu.be/ABC12303'), 'ABC12303')
+ assert.equal(requestHandler.getYouTubeId('http://youtu.be/ABC12304?feature=youtube_gdata_player'), 'ABC12304')
+ })
+
+ it('handles youtube v= and vi= formats', () => {
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/ytscreeningroom?v=ABC1230'), 'ABC1230')
+ assert.equal(requestHandler.getYouTubeId('https://www.youtube.com/watch?v=ABC12301'), 'ABC12301')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12302&list=abc123&index=2&feature=plpp_video'), 'ABC12302')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12303&feature=channel'), 'ABC12303')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12304&playnext_from=TL&videos=abc123&feature=sub'), 'ABC12304')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12305&feature=channel'), 'ABC12305')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12306&playnext_from=TL&videos=abc123&feature=sub'), 'ABC12306')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12307'), 'ABC12307')
+ assert.equal(requestHandler.getYouTubeId('http://youtube.com/?v=ABC12308&feature=youtube_gdata_player'), 'ABC12308')
+ assert.equal(requestHandler.getYouTubeId('http://youtube.com/?vi=ABC12309&feature=youtube_gdata_player'), 'ABC12309')
+ assert.equal(requestHandler.getYouTubeId('http://youtube.com/watch?v=ABC12310&feature=youtube_gdata_player'), 'ABC12310')
+ assert.equal(requestHandler.getYouTubeId('http://youtube.com/watch?vi=ABC12311&feature=youtube_gdata_player'), 'ABC12311')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12312&feature=youtube_gdata_player'), 'ABC12312')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/watch?v=ABC12313&feature=youtu.be'), 'ABC12313')
+ })
+
+ it('handles youtube /v/ and /vi/ formats', () => {
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/v/ABC1230'), 'ABC1230')
+ assert.equal(requestHandler.getYouTubeId('http://youtube.com/v/ABC12301?feature=youtube_gdata_player'), 'ABC12301')
+ assert.equal(requestHandler.getYouTubeId('http://youtube.com/vi/ABC12302?feature=youtube_gdata_player'), 'ABC12302')
+ assert.equal(requestHandler.getYouTubeId('https://i.ytimg.com/vi/0okagl9U2eo/hqdefault.jpg'), '0okagl9U2eo')
+ })
+
+ it('handles youtube image /an_webp/{id}/ formats', () => {
+ assert.equal(requestHandler.getYouTubeId('https://i.ytimg.com/an_webp/MYDcdp-VNmQ/mqdefault_6s.webp'), 'MYDcdp-VNmQ')
+ })
+
+ it('handles youtube /embed/ formats', () => {
+ assert.equal(requestHandler.getYouTubeId('https://www.youtube.com/embed/ABC1230'), 'ABC1230')
+ assert.equal(requestHandler.getYouTubeId('www.youtube-nocookie.com/embed/ABC12301?rel=0'), 'ABC12301')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/embed/ABC12302?rel=0'), 'ABC12302')
+ })
+
+ it('handles youtube /user/ formats', () => {
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/user/username#p/u/1/ABC1230'), 'ABC1230')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/user/username#p/a/u/2/ABC12301'), 'ABC12301')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/user/username#p/u/1/ABC12302?rel=0'), 'ABC12302')
+ })
+
+ it('handles youtube attribution_links', () => {
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?u=%2Fwatch%3Fv%3DABC12300%26feature%3Dshare&a=JdfC0C9V6ZI'), 'ABC12300')
+ assert.equal(requestHandler.getYouTubeId('https://www.youtube.com/attribution_link?a=JdfC0C9V6ZI&u=%2Fwatch%3Fv%3DABC12301%26feature%3Dshare'), 'ABC12301')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?u=/watch?v=ABC12302&feature=share&list=UUsnCjinFcybOuyJU1NFOJmg&a=LjnCygXKl21WkJdyKu9O-w'), 'ABC12302')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?u=/watch?v=ABC12303&feature=share&a=9QlmP1yvjcllp0h3l0NwuA'), 'ABC12303')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?a=fF1CWYwxCQ4&u=/watch?v=ABC12304&feature=em-uploademail'), 'ABC12304')
+ assert.equal(requestHandler.getYouTubeId('http://www.youtube.com/attribution_link?a=fF1CWYwxCQ4&feature=em-uploademail&u=/watch?v=ABC12305'), 'ABC12305')
+ })
+ })
+
+ describe('stripParameters', function () {
+ it('null case', function () {
+ const result = requestHandler.stripParameters()
+ assert.equal(result, '')
+ })
+
+ it('string with parms', function () {
+ const result = requestHandler.stripParameters('this is test')
+ assert.equal(result, 'this is test')
+ })
+
+ it('string with /', function () {
+ const result = requestHandler.stripParameters('this is/test')
+ assert.equal(result, 'this is')
+ })
+
+ it('string with ?', function () {
+ const result = requestHandler.stripParameters('this is?test')
+ assert.equal(result, 'this is')
+ })
+ })
+
+ describe('smartQuotes', function () {
+ it('null case', function () {
+ const result = requestHandler.smartQuotes()
+ assert.equal(result, '')
+ })
+
+ it('regular quote', function () {
+ const result = requestHandler.smartQuotes(`'test'`)
+ assert.equal(result, `‘test’`)
+ })
+
+ it('double quote (start)', function () {
+ const result = requestHandler.smartQuotes(`'test'`)
+ assert.equal(result, `‘test’`)
+ })
+
+ it('double quote (start)', function () {
+ const result = requestHandler.smartQuotes(`this is "test"`)
+ assert.equal(result, `this is “test”`)
+ })
+
+ it('compilation 1', function () {
+ const result = requestHandler.smartQuotes(`Ma'am, this "test" is from '95`)
+ assert.equal(result, `Ma’am, this “test” is from ’95`)
+ })
+
+ it('compilation 2', function () {
+ const result = requestHandler.smartQuotes(`something of 'Something's`)
+ assert.equal(result, `something of ’Something’s`)
+ })
+ })
+
+ describe('removeByPrefix', function () {
+ it('null case', function () {
+ const result = requestHandler.removeByPrefix()
+ assert.equal(result, '')
+ })
+
+ it('case with param null', function () {
+ const result = requestHandler.removeByPrefix(null)
+ assert.equal(result, '')
+ })
+
+ it('removes @ prefix', function () {
+ const result = requestHandler.removeByPrefix('test @this')
+ assert.equal(result, 'test this')
+ })
+
+ it('removes by prefix', function () {
+ const result = requestHandler.removeByPrefix(' by me author')
+ assert.equal(result, 'me author')
+ })
+
+ it('removes BY prefix', function () {
+ const result = requestHandler.removeByPrefix(' BY me author')
+ assert.equal(result, 'me author')
+ })
+ })
+
+ describe('createTitle', function () {
+ it('null case', function () {
+ const result = requestHandler.createTitle()
+ assert.equal(result, '')
+ })
+
+ it('case with param null', function () {
+ const result = requestHandler.createTitle(null)
+ assert.equal(result, '')
+ })
+
+ it('trim string', function () {
+ const result = requestHandler.createTitle(' this is test ')
+ assert.equal(result, 'this is test')
+ })
+
+ it('remove double and more spaces', function () {
+ const result = requestHandler.createTitle('this is test ')
+ assert.equal(result, 'this is test')
+ })
+
+ it('create smart quotes', function () {
+ const result = requestHandler.createTitle(`this "is" test which is 'ok'`)
+ assert.strictEqual(result, `this “is” test which is ‘ok’`)
+ })
+ })
+
+ describe('isAbsoluteUrl', function () {
+ it('null case', function () {
+ const result = requestHandler.isAbsoluteUrl()
+ assert.equal(result, undefined)
+ })
+
+ it('object was send in', function () {
+ const result = requestHandler.isAbsoluteUrl({})
+ assert.equal(result, undefined)
+ })
+
+ it('http url', function () {
+ const result = requestHandler.isAbsoluteUrl('http://clifton.io')
+ assert.equal(result, true)
+ })
+
+ it('http url', function () {
+ const result = requestHandler.isAbsoluteUrl('https://clifton.io')
+ assert.equal(result, true)
+ })
+
+ it('data url', function () {
+ const result = requestHandler.isAbsoluteUrl('data:text/plain;base64,31c4c5flv')
+ assert.equal(result, true)
+ })
+
+ it('file url', function () {
+ const result = requestHandler.isAbsoluteUrl('file://clifton.io')
+ assert.equal(result, true)
+ })
+ })
+
+ describe('resolveUrl', function () {
+ it('null case', function () {
+ const result = requestHandler.resolveUrl()
+ assert.equal(result, null)
+ })
+
+ it('args are not urls', function () {
+ const result = requestHandler.resolveUrl('brave', 'com')
+ assert.equal(result, 'brave')
+ })
+
+ it('we only have base url', function () {
+ const result = requestHandler.resolveUrl('https://brave.com')
+ assert.equal(result, 'https://brave.com')
+ })
+
+ it('relative path is added', function () {
+ const result = requestHandler.resolveUrl('https://brave.com', 'test')
+ assert.equal(result, 'https://brave.com/test')
+ })
+ })
+
+ describe('isString', function () {
+ it('null case', function () {
+ const result = requestHandler.isString()
+ assert.equal(result, false)
+ })
+
+ it('we send object in', function () {
+ const result = requestHandler.isString({})
+ assert.equal(result, false)
+ })
+
+ it('we send number in', function () {
+ const result = requestHandler.isString(10)
+ assert.equal(result, false)
+ })
+
+ it('we send string in', function () {
+ const result = requestHandler.isString('I am string')
+ assert.equal(result, true)
+ })
+ })
+})
diff --git a/test/unit/app/filteringTest.js b/test/unit/app/filteringTest.js
index 961ff19a174..a0938284e38 100644
--- a/test/unit/app/filteringTest.js
+++ b/test/unit/app/filteringTest.js
@@ -92,15 +92,44 @@ describe('filtering unit tests', function () {
isResourceEnabledStub.restore()
})
- it('sets the referer to the origin', function () {
- const url = 'https://cdnp3.stackassets.com/574db2390a12942fcef927356dadc6f9955edea9/store/fe3eb8fc014a20f2d25810b3c4f4b5b0db8695adfd7e8953721a55c51b90/sale_7217_primary_image.jpg'
- const firstPartyUrl = 'https://slashdot.org/'
- const requestHeaders = {
- Referer: 'https://brave.com'
- }
- const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)
+ describe('stubs referer for third-party referer', function () {
+ const firstPartyUrl = 'https://brave.com'
+ it('when the hosts are completely different', function () {
+ const url = 'https://cdnp3.stackassets.com/574db2390a12942fcef927356dadc6f9955edea9/store/fe3eb8fc014a20f2d25810b3c4f4b5b0db8695adfd7e8953721a55c51b90/sale_7217_primary_image.jpg'
+ const requestHeaders = {
+ Referer: 'https://brave.com'
+ }
+ const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)
+ assert.equal(result.Referer, 'https://cdnp3.stackassets.com')
+ })
+ it('when the hosts have different base domains according to the PSL', function () {
+ const url = 'https://diracdeltas.github.io/foo?abc#test'
+ const requestHeaders = {
+ Referer: 'https://github.io'
+ }
+ const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)
+ assert.equal(result.Referer, 'https://diracdeltas.github.io')
+ })
+ })
- assert.equal(result.Referer, 'https://cdnp3.stackassets.com')
+ describe('does not change referer for first-party referer', function () {
+ const firstPartyUrl = 'https://brave.com'
+ it('keeps referer when hosts are the same', function () {
+ const url = 'https://test.github.io/test'
+ const requestHeaders = {
+ Referer: 'https://test.github.io/foo'
+ }
+ const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)
+ assert.equal(result.Referer, 'https://test.github.io/foo')
+ })
+ it('keeps referer when hosts share a baseDomain', function () {
+ const url = 'https://docs.google.com'
+ const requestHeaders = {
+ Referer: 'https://2.drive.google.com/mydocument#abc'
+ }
+ const result = filtering.applyCookieSetting(requestHeaders, url, firstPartyUrl, false)
+ assert.equal(result.Referer, 'https://2.drive.google.com/mydocument#abc')
+ })
})
describe('when there is a referer exception', function () {
diff --git a/test/unit/app/migrations/20180518_upholdTest.js b/test/unit/app/migrations/20180518_upholdTest.js
new file mode 100644
index 00000000000..547ece2f0d2
--- /dev/null
+++ b/test/unit/app/migrations/20180518_upholdTest.js
@@ -0,0 +1,69 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* global describe, it */
+const assert = require('assert')
+
+const migration = require('../../../../app/migrations/20180518_uphold')
+
+require('../../braveUnit')
+
+describe('20180518_uphold migration', function () {
+ it('does not run if global fingerprint protection is enabled', function () {
+ let data = {
+ fingerprintingProtectionAll: {
+ enabled: true
+ },
+ lastAppVersion: '0.22.714'
+ }
+ assert.equal(migration(data), false)
+ })
+
+ it('does not run if last app version is missing (new installs)', function () {
+ let data = {}
+ assert.equal(migration(data), false)
+ })
+
+ it('does not run if last app version is greater than 0.22.714', function () {
+ let data = {
+ lastAppVersion: '0.22.715'
+ }
+ assert.equal(migration(data), false)
+ })
+
+ it('runs if last app version is 0.22.714', function () {
+ let data = {
+ lastAppVersion: '0.22.714'
+ }
+ assert.equal(migration(data), true)
+ })
+
+ it('runs if last app version is older than 0.22.714', function () {
+ let data = {
+ lastAppVersion: '0.22.13'
+ }
+ assert.equal(migration(data), true)
+ })
+
+ it('sets fingerprintingProtection for the site (if not already set)', function () {
+ let data = {
+ lastAppVersion: '0.22.13'
+ }
+ migration(data)
+ assert.equal(data.siteSettings['https?://uphold.com'].fingerprintingProtection, 'allowAllFingerprinting')
+ })
+
+ it('does not overwrite an existing fingerprintingProtection setting for the site', function () {
+ let data = {
+ lastAppVersion: '0.22.13',
+ siteSettings: {
+ 'https?://uphold.com': {
+ fingerprintingProtection: 'blockAllFingerprinting'
+ }
+ }
+ }
+ migration(data)
+ assert.equal(data.siteSettings['https?://uphold.com'].fingerprintingProtection, 'blockAllFingerprinting')
+ })
+})
diff --git a/test/unit/app/renderer/components/common/messageBoxTest.js b/test/unit/app/renderer/components/common/messageBoxTest.js
index 15277c896ea..d497d076060 100644
--- a/test/unit/app/renderer/components/common/messageBoxTest.js
+++ b/test/unit/app/renderer/components/common/messageBoxTest.js
@@ -41,6 +41,25 @@ let appState = Immutable.fromJS({
}
})
+const createAppState = detail => Immutable.fromJS({
+ windows: [{
+ windowId: 1,
+ windowUUID: 'uuid'
+ }],
+ tabs: [{
+ tabId: tabId,
+ windowId: 1,
+ windowUUID: 'uuid',
+ url: 'https://brave.com',
+ messageBoxDetail: detail
+ }],
+ tabsInternal: {
+ index: {
+ 1: 0
+ }
+ }
+})
+
describe('MessageBox component unit tests', function () {
before(function () {
mockery.enable({
@@ -60,7 +79,7 @@ describe('MessageBox component unit tests', function () {
describe('Rendering', function () {
before(function () {
- appStoreRenderer.state = Immutable.fromJS(appState)
+ appStoreRenderer.state = createAppState(detail1)
})
it('renders itself inside a dialog component', function () {
const wrapper = mount(
@@ -98,6 +117,19 @@ describe('MessageBox component unit tests', function () {
assert.equal(wrapper.find('button[data-l10n-id="Cancel"][data-test-id="secondaryColor"]').length, 1)
})
+ it('renders the PromptTextBox when input is allowed', function () {
+ appStoreRenderer.state = createAppState(Object.assign({}, detail1, {
+ allowInput: true
+ }))
+ const wrapper = mount(
+
+ )
+ assert.equal(wrapper.find('PromptTextBox').length, 1)
+ })
+
it('hides the suppress checkbox if showSuppress is false', function () {
const appState2 = appState.setIn(['tabs', 0, 'messageBoxDetail', 'showSuppress'], false)
appStoreRenderer.state = Immutable.fromJS(appState2)
@@ -158,5 +190,27 @@ describe('MessageBox component unit tests', function () {
assert.equal(spy.withArgs(tabId, response).calledOnce, true)
appActions.tabMessageBoxDismissed.restore()
})
+
+ it('calls appActions.tabMessageBoxDismissed with input input is allowed', function () {
+ const expectedInput = 'some input'
+ appStoreRenderer.state = createAppState(Object.assign({}, detail1, {
+ allowInput: true,
+ defaultPromptText: expectedInput
+ }))
+ const spy = sinon.spy(appActions, 'tabMessageBoxDismissed')
+ const wrapper = mount(
+
+ )
+ const response = {
+ suppress: detail1.suppress,
+ result: false,
+ input: expectedInput
+ }
+ wrapper.find('button[data-l10n-id="Cancel"][data-test-id="secondaryColor"]').simulate('click')
+ assert.equal(spy.withArgs(tabId, response).calledOnce, true)
+ appActions.tabMessageBoxDismissed.restore()
+ })
})
})
diff --git a/test/unit/app/renderer/components/frame/frameTest.js b/test/unit/app/renderer/components/frame/frameTest.js
index ee7fe9e7477..24daa090667 100644
--- a/test/unit/app/renderer/components/frame/frameTest.js
+++ b/test/unit/app/renderer/components/frame/frameTest.js
@@ -47,8 +47,7 @@ describe.skip('Frame component unit tests', function () {
const fakeWindowActions = {
frameShortcutChanged: () => {},
setFindbarShown: () => {},
- setActiveFrame: () => {},
- setLastZoomPercentage: () => {}
+ setActiveFrame: () => {}
}
const domUtil = {
diff --git a/test/unit/app/renderer/components/preferences/payments/ledgerTableTest.js b/test/unit/app/renderer/components/preferences/payments/ledgerTableTest.js
index 167a651f07f..9651dbb3f38 100644
--- a/test/unit/app/renderer/components/preferences/payments/ledgerTableTest.js
+++ b/test/unit/app/renderer/components/preferences/payments/ledgerTableTest.js
@@ -16,36 +16,31 @@ const fivePublishers = {
[
'https?://times.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 10
+ ledgerPayments: true
})
],
[
'https?://cnn.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 15
+ ledgerPayments: true
})
],
[
'https?://brianbondy.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 0
+ ledgerPayments: true
})
],
[
'https?://github.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 0
+ ledgerPayments: true
})
],
[
'https?://clifton.io',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 0
+ ledgerPayments: true
})
]
]),
@@ -161,8 +156,7 @@ describe('LedgerTable component', function () {
[
'https?://times.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 0
+ ledgerPayments: true
})
]
])
@@ -202,22 +196,19 @@ describe('LedgerTable component', function () {
[
'https?://times.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 10
+ ledgerPayments: true
})
],
[
'https?://cnn.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 15
+ ledgerPayments: true
})
],
[
'https?://brianbondy.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 0
+ ledgerPayments: true
})
]
])
@@ -291,15 +282,13 @@ describe('LedgerTable component', function () {
[
'https?://times.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 10
+ ledgerPayments: true
})
],
[
'https?://cnn.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 15
+ ledgerPayments: true
})
]
])
@@ -357,8 +346,7 @@ describe('LedgerTable component', function () {
[
'https?://times.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 42
+ ledgerPayments: true
})
]
])
@@ -398,37 +386,32 @@ describe('LedgerTable component', function () {
[
'https?://times.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 10
+ ledgerPayments: true
})
],
[
'https?://cnn.com',
Immutable.Map({
ledgerPayments: true,
- ledgerPinPercentage: 15,
ledgerPaymentsShown: false
})
],
[
'https?://brianbondy.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 0
+ ledgerPayments: true
})
],
[
'https?://github.com',
Immutable.Map({
- ledgerPayments: true,
- ledgerPinPercentage: 0
+ ledgerPayments: true
})
],
[
'https?://clifton.io',
Immutable.Map({
ledgerPayments: true,
- ledgerPinPercentage: 0,
ledgerPaymentsShown: false
})
]
diff --git a/test/unit/app/renderer/components/preferences/paymentsTabTest.js b/test/unit/app/renderer/components/preferences/paymentsTabTest.js
index 4c7b9b12b65..c982a20aeee 100644
--- a/test/unit/app/renderer/components/preferences/paymentsTabTest.js
+++ b/test/unit/app/renderer/components/preferences/paymentsTabTest.js
@@ -9,10 +9,9 @@ const assert = require('assert')
const Immutable = require('immutable')
const fakeElectron = require('../../../../lib/fakeElectron')
const fakeSettings = require('../../../../lib/fakeSettings')
-const {batToCurrencyString} = require('../../../../../../app/common/lib/ledgerUtil')
const {advancedSettingsDialog} = require('../../../../../lib/selectors')
-let PaymentsTab, EnabledContent
+let PaymentsTab
require('../../../../braveUnit')
describe('PaymentsTab component', function () {
@@ -54,6 +53,8 @@ describe('PaymentsTab component', function () {
// Mocks the icon used in payments tab
mockery.registerMock('../../../extensions/brave/img/ledger/cryptoIcons/BAT_icon.svg')
mockery.registerMock('../../../../../img/toolbar/stoploading_btn.svg')
+ mockery.registerMock('../../../../extensions/brave/img/ledger/BAT_captcha_dragicon.png')
+ mockery.registerMock('../../../../extensions/brave/img/ledger/BAT_captcha_BG_arrow.png')
// Mocks the icons used in addFundsDialog and its steps
mockery.registerMock('../../../../../../extensions/brave/img/ledger/wallet_icon.svg')
mockery.registerMock('../../../../../../extensions/brave/img/ledger/cryptoIcons/ETH_icon.svg')
@@ -68,7 +69,6 @@ describe('PaymentsTab component', function () {
fakeSettings.mockReturnValue = false
window.chrome = fakeElectron
PaymentsTab = require('../../../../../../app/renderer/components/preferences/paymentsTab')
- EnabledContent = require('../../../../../../app/renderer/components/preferences/payment/enabledContent')
})
after(function () {
mockery.disable()
@@ -175,53 +175,6 @@ describe('PaymentsTab component', function () {
})
})
- describe('fundsamount functionality', function () {
- it('does not display if wallet not created', function () {
- fakeSettings.mockReturnValue = true
- const wrapper = mount(
-
- )
- const inst = wrapper.instance()
- assert.equal(inst.fundsAmount, null)
- })
-
- it('handles expected balance', function () {
- fakeSettings.mockReturnValue = true
- const wrapper = mount(
-
- )
- assert.equal(wrapper.find('[data-test-id="fundsAmount"]').length, 1)
- })
-
- it.skip('renders full balance correctly', function () {
- fakeSettings.mockReturnValue = true
- const wrapper = mount(
-
- )
- const inst = wrapper.instance()
- assert.equal(batToCurrencyString(10, inst.props.ledgerData), '10.00 USD')
- })
-
- it.skip('renders partial balance correctly', function () {
- fakeSettings.mockReturnValue = true
- const wrapper = mount(
-
- )
- const inst = wrapper.instance()
- assert.equal(batToCurrencyString(10, inst.props.ledgerData), '2.00 USD')
- })
- })
-
describe('advanced ledger settings content', function () {
it('defaults to an 8 second minimum visit duration', function () {
fakeSettings.mockReturnValue = true
diff --git a/test/unit/app/renderer/components/tabs/content/closeTabIconTest.js b/test/unit/app/renderer/components/tabs/content/closeTabIconTest.js
index 76388f87a67..4c091b8b97c 100644
--- a/test/unit/app/renderer/components/tabs/content/closeTabIconTest.js
+++ b/test/unit/app/renderer/components/tabs/content/closeTabIconTest.js
@@ -64,7 +64,6 @@ describe('Tabs content - CloseTabIcon', function () {
useCleanCache: true
})
mockery.registerMock('electron', fakeElectron)
- mockery.registerMock('../../../../extensions/brave/img/tabs/close_btn.svg')
windowStore = require('../../../../../../../js/stores/windowStore')
appStore = require('../../../../../../../js/stores/appStoreRenderer')
CloseTabIcon = require('../../../../../../../app/renderer/components/tabs/content/closeTabIcon')
diff --git a/test/unit/app/sessionStoreShutdownTest.js b/test/unit/app/sessionStoreShutdownTest.js
index 016cc1e0eb0..156759974db 100644
--- a/test/unit/app/sessionStoreShutdownTest.js
+++ b/test/unit/app/sessionStoreShutdownTest.js
@@ -36,6 +36,16 @@ describe('sessionStoreShutdown unit tests', function () {
const FakeWindow = require('../lib/fakeWindow')
const fakeAdBlock = require('../lib/fakeAdBlock')
+ const testRestorableWindowFrames = [
+ {
+ key: 1,
+ partitionNumber: 0,
+ src: 'https://brave.com',
+ location: 'https://brave.com',
+ unloaded: true
+ }
+ ]
+
before(function () {
this.clock = sinon.useFakeTimers()
mockery.enable({
@@ -120,21 +130,32 @@ describe('sessionStoreShutdown unit tests', function () {
})
it('works for first closed window', function () {
- const windowState = { a: 1, frames: [] }
+ const windowState = { a: 1, frames: testRestorableWindowFrames }
fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState)
process.emit(messages.UNDO_CLOSED_WINDOW)
assert(this.newWindowStub.calledOnce)
assert.deepEqual(this.newWindowStub.getCall(0).args[2].toJS(), windowState)
})
it('works for subsequent windows', function () {
- const windowState1 = { b: 1, frames: [] }
- const windowState2 = { x: 2, frames: [] }
+ const windowState1 = { b: 1, frames: testRestorableWindowFrames }
+ const windowState2 = { x: 2, frames: testRestorableWindowFrames }
fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState1)
fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState2)
process.emit(messages.UNDO_CLOSED_WINDOW)
assert(this.newWindowStub.calledOnce)
assert.deepEqual(this.newWindowStub.getCall(0).args[2].toJS(), windowState2)
})
+ // test for buffer window close (only case a window will be closed with no frames,
+ // since closing the last tab of a window closes the window with tab still there)
+ it('ignores windows with no frames', function () {
+ const windowState1 = { b: 1, frames: testRestorableWindowFrames }
+ const windowState2 = { x: 2, frames: [] }
+ fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState1)
+ fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState2)
+ process.emit(messages.UNDO_CLOSED_WINDOW)
+ assert(this.newWindowStub.calledOnce)
+ assert.deepEqual(this.newWindowStub.getCall(0).args[2].toJS(), windowState1)
+ })
})
describe('app before-quit event', function () {
@@ -182,10 +203,11 @@ describe('sessionStoreShutdown unit tests', function () {
})
it('remembers last closed window with no windows (Win32)', function (cb) {
isWindows = true
- const windowState = Immutable.fromJS({ a: 1 })
+ const windowState = { a: 1, frames: testRestorableWindowFrames }
fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState)
fakeElectron.app.emit('window-all-closed')
const saveAppStateStub = sinon.stub(sessionStore, 'saveAppState', (state) => {
+ console.log(state.toJS())
isWindows = false
assert.equal(saveAppStateStub.calledOnce, true)
saveAppStateStub.restore()
@@ -198,7 +220,7 @@ describe('sessionStoreShutdown unit tests', function () {
this.clock.tick(1)
})
it('remembers last closed window with no windows (Linux)', function (cb) {
- const windowState = Immutable.fromJS({ a: 1 })
+ const windowState = { a: 1, frames: testRestorableWindowFrames }
fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState)
fakeElectron.app.emit('window-all-closed')
const saveAppStateStub = sinon.stub(sessionStore, 'saveAppState', (state) => {
@@ -214,7 +236,7 @@ describe('sessionStoreShutdown unit tests', function () {
})
it('remembers last closed window with no windows (macOS)', function (cb) {
isDarwin = true
- const windowState = Immutable.fromJS({ a: 1 })
+ const windowState = Immutable.fromJS({ a: 1, frames: testRestorableWindowFrames })
fakeElectron.ipcMain.send(messages.LAST_WINDOW_STATE, {}, windowState)
fakeElectron.app.emit('window-all-closed')
const saveAppStateStub = sinon.stub(sessionStore, 'saveAppState', (state) => {
diff --git a/test/unit/app/sessionStoreTest.js b/test/unit/app/sessionStoreTest.js
index 9f730d4b19d..9eb13441486 100644
--- a/test/unit/app/sessionStoreTest.js
+++ b/test/unit/app/sessionStoreTest.js
@@ -1,22 +1,27 @@
-/* global describe, before, after, afterEach, it */
+/* global describe, before, beforeEach, after, afterEach, it */
const mockery = require('mockery')
const assert = require('assert')
const sinon = require('sinon')
const Immutable = require('immutable')
+const compareVersions = require('compare-versions')
const settings = require('../../../js/constants/settings')
const {makeImmutable} = require('../../../app/common/state/immutableUtil')
const downloadStates = require('../../../js/constants/downloadStates')
const siteTags = require('../../../js/constants/siteTags')
-const compareVersions = require('compare-versions')
+const ledgerStatuses = require('../../../app/common/constants/ledgerStatuses')
require('../braveUnit')
describe('sessionStore unit tests', function () {
+ let filtering
let sessionStore
+ let ledgerState
+
let shutdownClearHistory = false
let shutdownClearAutocompleteData = false
let shutdownClearAutofillData = false
let shutdownClearSiteSettings = false
+ let shutdownClearPublishers = false
const fakeElectron = require('../lib/fakeElectron')
const fakeAutofill = {
init: () => {},
@@ -38,6 +43,7 @@ describe('sessionStore unit tests', function () {
}
}
const fakeFiltering = {
+ clearHSTSData: () => {},
clearStorageData: () => {},
clearCache: () => {},
clearHistory: () => {}
@@ -85,16 +91,21 @@ describe('sessionStore unit tests', function () {
return shutdownClearAutofillData
case settings.SHUTDOWN_CLEAR_SITE_SETTINGS:
return shutdownClearSiteSettings
+ case settings.SHUTDOWN_CLEAR_PUBLISHERS:
+ return shutdownClearPublishers
default: return true
}
}
})
mockery.registerMock('./filtering', fakeFiltering)
+ filtering = require('./filtering')
+ ledgerState = require('../../../app/common/state/ledgerState')
sessionStore = require('../../../app/sessionStore')
})
after(function () {
mockery.disable()
+ mockery.deregisterAll()
})
describe('saveAppState', function () {
@@ -331,13 +342,13 @@ describe('sessionStore unit tests', function () {
describe('cleanAppData', function () {
it('clears notifications from the last session', function () {
- const data = Immutable.fromJS({notifications: ['message 1', 'message 2']})
+ const data = Immutable.fromJS({notifications: ['message 1', 'message 2'], ledger: {}})
const result = sessionStore.cleanAppData(data)
assert.deepEqual(result.get('notifications').toJS(), [])
})
it('deletes temp site settings', function () {
- const data = Immutable.fromJS({temporarySiteSettings: {site1: {setting1: 'value1'}}})
+ const data = Immutable.fromJS({temporarySiteSettings: {site1: {setting1: 'value1'}}, ledger: {}})
const result = sessionStore.cleanAppData(data)
assert.deepEqual(result.get('temporarySiteSettings').toJS(), {})
})
@@ -348,7 +359,8 @@ describe('sessionStore unit tests', function () {
settings: {
[settings.CHECK_DEFAULT_ON_STARTUP]: true
},
- defaultBrowserCheckComplete: 'test_value'
+ defaultBrowserCheckComplete: 'test_value',
+ ledger: {}
})
const result = sessionStore.cleanAppData(data)
assert.equal(result.get('defaultBrowserCheckComplete'), undefined)
@@ -362,7 +374,8 @@ describe('sessionStore unit tests', function () {
about: {
preferences: { recoverySucceeded: true }
}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data)
assert.deepEqual(result.getIn(['ui', 'about', 'preferences', 'recoverySucceeded']), undefined)
@@ -371,7 +384,8 @@ describe('sessionStore unit tests', function () {
it('does not throw an exception if not present', function () {
const data = Immutable.fromJS({
- ui: {}
+ ui: {},
+ ledger: {}
})
const result = sessionStore.cleanAppData(data)
assert.deepEqual(result.get('ui').toJS(), {})
@@ -388,7 +402,8 @@ describe('sessionStore unit tests', function () {
})
it('calls cleanPerWindowData for each item', function () {
const data = Immutable.fromJS({
- perWindowState: [{ 'window': 1 }, { 'window': 2 }]
+ perWindowState: [{ 'window': 1 }, { 'window': 2 }],
+ ledger: {}
})
const window1 = data.getIn(['perWindowState', 0])
const window2 = data.getIn(['perWindowState', 1])
@@ -405,7 +420,8 @@ describe('sessionStore unit tests', function () {
}, {
id: 2,
frames: [1, 2, 3]
- }]
+ }],
+ ledger: {}
})
const result = sessionStore.cleanAppData(data)
assert.equal(result.get('perWindowState').size, 1)
@@ -422,7 +438,7 @@ describe('sessionStore unit tests', function () {
})
it('calls autofill.clearAutocompleteData', function () {
const clearAutocompleteDataSpy = sinon.spy(fakeAutofill, 'clearAutocompleteData')
- const data = Immutable.Map()
+ const data = Immutable.fromJS({ledger: {}})
sessionStore.cleanAppData(data, true)
assert.equal(clearAutocompleteDataSpy.calledOnce, true)
clearAutocompleteDataSpy.restore()
@@ -438,7 +454,7 @@ describe('sessionStore unit tests', function () {
})
it('swallows exception', function () {
- const data = Immutable.Map()
+ const data = Immutable.fromJS({ledger: {}})
sessionStore.cleanAppData(data, true)
assert.ok(true)
})
@@ -453,7 +469,7 @@ describe('sessionStore unit tests', function () {
clearAutocompleteDataSpy.restore()
})
it('does not call autofill.clearAutocompleteData', function () {
- const data = Immutable.Map()
+ const data = Immutable.fromJS({ledger: {}})
sessionStore.cleanAppData(data, true)
assert.equal(clearAutocompleteDataSpy.notCalled, true)
})
@@ -486,7 +502,8 @@ describe('sessionStore unit tests', function () {
guid: ['value3', 'value4'],
timestamp: 'time2'
}
- }
+ },
+ ledger: {}
})
result = sessionStore.cleanAppData(data, true)
})
@@ -519,11 +536,11 @@ describe('sessionStore unit tests', function () {
describe('malformed input', function () {
it('does not throw an exception', function () {
- sessionStore.cleanAppData(Immutable.Map(), true)
- sessionStore.cleanAppData(Immutable.fromJS({autofill: 'stringValue'}), true)
- sessionStore.cleanAppData(Immutable.fromJS({autofill: {}}), true)
- sessionStore.cleanAppData(Immutable.fromJS({autofill: {addresses: 'stringValue'}}), true)
- sessionStore.cleanAppData(Immutable.fromJS({autofill: {creditCards: 'stringValue'}}), true)
+ sessionStore.cleanAppData(Immutable.fromJS({ledger: {}}), true)
+ sessionStore.cleanAppData(Immutable.fromJS({autofill: 'stringValue', ledger: {}}), true)
+ sessionStore.cleanAppData(Immutable.fromJS({autofill: {}, ledger: {}}), true)
+ sessionStore.cleanAppData(Immutable.fromJS({autofill: {addresses: 'stringValue'}, ledger: {}}), true)
+ sessionStore.cleanAppData(Immutable.fromJS({autofill: {creditCards: 'stringValue'}, ledger: {}}), true)
})
})
})
@@ -541,7 +558,8 @@ describe('sessionStore unit tests', function () {
guid: ['value3', 'value4'],
timestamp: 'time2'
}
- }
+ },
+ ledger: {}
})
sessionStore.cleanAppData(data, true)
})
@@ -561,7 +579,7 @@ describe('sessionStore unit tests', function () {
shutdownClearSiteSettings = false
})
it('clears siteSettings', function () {
- const data = Immutable.fromJS({siteSettings: {site1: {setting1: 'value1'}}})
+ const data = Immutable.fromJS({siteSettings: {site1: {setting1: 'value1'}}, ledger: {}})
const result = sessionStore.cleanAppData(data, true)
assert.deepEqual(result.get('siteSettings').toJS(), {})
})
@@ -569,18 +587,113 @@ describe('sessionStore unit tests', function () {
describe('when SHUTDOWN_CLEAR_SITE_SETTINGS is false', function () {
it('does not clear siteSettings', function () {
- const data = Immutable.fromJS({siteSettings: {site1: {setting1: 'value1'}}})
+ const data = Immutable.fromJS({siteSettings: {site1: {setting1: 'value1'}}, ledger: {}})
const result = sessionStore.cleanAppData(data, true)
assert.deepEqual(result.get('siteSettings').toJS(), data.get('siteSettings').toJS())
})
})
+ describe('when SHUTDOWN_CLEAR_PUBLISHERS', function () {
+ let resetPublishersSpy
+
+ before(() => {
+ resetPublishersSpy = sinon.spy(ledgerState, 'resetPublishers')
+ })
+
+ beforeEach(function () {
+ shutdownClearPublishers = false
+ })
+
+ afterEach(() => {
+ resetPublishersSpy.reset()
+ })
+
+ after(() => {
+ resetPublishersSpy.restore()
+ })
+
+ it('null case', function () {
+ sessionStore.cleanAppData(Immutable.fromJS({ledger: {}}), true)
+ assert(resetPublishersSpy.notCalled)
+ })
+
+ it('is true', function () {
+ shutdownClearPublishers = true
+ const data = Immutable.fromJS({
+ ledger: {
+ synopsis: {
+ publishers: {
+ 'youtube#channel:radio1slovenia': {
+ duration: 166431,
+ views: 2
+ }
+ }
+ }
+ }
+ })
+ const result = sessionStore.cleanAppData(data, true)
+ assert(resetPublishersSpy.calledOnce)
+ assert.deepEqual(result.getIn(['ledger', 'synopsis', 'publishers']).toJS(), {})
+ })
+
+ it('is false', function () {
+ const data = Immutable.fromJS({
+ ledger: {
+ synopsis: {
+ publishers: {
+ 'youtube#channel:radio1slovenia': {
+ duration: 166431,
+ views: 2
+ }
+ }
+ }
+ }
+ })
+ const result = sessionStore.cleanAppData(data, true)
+ const expectedResult = data
+ .set('createdFaviconDirectory', true)
+ .set('notifications', Immutable.List())
+ .set('temporarySiteSettings', Immutable.Map())
+
+ assert(resetPublishersSpy.notCalled)
+ assert.deepEqual(result.toJS(), expectedResult.toJS())
+ })
+
+ it('contribution in progress', function () {
+ shutdownClearPublishers = true
+ const data = Immutable.fromJS({
+ ledger: {
+ about: {
+ status: ledgerStatuses.IN_PROGRESS
+ },
+ synopsis: {
+ publishers: {
+ 'youtube#channel:radio1slovenia': {
+ duration: 166431,
+ views: 2
+ }
+ }
+ }
+ }
+ })
+ const result = sessionStore.cleanAppData(data, true)
+ const expectedResult = data
+ .set('createdFaviconDirectory', true)
+ .set('notifications', Immutable.List())
+ .set('temporarySiteSettings', Immutable.Map())
+
+ assert(resetPublishersSpy.notCalled)
+ assert.deepEqual(result.toJS(), expectedResult.toJS())
+ })
+ })
+
describe('with siteSettings', function () {
it('deletes Flash approval if expired', function () {
const data = Immutable.fromJS({
siteSettings: {
site1: {flash: 1, test: 2}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.equal(result.getIn(['siteSettings', 'site1', 'flash']), undefined)
@@ -590,7 +703,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
siteSettings: {
site1: {flash: Infinity, test: 2}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.equal(result.getIn(['siteSettings', 'site1', 'flash']), Infinity)
@@ -600,7 +714,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
siteSettings: {
site1: {noScript: 1, test: 2}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.equal(result.getIn(['siteSettings', 'noScript']), undefined)
@@ -610,7 +725,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
siteSettings: {
site1: {noScriptExceptions: true, test: 2}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.equal(result.getIn(['siteSettings', 'site1', 'noScriptExceptions']), undefined)
@@ -620,7 +736,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
siteSettings: {
site1: {runInsecureContent: true, test: 2}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.equal(result.getIn(['siteSettings', 'site1', 'runInsecureContent']), undefined)
@@ -630,7 +747,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
siteSettings: {
site1: {}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.equal(result.getIn(['siteSettings', 'site1']), undefined)
@@ -647,7 +765,8 @@ describe('sessionStore unit tests', function () {
it('deletes temporary entries used in about:history', function () {
const data = Immutable.fromJS({
about: {history: true},
- sites: {entry1: {}}
+ sites: {entry1: {}},
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, true)
assert.equal(result.getIn(['about', 'history']), undefined)
@@ -655,7 +774,8 @@ describe('sessionStore unit tests', function () {
it('deletes top site entries used in about:newtab', function () {
const data = Immutable.fromJS({
about: {newtab: true},
- sites: {entry1: {}}
+ sites: {entry1: {}},
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, true)
assert.equal(result.getIn(['about', 'newtab']), undefined)
@@ -668,7 +788,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
downloads: {
entry1: {}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, true)
assert.equal(result.get('downloads'), undefined)
@@ -680,7 +801,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
downloads: {
entry1: {startTime: 1}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.deepEqual(result.get('downloads').toJS(), {})
@@ -690,7 +812,8 @@ describe('sessionStore unit tests', function () {
const data = Immutable.fromJS({
downloads: {
entry1: {startTime: new Date().getTime()}
- }
+ },
+ ledger: {}
})
const result = sessionStore.cleanAppData(data, false)
assert.deepEqual(result.get('downloads').toJS(), data.get('downloads').toJS())
@@ -701,7 +824,8 @@ describe('sessionStore unit tests', function () {
return Immutable.fromJS({
downloads: {
entry1: {startTime: new Date().getTime(), state}
- }
+ },
+ ledger: {}
})
}
@@ -741,7 +865,7 @@ describe('sessionStore unit tests', function () {
describe('with tabState', function () {
it('calls getPersistentState', function () {
const getPersistentStateSpy = sinon.spy(fakeTabState, 'getPersistentState')
- const data = Immutable.Map()
+ const data = Immutable.fromJS({ledger: {}})
sessionStore.cleanAppData(data)
assert.equal(getPersistentStateSpy.calledOnce, true)
getPersistentStateSpy.restore()
@@ -749,7 +873,7 @@ describe('sessionStore unit tests', function () {
it('deletes tabState if an exception is thrown', function () {
const getPersistentStateSpy = sinon.stub(fakeTabState, 'getPersistentState').throws('oh noes')
- const data = Immutable.fromJS({tabs: true})
+ const data = Immutable.fromJS({tabs: true, ledger: {}})
const result = sessionStore.cleanAppData(data)
assert.deepEqual(result.get('tabs').toJS(), [])
getPersistentStateSpy.restore()
@@ -759,7 +883,7 @@ describe('sessionStore unit tests', function () {
describe('with windowState', function () {
it('calls getPersistentState', function () {
const getPersistentStateSpy = sinon.spy(fakeWindowState, 'getPersistentState')
- const data = Immutable.Map()
+ const data = Immutable.fromJS({ledger: {}})
sessionStore.cleanAppData(data)
assert.equal(getPersistentStateSpy.calledOnce, true)
getPersistentStateSpy.restore()
@@ -767,7 +891,7 @@ describe('sessionStore unit tests', function () {
it('deletes windowState if an exception is thrown', function () {
const getPersistentStateSpy = sinon.stub(fakeWindowState, 'getPersistentState').throws('oh noes')
- const data = Immutable.fromJS({windows: true})
+ const data = Immutable.fromJS({windows: true, ledger: {}})
const result = sessionStore.cleanAppData(data)
assert.equal(result.windows, undefined)
getPersistentStateSpy.restore()
@@ -789,6 +913,7 @@ describe('sessionStore unit tests', function () {
let localeInitSpy
let backupSessionStub
let runImportDefaultSettings
+ let clearHSTSDataSpy
before(function () {
runPreMigrationsSpy = sinon.spy(sessionStore, 'runPreMigrations')
@@ -798,6 +923,7 @@ describe('sessionStore unit tests', function () {
localeInitSpy = sinon.spy(fakeLocale, 'init')
backupSessionStub = sinon.stub(sessionStore, 'backupSession')
runImportDefaultSettings = sinon.spy(sessionStore, 'runImportDefaultSettings')
+ clearHSTSDataSpy = sinon.spy(filtering, 'clearHSTSData')
})
after(function () {
@@ -807,6 +933,27 @@ describe('sessionStore unit tests', function () {
runPostMigrationsSpy.restore()
localeInitSpy.restore()
backupSessionStub.restore()
+ clearHSTSDataSpy.restore()
+ })
+
+ describe('check clearHSTSData invocations', function () {
+ describe('if lastAppVersion is 0.23', function () {
+ it('clearHSTSData is not invoked', function () {
+ let exampleState = sessionStore.defaultAppState()
+ exampleState.lastAppVersion = '0.23'
+ sessionStore.runPreMigrations(exampleState)
+ assert.equal(clearHSTSDataSpy.notCalled, true)
+ })
+ })
+
+ describe('if lastAppVersion is 0.21', function () {
+ it('clearHSTSData is calledOnce', function () {
+ let exampleState = sessionStore.defaultAppState()
+ exampleState.lastAppVersion = '0.21'
+ sessionStore.runPreMigrations(exampleState)
+ assert.equal(clearHSTSDataSpy.calledOnce, true)
+ })
+ })
})
describe('when reading the session file', function () {
@@ -950,6 +1097,9 @@ describe('sessionStore unit tests', function () {
},
'https://www.youtube.com': {
autoplay: true
+ },
+ 'https?://uphold.com': {
+ fingerprintingProtection: 'allowAllFingerprinting'
}
}
runImportDefaultSettings.reset()
@@ -1091,7 +1241,7 @@ describe('sessionStore unit tests', function () {
before(function () {
readFileSyncStub = sinon.stub(fakeFileSystem, 'readFileSync').returns(JSON.stringify({
cleanedOnShutdown: true,
- lastAppVersion: 'NOT A REAL VERSION'
+ lastAppVersion: '0.0.1'
}))
})
after(function () {
diff --git a/test/unit/app/siteHacksTest.js b/test/unit/app/siteHacksTest.js
index 0cb667745e2..b46c41dac01 100644
--- a/test/unit/app/siteHacksTest.js
+++ b/test/unit/app/siteHacksTest.js
@@ -1,7 +1,8 @@
-/* global describe, before, after, it */
+/* global describe, before, beforeEach, after, it */
const mockery = require('mockery')
const assert = require('assert')
const sinon = require('sinon')
+const Immutable = require('immutable')
require('../braveUnit')
@@ -9,9 +10,9 @@ describe('siteHacks unit tests', function () {
let siteHacks
let siteHacksData
let beforeSendCB
- // let beforeRequestCB
let urlParse
let filtering
+ let appState
const fakeElectron = require('../lib/fakeElectron')
const fakeAdBlock = require('../lib/fakeAdBlock')
const fakeFiltering = {
@@ -44,6 +45,9 @@ describe('siteHacks unit tests', function () {
mockery.registerMock('./filtering', fakeFiltering)
siteHacksData = require('../../../js/data/siteHacks')
mockery.registerMock('../js/data/siteHacks', siteHacksData)
+ mockery.registerMock('../js/stores/appStore', {
+ getState: () => appState
+ })
siteHacks = require('../../../app/siteHacks')
})
@@ -87,7 +91,6 @@ describe('siteHacks unit tests', function () {
onBeforeSendHeadersSpy = sinon.spy(siteHacksData.siteHacks['adobe.com'], 'onBeforeSendHeaders')
if (typeof beforeSendCB === 'function') {
- // result = beforeSendCB(details)
beforeSendCB(details)
}
})
@@ -110,14 +113,190 @@ describe('siteHacks unit tests', function () {
it('calls Filtering.registerBeforeRequestFilteringCB', function () {
assert.equal(beforeRequestSpy.calledOnce, true)
})
+ })
+
+ describe('setReferralHeaders', function () {
+ const headers = [
+ {
+ domains: [ 'test.com', 'domain.si' ],
+ headers: { 'X-Brave-Partner': 'partner', 'X-something': 'ok' },
+ cookieNames: [],
+ expiration: 0
+ }
+ ]
+
+ beforeEach(() => {
+ siteHacks.resetReferralHeaders(null)
+ })
+
+ it('headers are missing', function () {
+ siteHacks.setReferralHeaders(null)
+ assert.equal(siteHacks.getReferralHeaders(), null)
+ })
+
+ it('headers are immutable list', function () {
+ siteHacks.setReferralHeaders(Immutable.fromJS(headers))
+ assert.deepEqual(siteHacks.getReferralHeaders(), headers)
+ })
+
+ it('headers are regular array', function () {
+ siteHacks.setReferralHeaders(headers)
+ assert.deepEqual(siteHacks.getReferralHeaders(), headers)
+ })
+
+ it('headers is single object', function () {
+ siteHacks.setReferralHeaders({
+ domains: [ 'test.com', 'domain.si' ],
+ headers: { 'X-Brave-Partner': 'partner', 'X-something': 'ok' },
+ cookieNames: [],
+ expiration: 0
+ })
+ assert.deepEqual(siteHacks.getReferralHeaders(), headers)
+ })
+ })
+
+ describe('beforeHeaders', function () {
+ describe('referral headers', function () {
+ const details = {
+ resourceType: 'mainFrame',
+ requestHeaders: {
+ 'User-Agent': 'Brave Chrome/60.0.3112.101'
+ },
+ url: 'https://test.com',
+ tabId: 1
+ }
+
+ const detailExpected = {
+ cancel: undefined,
+ customCookie: undefined,
+ requestHeaders: undefined,
+ resourceName: 'siteHacks'
+ }
+
+ const headers = [
+ {
+ domains: [ 'test.com', 'domain.si' ],
+ headers: { 'X-Brave-Partner': 'partner' },
+ cookieNames: [],
+ expiration: 0
+ }
+ ]
- // describe('in the callback passed into registerBeforeRequestFilteringCB', function () {
- // let result
- // before(function () {
- // if (typeof beforeRequestCB === 'function') {
- // result = beforeRequestCB()
- // }
- // })
- // })
+ beforeEach(() => {
+ siteHacks.resetReferralHeaders()
+ appState = null
+ })
+
+ describe('are not set', function () {
+ it('app state is null', function () {
+ const result = siteHacks.beforeHeaders(details)
+ assert.deepEqual(result, detailExpected)
+ assert.equal(siteHacks.getReferralHeaders(), null)
+ })
+
+ it('headers are now set', function () {
+ appState = Immutable.fromJS({
+ updates: {
+ referralHeaders: headers
+ }
+ })
+
+ const expectedReturn = {
+ cancel: undefined,
+ customCookie: undefined,
+ requestHeaders: {
+ 'X-Brave-Partner': 'partner',
+ 'User-Agent': 'Brave Chrome/60.0.3112.101'
+ },
+ resourceName: 'siteHacks'
+ }
+
+ const result = siteHacks.beforeHeaders(details)
+ assert.deepEqual(result, expectedReturn)
+ assert.deepEqual(siteHacks.getReferralHeaders(), headers)
+ })
+ })
+
+ describe('are set', function () {
+ it('domains are missing', function () {
+ siteHacks.setReferralHeaders({
+ headers: { 'X-Brave-Partner': 'partner' },
+ cookieNames: [],
+ expiration: 0
+ })
+
+ const result = siteHacks.beforeHeaders(details)
+ assert.deepEqual(result, detailExpected)
+ })
+
+ it('domain is not in the headers', function () {
+ siteHacks.setReferralHeaders({
+ domains: [ 'domain.si' ],
+ headers: { 'X-Brave-Partner': 'partner' },
+ cookieNames: [],
+ expiration: 0
+ })
+
+ const result = siteHacks.beforeHeaders(details)
+ assert.deepEqual(result, detailExpected)
+ })
+
+ it('headers are missing', function () {
+ siteHacks.setReferralHeaders({
+ domains: [ 'test.com' ],
+ cookieNames: [],
+ expiration: 0
+ })
+
+ const result = siteHacks.beforeHeaders(details)
+ assert.deepEqual(result, detailExpected)
+ })
+
+ it('header is set', function () {
+ siteHacks.setReferralHeaders({
+ domains: [ 'test.com', 'domain.si' ],
+ headers: { 'X-Brave-Partner': 'partner' },
+ cookieNames: [],
+ expiration: 0
+ })
+
+ const expectedReturn = {
+ resourceName: 'siteHacks',
+ requestHeaders: {
+ 'X-Brave-Partner': 'partner',
+ 'User-Agent': 'Brave Chrome/60.0.3112.101'
+ },
+ customCookie: undefined,
+ cancel: undefined
+ }
+
+ const result = siteHacks.beforeHeaders(details)
+ assert.deepEqual(result, expectedReturn)
+ })
+
+ it('multiple headers are set', function () {
+ siteHacks.setReferralHeaders({
+ domains: [ 'test.com', 'domain.si' ],
+ headers: { 'X-Brave-Partner': 'partner', 'X-something': 'ok' },
+ cookieNames: [],
+ expiration: 0
+ })
+
+ const expectedReturn = {
+ cancel: undefined,
+ customCookie: undefined,
+ requestHeaders: {
+ 'X-Brave-Partner': 'partner',
+ 'X-something': 'ok',
+ 'User-Agent': 'Brave Chrome/60.0.3112.101'
+ },
+ resourceName: 'siteHacks'
+ }
+
+ const result = siteHacks.beforeHeaders(details)
+ assert.deepEqual(result, expectedReturn)
+ })
+ })
+ })
})
})
diff --git a/test/unit/js/lib/baseDomainTest.js b/test/unit/js/lib/baseDomainTest.js
new file mode 100644
index 00000000000..869a63a40c0
--- /dev/null
+++ b/test/unit/js/lib/baseDomainTest.js
@@ -0,0 +1,39 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* global describe, it */
+
+const {getBaseDomain} = require('../../../../js/lib/baseDomain')
+const assert = require('assert')
+
+require('../../braveUnit')
+
+describe('getBaseDomain', function () {
+ it('regular domain and subdomains', function () {
+ const domain = 'brave.com'
+ assert.equal(domain, getBaseDomain('brave.com'))
+ assert.equal(domain, getBaseDomain('test.brave.com'))
+ assert.equal(domain, getBaseDomain('foo.test.brave.com'))
+ })
+ it('international domains', function () {
+ assert.equal('brave.comа', getBaseDomain('www.brave.xn--com-8cd'))
+ assert.equal('brave.\u9ce5\u53d6.jp', getBaseDomain('\u9ce5\u53d6.jp.brave.\u9ce5\u53d6.jp'))
+ assert.equal('ebаy.com', getBaseDomain('xn--eby-7cd.com'))
+ })
+ it('multi-part domains', function () {
+ assert.equal('diracdeltas.github.io', getBaseDomain('diracdeltas.github.io'))
+ assert.equal('diracdeltas.github.io', getBaseDomain('foo.diracdeltas.github.io'))
+ assert.equal('bar.ginoza.okinawa.jp', getBaseDomain('foo.bar.ginoza.okinawa.jp'))
+ assert.equal('brave.co.uk', 'brave.co.uk')
+ })
+ it('tlds', function () {
+ assert.equal('', getBaseDomain('github.io'))
+ assert.equal('', getBaseDomain('co.uk'))
+ })
+ it('non-hostname inputs', function () {
+ assert.equal('', getBaseDomain(''))
+ assert.equal('hello world', getBaseDomain('hello world'))
+ assert.equal('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]', getBaseDomain('[2001:0db8:85a3:0000:0000:8a2e:0370:7334]'))
+ assert.equal('http://2001::7334', getBaseDomain('http://2001::7334'))
+ })
+})
diff --git a/test/unit/js/stores/appStoreTest.js b/test/unit/js/stores/appStoreTest.js
new file mode 100644
index 00000000000..54b0ab34885
--- /dev/null
+++ b/test/unit/js/stores/appStoreTest.js
@@ -0,0 +1,151 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+/* global describe, before, after, afterEach, it */
+
+const mockery = require('mockery')
+// const assert = require('assert')
+// const sinon = require('sinon')
+const Immutable = require('immutable')
+const fakeElectron = require('../../lib/fakeElectron')
+// const windowConstants = require('../../../../js/constants/windowConstants')
+const appConstants = require('../../../../js/constants/appConstants')
+let doAction
+// let appStore
+let appActions
+require('../../braveUnit')
+
+describe('App store unit tests', function () {
+ const fakeDispatcher = {
+ register: (actionHandler) => {
+ doAction = actionHandler
+ },
+ registerLocalCallback: (actionHandler) => {
+ doAction = actionHandler
+ }
+ }
+
+ const reducers = [
+ '../../app/browser/reducers/downloadsReducer',
+ '../../app/browser/reducers/flashReducer',
+ '../../app/browser/reducers/dappReducer',
+ '../../app/browser/reducers/autoplayReducer',
+ '../../app/browser/reducers/tabsReducer',
+ '../../app/browser/reducers/urlBarSuggestionsReducer',
+ '../../app/browser/reducers/bookmarksReducer',
+ '../../app/browser/reducers/bookmarkFoldersReducer',
+ '../../app/browser/reducers/historyReducer',
+ '../../app/browser/reducers/pinnedSitesReducer',
+ '../../app/browser/reducers/windowsReducer',
+ '../../app/browser/reducers/syncReducer',
+ '../../app/browser/reducers/clipboardReducer',
+ '../../app/browser/reducers/passwordManagerReducer',
+ '../../app/browser/reducers/spellCheckerReducer',
+ '../../app/browser/reducers/tabMessageBoxReducer',
+ '../../app/browser/reducers/dragDropReducer',
+ '../../app/browser/reducers/extensionsReducer',
+ '../../app/browser/reducers/shareReducer',
+ '../../app/browser/reducers/updatesReducer',
+ '../../app/browser/reducers/aboutNewTabReducer',
+ '../../app/browser/reducers/braverySettingsReducer',
+ '../../app/browser/reducers/bookmarkToolbarReducer',
+ '../../app/browser/reducers/siteSettingsReducer',
+ '../../app/browser/reducers/pageDataReducer',
+ '../../app/browser/reducers/ledgerReducer',
+ '../../app/browser/menu'
+ ]
+
+ before(function () {
+ appActions = require('../../../../js/actions/appActions.js')
+ mockery.enable({
+ warnOnReplace: false,
+ warnOnUnregistered: false,
+ useCleanCache: true
+ })
+ mockery.registerMock('electron', fakeElectron)
+ mockery.registerMock('../dispatcher/appDispatcher', fakeDispatcher)
+ mockery.registerMock('../actions/appActions', appActions)
+ mockery.registerMock('ad-block', require('../../lib/fakeAdBlock'))
+ mockery.registerMock('leveldown', {})
+ mockery.registerMock('../../app/browser/api/topSites', {
+ calculateTopSites: () => {}
+ })
+
+ const modulesNeedingInit = [
+ '../../app/filtering',
+ '../../app/browser/basicAuth',
+ '../../app/browser/webtorrent',
+ '../../app/browser/profiles',
+ '../../app/sync'
+ ]
+ modulesNeedingInit.forEach((moduleNeedingInit) => {
+ mockery.registerMock(moduleNeedingInit, {
+ init: (appState, action, appStore) => {}
+ })
+ })
+
+ require('../../../../js/stores/appStore.js')
+ })
+
+ after(function () {
+ mockery.disable()
+ })
+
+ const callWithMissingValues = (labelForUnitTest, fieldName, demoAction) => {
+ describe(labelForUnitTest, function () {
+ afterEach(function () {
+ reducers.forEach((reducer) => {
+ mockery.deregisterMock(reducer)
+ })
+ })
+
+ const performCall = (field) => {
+ const fakeReducer = (state, action, immutableAction) => {
+ return Immutable.fromJS(field)
+ }
+ reducers.forEach((reducer) => {
+ mockery.registerMock(reducer, fakeReducer)
+ })
+ require('../../../../js/stores/appStore.js')
+ doAction({actionType: appConstants.APP_SET_STATE})
+ doAction(demoAction)
+ }
+
+ it(`does not throw exception when \`${fieldName}\` is missing from appState`, function () {
+ performCall({})
+ })
+
+ it(`does not throw exception when \`${fieldName}\` is undefined`, function () {
+ const field = {}
+ field[fieldName] = undefined
+ performCall(field)
+ })
+
+ it(`does not throw exception when \`${fieldName}\` is null`, function () {
+ const field = {}
+ field[fieldName] = null
+ performCall(field)
+ })
+ })
+ }
+
+ describe('doAction', function () {
+ callWithMissingValues(
+ 'APP_SHOW_NOTIFICATION',
+ 'notifications',
+ {
+ actionType: appConstants.APP_SHOW_NOTIFICATION
+ }
+ )
+
+ callWithMissingValues(
+ 'APP_HIDE_NOTIFICATION',
+ 'notifications',
+ {
+ actionType: appConstants.APP_HIDE_NOTIFICATION
+ }
+ )
+
+ // TODO: add your tests if you modify appStore.js :)
+ })
+})
diff --git a/test/unit/js/stores/windowStoreTest.js b/test/unit/js/stores/windowStoreTest.js
index fb1d53c9531..17a5ecde701 100644
--- a/test/unit/js/stores/windowStoreTest.js
+++ b/test/unit/js/stores/windowStoreTest.js
@@ -295,6 +295,70 @@ describe('Window store unit tests', function () {
})
})
+ describe('WINDOW_CLEAR_CLOSED_FRAMES', function () {
+ const demoAction = {
+ actionType: windowConstants.WINDOW_CLEAR_CLOSED_FRAMES,
+ location: 'https://brave.com'
+ }
+
+ afterEach(function () {
+ reducers.forEach((reducer) => {
+ mockery.deregisterMock(reducer)
+ })
+ })
+
+ it('does not throw exception when `closedFrames` is missing from windowState', function () {
+ const fakeReducer = (state, action) => {
+ return Immutable.fromJS({})
+ }
+ reducers.forEach((reducer) => {
+ mockery.registerMock(reducer, fakeReducer)
+ })
+ doAction(demoAction)
+ })
+
+ it('does not throw exception when `closedFrames` is undefined', function () {
+ const fakeReducer = (state, action) => {
+ return Immutable.fromJS({closedFrames: undefined})
+ }
+ reducers.forEach((reducer) => {
+ mockery.registerMock(reducer, fakeReducer)
+ })
+ doAction(demoAction)
+ })
+
+ it('does not throw exception when `closedFrames` is null', function () {
+ const fakeReducer = (state, action) => {
+ return Immutable.fromJS({closedFrames: null})
+ }
+ reducers.forEach((reducer) => {
+ mockery.registerMock(reducer, fakeReducer)
+ })
+ doAction(demoAction)
+ })
+
+ it('removes the specified location from closedFrames', function () {
+ const fakeReducer = (state, action) => {
+ return Immutable.fromJS({
+ closedFrames: [{
+ location: 'https://example.com'
+ }, {
+ location: 'https://brave.com'
+ }]
+ })
+ }
+ reducers.forEach((reducer) => {
+ mockery.registerMock(reducer, fakeReducer)
+ })
+ doAction(demoAction)
+
+ // get the updated windowState (AFTER doAction runs)
+ windowStore = require('../../../../js/stores/windowStore.js')
+ const windowState = windowStore.getState()
+ assert.equal(windowState.get('closedFrames').size, 1)
+ })
+ })
+
// TODO: add your tests if you modify windowStore.js :)
})
})
diff --git a/test/unit/lib/fakeTab.js b/test/unit/lib/fakeTab.js
index e28b176e949..0d0acea0ed1 100644
--- a/test/unit/lib/fakeTab.js
+++ b/test/unit/lib/fakeTab.js
@@ -17,6 +17,8 @@ function FakeTab (id, windowId, guestInstanceId = nextGuestInstanceId++) {
this._isDestroyed = false
this._canGoBack = false
this._canGoForward = false
+ this._isPlaceholder = false
+ this._zoomPercent = 100
}
util.inherits(FakeTab, EventEmitter)
@@ -46,4 +48,12 @@ proto.canGoForward = function () {
return this._canGoForward
}
+proto.isPlaceholder = function () {
+ return this._isPlaceholder
+}
+
+proto.getZoomPercent = function () {
+ return this._zoomPercent
+}
+
module.exports = FakeTab
diff --git a/test/unit/lib/fakeWindow.js b/test/unit/lib/fakeWindow.js
index 436268c6b99..ba2701afbfd 100644
--- a/test/unit/lib/fakeWindow.js
+++ b/test/unit/lib/fakeWindow.js
@@ -12,6 +12,7 @@ function FakeWindow (id) {
this.webContents = Object.assign(new EventEmitter())
this.webContents.send = this.webContents.emit
this._isVisible = false
+ this.webContents.browserWindowOptions = { }
}
util.inherits(FakeWindow, EventEmitter)
diff --git a/test/unit/lib/urlutilTest.js b/test/unit/lib/urlutilTest.js
index 387eec37819..c103852f11c 100644
--- a/test/unit/lib/urlutilTest.js
+++ b/test/unit/lib/urlutilTest.js
@@ -1,485 +1,4 @@
-/* global describe, it */
-const urlUtil = require('../../../js/lib/urlutil')
-const assert = require('assert')
+const runMuonCompatibleTests = require('../runMuonCompatibleTests')
+const components = require('./urlutilTestComponents')
-require('../braveUnit')
-
-describe('urlutil', function () {
- describe('getScheme', function () {
- it('null for empty', function () {
- assert.equal(urlUtil.getScheme('/file/path/to/file'), null)
- })
- it('localhost: for localhost', function () {
- assert.equal(urlUtil.getScheme('localhost://127.0.0.1'), 'localhost:')
- })
- it('gets scheme with :', function () {
- assert.equal(urlUtil.getScheme('data:datauri'), 'data:')
- })
- it('host:port is not recognized as a scheme', function () {
- assert.equal(urlUtil.getScheme('localhost:8089'), null)
- })
- it('gets scheme with ://', function () {
- assert.equal(urlUtil.getScheme('http://www.brave.com'), 'http://')
- })
- })
-
- describe('prependScheme', function () {
- it('returns null when input is null', function () {
- assert.equal(urlUtil.prependScheme(null), null)
- })
- it('returns undefined when input is undefined', function () {
- assert.equal(urlUtil.prependScheme(), undefined)
- })
- it('prepends file:// to absolute file path', function () {
- assert.equal(urlUtil.prependScheme('/file/path/to/file'), 'file:///file/path/to/file')
- })
- it('defaults to http://', function () {
- assert.equal(urlUtil.prependScheme('www.brave.com'), 'http://www.brave.com')
- })
- it('keeps schema if already exists', function () {
- assert.equal(urlUtil.prependScheme('https://www.brave.com'), 'https://www.brave.com')
- })
- })
-
- describe('isNotURL', function () {
- describe('returns false when input:', function () {
- it('is a valid URL', function () {
- assert.equal(urlUtil.isNotURL('brave.com'), false)
- })
- it('is an absolute file path without scheme', function () {
- assert.equal(urlUtil.isNotURL('/file/path/to/file'), false)
- })
- it('is an absolute file path with scheme', function () {
- assert.equal(urlUtil.isNotURL('file:///file/path/to/file'), false)
- })
- describe('for special pages', function () {
- it('is a data URI', function () {
- assert.equal(urlUtil.isNotURL('data:text/html,hi'), false)
- })
- it('is a view source URL', function () {
- assert.equal(urlUtil.isNotURL('view-source://url-here'), false)
- })
- it('is a mailto link', function () {
- assert.equal(urlUtil.isNotURL('mailto:brian@brave.com'), false)
- })
- it('is an about page', function () {
- assert.equal(urlUtil.isNotURL('about:preferences'), false)
- })
- it('is a chrome-extension page', function () {
- assert.equal(urlUtil.isNotURL('chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js'), false)
- })
- it('is a magnet URL', function () {
- assert.equal(urlUtil.isNotURL('chrome://gpu'), false)
- })
- it('is a chrome page', function () {
- assert.equal(urlUtil.isNotURL('magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C'), false)
- })
- })
- it('contains a hostname and port number', function () {
- assert.equal(urlUtil.isNotURL('someBraveServer:8089'), false)
- })
- it('starts or ends with whitespace', function () {
- assert.equal(urlUtil.isNotURL(' http://brave.com '), false)
- assert.equal(urlUtil.isNotURL('\n\nhttp://brave.com\n\n'), false)
- assert.equal(urlUtil.isNotURL('\t\thttp://brave.com\t\t'), false)
- })
- it('is a URL which contains basic auth user/pass', function () {
- assert.equal(urlUtil.isNotURL('http://username:password@example.com'), false)
- })
- it('is localhost (case-insensitive)', function () {
- assert.equal(urlUtil.isNotURL('LoCaLhOsT'), false)
- })
- it('is a hostname (not a domain)', function () {
- assert.equal(urlUtil.isNotURL('http://computer001/phpMyAdmin'), false)
- })
- it('ends with period (input contains a forward slash and domain)', function () {
- assert.equal(urlUtil.isNotURL('brave.com/test/cc?_ri_=3vv-8-e.'), false)
- })
- it('is a string with whitespace but has schema', function () {
- assert.equal(urlUtil.isNotURL('https://wwww.brave.com/test space.jpg'), false)
- })
- it('has custom protocol', function () {
- assert.equal(urlUtil.isNotURL('brave://test'), false)
- })
- })
-
- describe('returns true when input:', function () {
- it('is null or undefined', function () {
- assert.equal(urlUtil.isNotURL(), true)
- assert.equal(urlUtil.isNotURL(null), true)
- })
- it('is not a string', function () {
- assert.equal(urlUtil.isNotURL(false), true)
- assert.equal(urlUtil.isNotURL(333.449), true)
- })
- it('is a quoted string', function () {
- assert.equal(urlUtil.isNotURL('"search term here"'), true)
- })
- it('is a pure string (no TLD)', function () {
- assert.equal(urlUtil.isNotURL('brave'), true)
- })
- describe('search query', function () {
- it('starts with ?', function () {
- assert.equal(urlUtil.isNotURL('?brave'), true)
- })
- it('has a question mark followed by a space', function () {
- assert.equal(urlUtil.isNotURL('? brave'), true)
- })
- it('starts with .', function () {
- assert.equal(urlUtil.isNotURL('.brave'), true)
- })
- it('ends with . (input does NOT contain a forward slash)', function () {
- assert.equal(urlUtil.isNotURL('brave.'), true)
- })
- it('ends with period (input contains only a forward slash)', function () {
- assert.equal(urlUtil.isNotURL('brave/com/test/cc?_ri_=3vv-8-e.'), true)
- })
- })
- it('is a string with schema but invalid domain name', function () {
- assert.equal(urlUtil.isNotURL('https://www.bra ve.com/test space.jpg'), true)
- })
- it('contains more than one word', function () {
- assert.equal(urlUtil.isNotURL('brave is cool'), true)
- })
- it('is not an about page / view source / data URI / mailto / etc', function () {
- assert.equal(urlUtil.isNotURL('not-a-chrome-extension:'), true)
- assert.equal(urlUtil.isNotURL('mailtoo:'), true)
- })
- it('is a URL (without protocol) which contains basic auth user/pass', function () {
- assert.equal(urlUtil.isNotURL('username:password@example.com'), true)
- })
- it('has space in schema', function () {
- assert.equal(urlUtil.isNotURL('https ://brave.com'), true)
- })
- })
- })
-
- describe('getUrlFromInput', function () {
- it('returns empty string when input is null', function () {
- assert.equal(urlUtil.getUrlFromInput(null), '')
- })
- it('returns empty string when input is undefined', function () {
- assert.equal(urlUtil.getUrlFromInput(), '')
- })
- it('calls prependScheme', function () {
- assert.equal(urlUtil.getUrlFromInput('/file/path/to/file'), 'file:///file/path/to/file')
- })
- })
-
- describe('isURL', function () {
- it('returns !isNotURL', function () {
- assert.equal(urlUtil.isURL('brave.com'), !urlUtil.isNotURL('brave.com'))
- assert.equal(urlUtil.isURL('brave is cool'), !urlUtil.isNotURL('brave is cool'))
- assert.equal(urlUtil.isURL('mailto:brian@brave.com'), !urlUtil.isNotURL('mailto:brian@brave.com'))
- })
- })
-
- describe('isFileType', function () {
- it('relative file', function () {
- assert.equal(urlUtil.isFileType('/file/abc/test.pdf', 'pdf'), true)
- })
- it('relative path', function () {
- assert.equal(urlUtil.isFileType('/file/abc/test', 'pdf'), false)
- })
- it('JPG URL', function () {
- assert.equal(urlUtil.isFileType('http://example.com/test/ABC.JPG?a=b#test', 'jpg'), true)
- })
- it('non-JPG URL', function () {
- assert.equal(urlUtil.isFileType('http://example.com/test/jpg', 'jpg'), false)
- })
- it('invalid URL', function () {
- assert.equal(urlUtil.isFileType('foo', 'jpg'), false)
- })
- })
-
- describe('toPDFJSLocation', function () {
- const baseUrl = 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/'
- it('pdf', function () {
- assert.equal(urlUtil.toPDFJSLocation('http://abc.com/test.pdf'), baseUrl + 'content/web/viewer.html?file=http%3A%2F%2Fabc.com%2Ftest.pdf')
- })
- it('non-pdf', function () {
- assert.equal(urlUtil.toPDFJSLocation('http://abc.com/test.pdf.txt'), 'http://abc.com/test.pdf.txt')
- })
- it('file url', function () {
- assert.equal(urlUtil.toPDFJSLocation('file://abc.com/test.pdf.txt'), 'file://abc.com/test.pdf.txt')
- })
- it('empty', function () {
- assert.equal(urlUtil.toPDFJSLocation(''), '')
- })
- })
-
- describe('getPDFViewerUrl', function () {
- const baseUrl = 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/content/web/viewer.html?file='
- it('regular url', function () {
- assert.equal(urlUtil.getPDFViewerUrl('http://example.com'), baseUrl + 'http%3A%2F%2Fexample.com')
- })
- it('file url', function () {
- assert.equal(urlUtil.getPDFViewerUrl('file:///Users/yan/some files/test.pdf'), baseUrl + 'file%3A%2F%2F%2FUsers%2Fyan%2Fsome%20files%2Ftest.pdf')
- })
- })
-
- describe('getHostname', function () {
- it('returns undefined if the URL is invalid', function () {
- assert.equal(urlUtil.getHostname(null), undefined)
- })
- it('returns the host field (including port number)', function () {
- assert.equal(urlUtil.getHostname('https://brave.com:8080/test/'), 'brave.com:8080')
- })
- it('allows you to exclude the port number', function () {
- assert.equal(urlUtil.getHostname('https://brave.com:8080/test/', true), 'brave.com')
- })
- })
-
- describe('getHostnamePatterns', function () {
- it('gets bare domain hostname patterns', function () {
- // XXX: *.com probably should be excluded
- assert.deepEqual(urlUtil.getHostnamePatterns('http://brave.com'),
- ['brave.com', '*.com', 'brave.*'])
- })
- it('gets subdomain hostname patterns', function () {
- assert.deepEqual(urlUtil.getHostnamePatterns('https://bar.brave.com'),
- ['bar.brave.com',
- '*.brave.com',
- 'bar.*.com',
- 'bar.brave.*'])
- assert.deepEqual(urlUtil.getHostnamePatterns('https://foo.bar.brave.com'),
- ['foo.bar.brave.com',
- '*.bar.brave.com',
- 'foo.*.brave.com',
- 'foo.bar.*.com',
- 'foo.bar.brave.*',
- '*.brave.com'])
- })
- })
-
- describe('getLocationIfPDF', function () {
- it('gets location for PDF JS URL', function () {
- assert.equal(urlUtil.getLocationIfPDF('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf'),
- 'https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf')
- })
- it('gets location for PDF JS viewer URL', function () {
- assert.equal(urlUtil.getLocationIfPDF('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/content/web/viewer.html?file=http%3A%2F%2Funec.edu.az%2Fapplication%2Fuploads%2F2014%2F12%2Fpdf-sample.pdf'),
- 'http://unec.edu.az/application/uploads/2014/12/pdf-sample.pdf')
- })
- it('does not remove wayback machine url location for PDF JS URL', function () {
- assert.equal(urlUtil.getLocationIfPDF('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/https://web.archive.org/web/20160106152308/http://stlab.adobe.com/wiki/images/d/d3/Test.pdf'),
- 'https://web.archive.org/web/20160106152308/http://stlab.adobe.com/wiki/images/d/d3/Test.pdf')
- })
- it('does not modify location for non-pdf URL', function () {
- assert.equal(urlUtil.getLocationIfPDF('https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf'),
- 'https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf')
- assert.equal(urlUtil.getLocationIfPDF('chrome-extension://blank'), 'chrome-extension://blank')
- assert.equal(urlUtil.getLocationIfPDF(null), null)
- })
- it('gets location for file: PDF URL', function () {
- let url = 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/file:///Users/yan/Downloads/test.pdf'
- assert.equal(urlUtil.getLocationIfPDF(url), 'file:///Users/yan/Downloads/test.pdf')
- })
- })
-
- describe('getDefaultFaviconUrl', function () {
- it('returns empty string if input is not a URL', function () {
- assert.equal(urlUtil.getDefaultFaviconUrl('invalid-url-goes-here'), '')
- })
- it('returns the default favicon URL when given a valid URL', function () {
- assert.equal(urlUtil.getDefaultFaviconUrl('https://brave.com'), 'https://brave.com/favicon.ico')
- })
- it('includes the port in the response when given a valid URL with a port number', function () {
- assert.equal(urlUtil.getDefaultFaviconUrl('https://brave.com:8080'), 'https://brave.com:8080/favicon.ico')
- })
- })
-
- describe('getPunycodeUrl', function () {
- it('returns original string if input is ASCII', function () {
- assert.equal(urlUtil.getPunycodeUrl('invalid-url-goes-here'), 'invalid-url-goes-here')
- })
- it('returns punycode ASCII string if input is non-ASCII', function () {
- assert.equal(urlUtil.getPunycodeUrl('ebаy.com'), 'xn--eby-7cd.com')
- })
- it('returns the punycode URL when given a valid URL', function () {
- assert.equal(urlUtil.getPunycodeUrl('http://brave:brave@ebаy.com:1234/brave#brave'), 'http://brave:brave@xn--eby-7cd.com:1234/brave#brave')
- })
- })
-
- describe('isPotentialPhishingUrl', function () {
- it('returns false if input is not a URL', function () {
- assert.equal(urlUtil.isPotentialPhishingUrl(null), false)
- })
- it('returns false if input is a regular URL', function () {
- assert.equal(urlUtil.isPotentialPhishingUrl(' https://google.com'), false)
- })
- it('returns true if input is a data URL', function () {
- assert.equal(urlUtil.isPotentialPhishingUrl('data:text/html,'), true)
- })
- it('returns true if input is a blob URL', function () {
- assert.equal(urlUtil.isPotentialPhishingUrl(' BLOB:foo '), true)
- })
- })
-
- describe('isFileScheme', function () {
- describe('returns true when input:', function () {
- it('is an absolute file path with scheme', function () {
- assert.equal(urlUtil.isFileScheme('file:///file/path/to/file'), true)
- })
- })
- describe('returns false when input:', function () {
- it('is an absolute file path without scheme', function () {
- assert.equal(urlUtil.isFileScheme('/file/path/to/file'), false)
- })
- it('is a URL', function () {
- assert.equal(urlUtil.isFileScheme('http://brave.com'), false)
- })
- it('has custom protocol', function () {
- assert.equal(urlUtil.isFileScheme('brave://test'), false)
- })
- })
- })
-
- describe('getDisplayHost', function () {
- it('url is http', function () {
- const result = urlUtil.getDisplayHost('http://brave.com')
- assert.equal(result, 'brave.com')
- })
-
- it('url is https', function () {
- const result = urlUtil.getDisplayHost('https://brave.com')
- assert.equal(result, 'brave.com')
- })
-
- it('url is file', function () {
- const result = urlUtil.getDisplayHost('file://brave.text')
- assert.equal(result, 'file://brave.text')
- })
- })
-
- describe('getOrigin', function () {
- it('returns file:/// for any file url', function () {
- assert.strictEqual(urlUtil.getOrigin('file://'), 'file:///')
- assert.strictEqual(urlUtil.getOrigin('file:///'), 'file:///')
- assert.strictEqual(urlUtil.getOrigin('file:///some'), 'file:///')
- assert.strictEqual(urlUtil.getOrigin('file:///some/'), 'file:///')
- assert.strictEqual(urlUtil.getOrigin('file:///some/path'), 'file:///')
- })
- it('gets URL origin for simple url', function () {
- assert.strictEqual(urlUtil.getOrigin('https://abc.bing.com'), 'https://abc.bing.com')
- })
- it('gets URL origin for url with port', function () {
- assert.strictEqual(urlUtil.getOrigin('https://bing.com:443/?test=1#abc'), 'https://bing.com:443')
- })
- it('gets URL origin for IP host', function () {
- assert.strictEqual(urlUtil.getOrigin('http://127.0.0.1:443/?test=1#abc'), 'http://127.0.0.1:443')
- })
- it('gets URL origin for slashless protocol URL', function () {
- assert.strictEqual(urlUtil.getOrigin('about:test/foo'), 'about:test')
- })
- it('returns null for invalid URL', function () {
- assert.strictEqual(urlUtil.getOrigin('abc'), null)
- })
- it('returns null for empty URL', function () {
- assert.strictEqual(urlUtil.getOrigin(''), null)
- })
- it('returns null for null URL', function () {
- assert.strictEqual(urlUtil.getOrigin(null), null)
- })
- it('returns correct result for URL with hostname that is a scheme', function () {
- assert.strictEqual(urlUtil.getOrigin('http://http/test'), 'http://http')
- })
- })
-
- describe('stripLocation', function () {
- it('null scenario', function () {
- const result = urlUtil.stripLocation(null)
- assert.equal(result, '')
- })
-
- it('empty string', function () {
- const result = urlUtil.stripLocation('')
- assert.equal(result, '')
- })
-
- it('normal url without # or /', function () {
- const result = urlUtil.stripLocation('https://brave.com')
- assert.equal(result, 'https://brave.com')
- })
-
- it('normal url with # but not at the end', function () {
- const result = urlUtil.stripLocation('https://brave.com#title')
- assert.equal(result, 'https://brave.com#title')
- })
-
- it('normal url with # at the end', function () {
- const result = urlUtil.stripLocation('https://brave.com#')
- assert.equal(result, 'https://brave.com')
- })
-
- it('normal url with / at the end', function () {
- const result = urlUtil.stripLocation('https://brave.com/')
- assert.equal(result, 'https://brave.com')
- })
-
- it('normal url with /# at the end', function () {
- const result = urlUtil.stripLocation('https://brave.com/#')
- assert.equal(result, 'https://brave.com')
- })
-
- it('normal url with white space at the end', function () {
- const result = urlUtil.stripLocation('https://brave.com ')
- assert.equal(result, 'https://brave.com')
- })
- })
-
- describe('parseFaviconDataUrl', function () {
- it('null scenario', function () {
- const result = urlUtil.parseFaviconDataUrl(null)
- assert.equal(result, null)
- })
- it('empty string', function () {
- const result = urlUtil.parseFaviconDataUrl('')
- assert.equal(result, null)
- })
- it('regular URL', function () {
- const result = urlUtil.parseFaviconDataUrl('http://example.com')
- assert.equal(result, null)
- })
- it('non-image data URL', function () {
- const result = urlUtil.parseFaviconDataUrl('data:text/plain;charset=UTF-8;page=21,the%20data:1234,5678')
- assert.equal(result, null)
- })
- it('non-base64 data URL', function () {
- const result = urlUtil.parseFaviconDataUrl('data:image/jpg,foo')
- assert.equal(result, null)
- })
- it('no-extension data URL', function () {
- const result = urlUtil.parseFaviconDataUrl('data:image/;base64,foo')
- assert.equal(result, null)
- })
- it('valid jpg', function () {
- const jpg = 'data:image/jpeg;base64,' +
- '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kf' +
- 'r6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O////////' +
- '////////////////////////////////////////////////////////////wAARCAAYAEADAREA' +
- '//AhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAQMAAgQF/8QAJRABAAIBBAEEAgMAAAAAAAAAAQIR' +
- '//AAMSITEEEyJBgTORUWFx/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAA' +
- '//AAD/2gAMAwEAAhEDEQA/AOgM52xQDrjvAV5Xv0vfKUALlTQfeBm0HThMNHXkL0Lw/swN5qgA8yT4' +
- '//MCS1OEOJV8mBz9Z05yfW8iSx7p4j+jA1aD6Wj7ZMzstsfvAas4UyRHvjrAkC9KhpLMClQntlqFc2' +
- '//X1gUj4viwVObKrddH9YDoHvuujAEuNV+bLwFS8XxdSr+Cq3Vf+4F5RgQl6ZR2p1eAzU/HX80YBYy' +
- '//JLCuexwJCO2O1bwCRidAfWBSctswbI12GAJT3yiwFR7+MBjGK2g/WAJR3FdF84E2rK5VR0YH/9k='
- const expected = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kf' +
- 'r6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O////////' +
- '////////////////////////////////////////////////////////////wAARCAAYAEADAREA' +
- '//AhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAQMAAgQF/8QAJRABAAIBBAEEAgMAAAAAAAAAAQIR' +
- '//AAMSITEEEyJBgTORUWFx/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAA' +
- '//AAD/2gAMAwEAAhEDEQA/AOgM52xQDrjvAV5Xv0vfKUALlTQfeBm0HThMNHXkL0Lw/swN5qgA8yT4' +
- '//MCS1OEOJV8mBz9Z05yfW8iSx7p4j+jA1aD6Wj7ZMzstsfvAas4UyRHvjrAkC9KhpLMClQntlqFc2' +
- '//X1gUj4viwVObKrddH9YDoHvuujAEuNV+bLwFS8XxdSr+Cq3Vf+4F5RgQl6ZR2p1eAzU/HX80YBYy' +
- '//JLCuexwJCO2O1bwCRidAfWBSctswbI12GAJT3yiwFR7+MBjGK2g/WAJR3FdF84E2rK5VR0YH/9k='
- const result = urlUtil.parseFaviconDataUrl(jpg)
- assert.deepEqual(result, {data: expected, ext: 'jpeg'})
- })
- it('valid png', function () {
- const png = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU//5ErkJggg=='
- const result = urlUtil.parseFaviconDataUrl(png)
- assert.deepEqual(result, {data: 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU//5ErkJggg==', ext: 'png'})
- })
- })
-})
+runMuonCompatibleTests('urlutil', components)
diff --git a/test/unit/lib/urlutilTestComponents.js b/test/unit/lib/urlutilTestComponents.js
new file mode 100644
index 00000000000..55dd829f862
--- /dev/null
+++ b/test/unit/lib/urlutilTestComponents.js
@@ -0,0 +1,570 @@
+// lazy load requires for dual use in and outside muon
+const urlUtil = () => require('../../../js/lib/urlutil')
+
+module.exports = {
+ 'getScheme': {
+ 'null for empty': (test) => {
+ test.equal(urlUtil().getScheme('/file/path/to/file'), null)
+ },
+ 'localhost: for localhost': (test) => {
+ test.equal(urlUtil().getScheme('localhost://127.0.0.1'), 'localhost:')
+ },
+ 'gets scheme with :': (test) => {
+ test.equal(urlUtil().getScheme('data:datauri'), 'data:')
+ },
+ 'host:port is not recognized as a scheme': (test) => {
+ test.equal(urlUtil().getScheme('localhost:8089'), null)
+ },
+ 'gets scheme with ://': (test) => {
+ test.equal(urlUtil().getScheme('http://www.brave.com'), 'http://')
+ }
+ },
+
+ 'prependScheme': {
+ 'returns null when input is null': (test) => {
+ test.equal(urlUtil().prependScheme(null), null)
+ },
+ 'returns undefined when input is undefined': (test) => {
+ test.equal(urlUtil().prependScheme(), undefined)
+ },
+ 'prepends file:// to absolute file path': (test) => {
+ test.equal(urlUtil().prependScheme('/file/path/to/file'), 'file:///file/path/to/file')
+ },
+ 'defaults to http://': (test) => {
+ test.equal(urlUtil().prependScheme('www.brave.com'), 'http://www.brave.com')
+ },
+ 'keeps schema if already exists': (test) => {
+ test.equal(urlUtil().prependScheme('https://www.brave.com'), 'https://www.brave.com')
+ }
+ },
+
+ 'isNotURL': {
+ 'returns false when input:': {
+ 'is a valid URL': (test) => {
+ test.equal(urlUtil().isNotURL('brave.com'), false)
+ },
+ 'is an absolute file path without scheme': (test) => {
+ test.equal(urlUtil().isNotURL('/file/path/to/file'), false)
+ },
+ 'is an absolute file path with scheme': (test) => {
+ test.equal(urlUtil().isNotURL('file:///file/path/to/file'), false)
+ },
+ 'for special pages': {
+ 'is a data URI': (test) => {
+ test.equal(urlUtil().isNotURL('data:text/html,hi'), false)
+ },
+ 'is a view source URL': (test) => {
+ test.equal(urlUtil().isNotURL('view-source://url-here'), false)
+ },
+ 'is a mailto link': (test) => {
+ test.equal(urlUtil().isNotURL('mailto:brian@brave.com'), false)
+ },
+ 'is an about page': (test) => {
+ test.equal(urlUtil().isNotURL('about:preferences'), false)
+ },
+ 'is a chrome-extension page': (test) => {
+ test.equal(urlUtil().isNotURL('chrome-extension://fmfcbgogabcbclcofgocippekhfcmgfj/cast_sender.js'), false)
+ },
+ 'is a magnet URL': (test) => {
+ test.equal(urlUtil().isNotURL('chrome://gpu'), false)
+ },
+ 'is a chrome page': (test) => {
+ test.equal(urlUtil().isNotURL('magnet:?xt=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C'), false)
+ }
+ },
+ 'contains a hostname and port number': (test) => {
+ test.equal(urlUtil().isNotURL('someBraveServer:8089'), false)
+ },
+ 'starts or ends with whitespace': (test) => {
+ test.equal(urlUtil().isNotURL(' http://brave.com '), false)
+ test.equal(urlUtil().isNotURL('\n\nhttp://brave.com\n\n'), false)
+ test.equal(urlUtil().isNotURL('\t\thttp://brave.com\t\t'), false)
+ },
+ 'is a URL which contains basic auth user/pass': (test) => {
+ test.equal(urlUtil().isNotURL('http://username:password@example.com'), false)
+ },
+ 'is localhost (case-insensitive)': (test) => {
+ test.equal(urlUtil().isNotURL('LoCaLhOsT'), false)
+ },
+ 'is a hostname (not a domain)': (test) => {
+ test.equal(urlUtil().isNotURL('http://computer001/phpMyAdmin'), false)
+ },
+ 'ends with period (input contains a forward slash and domain)': (test) => {
+ test.equal(urlUtil().isNotURL('brave.com/test/cc?_ri_=3vv-8-e.'), false)
+ },
+ 'is a string with whitespace but has schema': (test) => {
+ test.equal(urlUtil().isNotURL('https://wwww.brave.com/test space.jpg'), false)
+ },
+ 'has custom protocol': (test) => {
+ test.equal(urlUtil().isNotURL('brave://test'), false)
+ }
+ },
+
+ 'returns true when input:': {
+ 'is null or undefined': (test) => {
+ test.equal(urlUtil().isNotURL(), true)
+ test.equal(urlUtil().isNotURL(null), true)
+ },
+ 'is not a string': (test) => {
+ test.equal(urlUtil().isNotURL(false), true)
+ test.equal(urlUtil().isNotURL(333.449), true)
+ },
+ 'is a quoted string': (test) => {
+ test.equal(urlUtil().isNotURL('"search term here"'), true)
+ },
+ 'is a pure string (no TLD)': (test) => {
+ test.equal(urlUtil().isNotURL('brave'), true)
+ },
+ 'search query': {
+ 'starts with question mark': (test) => {
+ test.equal(urlUtil().isNotURL('?brave'), true)
+ },
+ 'has a question mark followed by a space': (test) => {
+ test.equal(urlUtil().isNotURL('? brave'), true)
+ },
+ 'starts with period': (test) => {
+ test.equal(urlUtil().isNotURL('.brave'), true)
+ },
+ 'ends with period (input does NOT contain a forward slash)': (test) => {
+ test.equal(urlUtil().isNotURL('brave.'), true)
+ },
+ 'ends with period (input contains only a forward slash)': (test) => {
+ test.equal(urlUtil().isNotURL('brave/com/test/cc?_ri_=3vv-8-e.'), true)
+ }
+ },
+ 'is a string with schema but invalid domain name': (test) => {
+ test.equal(urlUtil().isNotURL('https://www.bra ve.com/test space.jpg'), true)
+ },
+ 'contains more than one word': (test) => {
+ test.equal(urlUtil().isNotURL('brave is cool'), true)
+ },
+ 'is not an about page / view source / data URI / mailto / etc': (test) => {
+ test.equal(urlUtil().isNotURL('not-a-chrome-extension:'), true)
+ test.equal(urlUtil().isNotURL('mailtoo:'), true)
+ },
+ 'is a URL (without protocol) which contains basic auth user/pass': (test) => {
+ test.equal(urlUtil().isNotURL('username:password@example.com'), true)
+ },
+ 'has space in schema': (test) => {
+ test.equal(urlUtil().isNotURL('https ://brave.com'), true)
+ }
+ }
+ },
+
+ 'getUrlFromInput': {
+ 'returns empty string when input is null': (test) => {
+ test.equal(urlUtil().getUrlFromInput(null), '')
+ },
+ 'returns empty string when input is undefined': (test) => {
+ test.equal(urlUtil().getUrlFromInput(), '')
+ },
+ 'calls prependScheme': (test) => {
+ test.equal(urlUtil().getUrlFromInput('/file/path/to/file'), 'file:///file/path/to/file')
+ }
+ },
+
+ 'isURL': {
+ 'returns !isNotURL': (test) => {
+ test.equal(urlUtil().isURL('brave.com'), !urlUtil().isNotURL('brave.com'))
+ test.equal(urlUtil().isURL('brave is cool'), !urlUtil().isNotURL('brave is cool'))
+ test.equal(urlUtil().isURL('mailto:brian@brave.com'), !urlUtil().isNotURL('mailto:brian@brave.com'))
+ }
+ },
+
+ 'isFileType': {
+ 'relative file': (test) => {
+ test.equal(urlUtil().isFileType('file:///file/abc/test.pdf', 'pdf'), true)
+ },
+ 'relative path': (test) => {
+ test.equal(urlUtil().isFileType('file:///file/abc/test', 'pdf'), false)
+ },
+ 'JPG URL': (test) => {
+ test.equal(urlUtil().isFileType('http://example.com/test/ABC.JPG?a=b#test', 'jpg'), true)
+ },
+ 'non-JPG URL': (test) => {
+ test.equal(urlUtil().isFileType('http://example.com/test/jpg', 'jpg'), false)
+ },
+ 'invalid URL': (test) => {
+ test.equal(urlUtil().isFileType('foo', 'jpg'), false)
+ }
+ },
+
+ 'toPDFJSLocation': {
+ 'pdf': (test) => {
+ const baseUrl = 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/'
+ test.equal(urlUtil().toPDFJSLocation('http://abc.com/test.pdf'), baseUrl + 'content/web/viewer.html?file=http%3A%2F%2Fabc.com%2Ftest.pdf')
+ },
+ 'non-pdf': (test) => {
+ test.equal(urlUtil().toPDFJSLocation('http://abc.com/test.pdf.txt'), 'http://abc.com/test.pdf.txt')
+ },
+ 'file url': (test) => {
+ test.equal(urlUtil().toPDFJSLocation('file://abc.com/test.pdf.txt'), 'file://abc.com/test.pdf.txt')
+ },
+ 'empty': (test) => {
+ test.equal(urlUtil().toPDFJSLocation(''), '')
+ }
+ },
+
+ 'getPDFViewerUrl': {
+ 'regular url': (test) => {
+ const baseUrl = 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/content/web/viewer.html?file='
+ test.equal(urlUtil().getPDFViewerUrl('http://example.com'), baseUrl + 'http%3A%2F%2Fexample.com')
+ },
+ 'file url': (test) => {
+ const baseUrl = 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/content/web/viewer.html?file='
+ test.equal(urlUtil().getPDFViewerUrl('file:///Users/yan/some files/test.pdf'), baseUrl + 'file%3A%2F%2F%2FUsers%2Fyan%2Fsome%20files%2Ftest.pdf')
+ }
+ },
+
+ 'getHostname': {
+ 'returns undefined if the URL is invalid': (test) => {
+ test.equal(urlUtil().getHostname(null), undefined)
+ },
+ 'returns the host field (including port number)': (test) => {
+ test.equal(urlUtil().getHostname('https://brave.com:8080/test/'), 'brave.com:8080')
+ },
+ 'allows you to exclude the port number': (test) => {
+ test.equal(urlUtil().getHostname('https://brave.com:8080/test/', true), 'brave.com')
+ }
+ },
+
+ 'getHostnamePatterns': {
+ 'gets bare domain hostname patterns': (test) => {
+ // XXX: *.com probably should be excluded
+ test.deepEqual(urlUtil().getHostnamePatterns('http://brave.com'),
+ ['brave.com', '*.com', 'brave.*'])
+ },
+ 'gets subdomain hostname patterns': (test) => {
+ test.deepEqual(urlUtil().getHostnamePatterns('https://bar.brave.com'),
+ ['bar.brave.com',
+ '*.brave.com',
+ 'bar.*.com',
+ 'bar.brave.*'])
+ test.deepEqual(urlUtil().getHostnamePatterns('https://foo.bar.brave.com'),
+ ['foo.bar.brave.com',
+ '*.bar.brave.com',
+ 'foo.*.brave.com',
+ 'foo.bar.*.com',
+ 'foo.bar.brave.*',
+ '*.brave.com'])
+ }
+ },
+
+ 'getLocationIfPDF': {
+ 'gets location for PDF JS URL': (test) => {
+ test.equal(urlUtil().getLocationIfPDF('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf'),
+ 'https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf')
+ },
+ 'gets location for PDF JS viewer URL': (test) => {
+ test.equal(urlUtil().getLocationIfPDF('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/content/web/viewer.html?file=http%3A%2F%2Funec.edu.az%2Fapplication%2Fuploads%2F2014%2F12%2Fpdf-sample.pdf'),
+ 'http://unec.edu.az/application/uploads/2014/12/pdf-sample.pdf')
+ },
+ 'does not remove wayback machine url location for PDF JS URL': (test) => {
+ test.equal(urlUtil().getLocationIfPDF('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/https://web.archive.org/web/20160106152308/http://stlab.adobe.com/wiki/images/d/d3/Test.pdf'),
+ 'https://web.archive.org/web/20160106152308/http://stlab.adobe.com/wiki/images/d/d3/Test.pdf')
+ },
+ 'does not modify location for non-pdf URL': (test) => {
+ test.equal(urlUtil().getLocationIfPDF('https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf'),
+ 'https://www.blackhat.co…king-Kernel-Address-Space-Layout-Randomization-KASLR-With-Intel-TSX-wp.pdf')
+ test.equal(urlUtil().getLocationIfPDF('chrome-extension://blank'), 'chrome-extension://blank')
+ test.equal(urlUtil().getLocationIfPDF(null), null)
+ },
+ 'gets location for file: PDF URL': (test) => {
+ let url = 'chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/file:///Users/yan/Downloads/test.pdf'
+ test.equal(urlUtil().getLocationIfPDF(url), 'file:///Users/yan/Downloads/test.pdf')
+ }
+ },
+
+ 'getDefaultFaviconUrl': {
+ 'returns empty string if input is not a URL': (test) => {
+ test.equal(urlUtil().getDefaultFaviconUrl('invalid-url-goes-here'), '')
+ },
+ 'returns the default favicon URL when given a valid URL': (test) => {
+ test.equal(urlUtil().getDefaultFaviconUrl('https://brave.com'), 'https://brave.com/favicon.ico')
+ },
+ 'includes the port in the response when given a valid URL with a port number': (test) => {
+ test.equal(urlUtil().getDefaultFaviconUrl('https://brave.com:8080'), 'https://brave.com:8080/favicon.ico')
+ }
+ },
+
+ 'getPunycodeUrl': {
+ 'returns original string if input is ASCII': (test) => {
+ test.equal(urlUtil().getPunycodeUrl('invalid-url-goes-here'), 'invalid-url-goes-here')
+ },
+ 'returns punycode ASCII string if input is non-ASCII': (test) => {
+ test.equal(urlUtil().getPunycodeUrl('ebаy.com'), 'xn--eby-7cd.com')
+ },
+ 'returns the punycode URL when given a valid URL': (test) => {
+ test.equal(urlUtil().getPunycodeUrl('http://brave:brave@ebаy.com:1234/brave#brave'), 'http://brave:brave@xn--eby-7cd.com:1234/brave#brave')
+ },
+ 'returns the punycode URL when given a URL contains @': (test) => {
+ test.equal(urlUtil().getPunycodeUrl('ebаy.com/@ebаy.com'), 'xn--eby-7cd.com/@xn--eby-7cd.com')
+ }
+ },
+
+ 'isPotentialPhishingUrl': {
+ 'returns false if input is not a URL': (test) => {
+ test.equal(urlUtil().isPotentialPhishingUrl(null), false)
+ },
+ 'returns false if input is a regular URL': (test) => {
+ test.equal(urlUtil().isPotentialPhishingUrl(' https://google.com'), false)
+ },
+ 'returns true if input is a data URL': (test) => {
+ test.equal(urlUtil().isPotentialPhishingUrl('data:text/html,'), true)
+ },
+ 'returns true if input is a blob URL': (test) => {
+ test.equal(urlUtil().isPotentialPhishingUrl(' BLOB:foo '), true)
+ }
+ },
+
+ 'isFileScheme': {
+ 'returns true when input:': {
+ 'is an absolute file path with scheme': (test) => {
+ test.equal(urlUtil().isFileScheme('file:///file/path/to/file'), true)
+ }
+ },
+ 'returns false when input:': {
+ 'is an absolute file path without scheme': (test) => {
+ test.equal(urlUtil().isFileScheme('/file/path/to/file'), false)
+ },
+ 'is a URL': (test) => {
+ test.equal(urlUtil().isFileScheme('http://brave.com'), false)
+ },
+ 'has custom protocol': (test) => {
+ test.equal(urlUtil().isFileScheme('brave://test'), false)
+ }
+ }
+ },
+
+ 'getDisplayHost': {
+ 'url is http': (test) => {
+ const result = urlUtil().getDisplayHost('http://brave.com')
+ test.equal(result, 'brave.com')
+ },
+
+ 'url is https': (test) => {
+ const result = urlUtil().getDisplayHost('https://brave.com')
+ test.equal(result, 'brave.com')
+ },
+
+ 'url is file': (test) => {
+ const result = urlUtil().getDisplayHost('file://brave.text')
+ test.equal(result, 'file://brave.text')
+ }
+ },
+
+ 'getOrigin': {
+ 'returns file:/// for any file url': (test) => {
+ test.strictEqual(urlUtil().getOrigin('file://'), 'file:///')
+ test.strictEqual(urlUtil().getOrigin('file:///'), 'file:///')
+ test.strictEqual(urlUtil().getOrigin('file:///some'), 'file:///')
+ test.strictEqual(urlUtil().getOrigin('file:///some/'), 'file:///')
+ test.strictEqual(urlUtil().getOrigin('file:///some/path'), 'file:///')
+ },
+ 'gets URL origin for simple url': (test) => {
+ test.strictEqual(urlUtil().getOrigin('https://abc.bing.com'), 'https://abc.bing.com')
+ },
+ 'gets URL origin for url with port': (test) => {
+ test.strictEqual(urlUtil().getOrigin('https://bing.com:8000/?test=1#abc'), 'https://bing.com:8000')
+ },
+ 'gets URL origin for IP host': (test) => {
+ test.strictEqual(urlUtil().getOrigin('http://127.0.0.1:443/?test=1#abc'), 'http://127.0.0.1:443')
+ },
+ 'gets URL origin for about:': (test) => {
+ test.strictEqual(urlUtil().getOrigin('about:preferences#abc'), 'about:preferences')
+ },
+ 'gets URL origin for slashless protocol URL': (test) => {
+ test.strictEqual(urlUtil().getOrigin('about:test'), 'about:test')
+ test.strictEqual(urlUtil().getOrigin('about:test/'), 'about:test')
+ test.strictEqual(urlUtil().getOrigin('about:test/foo'), 'about:test')
+ test.strictEqual(urlUtil().getOrigin('about:test/foo/bar'), 'about:test')
+ test.strictEqual(urlUtil().getOrigin('about:test/foo/bar#baz'), 'about:test')
+ },
+ 'returns null for invalid URL': (test) => {
+ test.strictEqual(urlUtil().getOrigin('abc'), null)
+ },
+ 'returns null for empty URL': (test) => {
+ test.strictEqual(urlUtil().getOrigin(''), null)
+ },
+ 'returns null for null URL': (test) => {
+ test.strictEqual(urlUtil().getOrigin(null), null)
+ },
+ 'returns correct result for URL with hostname that is a scheme': (test) => {
+ test.strictEqual(urlUtil().getOrigin('http://http/test'), 'http://http')
+ }
+ },
+
+ 'stripLocation': {
+ 'null scenario': (test) => {
+ const result = urlUtil().stripLocation(null)
+ test.equal(result, '')
+ },
+
+ 'empty string': (test) => {
+ const result = urlUtil().stripLocation('')
+ test.equal(result, '')
+ },
+
+ 'normal url without hash or slash': (test) => {
+ const result = urlUtil().stripLocation('https://brave.com')
+ test.equal(result, 'https://brave.com')
+ },
+
+ 'normal url with hash but not at the end': (test) => {
+ const result = urlUtil().stripLocation('https://brave.com#title')
+ test.equal(result, 'https://brave.com#title')
+ },
+
+ 'normal url with hash at the end': (test) => {
+ const result = urlUtil().stripLocation('https://brave.com#')
+ test.equal(result, 'https://brave.com')
+ },
+
+ 'normal url with slash at the end': (test) => {
+ const result = urlUtil().stripLocation('https://brave.com/')
+ test.equal(result, 'https://brave.com')
+ },
+
+ 'normal url with slash hash at the end': (test) => {
+ const result = urlUtil().stripLocation('https://brave.com/#')
+ test.equal(result, 'https://brave.com')
+ },
+
+ 'normal url with white space at the end': (test) => {
+ const result = urlUtil().stripLocation('https://brave.com ')
+ test.equal(result, 'https://brave.com')
+ }
+ },
+
+ 'parseFaviconDataUrl': {
+ 'null scenario': (test) => {
+ const result = urlUtil().parseFaviconDataUrl(null)
+ test.equal(result, null)
+ },
+ 'empty string': (test) => {
+ const result = urlUtil().parseFaviconDataUrl('')
+ test.equal(result, null)
+ },
+ 'regular URL': (test) => {
+ const result = urlUtil().parseFaviconDataUrl('http://example.com')
+ test.equal(result, null)
+ },
+ 'non-image data URL': (test) => {
+ const result = urlUtil().parseFaviconDataUrl('data:text/plain;charset=UTF-8;page=21,the%20data:1234,5678')
+ test.equal(result, null)
+ },
+ 'non-base64 data URL': (test) => {
+ const result = urlUtil().parseFaviconDataUrl('data:image/jpg,foo')
+ test.equal(result, null)
+ },
+ 'no-extension data URL': (test) => {
+ const result = urlUtil().parseFaviconDataUrl('data:image/;base64,foo')
+ test.equal(result, null)
+ },
+ 'valid jpg': (test) => {
+ const jpg = 'data:image/jpeg;base64,' +
+ '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kf' +
+ 'r6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O////////' +
+ '////////////////////////////////////////////////////////////wAARCAAYAEADAREA' +
+ '//AhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAQMAAgQF/8QAJRABAAIBBAEEAgMAAAAAAAAAAQIR' +
+ '//AAMSITEEEyJBgTORUWFx/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAA' +
+ '//AAD/2gAMAwEAAhEDEQA/AOgM52xQDrjvAV5Xv0vfKUALlTQfeBm0HThMNHXkL0Lw/swN5qgA8yT4' +
+ '//MCS1OEOJV8mBz9Z05yfW8iSx7p4j+jA1aD6Wj7ZMzstsfvAas4UyRHvjrAkC9KhpLMClQntlqFc2' +
+ '//X1gUj4viwVObKrddH9YDoHvuujAEuNV+bLwFS8XxdSr+Cq3Vf+4F5RgQl6ZR2p1eAzU/HX80YBYy' +
+ '//JLCuexwJCO2O1bwCRidAfWBSctswbI12GAJT3yiwFR7+MBjGK2g/WAJR3FdF84E2rK5VR0YH/9k='
+ const expected = '/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDADIiJSwlHzIsKSw4NTI7S31RS0VFS5ltc1p9tZ++u7Kf' +
+ 'r6zI4f/zyNT/16yv+v/9////////wfD/////////////2wBDATU4OEtCS5NRUZP/zq/O////////' +
+ '////////////////////////////////////////////////////////////wAARCAAYAEADAREA' +
+ '//AhEBAxEB/8QAGQAAAgMBAAAAAAAAAAAAAAAAAQMAAgQF/8QAJRABAAIBBAEEAgMAAAAAAAAAAQIR' +
+ '//AAMSITEEEyJBgTORUWFx/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAA' +
+ '//AAD/2gAMAwEAAhEDEQA/AOgM52xQDrjvAV5Xv0vfKUALlTQfeBm0HThMNHXkL0Lw/swN5qgA8yT4' +
+ '//MCS1OEOJV8mBz9Z05yfW8iSx7p4j+jA1aD6Wj7ZMzstsfvAas4UyRHvjrAkC9KhpLMClQntlqFc2' +
+ '//X1gUj4viwVObKrddH9YDoHvuujAEuNV+bLwFS8XxdSr+Cq3Vf+4F5RgQl6ZR2p1eAzU/HX80YBYy' +
+ '//JLCuexwJCO2O1bwCRidAfWBSctswbI12GAJT3yiwFR7+MBjGK2g/WAJR3FdF84E2rK5VR0YH/9k='
+ const result = urlUtil().parseFaviconDataUrl(jpg)
+ test.deepEqual(result, {data: expected, ext: 'jpeg'})
+ },
+ 'valid png': (test) => {
+ const png = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU//5ErkJggg=='
+ const result = urlUtil().parseFaviconDataUrl(png)
+ test.deepEqual(result, {data: 'iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU//5ErkJggg==', ext: 'png'})
+ }
+ },
+
+ 'isInternalUrl': {
+ 'null scenario': (test) => {
+ const result = urlUtil().isInternalUrl(null)
+ test.equal(result, false)
+ },
+ 'localhost': (test) => {
+ const result = urlUtil().isInternalUrl('http://localhost:399/abc')
+ test.equal(result, true)
+ },
+ 'localhost.com': (test) => {
+ const result = urlUtil().isInternalUrl('http://localhost.com:399/abc')
+ test.equal(result, false)
+ },
+ 'invalid URL': (test) => {
+ const result = urlUtil().isInternalUrl('adsf')
+ test.equal(result, false)
+ },
+ 'local IP': (test) => {
+ const result = urlUtil().isInternalUrl('http://192.168.1.255:3000')
+ test.equal(result, true)
+ const result2 = urlUtil().isInternalUrl('http://127.0.0.1/')
+ test.equal(result2, true)
+ },
+ 'remote IP': (test) => {
+ const result = urlUtil().isInternalUrl('http://54.0.0.1:3000')
+ test.equal(result, false)
+ },
+ 'local IPv6': (test) => {
+ const result = urlUtil().isInternalUrl('https://[::1]:3000')
+ test.equal(result, true)
+ const result2 = urlUtil().isInternalUrl('http://[fe80::c12:79e9:bd20:31e1]/')
+ test.equal(result2, true)
+ },
+ 'remote IPv6': (test) => {
+ const result = urlUtil().isInternalUrl('http://[2001:4860:4860::8888]:8000')
+ test.equal(result, false)
+ },
+ '.local URL': (test) => {
+ const result = urlUtil().isInternalUrl('https://adsf.local')
+ test.equal(result, true)
+ }
+ },
+
+ 'isUrlPDF': {
+ 'null case': (test) => {
+ const result = urlUtil().isUrlPDF(null)
+ test.equal(result, false)
+ },
+
+ 'url is not pdf': (test) => {
+ const result = urlUtil().isUrlPDF('https://clifton.io')
+ test.equal(result, false)
+ },
+
+ 'url is pdf': (test) => {
+ const result = urlUtil().isUrlPDF('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/http://www.test.com/test.pdf')
+ test.equal(result, true)
+ }
+ },
+
+ 'getUrlFromPDFUrl': {
+ 'null case': (test) => {
+ const result = urlUtil().getUrlFromPDFUrl(null)
+ test.equal(result, null)
+ },
+
+ 'url is not PDF': (test) => {
+ const result = urlUtil().getUrlFromPDFUrl('https://clifton.io')
+ test.equal(result, 'https://clifton.io')
+ },
+
+ 'url is pdf': (test) => {
+ const result = urlUtil().getUrlFromPDFUrl('chrome-extension://jdbefljfgobbmcidnmpjamcbhnbphjnb/http://www.test.com/test.pdf')
+ test.equal(result, 'http://www.test.com/test.pdf')
+ }
+ }
+}
diff --git a/test/unit/runMuonCompatibleTests.js b/test/unit/runMuonCompatibleTests.js
new file mode 100644
index 00000000000..0a257963d25
--- /dev/null
+++ b/test/unit/runMuonCompatibleTests.js
@@ -0,0 +1,31 @@
+/* global describe, it, before, after */
+
+const assert = require('assert')
+require('./braveUnit')
+
+const executeTests = (name, tests) => {
+ describe(name, function () {
+ const runnableTests = Object.keys(tests).filter((k) => typeof tests[k] === 'function')
+ if (runnableTests.length) {
+ for (let testName of runnableTests) {
+ if (testName === 'before') {
+ before(tests[testName])
+ } else if (testName === 'after') {
+ after(tests[testName])
+ } else {
+ const wrapper = tests[testName].length > 1
+ ? function (cb) { tests[testName].call(this, assert, cb) }
+ : function () { tests[testName].call(this, assert) }
+ it(testName, wrapper)
+ }
+ }
+ }
+
+ const testGroups = Object.keys(tests).filter((k) => typeof tests[k] === 'object')
+ for (let groupName of testGroups) {
+ executeTests(groupName, tests[groupName])
+ }
+ })
+}
+
+module.exports = executeTests
diff --git a/test/vms/vagrant/centos/Vagrantfile b/test/vms/vagrant/centos/Vagrantfile
deleted file mode 100644
index b4a56c0a63e..00000000000
--- a/test/vms/vagrant/centos/Vagrantfile
+++ /dev/null
@@ -1,8 +0,0 @@
-Vagrant.configure('2') do |config|
- vm_ram = ENV['VAGRANT_VM_RAM'] || 10000
- vm_cpu = ENV['VAGRANT_VM_CPU'] || 10
-
- config.vm.box = "centos/7"
- config.vm.provision :shell, :inline => "/vagrant/init"
-
-end
diff --git a/test/vms/vagrant/centos/build b/test/vms/vagrant/centos/build
deleted file mode 100755
index 125d5458dbb..00000000000
--- a/test/vms/vagrant/centos/build
+++ /dev/null
@@ -1,26 +0,0 @@
-#!/bin/bash
-set -ex
-wget -O installer https://sh.rustup.rs
-bash installer -y -v
-echo "export SCCACHE_BUCKET='brave-sc-cache'" >> ~/.bashrc
-echo 'export PATH="$HOME/.cargo/bin:$PATH"' >> ~/.bashrc
-export PATH="$HOME/.cargo/bin:$PATH"
-export SCCACHE_BUCKET='brave-sc-cache'
-cargo install sccache
-
-curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
-export MANPATH=/tmp/
-export NVM_DIR="/home/vagrant/.nvm"
-[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
-source ~/.nvm/nvm.sh
-nvm install stable
-nvm use stable
-
-
-cd /build
-git clone https://github.com/posix4e/browser-laptop-bootstrap
-cd browser-laptop-bootstrap
-cat /vagrant/patch-for-sccache | patch -p1
-npm install
-npm run init
-npm run build
diff --git a/test/vms/vagrant/centos/init b/test/vms/vagrant/centos/init
deleted file mode 100755
index c3320117469..00000000000
--- a/test/vms/vagrant/centos/init
+++ /dev/null
@@ -1,6 +0,0 @@
-#!/bin/bash
-set -exu
-yum update -y
-yum install createrepo yum-utils git wget gcc clang make patch -y
-mkdir /build
-chown -R vagrant /build
diff --git a/test/vms/vagrant/jessie/Vagrantfile b/test/vms/vagrant/jessie/Vagrantfile
deleted file mode 100644
index 2c05c67cd83..00000000000
--- a/test/vms/vagrant/jessie/Vagrantfile
+++ /dev/null
@@ -1,30 +0,0 @@
-Vagrant.configure('2') do |config|
- vm_ram = ENV['VAGRANT_VM_RAM'] || 8192
- vm_cpu = ENV['VAGRANT_VM_CPU'] || 10
- config.vm.box = "debian/jessie64"
-
-
- config.vm.provider :virtualbox do |vb|
- vb.customize ["modifyvm", :id, "--memory", vm_ram, "--cpus", vm_cpu]
- file_to_disk = File.realpath( "." ).to_s + "/disk.vdi"
- if ARGV[0] == "up" && ! File.exist?(file_to_disk)
- puts "Creating 30GB disk #{file_to_disk}."
- vb.customize [
- 'createhd',
- '--filename', file_to_disk,
- '--format', 'VDI',
- '--size', 300000 * 1024 # 30 GB
- ]
- vb.customize [
- 'storageattach', :id,
- '--storagectl', 'SATA Controller',
- '--port', 1, '--device', 0,
- '--type', 'hdd', '--medium',
- file_to_disk
- ]
- end
- end
-
- config.vm.provision :shell, :inline => "/vagrant/init"
-
-end
diff --git a/test/vms/vagrant/jessie/build b/test/vms/vagrant/jessie/build
deleted file mode 100755
index 4b57ef3f8af..00000000000
--- a/test/vms/vagrant/jessie/build
+++ /dev/null
@@ -1,12 +0,0 @@
-#!/bin/bash
-set -exu
-curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.32.1/install.sh | bash
-export NVM_DIR="/home/vagrant/.nvm"
-[ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" # This loads nvm
-nvm install stable
-nvm use stable
-cd /build
-git clone https://github.com/posix4e/browser-laptop-bootstrap
-npm run init
-npm run build
-exec bash
diff --git a/test/vms/vagrant/jessie/init b/test/vms/vagrant/jessie/init
deleted file mode 100755
index 5ae45548588..00000000000
--- a/test/vms/vagrant/jessie/init
+++ /dev/null
@@ -1,46 +0,0 @@
-#!/bin/bash
-set -exu
-
-until apt-get update -y
- do echo "Doh!"
-done
-until apt-get install system-config-lvm lvm2 -y
- do echo "GGGG"
-done
-
-if [ -f /etc/stratos_dev_env_disk_added_date ]
-then
- echo "Stratos runtime already provisioned so exiting."
- exit 0
-fi
-
-
-fdisk -u /dev/sdb < /etc/stratos_dev_env_disk_added_date
-
-apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E1DF1F24
-cat > /etc/apt/sources.list.d/git.list << EOF
-deb-src http://ppa.launchpad.net/git-core/ppa/ubuntu precise main
-EOF
-
-chown -R vagrant /build
-
-apt-get update -y
-apt-get install build-essential clang libdbus-1-dev libgtk2.0-dev \
- libnotify-dev libgconf2-dev \
- libasound2-dev libcap-dev libcups2-dev libxtst-dev \
- libxss1 libnss3-dev gcc-multilib g++-multilib curl \
- gperf bison git python-software-properties python g++ make libgl1-mesa-dev -y
diff --git a/test/vms/vagrant/ubuntu-14.04/script.sh b/test/vms/vagrant/ubuntu-14.04/script.sh
index fce2157f46e..a751e4eebca 100644
--- a/test/vms/vagrant/ubuntu-14.04/script.sh
+++ b/test/vms/vagrant/ubuntu-14.04/script.sh
@@ -11,7 +11,7 @@ user-session=ubuntu
greeter-session=unity-greeter' >/etc/lightdm/lightdm.conf"
sudo apt-get install -y git
sudo apt-get install -y curl
-curl -sL https://deb.nodesource.com/setup_5.x | sudo -E bash -
+curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -
sudo apt-get install -y nodejs
sudo npm install -g node-gyp@3.2.1
sudo service lightdm start
diff --git a/tools/buildInstaller.js b/tools/buildInstaller.js
index 33964e81ccd..1f3c045d667 100644
--- a/tools/buildInstaller.js
+++ b/tools/buildInstaller.js
@@ -128,7 +128,8 @@ if (isDarwin) {
'cd ..',
'build ' +
`--prepackaged="${buildDir}/${appName}.app" ` +
- `--config=res/${channel}/builderConfig.json `,
+ `--config=res/${channel}/builderConfig.json ` +
+ '--publish=never',
// Create an update zip
'ditto -c -k --sequesterRsrc --keepParent ' + buildDir + `/${appName}.app dist/${appName}-` + VersionInfo.braveVersion + '.zip'
diff --git a/tools/cibuild.py b/tools/cibuild.py
index 06658ab445d..228841efbf1 100755
--- a/tools/cibuild.py
+++ b/tools/cibuild.py
@@ -4,8 +4,8 @@
import subprocess
import sys
import os.path
-MUON_VERSION = '5.0.2'
-CHROMEDRIVER_VERSION = '2.33'
+MUON_VERSION = '6.0.12'
+CHROMEDRIVER_VERSION = '2.36'
SOURCE_ROOT = os.path.abspath(os.path.dirname(os.path.dirname(__file__)))
TARGET_ARCH= os.environ['TARGET_ARCH'] if os.environ.has_key('TARGET_ARCH') else 'x64'
os.environ['npm_config_arch'] = TARGET_ARCH
@@ -37,7 +37,12 @@ def run_script(script, args=[]):
sys.stderr.write('\nRunning ' + script +'\n')
sys.stderr.flush()
script = os.path.join(SOURCE_ROOT, 'tools', script)
- subprocess.check_call([sys.executable, script] + args)
+ try:
+ output = subprocess.check_output([sys.executable, script] + args, stderr=subprocess.STDOUT)
+ print output
+ except subprocess.CalledProcessError as e:
+ print e.output
+ raise e
PLATFORM = {
diff --git a/tools/electronBuilderHack.js b/tools/electronBuilderHack.js
index 1829bc033d5..720a2f9d975 100644
--- a/tools/electronBuilderHack.js
+++ b/tools/electronBuilderHack.js
@@ -28,4 +28,6 @@ if (isDarwin) {
)
}
-execute(cmds, env, console.log.bind(null, 'done'))
+if (cmds.length > 0) {
+ execute(cmds, env, console.log.bind(null, 'done'))
+}
diff --git a/tools/test.js b/tools/test.js
index 0c93e248e43..79b609ddfea 100644
--- a/tools/test.js
+++ b/tools/test.js
@@ -15,6 +15,9 @@ switch (TEST_DIR) {
case 'codecov':
cmd.push('bash tools/codecov.sh')
break
+ case 'security':
+ cmd.push('npm run check-security')
+ break
case 'performance':
// 2017-09-28 Use debug builds for tests which require muon to run with
// --debug, currently broken in Linux on prod muon builds.
@@ -23,7 +26,7 @@ switch (TEST_DIR) {
}
// Intentionally no break, because perf tests also run the below
default: // eslint-disable-line
- cmd.push(`mocha "test/${TEST_DIR}/**/*Test.js"`)
+ cmd.push(`mocha "test/${TEST_DIR}/**/*Test.js" --globals chrome,DOMParser,XMLSerializer`)
}
execute(cmd, process.env, (err) => {
diff --git a/tools/upload.py b/tools/upload.py
index 4a60b6633bd..5744c8abff1 100755
--- a/tools/upload.py
+++ b/tools/upload.py
@@ -9,6 +9,7 @@
TARGET_ARCH= os.environ['TARGET_ARCH'] if os.environ.has_key('TARGET_ARCH') else 'x64'
def main():
+ print('Running upload...')
github = GitHub(auth_token())
releases = github.repos(BROWSER_LAPTOP_REPO).releases.get()
tag = 'v' + json.load(open('package.json'))['version']
@@ -20,7 +21,7 @@ def main():
release = create_or_get_release_draft(github, releases, tag,
tag_exists)
for f in get_files_to_upload():
- upload_browser_laptop(github,release, f)
+ upload_browser_laptop(github, release, f)
def get_channel_display_name():
d = {'dev': 'Release', 'beta': 'Beta', 'developer': 'Developer', 'nightly': 'Nightly'}
@@ -36,6 +37,7 @@ def get_files_to_upload():
def upload_browser_laptop(github, release, file_path):
filename = os.path.basename(file_path)
+ print('upload_browser_laptop: ' + filename)
try:
for asset in release['assets']:
if asset['name'] == filename:
diff --git a/tools/upload_to_aptly b/tools/upload_to_aptly
index cc2285e680d..e6bb2f28c63 100755
--- a/tools/upload_to_aptly
+++ b/tools/upload_to_aptly
@@ -7,7 +7,7 @@ GPG_KEY=${2:-4A1B4360}
KEY_NAME=keys.asc
KEY_FILE=/tmp/${KEY_NAME}
SNAP_TAG=`date +'%s'`
-DIST='artful zesty yakkety xenial jessie trusty serena stretch'
+DIST='artful zesty yakkety xenial jessie trusty serena stretch bionic buster'
cat < $HOME/.aptly.conf
{ "rootDir": "$HOME/.aptly",
@@ -79,5 +79,5 @@ for i in ${DIST}
done
for i in ${DIST}
- do aptly publish snapshot -force-overwrite=true -passphrase=$PASSPHRASE -gpg-key=${GPG_KEY} ${i}-snapshot s3:${OPTION}:
+ do aptly publish snapshot -force-overwrite=true -gpg-key=${GPG_KEY} ${i}-snapshot s3:${OPTION}:
done
diff --git a/tools/upload_to_rpm_repo b/tools/upload_to_rpm_repo
index c20275070fd..03326edf4e4 100755
--- a/tools/upload_to_rpm_repo
+++ b/tools/upload_to_rpm_repo
@@ -16,7 +16,7 @@ echo "%_signature gpg
rm -rf $TMP_REPO
mkdir -pv $TMP_REPO/x86_64
if !rpm --checksig dist/*.rpm | grep pgp; then
- env GPG_PASS=$PASSPHRASE ./tools/auto_rpm_sign
+ ./tools/auto_rpm_sign
rpm --checksig dist/*.rpm | grep pgp
fi
# Ensure the rpm has the correct signature before continuing
diff --git a/webpack.config.js b/webpack.config.js
index 272141a71bd..74ab1e3c757 100644
--- a/webpack.config.js
+++ b/webpack.config.js
@@ -122,6 +122,9 @@ function production () { // eslint-disable-line
parallel: true,
uglifyOptions: {
compress: {
+ // inline is buggy as of uglify-es 3.3.7
+ // https://github.com/mishoo/UglifyJS2/issues/2842
+ inline: 1,
warnings: false
},
mangle: {