diff --git a/.dockerignore b/.dockerignore
deleted file mode 100644
index 3b406630..00000000
--- a/.dockerignore
+++ /dev/null
@@ -1,72 +0,0 @@
-# Various Node ignoramuses.
-
-logs
-*.log
-npm-debug.log*
-pids
-*.pid
-*.seed
-lib-cov
-coverage
-.grunt
-.lock-wscript
-build/Release
-node_modules
-jspm_modules
-.npm
-.node_repl_history
-
-# Various Windows ignoramuses.
-Thumbs.db
-ehthumbs.db
-Desktop.ini
-$RECYCLE.BIN/
-*.cab
-*.msi
-*.msm
-*.msp
-*.lnk
-
-# Various OSX ignoramuses.
-.DS_Store
-.AppleDouble
-.LSOverride
-Icon
-._*
-.DocumentRevisions-V100
-.fseventsd
-.Spotlight-V100
-.TemporaryItems
-.Trashes
-.VolumeIcon.icns
-.AppleDB
-.AppleDesktop
-Network Trash Folder
-Temporary Items
-.apdisk
-
-# Various Linux ignoramuses.
-
-.fuse_hidden*
-.directory
-.Trash-*
-
-# Various Magic Mirror ignoramuses and anti-ignoramuses.
-
-# Don't ignore the node_helper core module.
-!/modules/node_helper
-!/modules/node_helper/**
-
-# Ignore all modules except the default modules.
-/modules/**
-!/modules/default/**
-
-# Ignore changes to the custom css files.
-/css/custom.css
-
-# Ignore unnecessary files for docker
-CHANGELOG.md
-LICENSE.md
-README.md
-Gruntfile.js
-.*
diff --git a/.eslintignore b/.eslintignore
index ee60c2ea..7862c971 100644
--- a/.eslintignore
+++ b/.eslintignore
@@ -3,4 +3,3 @@ vendor/*
!/modules/default/**
!/modules/node_helper
!/modules/node_helper/**
-!/modules/default/defaultmodules.js
diff --git a/.eslintrc.json b/.eslintrc.json
index 150a081d..16be57c8 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -2,15 +2,23 @@
"rules": {
"indent": ["error", "tab"],
"quotes": ["error", "double"],
+ "semi": ["error"],
"max-len": ["error", 250],
"curly": "error",
"camelcase": ["error", {"properties": "never"}],
- "no-trailing-spaces": ["error"],
+ "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 1 }],
+ "no-trailing-spaces": ["error", {"ignoreComments": false }],
"no-irregular-whitespace": ["error"]
},
"env": {
"browser": true,
"node": true,
"es6": true
- }
+ },
+ "parserOptions": {
+ "sourceType": "module",
+ "ecmaFeatures": {
+ "globalReturn": true
+ }
+ }
}
diff --git a/.github/stale.yml b/.github/stale.yml
new file mode 100644
index 00000000..136532c1
--- /dev/null
+++ b/.github/stale.yml
@@ -0,0 +1,19 @@
+# Number of days of inactivity before an issue becomes stale
+daysUntilStale: 60
+# Number of days of inactivity before a stale issue is closed
+daysUntilClose: 7
+# Issues with these labels will never be considered stale
+exemptLabels:
+ - pinned
+ - security
+ - under investigation
+ - pr welcome
+# Label to use when marking an issue as stale
+staleLabel: wontfix
+# Comment to post when marking an issue as stale. Set to `false` to disable
+markComment: >
+ This issue has been automatically marked as stale because it has not had
+ recent activity. It will be closed if no further activity occurs. Thank you
+ for your contributions.
+# Comment to post when closing a stale issue. Set to `false` to disable
+closeComment: false
diff --git a/.gitignore b/.gitignore
index ecb483e8..5733c750 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,6 +16,12 @@ jspm_modules
.npm
.node_repl_history
+# Visual Studio Code ignoramuses.
+.vscode/
+
+# IDE Code ignoramuses.
+.idea/
+
# Various Windows ignoramuses.
Thumbs.db
ehthumbs.db
diff --git a/.stylelintrc b/.stylelintrc.json
similarity index 100%
rename from .stylelintrc
rename to .stylelintrc.json
diff --git a/.travis.yml b/.travis.yml
index 5f6f2821..d98a72cd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,16 +1,18 @@
language: node_js
node_js:
- - "7"
- - "6"
- - "5.1"
+ - "8"
before_script:
+ - yarn danger ci
- npm install grunt-cli -g
- "export DISPLAY=:99.0"
- "sh -e /etc/init.d/xvfb start"
- sleep 5
script:
- grunt
-- npm test
+- npm run test:unit
+- npm run test:e2e
+after_script:
+ - npm list
cache:
directories:
- node_modules
diff --git a/CHANGELOG.md b/CHANGELOG.md
old mode 100644
new mode 100755
index c2490fde..96ad2bf6
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,10 +1,372 @@
# MagicMirror² Change Log
+
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
-## [2.1.2] - Unreleased
+---
+
+❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core.
+
+## [2.9.0] - Unreleased (Develop Branch)
+
+*This release is scheduled to be released on 2019-10-01.*
+
+### Added
+- Add test check URLs of vendors 200 and 404 HTTP CODE.
+
+### Updated
+- Updatenotification module: Display update notification for a limited (configurable) time.
+
+### Fixed
+- Updatenotification module: Properly handle race conditions, prevent crash.
+- Send `NEWS_FEED` notification also for the first news messages which are shown
+- Fixed issue where weather module would not refresh data after a network or API outage [#1722](https://github.com/MichMich/MagicMirror/issues/1722)
+
+## [2.8.0] - 2019-07-01
+
+ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
+
+### Added
+- Option to show event location in calendar
+- Finnish translation for "Feels" and "Weeks"
+- Russian translation for “Feels”
+- Calendar module: added `nextDaysRelative` config option
+- Add `broadcastPastEvents` config option for calendars to include events from the past `maximumNumberOfDays` in event broadcasts
+- Added feature to broadcast news feed items `NEWS_FEED` and updated news items `NEWS_FEED_UPDATED` in default [newsfeed](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/newsfeed) module (when news is updated) with documented default and `config.js` options in [README.md](https://github.com/MichMich/MagicMirror/blob/develop/modules/default/newsfeed/README.md)
+- Added notifications to default `clock` module broadcasting `CLOCK_SECOND` and `CLOCK_MINUTE` for the respective time elapsed.
+- Added UK Met Office Datapoint feed as a provider in the default weather module.
+- Added new provider class
+- Added suncalc.js dependency to calculate sun times (not provided in UK Met Office feed)
+- Added "tempUnits" and "windUnits" to allow, for example, temp in metric (i.e. celsius) and wind in imperial (i.e. mph). These will override "units" if specified, otherwise the "units" value will be used.
+- Use Feels Like temp from feed if present
+- Optionally display probability of precipitation (PoP) in current weather (UK Met Office data)
+- Automatically try to fix eslint errors by passing `--fix` option to it
+- Added sunrise and sunset times to weathergov weather provider [#1705](https://github.com/MichMich/MagicMirror/issues/1705)
+- Added "useLocationAsHeader" to display "location" in `config.js` as header when location name is not returned
+- Added to `newsfeed.js`: in order to design the news article better with css, three more class-names were introduced: newsfeed-desc, newsfeed-desc, newsfeed-desc
+
+### Updated
+- English translation for "Feels" to "Feels like"
+- Fixed the example calender url in `config.js.sample`
+- Update `ical.js` to solve various calendar issues.
+- Update weather city list url [#1676](https://github.com/MichMich/MagicMirror/issues/1676)
+- Only update clock once per minute when seconds aren't shown
+
+### Fixed
+- Fixed uncaught exception, race condition on module update
+- Fixed issue [#1696](https://github.com/MichMich/MagicMirror/issues/1696), some ical files start date to not parse to date type
+- Allowance HTML5 autoplay-policy (policy is changed from Chrome 66 updates)
+- Handle SIGTERM messages
+- Fixes sliceMultiDayEvents so it respects maximumNumberOfDays
+- Minor types in default NewsFeed [README.md](https://github.com/MichMich/MagicMirror/blob/develop/modules/default/newsfeed/README.md)
+- Fix typos and small syntax errors, cleanup dependencies, remove multiple-empty-lines, add semi-rule
+- Fixed issues with calendar not displaying one-time changes to repeating events
+- Updated the fetchedLocationName variable in currentweather.js so that city shows up in the header
+
+### Updated installer
+- give non-pi2+ users (pi0, odroid, jetson nano, mac, windows, ...) option to continue install
+- use current username vs hardcoded 'pi' to support non-pi install
+- check for npm installed. node install doesn't do npm anymore
+- check for mac as part of PM2 install, add install option string
+- update pm2 config with current username instead of hard coded 'pi'
+- check for screen saver config, "/etc/xdg/lxsession", bypass if not setup
+
+## [2.7.1] - 2019-04-02
+
+Fixed `package.json` version number.
+
+## [2.7.0] - 2019-04-01
+
+ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md).
+
+### Added
+- Italian translation for "Feels"
+- Basic Klingon (tlhIngan Hol) translations
+- Disabled the screensaver on raspbian with installation script
+- Added option to truncate the number of vertical lines a calendar item can span if `wrapEvents` is enabled.
+- Danish translation for "Feels" and "Weeks"
+- Added option to split multiple day events in calendar to separate numbered events
+- Slovakian translation
+- Alerts now can contain Font Awesome icons
+- Notifications display time can be set in request
+- Newsfeed: added support for `ARTICLE_INFO_REQUEST` notification
+- Add `name` config option for calendars to be sent along with event broadcasts
+
+### Updated
+- Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500)
+- Updated modernizr code in alert module, fixed a small typo there too
+- More verbose error message on console if the config is malformed
+- Updated installer script to install Node.js version 10.x
+
+### Fixed
+- Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503), [#1511](https://github.com/MichMich/MagicMirror/issues/1511).
+- Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MichMich/MagicMirror/issues/1285).
+- Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504).
+- Fixed analogue clock border display issue where non-black backgrounds used (previous fix for issue 611)
+- Fixed compatibility issues caused when modules request different versions of Font Awesome, see issue [#1522](https://github.com/MichMich/MagicMirror/issues/1522). MagicMirror now uses [Font Awesome 5 with v4 shims included for backwards compatibility](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4#shims).
+- Installation script problems with raspbian
+- Calendar: only show repeating count if the event is actually repeating [#1534](https://github.com/MichMich/MagicMirror/pull/1534)
+- Calendar: Fix exdate handling when multiple values are specified (comma separated)
+- Calendar: Fix relative date handling for fulldate events, calculate difference always from start of day [#1572](https://github.com/MichMich/MagicMirror/issues/1572)
+- Fix null dereference in moduleNeedsUpdate when the module isn't visible
+- Calendar: Fixed event end times by setting default calendarEndTime to "LT" (Local time format). [#1479]
+- Calendar: Fixed missing calendar fetchers after server process restarts [#1589](https://github.com/MichMich/MagicMirror/issues/1589)
+- Notification: fixed background color (was white text on white background)
+- Use getHeader instead of data.header when creating the DOM so overwriting the function also propagates into it
+- Fix documentation of `useKMPHwind` option in currentweather
+
+### New weather module
+- Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
+- Dimmed loading indicator for weather forecast.
+- Implemented config option `decimalSymbol` [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
+- Aligned indoor values in current weather vertical [#1499](https://github.com/MichMich/MagicMirror/issues/1499).
+- Added humidity support to nunjuck unit filter.
+- Do not display degree symbol for temperature in Kelvin [#1503](https://github.com/MichMich/MagicMirror/issues/1503).
+- Weather forecast now works with openweathermap for both, `/forecast` and `/forecast/daily`, in new weather module. If you use the `/forecast`-weatherEndpoint, the hourly data are converted to daily data, see issues [#1504](https://github.com/MichMich/MagicMirror/issues/1504), [#1513](https://github.com/MichMich/MagicMirror/issues/1513).
+- Added fade, fadePoint and maxNumberOfDays properties to the forecast mode [#1516](https://github.com/MichMich/MagicMirror/issues/1516)
+- Fixed Loading string and decimalSymbol string replace [#1538](https://github.com/MichMich/MagicMirror/issues/1538)
+- Show Snow amounts in new weather module [#1545](https://github.com/MichMich/MagicMirror/issues/1545)
+- Added weather.gov as a new weather provider for US locations
+
+## [2.6.0] - 2019-01-01
+
+ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues updating, make sure you are running the latest version of Node.
+
+### ✨ Experimental ✨
+- New default [module weather](modules/default/weather). This module will eventually replace the current `currentweather` and `weatherforecast` modules. The new module is still pretty experimental, but it's included so you can give it a try and help us improve this module. Please give us you feedback using [this forum post](https://forum.magicmirror.builders/topic/9335/default-weather-module-refactoring).
+
+A huge, huge, huge thanks to user @fewieden for all his hard work on the new `weather` module!
+
+### Added
+- Possibility to add classes to the cell of symbol, title and time of the events of calendar.
+- Font-awesome 5, still has 4 for backwards compatibility.
+- Missing `showEnd` in calendar documentation
+- Screenshot for the new feed module
+- Screenshot for the compliments module
+- Screenshot for the clock module
+- Screenshot for the current weather
+- Screenshot for the weather forecast module
+- Portuguese translation for "Feels"
+- Croatian translation
+- Fading for dateheaders timeFormat in Calendar [#1464](https://github.com/MichMich/MagicMirror/issues/1464)
+- Documentation for the existing `scale` option in the Weather Forecast module.
+
+### Fixed
+- Allow to parse recurring calendar events where the start date is before 1900
+- Fixed Polish translation for Single Update Info
+- Ignore entries with unparseable details in the calendar module
+- Bug showing FullDayEvents one day too long in calendar fixed
+- Bug in newsfeed when `removeStartTags` is used on the description [#1478](https://github.com/MichMich/MagicMirror/issues/1478)
+
+### Updated
+- The default calendar setting `showEnd` is changed to `false`.
### Changed
+- The Weather Forecast module by default displays the ° symbol after every numeric value to be consistent with the Current Weather module.
+
+
+## [2.5.0] - 2018-10-01
+
+### Added
+- Romanian translation for "Feels"
+- Support multi-line compliments
+- Simplified Chinese translation for "Feels"
+- Polish translate for "Feels"
+- French translate for "Feels"
+- Translations for newsfeed module
+- Support for toggling news article in fullscreen
+- Hungarian translation for "Feels" and "Week"
+- Spanish translation for "Feels"
+- Add classes instead of inline style to the message from the module Alert
+- Support for events having a duration instead of an end
+- Support for showing end of events through config parameters showEnd and dateEndFormat
+
+### Fixed
+- Fixed gzip encoded calendar loading issue #1400.
+- Mixup between german and spanish translation for newsfeed.
+- Fixed close dates to be absolute, if no configured in the config.js - module Calendar
+- Fixed the updatenotification module message about new commits in the repository, so they can be correctly localized in singular and plural form.
+- Fix for weatherforecast rainfall rounding [#1374](https://github.com/MichMich/MagicMirror/issues/1374)
+- Fix calendar parsing issue for Midori on RasperryPi Zero w, related to issue #694.
+- Fix weather city ID link in sample config
+- Fixed issue with clientonly not updating with IP address and port provided on command line.
+
+### Updated
+
+- Updated Simplified Chinese translation
+- Swedish translations
+- Hungarian translations for the updatenotification module
+- Updated Norsk bokmål translation
+- Updated Norsk nynorsk translation
+- Consider multi days event as full day events
+
+## [2.4.1] - 2018-07-04
+
+### Fixed
+
+- Fix weather parsing issue #1332.
+
+## [2.4.0] - 2018-07-01
+
+⚠️ **Warning:** This release includes an updated version of Electron. This requires a Raspberry Pi configuration change to allow the best performance and prevent the CPU from overheating. Please read the information on the [MagicMirror Wiki](https://github.com/michmich/magicmirror/wiki/configuring-the-raspberry-pi#enable-the-open-gl-driver-to-decrease-electrons-cpu-usage).
+
+ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
+
+### Added
+
+- Enabled translation of feelsLike for module currentweather
+- Added support for on-going calendar events
+- Added scroll up in fullscreen newsfeed article view
+- Changed fullscreen newsfeed width from 100% to 100vw (better results)
+- Added option to calendar module that colors only the symbol instead of the whole line
+- Added option for new display format in the calendar module with date headers with times/events below.
+- Ability to fetch compliments from a remote server
+- Add regex filtering to calendar module
+- Customize classes for table
+- Added option to newsfeed module to only log error parsing a news article if enabled
+- Add update translations for Português Brasileiro
+
+### Changed
+- Upgrade to Electron 2.0.0.
+- Remove yarn-or-npm which breaks production builds.
+- Invoke module suspend even if no dom content. [#1308](https://github.com/MichMich/MagicMirror/issues/1308)
+
+### Fixed
+- Fixed issue where wind chill could not be displayed in Fahrenheit. [#1247](https://github.com/MichMich/MagicMirror/issues/1247)
+- Fixed issues where a module crashes when it tries to dismiss a non existing alert. [#1240](https://github.com/MichMich/MagicMirror/issues/1240)
+- In default module currentWeather/currentWeather.js line 296, 300, self.config.animationSpeed can not be found because the notificationReceived function does not have "self" variable.
+- Fixed browser-side code to work on the Midori browser.
+- Fixed issue where heat index was reporting incorrect values in Celsius and Fahrenheit. [#1263](https://github.com/MichMich/MagicMirror/issues/1263)
+- Fixed weatherforecast to use dt_txt field instead of dt to handle timezones better
+- Newsfeed now remembers to show the description when `"ARTICLE_LESS_DETAILS"` is called if the user wants to always show the description. [#1282](https://github.com/MichMich/MagicMirror/issues/1282)
+- `clientonly/*.js` is now linted, and one linting error is fixed
+- Fix issue #1196 by changing underscore to hyphen in locale id, in align with momentjs.
+- Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MichMich/MagicMirror/issues/1263)
+
+### Updated
+- Updated Italian translation
+- Updated German translation
+- Updated Dutch translation
+
+## [2.3.1] - 2018-04-01
+
+### Fixed
+- Downgrade electron to 1.4.15 to solve the black screen issue.[#1243](https://github.com/MichMich/MagicMirror/issues/1243)
+
+## [2.3.0] - 2018-04-01
+
+### Added
+
+- Add new settings in compliments module: setting time intervals for morning and afternoon
+- Add system notification `MODULE_DOM_CREATED` for notifying each module when their Dom has been fully loaded.
+- Add types for module.
+- Implement Danger.js to notify contributors when CHANGELOG.md is missing in PR.
+- Allow to scroll in full page article view of default newsfeed module with gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures)
+- Changed 'compliments.js' - update DOM if remote compliments are loaded instead of waiting one updateInterval to show custom compliments
+- Automated unit tests utils, deprecated, translator, cloneObject(lockstrings)
+- Automated integration tests translations
+- Add advanced filtering to the excludedEvents configuration of the default calendar module
+- New currentweather module config option: `showFeelsLike`: Shows how it actually feels like. (wind chill or heat index)
+- New currentweather module config option: `useKMPHwind`: adds an option to see wind speed in Kmph instead of just m/s or Beaufort.
+- Add dc:date to parsing in newsfeed module, which allows parsing of more rss feeds.
+
+### Changed
+- Add link to GitHub repository which contains the respective Dockerfile.
+- Optimized automated unit tests cloneObject, cmpVersions
+- Update notifications use now translation templates instead of normal strings.
+- Yarn can be used now as an installation tool
+- Changed Electron dependency to v1.7.13.
+
+### Fixed
+- News article in fullscreen (iframe) is now shown in front of modules.
+- Forecast respects maxNumberOfDays regardless of endpoint.
+- Fix exception on translation of objects.
+
+## [2.2.2] - 2018-01-02
+
+### Added
+
+- Add missing `package-lock.json`.
+
+### Changed
+
+- Changed Electron dependency to v1.7.10.
+
+## [2.2.1] - 2018-01-01
+
+### Fixed
+- Fixed linting errors.
+
+## [2.2.0] - 2018-01-01
+
+**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
+
+### Changed
+- Calender week is now handled with a variable translation in order to move number language specific.
+- Reverted the Electron dependency back to 1.4.15 since newer version don't seem to work on the Raspberry Pi very well.
+
+### Added
+- Add option to use [Nunjucks](https://mozilla.github.io/nunjucks/) templates in modules. (See `helloworld` module as an example.)
+- Add Bulgarian translations for MagicMirror² and Alert module.
+- Add graceful shutdown of modules by calling `stop` function of each `node_helper` on SIGINT before exiting.
+- Link update subtext to Github diff of current version versus tracking branch.
+- Add Catalan translation.
+- Add ability to filter out newsfeed items based on prohibited words found in title (resolves #1071)
+- Add options to truncate description support of a feed in newsfeed module
+- Add reloadInterval option for particular feed in newsfeed module
+- Add no-cache entries of HTTP headers in newsfeed module (fetcher)
+- Add Czech translation.
+- Add option for decimal symbols other than the decimal point for temperature values in both default weather modules: WeatherForecast and CurrentWeather.
+
+### Fixed
+- Fixed issue with calendar module showing more than `maximumEntries` allows
+- WeatherForecast and CurrentWeather are now using HTTPS instead of HTTP
+- Correcting translation for Indonesian language
+- Fix issue where calendar icons wouldn't align correctly
+
+## [2.1.3] - 2017-10-01
+
+**Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`
+
+### Changed
+- Remove Roboto fonts files inside `fonts` and these are installed by npm install command.
+
+### Added
+- Add `clientonly` script to start only the electron client for a remote server.
+- Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module.
+- Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git.
+- Add unit test the capitalizeFirstLetter function of newsfeed module.
+- Add new unit tests for function `shorten` in calendar module.
+- Add new unit tests for function `getLocaleSpecification` in calendar module.
+- Add unit test for js/class.js.
+- Add unit tests for function `roundValue` in currentweather module.
+- Add test e2e showWeek feature in spanish language.
+- Add warning Log when is used old authentication method in the calendar module.
+- Add test e2e for helloworld module with default config text.
+- Add ability for `currentweather` module to display indoor humidity via INDOOR_HUMIDITY notification.
+- Add Welsh (Cymraeg) translation.
+- Add Slack badge to Readme.
+
+### Updated
+- Changed 'default.js' - listen on all attached interfaces by default.
+- Add execution of `npm list` after the test are ran in Travis CI.
+- Change hooks for the vendors e2e tests.
+- Add log when clientonly failed on starting.
+- Add warning color when are using full ip whitelist.
+- Set version of the `express-ipfilter` on 0.3.1.
+
+### Fixed
+- Fixed issue with incorrect alignment of analog clock when displayed in the center column of the MM.
+- Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM.
+- Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'.
+- Fixed issue with calendar module where global configuration of maximumEntries was not overridden by calendar specific config (see module doc).
+- Fixed issue where `this.file(filename)` returns a path with two hashes.
+- Workaround for the WeatherForecast API limitation.
+
+## [2.1.2] - 2017-07-01
+
+### Changed
+- Revert Docker related changes in favor of [docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror). All Docker images are outsourced. ([#856](https://github.com/MichMich/MagicMirror/pull/856))
- Change Docker base image (Debian + Node) to an arm based distro (AlpineARM + Node) ([#846](https://github.com/MichMich/MagicMirror/pull/846))
- Fix the dockerfile to have it running from the first time.
@@ -12,15 +374,33 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Add in option to wrap long calendar events to multiple lines using `wrapEvents` configuration option.
- Add test e2e `show title newsfeed` for newsfeed module.
- Add task to check configuration file.
-- Add test check URLs of vendors 200 and 404 HTTP CODE.
+- Add test check URLs of vendors.
+- Add test of match current week number on clock module with showWeek configuration.
- Add test default modules present modules/default/defaultmodules.js.
+- Add unit test calendar_modules function capFirst.
+- Add test for check if exists the directories present in defaults modules.
+- Add support for showing wind direction as an arrow instead of abbreviation in currentWeather module.
+- Add support for writing translation functions to support flexible word order
+- Add test for check if exits the directories present in defaults modules.
+- Add calendar option to set a separate date format for full day events.
+- Add ability for `currentweather` module to display indoor temperature via INDOOR_TEMPERATURE notification
+- Add ability to change the path of the `custom.css`.
+- Add translation Dutch to Alert module.
+- Added Romanian translation.
### Updated
- Added missing keys to Polish translation.
- Added missing key to German translation.
+- Added better translation with flexible word order to Finnish translation.
### Fixed
- Fix instruction in README for using automatically installer script.
+- Bug of duplicated compliments as described in [here](https://forum.magicmirror.builders/topic/2381/compliments-module-stops-cycling-compliments).
+- Fix double message about port when server is starting
+- Corrected Swedish translations for TODAY/TOMORROW/DAYAFTERTOMORROW.
+- Removed unused import from js/electron.js
+- Made calendar.js respect config.timeFormat irrespective of locale setting.
+- Fixed alignment of analog clock when a large calendar is displayed in the same side bar.
## [2.1.1] - 2017-04-01
@@ -28,18 +408,18 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Changed
- Add `anytime` group for Compliments module.
-- Compliments module can use remoteFile without default daytime arrays defined
+- Compliments module can use remoteFile without default daytime arrays defined.
- Installer: Use init config.js from config.js.sample.
- Switched out `rrule` package for `rrule-alt` and fixes in `ical.js` in order to fix calendar issues. ([#565](https://github.com/MichMich/MagicMirror/issues/565))
- Make mouse events pass through the region fullscreen_above to modules below.
- Scaled the splash screen down to make it a bit more subtle.
- Replace HTML tables with markdown tables in README files.
- Added `DAYAFTERTOMORROW`, `UPDATE_NOTIFICATION` and `UPDATE_NOTIFICATION_MODULE` to Finnish translations.
-- Run `npm test` on Travis automatically
+- Run `npm test` on Travis automatically.
- Show the splash screen image even when is reboot or halted.
-- Added some missing translaton strings in the sv.json file.
+- Added some missing translation strings in the sv.json file.
- Run task jsonlint to check translation files.
-- Restructured Test Suite
+- Restructured Test Suite.
### Added
- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)).
@@ -54,12 +434,12 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Option to use RegExp in Calendar's titleReplace.
- Hungarian Translation.
- Icelandic Translation.
-- Add use a script to prevent when is run by SSH session set DISPLAY enviroment.
-- Enable ability to set configuration file by the enviroment variable called MM_CONFIG_FILE.
+- Add use a script to prevent when is run by SSH session set DISPLAY environment.
+- Enable ability to set configuration file by the environment variable called MM_CONFIG_FILE.
- Option to give each calendar a different color.
- Option for colored min-temp and max-temp.
- Add test e2e helloworld.
-- Add test e2e enviroment.
+- Add test e2e environment.
- Add `chai-as-promised` npm module to devDependencies.
- Basic set of tests for clock module.
- Run e2e test in Travis.
@@ -77,10 +457,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added tests for Translations, dev argument, version, dev console.
- Added test anytime feature compliments module.
- Added test ipwhitelist configuration directive.
-- Added test for calendar module: default, basic-auth, backward compability, fail-basic-auth.
+- Added test for calendar module: default, basic-auth, backward compatibility, fail-basic-auth.
- Added meta tags to support fullscreen mode on iOS (for server mode)
- Added `ignoreOldItems` and `ignoreOlderThan` options to the News Feed module
-- Added test for MM_PORT enviroment variable.
+- Added test for MM_PORT environment variable.
- Added a configurable Week section to the clock module.
### Fixed
@@ -92,7 +472,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Module currentWeather: check if temperature received from api is defined.
- Fix an issue with module hidden status changing to `true` although lock string prevented showing it.
- Fix newsfeed module bug (removeStartTags)
-- Fix when is set MM_PORT enviroment variable.
+- Fix when is set MM_PORT environment variable.
- Fixed missing animation on `this.show(speed)` when module is alone in a region.
## [2.1.0] - 2016-12-31
@@ -114,8 +494,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/calendar) for more information.
- Possibility to use the the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/weatherforecast) for more information.
- Added option to show rain amount in the weatherforecast default module
-- Add module `updatenotification` to get an update whenever a new version is availabe. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information.
-- Add the abilty to set timezone on the date display in the Clock Module
+- Add module `updatenotification` to get an update whenever a new version is available. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information.
+- Add the ability to set timezone on the date display in the Clock Module
- Ability to set date format in calendar module
- Possibility to use currentweather for the compliments
- Added option `disabled` for modules.
@@ -154,7 +534,7 @@ This project adheres to [Semantic Versioning](http://semver.org/).
- Added ability to define "the day after tomorrow" for calendar events (Definition for German and Dutch already included).
- Added CII Badge (we are compliant with the CII Best Practices)
- Add support for doing http basic auth when loading calendars
-- Add the abilty to turn off and on the date display in the Clock Module
+- Add the ability to turn off and on the date display in the Clock Module
### Fixed
- Fix typo in installer.
@@ -177,8 +557,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- Prevent `getModules()` selectors from returning duplicate entries.
-- Append endpoints of weather modules with `/` to retreive the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337))
-- Corrected grammer in `module.js` from 'suspend' to 'suspended'.
+- Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337))
+- Corrected grammar in `module.js` from 'suspend' to 'suspended'.
- Fixed openweathermap.org URL in config sample.
- Prevent currentweather module from crashing when received data object is incorrect.
- Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MichMich/MagicMirror/issues/388))
diff --git a/Dockerfile b/Dockerfile
deleted file mode 100644
index 4ee863fb..00000000
--- a/Dockerfile
+++ /dev/null
@@ -1,27 +0,0 @@
-FROM izone/arm:node
-
-# Set env variables
-ENV NODE_ENV production
-ENV MM_PORT 8080
-
-WORKDIR /opt/magic_mirror
-
-# Cache node_modules
-COPY package.json /opt/magic_mirror
-RUN npm install
-
-# Copy all needed files
-COPY . /opt/magic_mirror
-
-# Save/Cache config and modules folder for docker-entrypoint
-COPY /modules /opt/magic_mirror/unmount_modules
-COPY /config /opt/magic_mirror/unmount_config
-
-# Convert docker-entrypoint.sh to unix format and grant execution privileges
-RUN apk update \
- && apk add dos2unix --update-cache --repository http://dl-3.alpinelinux.org/alpine/edge/testing/ --allow-untrusted \
- && dos2unix docker-entrypoint.sh \
- && chmod +x docker-entrypoint.sh
-
-EXPOSE $MM_PORT
-ENTRYPOINT ["/opt/magic_mirror/docker-entrypoint.sh"]
diff --git a/Gruntfile.js b/Gruntfile.js
index 8d069c82..ee4ab7b8 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -4,6 +4,7 @@ module.exports = function(grunt) {
pkg: grunt.file.readJSON("package.json"),
eslint: {
options: {
+ fix: "true",
configFile: ".eslintrc.json"
},
target: [
@@ -11,6 +12,7 @@ module.exports = function(grunt) {
"modules/default/*.js",
"modules/default/*/*.js",
"serveronly/*.js",
+ "clientonly/*.js",
"*.js",
"tests/**/*.js",
"!modules/default/alert/notificationFx.js",
@@ -25,7 +27,7 @@ module.exports = function(grunt) {
stylelint: {
simple: {
options: {
- configFile: ".stylelintrc"
+ configFile: ".stylelintrc.json"
},
src: [
"css/main.css",
@@ -41,11 +43,11 @@ module.exports = function(grunt) {
src: [
"package.json",
".eslintrc.json",
- ".stylelintrc",
+ ".stylelintrc.json",
+ "installers/pm2_MagicMirror.json",
"translations/*.json",
"modules/default/*/translations/*.json",
- "installers/pm2_MagicMirror.json",
- "vendor/package.js"
+ "vendor/package.json"
],
options: {
reporter: "jshint"
diff --git a/README.md b/README.md
index 29e5b65f..560b566a 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@
-
+
diff --git a/clientonly/index.js b/clientonly/index.js
new file mode 100644
index 00000000..895dacae
--- /dev/null
+++ b/clientonly/index.js
@@ -0,0 +1,104 @@
+/* jshint esversion: 6 */
+
+"use strict";
+
+// Use separate scope to prevent global scope pollution
+(function () {
+ var config = {};
+
+ // Helper function to get server address/hostname from either the commandline or env
+ function getServerAddress() {
+ // Helper function to get command line parameters
+ // Assumes that a cmdline parameter is defined with `--key [value]`
+ function getCommandLineParameter(key, defaultValue = undefined) {
+ var index = process.argv.indexOf(`--${key}`);
+ var value = index > -1 ? process.argv[index + 1] : undefined;
+ return value !== undefined ? String(value) : defaultValue;
+ }
+
+ // Prefer command line arguments over environment variables
+ ["address", "port"].forEach((key) => {
+ config[key] = getCommandLineParameter(key, process.env[key.toUpperCase()]);
+ });
+ }
+
+ function getServerConfig(url) {
+ // Return new pending promise
+ return new Promise((resolve, reject) => {
+ // Select http or https module, depending on reqested url
+ const lib = url.startsWith("https") ? require("https") : require("http");
+ const request = lib.get(url, (response) => {
+ var configData = "";
+
+ // Gather incoming data
+ response.on("data", function(chunk) {
+ configData += chunk;
+ });
+ // Resolve promise at the end of the HTTP/HTTPS stream
+ response.on("end", function() {
+ resolve(JSON.parse(configData));
+ });
+ });
+
+ request.on("error", function(error) {
+ reject(new Error(`Unable to read config from server (${url} (${error.message}`));
+ });
+ });
+ }
+
+ function fail(message, code = 1) {
+ if (message !== undefined && typeof message === "string") {
+ console.log(message);
+ } else {
+ console.log("Usage: 'node clientonly --address 192.168.1.10 --port 8080'");
+ }
+ process.exit(code);
+ }
+
+ getServerAddress();
+
+ (config.address && config.port) || fail();
+
+ // Only start the client if a non-local server was provided
+ if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].indexOf(config.address) === -1) {
+ getServerConfig(`http://${config.address}:${config.port}/config/`)
+ .then(function (configReturn) {
+ // Pass along the server config via an environment variable
+ var env = Object.create(process.env);
+ var options = { env: env };
+ configReturn.address = config.address;
+ configReturn.port = config.port;
+ env.config = JSON.stringify(configReturn);
+
+ // Spawn electron application
+ const electron = require("electron");
+ const child = require("child_process").spawn(electron, ["js/electron.js"], options);
+
+ // Pipe all child process output to current stdout
+ child.stdout.on("data", function (buf) {
+ process.stdout.write(`Client: ${buf}`);
+ });
+
+ // Pipe all child process errors to current stderr
+ child.stderr.on("data", function (buf) {
+ process.stderr.write(`Client: ${buf}`);
+ });
+
+ child.on("error", function (err) {
+ process.stdout.write(`Client: ${err}`);
+ });
+
+ child.on("close", (code) => {
+ if (code !== 0) {
+ console.log(`There something wrong. The clientonly is not running code ${code}`);
+ }
+ });
+
+ })
+ .catch(function (reason) {
+ fail(`Unable to connect to server: (${reason})`);
+ });
+ } else {
+ fail();
+ }
+}());
diff --git a/config/config.js.sample b/config/config.js.sample
index b2eeee8a..790ada34 100644
--- a/config/config.js.sample
+++ b/config/config.js.sample
@@ -9,6 +9,11 @@
*/
var config = {
+ address: "localhost", // Address to listen on, can be:
+ // - "localhost", "127.0.0.1", "::1" to listen on loopback interface
+ // - another specific IPv4/6 to listen on a specific interface
+ // - "", "0.0.0.0", "::" to listen on any interface
+ // Default, when address config is left out, is "localhost"
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses
// or add a specific IPv4 of 192.168.1.5 :
@@ -39,9 +44,8 @@ var config = {
config: {
calendars: [
{
- symbol: "calendar-check-o ",
- url: "webcal://www.calendarlabs.com/templates/ical/US-Holidays.ics"
- }
+ symbol: "calendar-check",
+ url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" }
]
}
},
@@ -54,7 +58,7 @@ var config = {
position: "top_right",
config: {
location: "New York",
- locationID: "", //ID from http://www.openweathermap.org/help/city_list.txt
+ locationID: "", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
appid: "YOUR_OPENWEATHER_API_KEY"
}
},
@@ -64,7 +68,7 @@ var config = {
header: "Weather Forecast",
config: {
location: "New York",
- locationID: "5128581", //ID from http://www.openweathermap.org/help/city_list.txt
+ locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city
appid: "YOUR_OPENWEATHER_API_KEY"
}
},
@@ -79,7 +83,9 @@ var config = {
}
],
showSourceTitle: true,
- showPublishDate: true
+ showPublishDate: true,
+ broadcastNewsFeeds: true,
+ broadcastNewsUpdates: true
}
},
]
diff --git a/css/main.css b/css/main.css
index 49bfe611..84f8c4d2 100644
--- a/css/main.css
+++ b/css/main.css
@@ -95,7 +95,7 @@ body {
header {
text-transform: uppercase;
font-size: 15px;
- font-family: "Roboto Condensed";
+ font-family: "Roboto Condensed", Arial, Helvetica, sans-serif;
font-weight: 400;
border-bottom: 1px solid #666;
line-height: 15px;
@@ -128,6 +128,10 @@ sup {
text-overflow: ellipsis;
}
+.pre-line {
+ white-space: pre-line;
+}
+
/**
* Region Definitions.
*/
@@ -151,6 +155,7 @@ sup {
.region.right {
right: 0;
+ text-align: right;
}
.region.top {
@@ -161,6 +166,10 @@ sup {
margin-bottom: 25px;
}
+.region.bottom .container {
+ margin-top: 25px;
+}
+
.region.top .container:empty {
margin-bottom: 0;
}
@@ -185,10 +194,6 @@ sup {
bottom: 0;
}
-.region.bottom .container {
- margin-top: 25px;
-}
-
.region.bottom .container:empty {
margin-top: 0;
}
@@ -231,10 +236,6 @@ sup {
text-align: left;
}
-.region.right {
- text-align: right;
-}
-
.region table {
width: 100%;
border-spacing: 0;
diff --git a/dangerfile.js b/dangerfile.js
new file mode 100644
index 00000000..6920cad9
--- /dev/null
+++ b/dangerfile.js
@@ -0,0 +1,17 @@
+import { danger, fail, warn } from "danger";
+
+// Check if the CHANGELOG.md file has been edited
+// Fail the build and post a comment reminding submitters to do so if it wasn't changed
+if (!danger.git.modified_files.includes("CHANGELOG.md")) {
+ warn("Please include an updated `CHANGELOG.md` file.
This way we can keep track of all the contributions.");
+}
+
+// Check if the PR request is send to the master branch.
+// This should only be done by MichMich.
+if (danger.github.pr.base.ref === "master" && danger.github.pr.user.login !== "MichMich") {
+ // Check if the PR body or title includes the text: #accepted.
+ // If not, the PR will fail.
+ if ((danger.github.pr.body + danger.github.pr.title).includes("#accepted")) {
+ fail("Please send all your pull requests to the `develop` branch.
Pull requests on the `master` branch will not be accepted.");
+ }
+}
diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh
deleted file mode 100644
index 3ab97502..00000000
--- a/docker-entrypoint.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-
-if [ ! -f /opt/magic_mirror/modules ]; then
- cp -Rn /opt/magic_mirror/unmount_modules/. /opt/magic_mirror/modules
-fi
-
-if [ ! -f /opt/magic_mirror/config ]; then
- cp -Rn /opt/magic_mirror/unmount_config/. /opt/magic_mirror/config
-fi
-
-node serveronly
diff --git a/fonts/LICENSE.txt b/fonts/LICENSE.txt
deleted file mode 100644
index 75b52484..00000000
--- a/fonts/LICENSE.txt
+++ /dev/null
@@ -1,202 +0,0 @@
-
- Apache License
- Version 2.0, January 2004
- http://www.apache.org/licenses/
-
- TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
-
- 1. Definitions.
-
- "License" shall mean the terms and conditions for use, reproduction,
- and distribution as defined by Sections 1 through 9 of this document.
-
- "Licensor" shall mean the copyright owner or entity authorized by
- the copyright owner that is granting the License.
-
- "Legal Entity" shall mean the union of the acting entity and all
- other entities that control, are controlled by, or are under common
- control with that entity. For the purposes of this definition,
- "control" means (i) the power, direct or indirect, to cause the
- direction or management of such entity, whether by contract or
- otherwise, or (ii) ownership of fifty percent (50%) or more of the
- outstanding shares, or (iii) beneficial ownership of such entity.
-
- "You" (or "Your") shall mean an individual or Legal Entity
- exercising permissions granted by this License.
-
- "Source" form shall mean the preferred form for making modifications,
- including but not limited to software source code, documentation
- source, and configuration files.
-
- "Object" form shall mean any form resulting from mechanical
- transformation or translation of a Source form, including but
- not limited to compiled object code, generated documentation,
- and conversions to other media types.
-
- "Work" shall mean the work of authorship, whether in Source or
- Object form, made available under the License, as indicated by a
- copyright notice that is included in or attached to the work
- (an example is provided in the Appendix below).
-
- "Derivative Works" shall mean any work, whether in Source or Object
- form, that is based on (or derived from) the Work and for which the
- editorial revisions, annotations, elaborations, or other modifications
- represent, as a whole, an original work of authorship. For the purposes
- of this License, Derivative Works shall not include works that remain
- separable from, or merely link (or bind by name) to the interfaces of,
- the Work and Derivative Works thereof.
-
- "Contribution" shall mean any work of authorship, including
- the original version of the Work and any modifications or additions
- to that Work or Derivative Works thereof, that is intentionally
- submitted to Licensor for inclusion in the Work by the copyright owner
- or by an individual or Legal Entity authorized to submit on behalf of
- the copyright owner. For the purposes of this definition, "submitted"
- means any form of electronic, verbal, or written communication sent
- to the Licensor or its representatives, including but not limited to
- communication on electronic mailing lists, source code control systems,
- and issue tracking systems that are managed by, or on behalf of, the
- Licensor for the purpose of discussing and improving the Work, but
- excluding communication that is conspicuously marked or otherwise
- designated in writing by the copyright owner as "Not a Contribution."
-
- "Contributor" shall mean Licensor and any individual or Legal Entity
- on behalf of whom a Contribution has been received by Licensor and
- subsequently incorporated within the Work.
-
- 2. Grant of Copyright License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- copyright license to reproduce, prepare Derivative Works of,
- publicly display, publicly perform, sublicense, and distribute the
- Work and such Derivative Works in Source or Object form.
-
- 3. Grant of Patent License. Subject to the terms and conditions of
- this License, each Contributor hereby grants to You a perpetual,
- worldwide, non-exclusive, no-charge, royalty-free, irrevocable
- (except as stated in this section) patent license to make, have made,
- use, offer to sell, sell, import, and otherwise transfer the Work,
- where such license applies only to those patent claims licensable
- by such Contributor that are necessarily infringed by their
- Contribution(s) alone or by combination of their Contribution(s)
- with the Work to which such Contribution(s) was submitted. If You
- institute patent litigation against any entity (including a
- cross-claim or counterclaim in a lawsuit) alleging that the Work
- or a Contribution incorporated within the Work constitutes direct
- or contributory patent infringement, then any patent licenses
- granted to You under this License for that Work shall terminate
- as of the date such litigation is filed.
-
- 4. Redistribution. You may reproduce and distribute copies of the
- Work or Derivative Works thereof in any medium, with or without
- modifications, and in Source or Object form, provided that You
- meet the following conditions:
-
- (a) You must give any other recipients of the Work or
- Derivative Works a copy of this License; and
-
- (b) You must cause any modified files to carry prominent notices
- stating that You changed the files; and
-
- (c) You must retain, in the Source form of any Derivative Works
- that You distribute, all copyright, patent, trademark, and
- attribution notices from the Source form of the Work,
- excluding those notices that do not pertain to any part of
- the Derivative Works; and
-
- (d) If the Work includes a "NOTICE" text file as part of its
- distribution, then any Derivative Works that You distribute must
- include a readable copy of the attribution notices contained
- within such NOTICE file, excluding those notices that do not
- pertain to any part of the Derivative Works, in at least one
- of the following places: within a NOTICE text file distributed
- as part of the Derivative Works; within the Source form or
- documentation, if provided along with the Derivative Works; or,
- within a display generated by the Derivative Works, if and
- wherever such third-party notices normally appear. The contents
- of the NOTICE file are for informational purposes only and
- do not modify the License. You may add Your own attribution
- notices within Derivative Works that You distribute, alongside
- or as an addendum to the NOTICE text from the Work, provided
- that such additional attribution notices cannot be construed
- as modifying the License.
-
- You may add Your own copyright statement to Your modifications and
- may provide additional or different license terms and conditions
- for use, reproduction, or distribution of Your modifications, or
- for any such Derivative Works as a whole, provided Your use,
- reproduction, and distribution of the Work otherwise complies with
- the conditions stated in this License.
-
- 5. Submission of Contributions. Unless You explicitly state otherwise,
- any Contribution intentionally submitted for inclusion in the Work
- by You to the Licensor shall be under the terms and conditions of
- this License, without any additional terms or conditions.
- Notwithstanding the above, nothing herein shall supersede or modify
- the terms of any separate license agreement you may have executed
- with Licensor regarding such Contributions.
-
- 6. Trademarks. This License does not grant permission to use the trade
- names, trademarks, service marks, or product names of the Licensor,
- except as required for reasonable and customary use in describing the
- origin of the Work and reproducing the content of the NOTICE file.
-
- 7. Disclaimer of Warranty. Unless required by applicable law or
- agreed to in writing, Licensor provides the Work (and each
- Contributor provides its Contributions) on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
- implied, including, without limitation, any warranties or conditions
- of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
- PARTICULAR PURPOSE. You are solely responsible for determining the
- appropriateness of using or redistributing the Work and assume any
- risks associated with Your exercise of permissions under this License.
-
- 8. Limitation of Liability. In no event and under no legal theory,
- whether in tort (including negligence), contract, or otherwise,
- unless required by applicable law (such as deliberate and grossly
- negligent acts) or agreed to in writing, shall any Contributor be
- liable to You for damages, including any direct, indirect, special,
- incidental, or consequential damages of any character arising as a
- result of this License or out of the use or inability to use the
- Work (including but not limited to damages for loss of goodwill,
- work stoppage, computer failure or malfunction, or any and all
- other commercial damages or losses), even if such Contributor
- has been advised of the possibility of such damages.
-
- 9. Accepting Warranty or Additional Liability. While redistributing
- the Work or Derivative Works thereof, You may choose to offer,
- and charge a fee for, acceptance of support, warranty, indemnity,
- or other liability obligations and/or rights consistent with this
- License. However, in accepting such obligations, You may act only
- on Your own behalf and on Your sole responsibility, not on behalf
- of any other Contributor, and only if You agree to indemnify,
- defend, and hold each Contributor harmless for any liability
- incurred by, or claims asserted against, such Contributor by reason
- of your accepting any such warranty or additional liability.
-
- END OF TERMS AND CONDITIONS
-
- APPENDIX: How to apply the Apache License to your work.
-
- To apply the Apache License to your work, attach the following
- boilerplate notice, with the fields enclosed by brackets "[]"
- replaced with your own identifying information. (Don't include
- the brackets!) The text should be enclosed in the appropriate
- comment syntax for the file format. We also recommend that a
- file or class name and description of purpose be included on the
- same "printed page" as the copyright notice for easier
- identification within third-party archives.
-
- Copyright [yyyy] [name of copyright owner]
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
diff --git a/fonts/Roboto-Black/Roboto-Black.ttf b/fonts/Roboto-Black/Roboto-Black.ttf
deleted file mode 100644
index fbde625d..00000000
Binary files a/fonts/Roboto-Black/Roboto-Black.ttf and /dev/null differ
diff --git a/fonts/Roboto-Black/Roboto-Black.woff b/fonts/Roboto-Black/Roboto-Black.woff
deleted file mode 100644
index 94b19305..00000000
Binary files a/fonts/Roboto-Black/Roboto-Black.woff and /dev/null differ
diff --git a/fonts/Roboto-Black/Roboto-Black.woff2 b/fonts/Roboto-Black/Roboto-Black.woff2
deleted file mode 100644
index c0cb786e..00000000
Binary files a/fonts/Roboto-Black/Roboto-Black.woff2 and /dev/null differ
diff --git a/fonts/Roboto-BlackItalic/Roboto-BlackItalic.ttf b/fonts/Roboto-BlackItalic/Roboto-BlackItalic.ttf
deleted file mode 100644
index 60f7782a..00000000
Binary files a/fonts/Roboto-BlackItalic/Roboto-BlackItalic.ttf and /dev/null differ
diff --git a/fonts/Roboto-BlackItalic/Roboto-BlackItalic.woff b/fonts/Roboto-BlackItalic/Roboto-BlackItalic.woff
deleted file mode 100644
index eb07f101..00000000
Binary files a/fonts/Roboto-BlackItalic/Roboto-BlackItalic.woff and /dev/null differ
diff --git a/fonts/Roboto-BlackItalic/Roboto-BlackItalic.woff2 b/fonts/Roboto-BlackItalic/Roboto-BlackItalic.woff2
deleted file mode 100644
index 6ad4604f..00000000
Binary files a/fonts/Roboto-BlackItalic/Roboto-BlackItalic.woff2 and /dev/null differ
diff --git a/fonts/Roboto-Bold/Roboto-Bold.ttf b/fonts/Roboto-Bold/Roboto-Bold.ttf
deleted file mode 100644
index a355c27c..00000000
Binary files a/fonts/Roboto-Bold/Roboto-Bold.ttf and /dev/null differ
diff --git a/fonts/Roboto-Bold/Roboto-Bold.woff b/fonts/Roboto-Bold/Roboto-Bold.woff
deleted file mode 100644
index d1ef48b4..00000000
Binary files a/fonts/Roboto-Bold/Roboto-Bold.woff and /dev/null differ
diff --git a/fonts/Roboto-Bold/Roboto-Bold.woff2 b/fonts/Roboto-Bold/Roboto-Bold.woff2
deleted file mode 100644
index 5658e9a7..00000000
Binary files a/fonts/Roboto-Bold/Roboto-Bold.woff2 and /dev/null differ
diff --git a/fonts/Roboto-BoldItalic/Roboto-BoldItalic.ttf b/fonts/Roboto-BoldItalic/Roboto-BoldItalic.ttf
deleted file mode 100644
index 3c9a7a37..00000000
Binary files a/fonts/Roboto-BoldItalic/Roboto-BoldItalic.ttf and /dev/null differ
diff --git a/fonts/Roboto-BoldItalic/Roboto-BoldItalic.woff b/fonts/Roboto-BoldItalic/Roboto-BoldItalic.woff
deleted file mode 100644
index 291c89dd..00000000
Binary files a/fonts/Roboto-BoldItalic/Roboto-BoldItalic.woff and /dev/null differ
diff --git a/fonts/Roboto-BoldItalic/Roboto-BoldItalic.woff2 b/fonts/Roboto-BoldItalic/Roboto-BoldItalic.woff2
deleted file mode 100644
index 75123709..00000000
Binary files a/fonts/Roboto-BoldItalic/Roboto-BoldItalic.woff2 and /dev/null differ
diff --git a/fonts/Roboto-Italic/Roboto-Italic.ttf b/fonts/Roboto-Italic/Roboto-Italic.ttf
deleted file mode 100644
index ff6046d5..00000000
Binary files a/fonts/Roboto-Italic/Roboto-Italic.ttf and /dev/null differ
diff --git a/fonts/Roboto-Italic/Roboto-Italic.woff b/fonts/Roboto-Italic/Roboto-Italic.woff
deleted file mode 100644
index 3bd43138..00000000
Binary files a/fonts/Roboto-Italic/Roboto-Italic.woff and /dev/null differ
diff --git a/fonts/Roboto-Italic/Roboto-Italic.woff2 b/fonts/Roboto-Italic/Roboto-Italic.woff2
deleted file mode 100644
index 77c81227..00000000
Binary files a/fonts/Roboto-Italic/Roboto-Italic.woff2 and /dev/null differ
diff --git a/fonts/Roboto-Light/Roboto-Light.ttf b/fonts/Roboto-Light/Roboto-Light.ttf
deleted file mode 100644
index 94c6bcc6..00000000
Binary files a/fonts/Roboto-Light/Roboto-Light.ttf and /dev/null differ
diff --git a/fonts/Roboto-Light/Roboto-Light.woff b/fonts/Roboto-Light/Roboto-Light.woff
deleted file mode 100644
index 1d1ad478..00000000
Binary files a/fonts/Roboto-Light/Roboto-Light.woff and /dev/null differ
diff --git a/fonts/Roboto-Light/Roboto-Light.woff2 b/fonts/Roboto-Light/Roboto-Light.woff2
deleted file mode 100644
index 166c8218..00000000
Binary files a/fonts/Roboto-Light/Roboto-Light.woff2 and /dev/null differ
diff --git a/fonts/Roboto-LightItalic/Roboto-LightItalic.ttf b/fonts/Roboto-LightItalic/Roboto-LightItalic.ttf
deleted file mode 100644
index 04cc0023..00000000
Binary files a/fonts/Roboto-LightItalic/Roboto-LightItalic.ttf and /dev/null differ
diff --git a/fonts/Roboto-LightItalic/Roboto-LightItalic.woff b/fonts/Roboto-LightItalic/Roboto-LightItalic.woff
deleted file mode 100644
index 3662bf40..00000000
Binary files a/fonts/Roboto-LightItalic/Roboto-LightItalic.woff and /dev/null differ
diff --git a/fonts/Roboto-LightItalic/Roboto-LightItalic.woff2 b/fonts/Roboto-LightItalic/Roboto-LightItalic.woff2
deleted file mode 100644
index 9ba7fbd2..00000000
Binary files a/fonts/Roboto-LightItalic/Roboto-LightItalic.woff2 and /dev/null differ
diff --git a/fonts/Roboto-Medium/Roboto-Medium.ttf b/fonts/Roboto-Medium/Roboto-Medium.ttf
deleted file mode 100644
index 39c63d74..00000000
Binary files a/fonts/Roboto-Medium/Roboto-Medium.ttf and /dev/null differ
diff --git a/fonts/Roboto-Medium/Roboto-Medium.woff b/fonts/Roboto-Medium/Roboto-Medium.woff
deleted file mode 100644
index 487ea69b..00000000
Binary files a/fonts/Roboto-Medium/Roboto-Medium.woff and /dev/null differ
diff --git a/fonts/Roboto-Medium/Roboto-Medium.woff2 b/fonts/Roboto-Medium/Roboto-Medium.woff2
deleted file mode 100644
index 2622b475..00000000
Binary files a/fonts/Roboto-Medium/Roboto-Medium.woff2 and /dev/null differ
diff --git a/fonts/Roboto-MediumItalic/Roboto-MediumItalic.ttf b/fonts/Roboto-MediumItalic/Roboto-MediumItalic.ttf
deleted file mode 100644
index dc743f0a..00000000
Binary files a/fonts/Roboto-MediumItalic/Roboto-MediumItalic.ttf and /dev/null differ
diff --git a/fonts/Roboto-MediumItalic/Roboto-MediumItalic.woff b/fonts/Roboto-MediumItalic/Roboto-MediumItalic.woff
deleted file mode 100644
index 70dea35a..00000000
Binary files a/fonts/Roboto-MediumItalic/Roboto-MediumItalic.woff and /dev/null differ
diff --git a/fonts/Roboto-MediumItalic/Roboto-MediumItalic.woff2 b/fonts/Roboto-MediumItalic/Roboto-MediumItalic.woff2
deleted file mode 100644
index 8b111d46..00000000
Binary files a/fonts/Roboto-MediumItalic/Roboto-MediumItalic.woff2 and /dev/null differ
diff --git a/fonts/Roboto-Regular/Roboto-Regular.ttf b/fonts/Roboto-Regular/Roboto-Regular.ttf
deleted file mode 100644
index 8c082c8d..00000000
Binary files a/fonts/Roboto-Regular/Roboto-Regular.ttf and /dev/null differ
diff --git a/fonts/Roboto-Regular/Roboto-Regular.woff b/fonts/Roboto-Regular/Roboto-Regular.woff
deleted file mode 100644
index 6ea53c20..00000000
Binary files a/fonts/Roboto-Regular/Roboto-Regular.woff and /dev/null differ
diff --git a/fonts/Roboto-Regular/Roboto-Regular.woff2 b/fonts/Roboto-Regular/Roboto-Regular.woff2
deleted file mode 100644
index 10cf92b8..00000000
Binary files a/fonts/Roboto-Regular/Roboto-Regular.woff2 and /dev/null differ
diff --git a/fonts/Roboto-Thin/Roboto-Thin.ttf b/fonts/Roboto-Thin/Roboto-Thin.ttf
deleted file mode 100644
index d6955502..00000000
Binary files a/fonts/Roboto-Thin/Roboto-Thin.ttf and /dev/null differ
diff --git a/fonts/Roboto-Thin/Roboto-Thin.woff b/fonts/Roboto-Thin/Roboto-Thin.woff
deleted file mode 100644
index b0e7c557..00000000
Binary files a/fonts/Roboto-Thin/Roboto-Thin.woff and /dev/null differ
diff --git a/fonts/Roboto-Thin/Roboto-Thin.woff2 b/fonts/Roboto-Thin/Roboto-Thin.woff2
deleted file mode 100644
index 5eee3b3e..00000000
Binary files a/fonts/Roboto-Thin/Roboto-Thin.woff2 and /dev/null differ
diff --git a/fonts/Roboto-ThinItalic/Roboto-ThinItalic.ttf b/fonts/Roboto-ThinItalic/Roboto-ThinItalic.ttf
deleted file mode 100644
index 07172ff6..00000000
Binary files a/fonts/Roboto-ThinItalic/Roboto-ThinItalic.ttf and /dev/null differ
diff --git a/fonts/Roboto-ThinItalic/Roboto-ThinItalic.woff b/fonts/Roboto-ThinItalic/Roboto-ThinItalic.woff
deleted file mode 100644
index 73f10ad4..00000000
Binary files a/fonts/Roboto-ThinItalic/Roboto-ThinItalic.woff and /dev/null differ
diff --git a/fonts/Roboto-ThinItalic/Roboto-ThinItalic.woff2 b/fonts/Roboto-ThinItalic/Roboto-ThinItalic.woff2
deleted file mode 100644
index 292c86f4..00000000
Binary files a/fonts/Roboto-ThinItalic/Roboto-ThinItalic.woff2 and /dev/null differ
diff --git a/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.ttf b/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.ttf
deleted file mode 100644
index fc28868a..00000000
Binary files a/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.ttf and /dev/null differ
diff --git a/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.woff b/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.woff
deleted file mode 100644
index cf577ca5..00000000
Binary files a/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.woff and /dev/null differ
diff --git a/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.woff2 b/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.woff2
deleted file mode 100644
index 8b2e28cd..00000000
Binary files a/fonts/RobotoCondensed-Bold/RobotoCondensed-Bold.woff2 and /dev/null differ
diff --git a/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.ttf b/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.ttf
deleted file mode 100644
index e1a648ff..00000000
Binary files a/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.ttf and /dev/null differ
diff --git a/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.woff b/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.woff
deleted file mode 100644
index 0b5db116..00000000
Binary files a/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.woff and /dev/null differ
diff --git a/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.woff2 b/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.woff2
deleted file mode 100644
index 5d3f2072..00000000
Binary files a/fonts/RobotoCondensed-BoldItalic/RobotoCondensed-BoldItalic.woff2 and /dev/null differ
diff --git a/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.ttf b/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.ttf
deleted file mode 100644
index 97ff9f1e..00000000
Binary files a/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.ttf and /dev/null differ
diff --git a/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.woff b/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.woff
deleted file mode 100644
index 4548bfa9..00000000
Binary files a/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.woff and /dev/null differ
diff --git a/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.woff2 b/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.woff2
deleted file mode 100644
index 04141901..00000000
Binary files a/fonts/RobotoCondensed-Italic/RobotoCondensed-Italic.woff2 and /dev/null differ
diff --git a/fonts/RobotoCondensed-Light/RobotoCondensed-Light.ttf b/fonts/RobotoCondensed-Light/RobotoCondensed-Light.ttf
deleted file mode 100644
index 2dae31e2..00000000
Binary files a/fonts/RobotoCondensed-Light/RobotoCondensed-Light.ttf and /dev/null differ
diff --git a/fonts/RobotoCondensed-Light/RobotoCondensed-Light.woff b/fonts/RobotoCondensed-Light/RobotoCondensed-Light.woff
deleted file mode 100644
index b797af13..00000000
Binary files a/fonts/RobotoCondensed-Light/RobotoCondensed-Light.woff and /dev/null differ
diff --git a/fonts/RobotoCondensed-Light/RobotoCondensed-Light.woff2 b/fonts/RobotoCondensed-Light/RobotoCondensed-Light.woff2
deleted file mode 100644
index 1e3b487a..00000000
Binary files a/fonts/RobotoCondensed-Light/RobotoCondensed-Light.woff2 and /dev/null differ
diff --git a/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.ttf b/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.ttf
deleted file mode 100644
index da108d3a..00000000
Binary files a/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.ttf and /dev/null differ
diff --git a/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.woff b/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.woff
deleted file mode 100644
index 8eae55a8..00000000
Binary files a/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.woff and /dev/null differ
diff --git a/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.woff2 b/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.woff2
deleted file mode 100644
index 947a1358..00000000
Binary files a/fonts/RobotoCondensed-LightItalic/RobotoCondensed-LightItalic.woff2 and /dev/null differ
diff --git a/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.ttf b/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.ttf
deleted file mode 100644
index c2304c14..00000000
Binary files a/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.ttf and /dev/null differ
diff --git a/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.woff b/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.woff
deleted file mode 100644
index 3e25d65d..00000000
Binary files a/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.woff and /dev/null differ
diff --git a/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.woff2 b/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.woff2
deleted file mode 100644
index d7c42c8c..00000000
Binary files a/fonts/RobotoCondensed-Regular/RobotoCondensed-Regular.woff2 and /dev/null differ
diff --git a/fonts/package-lock.json b/fonts/package-lock.json
new file mode 100644
index 00000000..c05e7b0d
--- /dev/null
+++ b/fonts/package-lock.json
@@ -0,0 +1,12 @@
+{
+ "name": "magicmirror-fonts",
+ "requires": true,
+ "lockfileVersion": 1,
+ "dependencies": {
+ "roboto-fontface": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.8.0.tgz",
+ "integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ=="
+ }
+ }
+}
diff --git a/fonts/package.json b/fonts/package.json
new file mode 100644
index 00000000..a4fb07de
--- /dev/null
+++ b/fonts/package.json
@@ -0,0 +1,15 @@
+{
+ "name": "magicmirror-fonts",
+ "description": "Package for fonts use by MagicMirror Core.",
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/MichMich/MagicMirror.git"
+ },
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/MichMich/MagicMirror/issues"
+ },
+ "dependencies": {
+ "roboto-fontface": "^0.8.0"
+ }
+}
diff --git a/fonts/roboto.css b/fonts/roboto.css
index ce9099da..11d3f41d 100644
--- a/fonts/roboto.css
+++ b/fonts/roboto.css
@@ -5,9 +5,9 @@
src:
local("Roboto Thin"),
local("Roboto-Thin"),
- url("Roboto-Thin/Roboto-Thin.woff2") format("woff2"),
- url("Roboto-Thin/Roboto-Thin.woff") format("woff"),
- url("Roboto-Thin/Roboto-Thin.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.ttf") format("truetype");
}
@font-face {
@@ -17,9 +17,9 @@
src:
local("Roboto Condensed Light"),
local("RobotoCondensed-Light"),
- url("RobotoCondensed-Light/RobotoCondensed-Light.woff2") format("woff2"),
- url("RobotoCondensed-Light/RobotoCondensed-Light.woff") format("woff"),
- url("RobotoCondensed-Light/RobotoCondensed-Light.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.ttf") format("truetype");
}
@font-face {
@@ -29,9 +29,9 @@
src:
local("Roboto Condensed"),
local("RobotoCondensed-Regular"),
- url("RobotoCondensed-Regular/RobotoCondensed-Regular.woff2") format("woff2"),
- url("RobotoCondensed-Regular/RobotoCondensed-Regular.woff") format("woff"),
- url("RobotoCondensed-Regular/RobotoCondensed-Regular.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.ttf") format("truetype");
}
@font-face {
@@ -41,9 +41,9 @@
src:
local("Roboto Condensed Bold"),
local("RobotoCondensed-Bold"),
- url("RobotoCondensed-Bold/RobotoCondensed-Bold.woff2") format("woff2"),
- url("RobotoCondensed-Bold/RobotoCondensed-Bold.woff") format("woff"),
- url("RobotoCondensed-Bold/RobotoCondensed-Bold.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.ttf") format("truetype");
}
@font-face {
@@ -53,9 +53,9 @@
src:
local("Roboto"),
local("Roboto-Regular"),
- url("Roboto-Regular/Roboto-Regular.woff2") format("woff2"),
- url("Roboto-Regular/Roboto-Regular.woff") format("woff"),
- url("Roboto-Regular/Roboto-Regular.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.ttf") format("truetype");
}
@font-face {
@@ -65,9 +65,9 @@
src:
local("Roboto Medium"),
local("Roboto-Medium"),
- url("Roboto-Medium/Roboto-Medium.woff2") format("woff2"),
- url("Roboto-Medium/Roboto-Medium.woff") format("woff"),
- url("Roboto-Medium/Roboto-Medium.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.ttf") format("truetype");
}
@font-face {
@@ -77,9 +77,9 @@
src:
local("Roboto Bold"),
local("Roboto-Bold"),
- url("Roboto-Bold/Roboto-Bold.woff2") format("woff2"),
- url("Roboto-Bold/Roboto-Bold.woff") format("woff"),
- url("Roboto-Bold/Roboto-Bold.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.ttf") format("truetype");
}
@font-face {
@@ -89,7 +89,7 @@
src:
local("Roboto Light"),
local("Roboto-Light"),
- url("Roboto-Light/Roboto-Light.woff2") format("woff2"),
- url("Roboto-Light/Roboto-Light.woff") format("woff"),
- url("Roboto-Light/Roboto-Light.ttf") format("truetype");
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff"),
+ url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.ttf") format("truetype");
}
diff --git a/fonts/yarn.lock b/fonts/yarn.lock
new file mode 100644
index 00000000..ccb550f3
--- /dev/null
+++ b/fonts/yarn.lock
@@ -0,0 +1,7 @@
+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
+# yarn lockfile v1
+
+
+roboto-fontface@^0.8.0:
+ version "0.8.0"
+ resolved "https://registry.yarnpkg.com/roboto-fontface/-/roboto-fontface-0.8.0.tgz#031a83c8f79932801a57d83bf743f37250163499"
diff --git a/index.html b/index.html
index 85951a85..d8604256 100644
--- a/index.html
+++ b/index.html
@@ -1,7 +1,7 @@
morning {
- this.config.compliments = JSON.parse(response);
+ var self = this;
+ if (this.config.remoteFile !== null) {
+ this.complimentFile(function(response) {
+ self.config.compliments = JSON.parse(response);
+ self.updateDom();
});
}
// Schedule update timer.
- var self = this;
setInterval(function() {
self.updateDom(self.config.fadeSpeed);
}, this.config.updateInterval);
@@ -96,14 +101,14 @@ Module.register("compliments", {
*/
complimentArray: function() {
var hour = moment().hour();
- var compliments = null;
+ var compliments;
- if (hour >= 3 && hour < 12) {
- compliments = this.config.compliments.morning;
- } else if (hour >= 12 && hour < 17) {
- compliments = this.config.compliments.afternoon;
- } else {
- compliments = this.config.compliments.evening;
+ if (hour >= this.config.morningStartTime && hour < this.config.morningEndTime && this.config.compliments.hasOwnProperty("morning")) {
+ compliments = this.config.compliments.morning.slice(0);
+ } else if (hour >= this.config.afternoonStartTime && hour < this.config.afternoonEndTime && this.config.compliments.hasOwnProperty("afternoon")) {
+ compliments = this.config.compliments.afternoon.slice(0);
+ } else if(this.config.compliments.hasOwnProperty("evening")) {
+ compliments = this.config.compliments.evening.slice(0);
}
if (typeof compliments === "undefined") {
@@ -117,18 +122,19 @@ Module.register("compliments", {
compliments.push.apply(compliments, this.config.compliments.anytime);
return compliments;
-
},
/* complimentFile(callback)
* Retrieve a file from the local filesystem
*/
complimentFile: function(callback) {
- var xobj = new XMLHttpRequest();
+ var xobj = new XMLHttpRequest(),
+ isRemote = this.config.remoteFile.indexOf("http://") === 0 || this.config.remoteFile.indexOf("https://") === 0,
+ path = isRemote ? this.config.remoteFile : this.file(this.config.remoteFile);
xobj.overrideMimeType("application/json");
- xobj.open("GET", this.file(this.config.remoteFile), true);
+ xobj.open("GET", path, true);
xobj.onreadystatechange = function() {
- if (xobj.readyState == 4 && xobj.status == "200") {
+ if (xobj.readyState === 4 && xobj.status === 200) {
callback(xobj.responseText);
}
};
@@ -153,13 +159,12 @@ Module.register("compliments", {
var compliment = document.createTextNode(complimentText);
var wrapper = document.createElement("div");
- wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright";
+ wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright pre-line";
wrapper.appendChild(compliment);
return wrapper;
},
-
// From data currentweather set weather type
setCurrentWeatherType: function(data) {
var weatherIconTable = {
@@ -185,12 +190,11 @@ Module.register("compliments", {
this.currentWeatherType = weatherIconTable[data.weather[0].icon];
},
-
// Override notification handler.
notificationReceived: function(notification, payload, sender) {
- if (notification == "CURRENTWEATHER_DATA") {
+ if (notification === "CURRENTWEATHER_DATA") {
this.setCurrentWeatherType(payload.data);
}
},
-});
\ No newline at end of file
+});
diff --git a/modules/default/compliments/compliments_screenshot.png b/modules/default/compliments/compliments_screenshot.png
new file mode 100644
index 00000000..12def320
Binary files /dev/null and b/modules/default/compliments/compliments_screenshot.png differ
diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md
index d70ec297..0ce7d59a 100644
--- a/modules/default/currentweather/README.md
+++ b/modules/default/currentweather/README.md
@@ -2,6 +2,11 @@
The `currentweather` module is one of the default modules of the MagicMirror.
This module displays the current weather, including the windspeed, the sunset or sunrise time, the temperature and an icon to display the current conditions.
+## Screenshot
+
+- Current weather screenshot
+
+
## Using the module
To use this module, add it to the modules array in the `config/config.js` file:
@@ -14,7 +19,7 @@ modules: [
config: {
// See 'Configuration options' for more information.
location: "Amsterdam,Netherlands",
- locationID: "", //Location ID from http://openweathermap.org/help/city_list.txt
+ locationID: "", //Location ID from http://bulk.openweathermap.org/sample/city.list.json.gz
appid: "abcde12345abcde12345abcde12345ab" //openweathermap.org API key.
}
}
@@ -29,7 +34,7 @@ The following properties can be configured:
| Option | Description
| ---------------------------- | -----------
| `location` | The location used for weather information.
**Example:** `'Amsterdam,Netherlands'`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
-| `locationID` | Location ID from [OpenWeatherMap](http://openweathermap.org/help/city_list.txt) **This will override anything you put in location.**
Leave blank if you want to use location.
**Example:** `1234567`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
+| `locationID` | Location ID from [OpenWeatherMap](https://openweathermap.org/find) **This will override anything you put in location.**
Leave blank if you want to use location.
**Example:** `1234567`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
| `appid` | The [OpenWeatherMap](https://home.openweathermap.org) API key, which can be obtained by creating an OpenWeatherMap account.
This value is **REQUIRED**
| `units` | What units to use. Specified by config.js
**Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` =Fahrenheit
**Default value:** `config.units`
| `roundTemp` | Round temperature value to nearest integer.
**Possible values:** `true` (round to integer) or `false` (display exact value with decimal point)
**Default value:** `false`
@@ -40,16 +45,22 @@ The following properties can be configured:
| `showPeriod` | Show the period (am/pm) with 12 hour format
**Possible values:** `true` or `false`
**Default value:** `true`
| `showPeriodUpper` | Show the period (AM/PM) with 12 hour format as uppercase
**Possible values:** `true` or `false`
**Default value:** `false`
| `showWindDirection` | Show the wind direction next to the wind speed.
**Possible values:** `true` or `false`
**Default value:** `true`
+| `showWindDirectionAsArrow` | Show the wind direction as an arrow instead of abbreviation
**Possible values:** `true` or `false`
**Default value:** `false`
| `showHumidity` | Show the current humidity
**Possible values:** `true` or `false`
**Default value:** `false`
-| `onlyTemp` | Show only current Temperature and weather icon.
**Possible values:** `true` or `false`
**Default value:** `false`
+| `showIndoorTemperature` | If you have another module that emits the INDOOR_TEMPERATURE notification, the indoor temperature will be displayed
**Default value:** `false`
+| `onlyTemp` | Show only current Temperature and weather icon without windspeed, sunset, sunrise time and feels like.
**Possible values:** `true` or `false`
**Default value:** `false`
+| `showFeelsLike` | Shows the Feels like temperature weather.
**Possible values:**`true` or `false`
**Default value:** `true`
+| `useKMPHwind` | Uses KMPH as units for windspeed.
**Possible values:**`true` or `false`
**Default value:** `false`
| `useBeaufort` | Pick between using the Beaufort scale for wind speed or using the default units.
**Possible values:** `true` or `false`
**Default value:** `true`
| `lang` | The language of the days.
**Possible values:** `en`, `nl`, `ru`, etc ...
**Default value:** uses value of _config.language_
+| `decimalSymbol` | The decimal symbol to use.
**Possible values:** `.`, `,` or any other symbol.
**Default value:** `.`
| `initialLoadDelay` | The initial delay before loading. If you have multiple modules that use the same API key, you might want to delay one of the requests. (Milliseconds)
**Possible values:** `1000` - `5000`
**Default value:** `0`
| `retryDelay` | The delay before retrying after a request failure. (Milliseconds)
**Possible values:** `1000` - `60000`
**Default value:** `2500`
| `apiVersion` | The OpenWeatherMap API version to use.
**Default value:** `2.5`
| `apiBase` | The OpenWeatherMap base URL.
**Default value:** `'http://api.openweathermap.org/data/'`
| `weatherEndpoint` | The OpenWeatherMap API endPoint.
**Default value:** `'weather'`
| `appendLocationNameToHeader` | If set to `true`, the returned location name will be appended to the header of the module, if the header is enabled. This is mainly intresting when using calender based weather.
**Default value:** `true`
+| `useLocationAsHeader` | If set to `true` and location is given a value, the value of location will be used as the header. This is useful if `locationName` was not returned.
**Default value:** `false`
| `calendarClass` | The class for the calender module to base the event based weather information on.
**Default value:** `'calendar'`
| `iconTable` | The conversion table to convert the weather conditions to weather-icons.
**Default value:** view tabel below.
diff --git a/modules/default/currentweather/currentweather.css b/modules/default/currentweather/currentweather.css
index a40be878..b7669bda 100644
--- a/modules/default/currentweather/currentweather.css
+++ b/modules/default/currentweather/currentweather.css
@@ -1,4 +1,5 @@
-.currentweather .weathericon {
+.currentweather .weathericon,
+.currentweather .fa-home {
font-size: 75%;
line-height: 65px;
display: inline-block;
diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js
index 6e23cdcf..562baf31 100644
--- a/modules/default/currentweather/currentweather.js
+++ b/modules/default/currentweather/currentweather.js
@@ -21,16 +21,23 @@ Module.register("currentweather",{
showPeriod: true,
showPeriodUpper: false,
showWindDirection: true,
+ showWindDirectionAsArrow: false,
useBeaufort: true,
+ appendLocationNameToHeader: false,
+ useKMPHwind: false,
lang: config.language,
+ decimalSymbol: ".",
showHumidity: false,
degreeLabel: false,
+ showIndoorTemperature: false,
+ showIndoorHumidity: false,
+ showFeelsLike: true,
initialLoadDelay: 0, // 0 seconds delay
retryDelay: 2500,
apiVersion: "2.5",
- apiBase: "http://api.openweathermap.org/data/",
+ apiBase: "https://api.openweathermap.org/data/",
weatherEndpoint: "weather",
appendLocationNameToHeader: true,
@@ -61,11 +68,11 @@ Module.register("currentweather",{
},
},
- // create a variable for the first upcoming calendaar event. Used if no location is specified.
+ // create a variable for the first upcoming calendar event. Used if no location is specified.
firstEvent: false,
// create a variable to hold the location name based on the API result.
- fetchedLocatioName: "",
+ fetchedLocationName: "",
// Define required scripts.
getScripts: function() {
@@ -81,7 +88,7 @@ Module.register("currentweather",{
getTranslations: function() {
// The translations for the default modules are defined in the core translation files.
// Therefor we can just return false. Otherwise we should have returned a dictionary.
- // If you're trying to build yiur own module including translations, check out the documentation.
+ // If you're trying to build your own module including translations, check out the documentation.
return false;
},
@@ -94,11 +101,14 @@ Module.register("currentweather",{
this.windSpeed = null;
this.windDirection = null;
+ this.windDeg = null;
this.sunriseSunsetTime = null;
this.sunriseSunsetIcon = null;
this.temperature = null;
+ this.indoorTemperature = null;
+ this.indoorHumidity = null;
this.weatherType = null;
-
+ this.feelsLike = null;
this.loaded = false;
this.scheduleUpdate(this.config.initialLoadDelay);
@@ -111,7 +121,6 @@ Module.register("currentweather",{
var small = document.createElement("div");
small.className = "normal medium";
-
var windIcon = document.createElement("span");
windIcon.className = "wi wi-strong-wind dimmed";
small.appendChild(windIcon);
@@ -122,7 +131,13 @@ Module.register("currentweather",{
if (this.config.showWindDirection) {
var windDirection = document.createElement("sup");
- windDirection.innerHTML = " " + this.translate(this.windDirection);
+ if (this.config.showWindDirectionAsArrow) {
+ if(this.windDeg !== null) {
+ windDirection.innerHTML = " ";
+ }
+ } else {
+ windDirection.innerHTML = " " + this.translate(this.windDirection);
+ }
small.appendChild(windDirection);
}
var spacer = document.createElement("span");
@@ -184,35 +199,81 @@ Module.register("currentweather",{
large.appendChild(weatherIcon);
var degreeLabel = "";
- if (this.config.degreeLabel) {
- switch (this.config.units ) {
+ if (this.config.units === "metric" || this.config.units === "imperial") {
+ degreeLabel += "°";
+ }
+ if(this.config.degreeLabel) {
+ switch(this.config.units) {
case "metric":
- degreeLabel = "C";
+ degreeLabel += "C";
break;
case "imperial":
- degreeLabel = "F";
+ degreeLabel += "F";
break;
case "default":
- degreeLabel = "K";
+ degreeLabel += "K";
break;
}
}
+ if (this.config.decimalSymbol === "") {
+ this.config.decimalSymbol = ".";
+ }
+
var temperature = document.createElement("span");
temperature.className = "bright";
- temperature.innerHTML = " " + this.temperature + "°" + degreeLabel;
+ temperature.innerHTML = " " + this.temperature.replace(".", this.config.decimalSymbol) + degreeLabel;
large.appendChild(temperature);
+ if (this.config.showIndoorTemperature && this.indoorTemperature) {
+ var indoorIcon = document.createElement("span");
+ indoorIcon.className = "fa fa-home";
+ large.appendChild(indoorIcon);
+
+ var indoorTemperatureElem = document.createElement("span");
+ indoorTemperatureElem.className = "bright";
+ indoorTemperatureElem.innerHTML = " " + this.indoorTemperature.replace(".", this.config.decimalSymbol) + degreeLabel;
+ large.appendChild(indoorTemperatureElem);
+ }
+
+ if (this.config.showIndoorHumidity && this.indoorHumidity) {
+ var indoorHumidityIcon = document.createElement("span");
+ indoorHumidityIcon.className = "fa fa-tint";
+ large.appendChild(indoorHumidityIcon);
+
+ var indoorHumidityElem = document.createElement("span");
+ indoorHumidityElem.className = "bright";
+ indoorHumidityElem.innerHTML = " " + this.indoorHumidity + "%";
+ large.appendChild(indoorHumidityElem);
+ }
+
wrapper.appendChild(large);
+
+ if (this.config.showFeelsLike && this.config.onlyTemp === false){
+ var small = document.createElement("div");
+ small.className = "normal medium";
+
+ var feelsLike = document.createElement("span");
+ feelsLike.className = "dimmed";
+ feelsLike.innerHTML = this.translate("FEELS") + " " + this.feelsLike + degreeLabel;
+ small.appendChild(feelsLike);
+
+ wrapper.appendChild(small);
+ }
+
return wrapper;
},
// Override getHeader method.
getHeader: function() {
- if (this.config.appendLocationNameToHeader) {
- return this.data.header + " " + this.fetchedLocatioName;
+ if (this.config.appendLocationNameToHeader && this.data.header !== undefined) {
+ return this.data.header + " " + this.fetchedLocationName;
}
+ if (this.config.useLocationAsHeader && this.config.location !== false) {
+ return this.config.location;
+ }
+
return this.data.header;
},
@@ -226,10 +287,9 @@ Module.register("currentweather",{
if (notification === "CALENDAR_EVENTS") {
var senderClasses = sender.data.classes.toLowerCase().split(" ");
if (senderClasses.indexOf(this.config.calendarClass.toLowerCase()) !== -1) {
- var lastEvent = this.firstEvent;
this.firstEvent = false;
- for (e in payload) {
+ for (var e in payload) {
var event = payload[e];
if (event.location || event.geo) {
this.firstEvent = event;
@@ -239,6 +299,14 @@ Module.register("currentweather",{
}
}
}
+ if (notification === "INDOOR_TEMPERATURE") {
+ this.indoorTemperature = this.roundValue(payload);
+ this.updateDom(this.config.animationSpeed);
+ }
+ if (notification === "INDOOR_HUMIDITY") {
+ this.indoorHumidity = this.roundValue(payload);
+ this.updateDom(this.config.animationSpeed);
+ }
},
/* updateWeather(compliments)
@@ -290,7 +358,7 @@ Module.register("currentweather",{
} else if(this.config.location) {
params += "q=" + this.config.location;
} else if (this.firstEvent && this.firstEvent.geo) {
- params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon
+ params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon;
} else if (this.firstEvent && this.firstEvent.location) {
params += "q=" + this.firstEvent.location;
} else {
@@ -320,15 +388,74 @@ Module.register("currentweather",{
this.humidity = parseFloat(data.main.humidity);
this.temperature = this.roundValue(data.main.temp);
+ this.fetchedLocationName = data.name;
+ this.feelsLike = 0;
if (this.config.useBeaufort){
this.windSpeed = this.ms2Beaufort(this.roundValue(data.wind.speed));
- }else {
+ } else if (this.config.useKMPHwind) {
+ this.windSpeed = parseFloat((data.wind.speed * 60 * 60) / 1000).toFixed(0);
+ } else {
this.windSpeed = parseFloat(data.wind.speed).toFixed(0);
}
+ // ONLY WORKS IF TEMP IN C //
+ var windInMph = parseFloat(data.wind.speed * 2.23694);
+
+ var tempInF = 0;
+ switch (this.config.units){
+ case "metric": tempInF = 1.8 * this.temperature + 32;
+ break;
+ case "imperial": tempInF = this.temperature;
+ break;
+ case "default":
+ var tc = this.temperature - 273.15;
+ tempInF = 1.8 * tc + 32;
+ break;
+ }
+
+ if (windInMph > 3 && tempInF < 50){
+ // windchill
+ var windChillInF = Math.round(35.74+0.6215*tempInF-35.75*Math.pow(windInMph,0.16)+0.4275*tempInF*Math.pow(windInMph,0.16));
+ var windChillInC = (windChillInF - 32) * (5/9);
+ // this.feelsLike = windChillInC.toFixed(0);
+
+ switch (this.config.units){
+ case "metric": this.feelsLike = windChillInC.toFixed(0);
+ break;
+ case "imperial": this.feelsLike = windChillInF.toFixed(0);
+ break;
+ case "default":
+ var tc = windChillInC + 273.15;
+ this.feelsLike = tc.toFixed(0);
+ break;
+ }
+
+ } else if (tempInF > 80 && this.humidity > 40){
+ // heat index
+ var Hindex = -42.379 + 2.04901523*tempInF + 10.14333127*this.humidity
+ - 0.22475541*tempInF*this.humidity - 6.83783*Math.pow(10,-3)*tempInF*tempInF
+ - 5.481717*Math.pow(10,-2)*this.humidity*this.humidity
+ + 1.22874*Math.pow(10,-3)*tempInF*tempInF*this.humidity
+ + 8.5282*Math.pow(10,-4)*tempInF*this.humidity*this.humidity
+ - 1.99*Math.pow(10,-6)*tempInF*tempInF*this.humidity*this.humidity;
+
+ switch (this.config.units){
+ case "metric": this.feelsLike = parseFloat((Hindex - 32) / 1.8).toFixed(0);
+ break;
+ case "imperial": this.feelsLike = Hindex.toFixed(0);
+ break;
+ case "default":
+ var tc = parseFloat((Hindex - 32) / 1.8) + 273.15;
+ this.feelsLike = tc.toFixed(0);
+ break;
+ }
+ } else {
+ this.feelsLike = parseFloat(this.temperature).toFixed(0);
+ }
this.windDirection = this.deg2Cardinal(data.wind.deg);
+ this.windDeg = data.wind.deg;
this.weatherType = this.config.iconTable[data.weather[0].icon];
var now = new Date();
@@ -359,7 +486,6 @@ Module.register("currentweather",{
this.sunriseSunsetTime = timeString;
this.sunriseSunsetIcon = (sunrise < now && sunset > now) ? "wi-sunset" : "wi-sunrise";
-
this.show(this.config.animationSpeed, {lockString:this.identifier});
this.loaded = true;
this.updateDom(this.config.animationSpeed);
@@ -386,6 +512,10 @@ Module.register("currentweather",{
/* ms2Beaufort(ms)
* Converts m2 to beaufort (windspeed).
*
+ * see:
+ * http://www.spc.noaa.gov/faq/tornado/beaufort.html
+ * https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale
+ *
* argument ms number - Windspeed in m/s.
*
* return number - Windspeed in beaufort.
@@ -443,10 +573,11 @@ Module.register("currentweather",{
*
* argument temperature number - Temperature.
*
- * return number - Rounded Temperature.
+ * return string - Rounded Temperature.
*/
roundValue: function(temperature) {
var decimals = this.config.roundTemp ? 0 : 1;
return parseFloat(temperature).toFixed(decimals);
}
+
});
diff --git a/modules/default/currentweather/weather_screenshot.png b/modules/default/currentweather/weather_screenshot.png
new file mode 100644
index 00000000..2f6e5257
Binary files /dev/null and b/modules/default/currentweather/weather_screenshot.png differ
diff --git a/modules/default/defaultmodules.js b/modules/default/defaultmodules.js
index fccf3c52..656ba6b8 100644
--- a/modules/default/defaultmodules.js
+++ b/modules/default/defaultmodules.js
@@ -16,7 +16,8 @@ var defaultModules = [
"helloworld",
"newsfeed",
"weatherforecast",
- "updatenotification"
+ "updatenotification",
+ "weather"
];
/*************** DO NOT EDIT THE LINE BELOW ***************/
diff --git a/modules/default/helloworld/helloworld.js b/modules/default/helloworld/helloworld.js
index bdd5356b..cf6cebfa 100644
--- a/modules/default/helloworld/helloworld.js
+++ b/modules/default/helloworld/helloworld.js
@@ -14,10 +14,11 @@ Module.register("helloworld",{
text: "Hello World!"
},
- // Override dom generator.
- getDom: function() {
- var wrapper = document.createElement("div");
- wrapper.innerHTML = this.config.text;
- return wrapper;
+ getTemplate: function () {
+ return "helloworld.njk";
+ },
+
+ getTemplateData: function () {
+ return this.config;
}
});
diff --git a/modules/default/helloworld/helloworld.njk b/modules/default/helloworld/helloworld.njk
new file mode 100644
index 00000000..005ca28e
--- /dev/null
+++ b/modules/default/helloworld/helloworld.njk
@@ -0,0 +1,5 @@
+
+{{text | safe}}
diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md
index 7c4ad48d..c6c630e1 100644
--- a/modules/default/newsfeed/README.md
+++ b/modules/default/newsfeed/README.md
@@ -2,6 +2,10 @@
The `newsfeed ` module is one of the default modules of the MagicMirror.
This module displays news headlines based on an RSS feed. Scrolling through news headlines happens time-based (````updateInterval````), but can also be controlled by sending news feed specific notifications to the module.
+## Screenshot
+- News Feed Screenshot using the NYT
+
+
## Using the module
### Configuration
@@ -39,8 +43,18 @@ MagicMirror's [notification mechanism](https://github.com/MichMich/MagicMirror/t
| ----------------------- | -----------
| `ARTICLE_NEXT` | Shows the next news title (hiding the summary or previously fully displayed article)
| `ARTICLE_PREVIOUS` | Shows the previous news title (hiding the summary or previously fully displayed article)
-| `ARTICLE_MORE_DETAILS` | When received the _first time_, shows the corresponding description of the currently displayed news title.
The module expects that the module's configuration option `showDescription` is set to `false` (default value).
When received a _second consecutive time_, shows the full news article in an IFRAME.
This requires that the news page can be embedded in an IFRAME, e.g. doesn't have the HTTP response header [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) set to e.g. `DENY`.
+| `ARTICLE_MORE_DETAILS` | When received the _first time_, shows the corresponding description of the currently displayed news title.
The module expects that the module's configuration option `showDescription` is set to `false` (default value).
When received a _second consecutive time_, shows the full news article in an IFRAME.
This requires that the news page can be embedded in an IFRAME, e.g. doesn't have the HTTP response header [X-Frame-Options](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Frame-Options) set to e.g. `DENY`.
When received the _next consecutive times_, reloads the page and scrolls down by `scrollLength` pixels to paginate through the article.
| `ARTICLE_LESS_DETAILS` | Hides the summary or full news article and only displays the news title of the currently viewed news item.
+| `ARTICLE_TOGGLE_FULL` | Toggles article in fullscreen.
+| `ARTICLE_INFO_REQUEST` | Causes `newsfeed` to respond with the notification `ARTICLE_INFO_RESPONSE`, the payload of which provides the `title`, `source`, `date`, `desc` and `url` of the current news title.
+
+#### Notifications sent by the module
+MagicMirror's [notification mechanism](https://github.com/MichMich/MagicMirror/tree/master/modules#thissendnotificationnotification-payload) can also be used to send notifications from the current module to all other modules. The following notifications are broadcasted from this module:
+
+| Notification Identifier | Description
+| ----------------------- | -----------
+| `NEWS_FEED` | Broadcast the current list of news items.
+| `NEWS_FEED_UPDATE` | Broadcasts the list of updates news items.
Note the payload of the sent notification event is ignored.
@@ -57,25 +71,32 @@ The third party [MMM-Gestures](https://github.com/thobach/MMM-Gestures) module s
The following properties can be configured:
-| Option | Description
-| ----------------- | -----------
-| `feeds` | An array of feed urls that will be used as source.
More info about this object can be found below.
**Default value:** `[{ title: "New York Times", url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml", encoding: "UTF-8" }]`
-| `showSourceTitle` | Display the title of the source.
**Possible values:** `true` or `false`
**Default value:** `true`
-| `showPublishDate` | Display the publish date of an headline.
**Possible values:** `true` or `false`
**Default value:** `true`
-| `showDescription` | Display the description of an item.
**Possible values:** `true` or `false`
**Default value:** `false`
-| `wrapTitle` | Wrap the title of the item to multiple lines.
**Possible values:** `true` or `false`
**Default value:** `true`
-| `wrapDescription` | Wrap the description of the item to multiple lines.
**Possible values:** `true` or `false`
**Default value:** `true`
-| `hideLoading` | Hide module instead of showing LOADING status.
**Possible values:** `true` or `false`
**Default value:** `false`
-| `reloadInterval` | How often does the content needs to be fetched? (Milliseconds)
**Possible values:** `1000` - `86400000`
**Default value:** `300000` (5 minutes)
-| `updateInterval` | How often do you want to display a new headline? (Milliseconds)
**Possible values:**`1000` - `60000`
**Default value:** `10000` (10 seconds)
-| `animationSpeed` | Speed of the update animation. (Milliseconds)
**Possible values:**`0` - `5000`
**Default value:** `2500` (2.5 seconds)
-| `maxNewsItems` | Total amount of news items to cycle through. (0 for unlimited)
**Possible values:**`0` - `...`
**Default value:** `0`
-| `ignoreOldItems` | Ignore news items that are outdated.
**Possible values:**`true` or `false
**Default value:** `false`
-| `ignoreOlderThan` | How old should news items be before they are considered outdated? (Milliseconds)
**Possible values:**`1` - `...`
**Default value:** `86400000` (1 day)
-| `removeStartTags` | Some newsfeeds feature tags at the **beginning** of their titles or descriptions, such as _[VIDEO]_. This setting allows for the removal of specified tags from the beginning of an item's description and/or title.
**Possible values:**`'title'`, `'description'`, `'both'`
-| `startTags` | List the tags you would like to have removed at the beginning of the feed item
**Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
-| `removeEndTags` | Remove specified tags from the **end** of an item's description and/or title.
**Possible values:**`'title'`, `'description'`, `'both'`
-| `endTags` | List the tags you would like to have removed at the end of the feed item
**Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
+| Option | Description
+| ------------------ | -----------
+| `feeds` | An array of feed urls that will be used as source.
More info about this object can be found below.
**Default value:** `[{ title: "New York Times", url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml", encoding: "UTF-8" }]`
You can add `reloadInterval` option to set particular reloadInterval to a feed.
+| `showSourceTitle` | Display the title of the source.
**Possible values:** `true` or `false`
**Default value:** `true`
+| `showPublishDate` | Display the publish date of an headline.
**Possible values:** `true` or `false`
**Default value:** `true`
+| `broadcastNewsFeeds` | Gives the ability to broadcast news feeds to all modules, by using ```sendNotification()``` when set to `true`, rather than ```sendSocketNotification()``` when `false`
**Possible values:** `true` or `false`
**Default value:** `true`
+| `broadcastNewsUpdates` | Gives the ability to broadcast news feed updates to all modules
**Possible values:** `true` or `false`
**Default value:** `true`
+| `showDescription` | Display the description of an item.
**Possible values:** `true` or `false`
**Default value:** `false`
+| `wrapTitle` | Wrap the title of the item to multiple lines.
**Possible values:** `true` or `false`
**Default value:** `true`
+| `wrapDescription` | Wrap the description of the item to multiple lines.
**Possible values:** `true` or `false`
**Default value:** `true`
+| `truncDescription` | Truncate description?
**Possible values:** `true` or `false`
**Default value:** `true`
+| `lengthDescription`| How many characters to be displayed for a truncated description?
**Possible values:** `1` - `500`
**Default value:** `400`
+| `hideLoading` | Hide module instead of showing LOADING status.
**Possible values:** `true` or `false`
**Default value:** `false`
+| `reloadInterval` | How often does the content needs to be fetched? (Milliseconds)
**Possible values:** `1000` - `86400000`
**Default value:** `300000` (5 minutes)
+| `updateInterval` | How often do you want to display a new headline? (Milliseconds)
**Possible values:**`1000` - `60000`
**Default value:** `10000` (10 seconds)
+| `animationSpeed` | Speed of the update animation. (Milliseconds)
**Possible values:**`0` - `5000`
**Default value:** `2500` (2.5 seconds)
+| `maxNewsItems` | Total amount of news items to cycle through. (0 for unlimited)
**Possible values:**`0` - `...`
**Default value:** `0`
+| `ignoreOldItems` | Ignore news items that are outdated.
**Possible values:**`true` or `false`
**Default value:** `false`
+| `ignoreOlderThan` | How old should news items be before they are considered outdated? (Milliseconds)
**Possible values:**`1` - `...`
**Default value:** `86400000` (1 day)
+| `removeStartTags` | Some news feeds feature tags at the **beginning** of their titles or descriptions, such as _[VIDEO]_. This setting allows for the removal of specified tags from the beginning of an item's description and/or title.
**Possible values:**`'title'`, `'description'`, `'both'`
+| `startTags` | List the tags you would like to have removed at the beginning of the feed item
**Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
+| `removeEndTags` | Remove specified tags from the **end** of an item's description and/or title.
**Possible values:**`'title'`, `'description'`, `'both'`
+| `endTags` | List the tags you would like to have removed at the end of the feed item
**Possible values:** `['TAG']` or `['TAG1','TAG2',...]`
+| `prohibitedWords` | Remove news feed item if one of these words is found anywhere in the title (case insensitive and greedy matching)
**Possible values:** `['word']` or `['word1','word2',...]`
+| `scrollLength` | Scrolls the full news article page by a given number of pixels when a `ARTICLE_MORE_DETAILS` notification is received and the full news article is already displayed.
**Possible values:** `1` or `10000`
**Default value:** `500`
+| `logFeedWarnings` | Log warnings when there is an error parsing a news article.
**Possible values:** `true` or `false`
**Default value:** `false`
The `feeds` property contains an array with multiple objects. These objects have the following properties:
diff --git a/modules/default/newsfeed/fetcher.js b/modules/default/newsfeed/fetcher.js
index f4fb44d9..4e3bcca7 100644
--- a/modules/default/newsfeed/fetcher.js
+++ b/modules/default/newsfeed/fetcher.js
@@ -14,9 +14,10 @@ var iconv = require("iconv-lite");
*
* attribute url string - URL of the news feed.
* attribute reloadInterval number - Reload interval in milliseconds.
+ * attribute logFeedWarnings boolean - Log warnings when there is an error parsing a news article.
*/
-var Fetcher = function(url, reloadInterval, encoding) {
+var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) {
var self = this;
if (reloadInterval < 1000) {
reloadInterval = 1000;
@@ -45,13 +46,13 @@ var Fetcher = function(url, reloadInterval, encoding) {
var title = item.title;
var description = item.description || item.summary || item.content || "";
- var pubdate = item.pubdate || item.published || item.updated;
+ var pubdate = item.pubdate || item.published || item.updated || item["dc:date"];
var url = item.url || item.link || "";
if (title && pubdate) {
var regex = /(<([^>]+)>)/ig;
- description = description.replace(regex, "");
+ description = description.toString().replace(regex, "");
items.push({
title: title,
@@ -60,18 +61,17 @@ var Fetcher = function(url, reloadInterval, encoding) {
url: url,
});
- } else {
-
- // console.log("Can't parse feed item:");
- // console.log(item);
- // console.log('Title: ' + title);
- // console.log('Description: ' + description);
- // console.log('Pubdate: ' + pubdate);
-
+ } else if (logFeedWarnings) {
+ console.log("Can't parse feed item:");
+ console.log(item);
+ console.log("Title: " + title);
+ console.log("Description: " + description);
+ console.log("Pubdate: " + pubdate);
}
});
- parser.on("end", function() {
+ parser.on("end", function() {
+ //console.log("end parsing - " + url);
self.broadcastItems();
scheduleTimer();
});
@@ -81,9 +81,10 @@ var Fetcher = function(url, reloadInterval, encoding) {
scheduleTimer();
});
-
nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]);
- headers = {"User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)"}
+ headers = {"User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)",
+ "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate",
+ "Pragma": "no-cache"};
request({uri: url, encoding: null, headers: headers})
.on("error", function(error) {
diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js
index b230fdb1..d358110c 100644
--- a/modules/default/newsfeed/newsfeed.js
+++ b/modules/default/newsfeed/newsfeed.js
@@ -20,11 +20,15 @@ Module.register("newsfeed",{
],
showSourceTitle: true,
showPublishDate: true,
+ broadcastNewsFeeds: true,
+ broadcastNewsUpdates: true,
showDescription: false,
wrapTitle: true,
wrapDescription: true,
+ truncDescription: true,
+ lengthDescription: 400,
hideLoading: false,
- reloadInterval: 5 * 60 * 1000, // every 5 minutes
+ reloadInterval: 5 * 60 * 1000, // every 5 minutes
updateInterval: 10 * 1000,
animationSpeed: 2.5 * 1000,
maxNewsItems: 0, // 0 for unlimited
@@ -33,8 +37,10 @@ Module.register("newsfeed",{
removeStartTags: "",
removeEndTags: "",
startTags: [],
- endTags: []
-
+ endTags: [],
+ prohibitedWords: [],
+ scrollLength: 500,
+ logFeedWarnings: false
},
// Define required scripts.
@@ -60,9 +66,11 @@ Module.register("newsfeed",{
this.newsItems = [];
this.loaded = false;
this.activeItem = 0;
+ this.scrollPosition = 0;
this.registerFeeds();
+ this.isShowingDescription = this.config.showDescription;
},
// Override socket notification handler.
@@ -84,7 +92,7 @@ Module.register("newsfeed",{
if (this.config.feedUrl) {
wrapper.className = "small bright";
- wrapper.innerHTML = "The configuration options for the newsfeed module have changed.
Please check the documentation.";
+ wrapper.innerHTML = this.translate("configuration_changed");
return wrapper;
}
@@ -97,7 +105,7 @@ Module.register("newsfeed",{
// this.config.showFullArticle is a run-time configuration, triggered by optional notifications
if (!this.config.showFullArticle && (this.config.showSourceTitle || this.config.showPublishDate)) {
var sourceAndTimestamp = document.createElement("div");
- sourceAndTimestamp.className = "light small dimmed";
+ sourceAndTimestamp.className = "newsfeed-source light small dimmed";
if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== "") {
sourceAndTimestamp.innerHTML = this.newsItems[this.activeItem].sourceTitle;
@@ -117,22 +125,22 @@ Module.register("newsfeed",{
//Remove selected tags from the beginning of rss feed items (title or description)
- if (this.config.removeStartTags == "title" || this.config.removeStartTags == "both") {
+ if (this.config.removeStartTags === "title" || this.config.removeStartTags === "both") {
for (f=0; f this.config.lengthDescription ? txtDesc.substring(0, this.config.lengthDescription) + "..." : txtDesc) : txtDesc);
wrapper.appendChild(description);
}
if (this.config.showFullArticle) {
var fullArticle = document.createElement("iframe");
fullArticle.className = "";
- fullArticle.style.width = "100%";
+ fullArticle.style.width = "100vw";
+ // very large height value to allow scrolling
+ fullArticle.height = "3000";
+ fullArticle.style.height = "3000";
fullArticle.style.top = "0";
fullArticle.style.left = "0";
- fullArticle.style.position = "fixed";
- fullArticle.height = window.innerHeight;
fullArticle.style.border = "none";
- fullArticle.src = this.newsItems[this.activeItem].url;
+ fullArticle.src = this.getActiveItemURL();
+ fullArticle.style.zIndex = 1;
wrapper.appendChild(fullArticle);
}
@@ -201,6 +212,10 @@ Module.register("newsfeed",{
return wrapper;
},
+ getActiveItemURL: function() {
+ return typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href;
+ },
+
/* registerFeeds()
* registers the feeds to be used by the backend.
*/
@@ -241,6 +256,32 @@ Module.register("newsfeed",{
if(this.config.maxNewsItems > 0) {
newsItems = newsItems.slice(0, this.config.maxNewsItems);
}
+
+ if(this.config.prohibitedWords.length > 0) {
+ newsItems = newsItems.filter(function(value){
+ for (var i=0; i < this.config.prohibitedWords.length; i++) {
+ if (value["title"].toLowerCase().indexOf(this.config.prohibitedWords[i].toLowerCase()) > -1) {
+ return false;
+ }
+ }
+ return true;
+ }, this);
+ }
+
+ // get updated news items and broadcast them
+ var updatedItems = [];
+ newsItems.forEach(value => {
+ if (this.newsItems.findIndex(value1 => value1 === value) === -1) {
+ // Add item to updated items list
+ updatedItems.push(value);
+ }
+ });
+
+ // check if updated items exist, if so and if we should broadcast these updates, then lets do so
+ if (this.config.broadcastNewsUpdates && updatedItems.length > 0) {
+ this.sendNotification("NEWS_FEED_UPDATE", {items: updatedItems});
+ }
+
this.newsItems = newsItems;
},
@@ -286,9 +327,19 @@ Module.register("newsfeed",{
self.updateDom(self.config.animationSpeed);
+ // Broadcast NewsFeed if needed
+ if (self.config.broadcastNewsFeeds) {
+ self.sendNotification("NEWS_FEED", {items: self.newsItems});
+ }
+
timer = setInterval(function() {
self.activeItem++;
self.updateDom(self.config.animationSpeed);
+
+ // Broadcast NewsFeed if needed
+ if (self.config.broadcastNewsFeeds) {
+ self.sendNotification("NEWS_FEED", {items: self.newsItems});
+ }
}, this.config.updateInterval);
},
@@ -304,8 +355,12 @@ Module.register("newsfeed",{
},
resetDescrOrFullArticleAndTimer: function() {
- this.config.showDescription = false;
+ this.isShowingDescription = this.config.showDescription;
this.config.showFullArticle = false;
+ this.scrollPosition = 0;
+ // reset bottom bar alignment
+ document.getElementsByClassName("region bottom bar")[0].style.bottom = "0";
+ document.getElementsByClassName("region bottom bar")[0].style.top = "inherit";
if(!timer){
this.scheduleUpdateInterval();
}
@@ -313,7 +368,7 @@ Module.register("newsfeed",{
notificationReceived: function(notification, payload, sender) {
Log.info(this.name + " - received notification: " + notification);
- if(notification == "ARTICLE_NEXT"){
+ if(notification === "ARTICLE_NEXT"){
var before = this.activeItem;
this.activeItem++;
if (this.activeItem >= this.newsItems.length) {
@@ -322,7 +377,7 @@ Module.register("newsfeed",{
this.resetDescrOrFullArticleAndTimer();
Log.info(this.name + " - going from article #" + before + " to #" + this.activeItem + " (of " + this.newsItems.length + ")");
this.updateDom(100);
- } else if(notification == "ARTICLE_PREVIOUS"){
+ } else if(notification === "ARTICLE_PREVIOUS"){
var before = this.activeItem;
this.activeItem--;
if (this.activeItem < 0) {
@@ -333,20 +388,60 @@ Module.register("newsfeed",{
this.updateDom(100);
}
// if "more details" is received the first time: show article summary, on second time show full article
- else if(notification == "ARTICLE_MORE_DETAILS"){
- this.config.showDescription = !this.config.showDescription;
- this.config.showFullArticle = !this.config.showDescription;
- clearInterval(timer);
- timer = null;
- Log.info(this.name + " - showing " + this.config.showDescription ? "article description" : "full article");
- this.updateDom(100);
- } else if(notification == "ARTICLE_LESS_DETAILS"){
+ else if(notification === "ARTICLE_MORE_DETAILS"){
+ // full article is already showing, so scrolling down
+ if(this.config.showFullArticle === true){
+ this.scrollPosition += this.config.scrollLength;
+ window.scrollTo(0, this.scrollPosition);
+ Log.info(this.name + " - scrolling down");
+ Log.info(this.name + " - ARTICLE_MORE_DETAILS, scroll position: " + this.config.scrollLength);
+ }
+ else {
+ this.showFullArticle();
+ }
+ } else if(notification === "ARTICLE_SCROLL_UP"){
+ if(this.config.showFullArticle === true){
+ this.scrollPosition -= this.config.scrollLength;
+ window.scrollTo(0, this.scrollPosition);
+ Log.info(this.name + " - scrolling up");
+ Log.info(this.name + " - ARTICLE_SCROLL_UP, scroll position: " + this.config.scrollLength);
+ }
+ } else if(notification === "ARTICLE_LESS_DETAILS"){
this.resetDescrOrFullArticleAndTimer();
Log.info(this.name + " - showing only article titles again");
this.updateDom(100);
+ } else if (notification === "ARTICLE_TOGGLE_FULL"){
+ if (this.config.showFullArticle){
+ this.activeItem++;
+ this.resetDescrOrFullArticleAndTimer();
+ } else {
+ this.showFullArticle();
+ }
+ } else if (notification === "ARTICLE_INFO_REQUEST"){
+ this.sendNotification("ARTICLE_INFO_RESPONSE", {
+ title: this.newsItems[this.activeItem].title,
+ source: this.newsItems[this.activeItem].sourceTitle,
+ date: this.newsItems[this.activeItem].pubdate,
+ desc: this.newsItems[this.activeItem].description,
+ url: this.getActiveItemURL()
+ });
} else {
Log.info(this.name + " - unknown notification, ignoring: " + notification);
}
},
+ showFullArticle: function() {
+ this.isShowingDescription = !this.isShowingDescription;
+ this.config.showFullArticle = !this.isShowingDescription;
+ // make bottom bar align to top to allow scrolling
+ if(this.config.showFullArticle === true){
+ document.getElementsByClassName("region bottom bar")[0].style.bottom = "inherit";
+ document.getElementsByClassName("region bottom bar")[0].style.top = "-90px";
+ }
+ clearInterval(timer);
+ timer = null;
+ Log.info(this.name + " - showing " + this.isShowingDescription ? "article description" : "full article");
+ this.updateDom(100);
+ }
+
});
diff --git a/modules/default/newsfeed/newsfeed_screenshot.png b/modules/default/newsfeed/newsfeed_screenshot.png
new file mode 100644
index 00000000..f4391e7d
Binary files /dev/null and b/modules/default/newsfeed/newsfeed_screenshot.png differ
diff --git a/modules/default/newsfeed/node_helper.js b/modules/default/newsfeed/node_helper.js
index af1d32b8..79c4d2fa 100644
--- a/modules/default/newsfeed/node_helper.js
+++ b/modules/default/newsfeed/node_helper.js
@@ -36,7 +36,7 @@ module.exports = NodeHelper.create({
var url = feed.url || "";
var encoding = feed.encoding || "UTF-8";
- var reloadInterval = config.reloadInterval || 5 * 60 * 1000;
+ var reloadInterval = feed.reloadInterval || config.reloadInterval || 5 * 60 * 1000;
if (!validUrl.isUri(url)) {
self.sendSocketNotification("INCORRECT_URL", url);
@@ -46,7 +46,7 @@ module.exports = NodeHelper.create({
var fetcher;
if (typeof self.fetchers[url] === "undefined") {
console.log("Create new news fetcher for url: " + url + " - Interval: " + reloadInterval);
- fetcher = new Fetcher(url, reloadInterval, encoding);
+ fetcher = new Fetcher(url, reloadInterval, encoding, config.logFeedWarnings);
fetcher.onReceive(function(fetcher) {
self.broadcastFeeds();
diff --git a/modules/default/newsfeed/translations/de.json b/modules/default/newsfeed/translations/de.json
new file mode 100644
index 00000000..9ec3ef7b
--- /dev/null
+++ b/modules/default/newsfeed/translations/de.json
@@ -0,0 +1,3 @@
+{
+ "configuration_changed": "Die Konfigurationsoptionen für das Newsfeed-Modul haben sich geändert. \nBitte überprüfen Sie die Dokumentation."
+}
\ No newline at end of file
diff --git a/modules/default/newsfeed/translations/en.json b/modules/default/newsfeed/translations/en.json
new file mode 100644
index 00000000..23b6100d
--- /dev/null
+++ b/modules/default/newsfeed/translations/en.json
@@ -0,0 +1,3 @@
+{
+ "configuration_changed": "The configuration options for the newsfeed module have changed.\nPlease check the documentation."
+}
\ No newline at end of file
diff --git a/modules/default/newsfeed/translations/es.json b/modules/default/newsfeed/translations/es.json
new file mode 100644
index 00000000..6143f68c
--- /dev/null
+++ b/modules/default/newsfeed/translations/es.json
@@ -0,0 +1,3 @@
+{
+ "configuration_changed": "Las opciones de configuración para el módulo de suministro de noticias han cambiado. \nVerifique la documentación."
+}
\ No newline at end of file
diff --git a/modules/default/newsfeed/translations/fr.json b/modules/default/newsfeed/translations/fr.json
new file mode 100644
index 00000000..85c6b412
--- /dev/null
+++ b/modules/default/newsfeed/translations/fr.json
@@ -0,0 +1,3 @@
+{
+ "configuration_changed": "Les options de configuration du module newsfeed ont changé. \nVeuillez consulter la documentation."
+}
\ No newline at end of file
diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js
index 6196552f..1f9d2f4d 100644
--- a/modules/default/updatenotification/node_helper.js
+++ b/modules/default/updatenotification/node_helper.js
@@ -10,11 +10,17 @@ module.exports = NodeHelper.create({
config: {},
updateTimer: null,
+ updateProcessStarted: false,
start: function () {
},
configureModules: function(modules) {
+
+ // Push MagicMirror itself , biggest chance it'll show up last in UI and isn't overwritten
+ // others will be added in front, asynchronously
+ simpleGits.push({"module": "default", "git": SimpleGit(path.normalize(__dirname + "/../../../"))});
+
for (moduleName in modules) {
if (defaultModules.indexOf(moduleName) < 0) {
// Default modules are included in the main MagicMirror repo
@@ -22,6 +28,7 @@ module.exports = NodeHelper.create({
var stat;
try {
+ //console.log("checking git for module="+moduleName)
stat = fs.statSync(path.join(moduleFolder, ".git"));
} catch(err) {
// Error when directory .git doesn't exist
@@ -36,35 +43,39 @@ module.exports = NodeHelper.create({
// No valid remote for folder, skip
return;
}
-
// Folder has .git and has at least one git remote, watch this folder
- simpleGits.push({"module": mn, "git": git});
+ simpleGits.unshift({"module": mn, "git": git});
});
}(moduleName, moduleFolder);
}
}
-
- // Push MagicMirror itself last, biggest chance it'll show up last in UI and isn't overwritten
- simpleGits.push({"module": "default", "git": SimpleGit(path.normalize(__dirname + "/../../../"))});
},
socketNotificationReceived: function (notification, payload) {
if (notification === "CONFIG") {
this.config = payload;
} else if(notification === "MODULES") {
- this.configureModules(payload);
- this.preformFetch();
+ // if this is the 1st time thru the update check process
+ if(this.updateProcessStarted==false ){
+ this.updateProcessStarted=true;
+ this.configureModules(payload);
+ this.preformFetch();
+ }
}
},
preformFetch() {
var self = this;
-
simpleGits.forEach(function(sg) {
sg.git.fetch().status(function(err, data) {
data.module = sg.module;
if (!err) {
- self.sendSocketNotification("STATUS", data);
+ sg.git.log({"-1": null}, function(err, data2) {
+ if (!err && data2.latest && "hash" in data2.latest) {
+ data.hash = data2.latest.hash;
+ self.sendSocketNotification("STATUS", data);
+ }
+ });
}
});
});
@@ -74,7 +85,7 @@ module.exports = NodeHelper.create({
scheduleNextFetch: function(delay) {
if (delay < 60 * 1000) {
- delay = 60 * 1000
+ delay = 60 * 1000;
}
var self = this;
diff --git a/modules/default/updatenotification/updatenotification.js b/modules/default/updatenotification/updatenotification.js
index f663f593..58c3995c 100644
--- a/modules/default/updatenotification/updatenotification.js
+++ b/modules/default/updatenotification/updatenotification.js
@@ -2,69 +2,114 @@ Module.register("updatenotification", {
defaults: {
updateInterval: 10 * 60 * 1000, // every 10 minutes
+ refreshInterval: 24 * 60 * 60 * 1000, // one day
},
- status: false,
+ suspended: false,
+ moduleList: {},
start: function () {
+ var self = this;
Log.log("Start updatenotification");
-
+ setInterval( () => { self.moduleList = {};self.updateDom(2) } , self.config.refreshInterval)
},
- notificationReceived: function(notification, payload, sender) {
+ notificationReceived: function (notification, payload, sender) {
if (notification === "DOM_OBJECTS_CREATED") {
this.sendSocketNotification("CONFIG", this.config);
this.sendSocketNotification("MODULES", Module.definitions);
- this.hide(0,{lockString: self.identifier});
+ //this.hide(0, { lockString: self.identifier });
}
},
socketNotificationReceived: function (notification, payload) {
if (notification === "STATUS") {
- this.status = payload;
- this.updateUI();
+ this.updateUI(payload);
}
},
- updateUI: function() {
+ updateUI: function (payload) {
var self = this;
- if (this.status && this.status.behind > 0) {
- self.updateDom(0);
- self.show(1000, {lockString: self.identifier});
- }
+ if (payload && payload.behind > 0) {
+ // if we haven't seen info for this module
+ if(this.moduleList[payload.module] == undefined){
+ // save it
+ this.moduleList[payload.module]=payload;
+ self.updateDom(2);
+ }
+ //self.show(1000, { lockString: self.identifier });
+
+ } else if (payload && payload.behind == 0){
+ // if the module WAS in the list, but shouldn't be
+ if(this.moduleList[payload.module] != undefined){
+ // remove it
+ delete this.moduleList[payload.module]
+ self.updateDom(2);
+ }
+ }
+ },
+
+ diffLink: function(module, text) {
+ var localRef = module.hash;
+ var remoteRef = module.tracking.replace(/.*\//, "");
+ return "" +
+ text +
+ "";
},
// Override dom generator.
getDom: function () {
var wrapper = document.createElement("div");
+ if(this.suspended==false){
+ // process the hash of module info found
+ for(key of Object.keys(this.moduleList)){
+ let m= this.moduleList[key]
- if (this.status && this.status.behind > 0) {
- var message = document.createElement("div");
- message.className = "small bright";
+ var message = document.createElement("div");
+ message.className = "small bright";
- var icon = document.createElement("i");
- icon.className = "fa fa-exclamation-circle";
- icon.innerHTML = " ";
- message.appendChild(icon);
+ var icon = document.createElement("i");
+ icon.className = "fa fa-exclamation-circle";
+ icon.innerHTML = " ";
+ message.appendChild(icon);
- var text = document.createElement("span");
- if (this.status.module == "default") {
- text.innerHTML = this.translate("UPDATE_NOTIFICATION");
- } else {
- text.innerHTML = this.translate("UPDATE_NOTIFICATION_MODULE").replace("MODULE_NAME", this.status.module);
+ var updateInfoKeyName = m.behind == 1 ? "UPDATE_INFO_SINGLE" : "UPDATE_INFO_MULTIPLE";
+
+ var subtextHtml = this.translate(updateInfoKeyName, {
+ COMMIT_COUNT: m.behind,
+ BRANCH_NAME: m.current
+ });
+
+ var text = document.createElement("span");
+ if (m.module == "default") {
+ text.innerHTML = this.translate("UPDATE_NOTIFICATION");
+ subtextHtml = this.diffLink(m,subtextHtml);
+ } else {
+ text.innerHTML = this.translate("UPDATE_NOTIFICATION_MODULE", {
+ MODULE_NAME: m.module
+ });
+ }
+ message.appendChild(text);
+
+ wrapper.appendChild(message);
+
+ var subtext = document.createElement("div");
+ subtext.innerHTML = subtextHtml;
+ subtext.className = "xsmall dimmed";
+ wrapper.appendChild(subtext);
}
- message.appendChild(text);
-
- wrapper.appendChild(message);
-
- var subtext = document.createElement("div");
- subtext.innerHTML = this.translate("UPDATE_INFO")
- .replace("COMMIT_COUNT", this.status.behind + " " + ((this.status.behind == 1)? "commit" : "commits"))
- .replace("BRANCH_NAME", this.status.current);
- subtext.className = "xsmall dimmed";
- wrapper.appendChild(subtext);
}
-
return wrapper;
+ },
+
+ suspend: function() {
+ this.suspended=true;
+ },
+ resume: function() {
+ this.suspended=false;
+ this.updateDom(2);
}
});
diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md
new file mode 100755
index 00000000..3e6905a7
--- /dev/null
+++ b/modules/default/weather/README.md
@@ -0,0 +1,120 @@
+# Weather Module
+
+This module is aimed to be the replacement for the current `currentweather` and `weatherforcast` modules. The module will be configurable to be used as a current weather view, or to show the forecast. This way the module can be used twice to fullfil both purposes.
+
+The biggest change is the use of weather providers. This way we are not bound to one API source. And users can choose which API they want to use as their source.
+
+The module is in a very early stage, and needs a lot of work. It's API isn't set in stone, so keep that in mind when you want to contribute.
+
+## Example
+
+ 
+
+## Usage
+
+To use this module, add it to the modules array in the `config/config.js` file:
+
+````javascript
+modules: [
+ {
+ module: "weather",
+ position: "top_right",
+ config: {
+ // See 'Configuration options' for more information.
+ type: 'current'
+ }
+ }
+]
+````
+
+## Configuration options
+
+The following properties can be configured:
+
+### General options
+
+| Option | Description
+| ---------------------------- | -----------
+| `weatherProvider` | Which weather provider should be used.
**Possible values:** `openweathermap` , `darksky` , `weathergov` or `ukmetoffice`
**Default value:** `openweathermap`
+| `type` | Which type of weather data should be displayed.
**Possible values:** `current` or `forecast`
**Default value:** `current`
+| `units` | What units to use. Specified by config.js
**Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit
**Default value:** `config.units`
+| `tempUnits` | What units to use for temperature. If specified overrides `units` setting. Specified by config.js
**Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit
**Default value:** `units`
+| `windUnits` | What units to use for wind speed. If specified overrides `units` setting. Specified by config.js
**Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` = Fahrenheit
**Default value:** `units`
+| `roundTemp` | Round temperature value to nearest integer.
**Possible values:** `true` (round to integer) or `false` (display exact value with decimal point)
**Default value:** `false`
+| `degreeLabel` | Show the degree label for your chosen units (Metric = C, Imperial = F, Kelvin = K).
**Possible values:** `true` or `false`
**Default value:** `false`
+| `updateInterval` | How often does the content needs to be fetched? (Milliseconds)
**Possible values:** `1000` - `86400000`
**Default value:** `600000` (10 minutes)
+| `animationSpeed` | Speed of the update animation. (Milliseconds)
**Possible values:** `0` - `5000`
**Default value:** `1000` (1 second)
+| `timeFormat` | Use 12 or 24 hour format.
**Possible values:** `12` or `24`
**Default value:** uses value of _config.timeFormat_
+| `showPeriod` | Show the period (am/pm) with 12 hour format
**Possible values:** `true` or `false`
**Default value:** `true`
+| `showPeriodUpper` | Show the period (AM/PM) with 12 hour format as uppercase
**Possible values:** `true` or `false`
**Default value:** `false`
+| `lang` | The language of the days.
**Possible values:** `en`, `nl`, `ru`, etc ...
**Default value:** uses value of _config.language_
+| `decimalSymbol` | The decimal symbol to use.
**Possible values:** `.`, `,` or any other symbol.
**Default value:** `.`
+| `initialLoadDelay` | The initial delay before loading. If you have multiple modules that use the same API key, you might want to delay one of the requests. (Milliseconds)
**Possible values:** `1000` - `5000`
**Default value:** `0`
+| `appendLocationNameToHeader` | If set to `true`, the returned location name will be appended to the header of the module, if the header is enabled. This is mainly interesting when using calender based weather.
**Default value:** `true`
+| `calendarClass` | The class for the calender module to base the event based weather information on.
**Default value:** `'calendar'`
+
+#### Current weather options
+
+| Option | Description
+| ---------------------------- | -----------
+| `onlyTemp` | Show only current Temperature and weather icon without windspeed, sunset, sunrise time and feels like.
**Possible values:** `true` or `false`
**Default value:** `false`
+| `useBeaufort` | Pick between using the Beaufort scale for wind speed or using the default units.
**Possible values:** `true` or `false`
**Default value:** `true`
+| `showWindDirection` | Show the wind direction next to the wind speed.
**Possible values:** `true` or `false`
**Default value:** `true`
+| `showWindDirectionAsArrow` | Show the wind direction as an arrow instead of abbreviation
**Possible values:** `true` or `false`
**Default value:** `false`
+| `showHumidity` | Show the current humidity
**Possible values:** `true` or `false`
**Default value:** `false`
+| `showIndoorTemperature` | If you have another module that emits the `INDOOR_TEMPERATURE` notification, the indoor temperature will be displayed
**Default value:** `false`
+| `showIndoorHumidity` | If you have another module that emits the `INDOOR_HUMIDITY` notification, the indoor humidity will be displayed
**Default value:** `false`
+| `showFeelsLike` | Shows the Feels like temperature weather.
**Possible values:** `true` or `false`
**Default value:** `true`
+
+#### Weather forecast options
+
+| Option | Description
+| ---------------------------- | -----------
+| `tableClass` | The class for the forecast table.
**Default value:** `'small'`
+| `colored` | If set to `true`, the min and max temperature are color coded.
**Default value:** `false`
+| `showPrecipitationAmount` | Show the amount of rain/snow in the forecast
**Possible values:** `true` or `false`
**Default value:** `false`
+| `fade` | Fade the future events to black. (Gradient)
**Possible values:** `true` or `false`
**Default value:** `true`
+| `fadePoint` | Where to start fade?
**Possible values:** `0` (top of the list) - `1` (bottom of list)
**Default value:** `0.25`
+| `maxNumberOfDays` | How many days of forecast to return. Specified by config.js
**Possible values:** `1` - `16`
**Default value:** `5` (5 days)
This value is optional. By default the weatherforecast module will return 5 days.
+
+### Openweathermap options
+
+| Option | Description
+| ---------------------------- | -----------
+| `apiVersion` | The OpenWeatherMap API version to use.
**Default value:** `2.5`
+| `apiBase` | The OpenWeatherMap base URL.
**Default value:** `'http://api.openweathermap.org/data/'`
+| `weatherEndpoint` | The OpenWeatherMap API endPoint.
**Possible values:** `/weather`, `/forecast` (free users) or `/forecast/daily` (paying users or old apiKey only)
**Default value:** `'/weather'`
+| `locationID` | Location ID from [OpenWeatherMap](https://openweathermap.org/find) **This will override anything you put in location.**
Leave blank if you want to use location.
**Example:** `1234567`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
+| `location` | The location used for weather information.
**Example:** `'Amsterdam,Netherlands'`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
+| `apiKey` | The [OpenWeatherMap](https://home.openweathermap.org) API key, which can be obtained by creating an OpenWeatherMap account.
This value is **REQUIRED**
+
+### Darksky options
+
+| Option | Description
+| ---------------------------- | -----------
+| `apiBase` | The DarkSky base URL. The darksky api has disabled [cors](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS), therefore a proxy is required.
**Possible value:** `'https://cors-anywhere.herokuapp.com/https://api.darksky.net'`
This value is **REQUIRED**
+| `weatherEndpoint` | The DarkSky API endPoint.
**Possible values:** `/forecast`
This value is **REQUIRED**
+| `apiKey` | The [DarkSky](https://darksky.net/dev/register) API key, which can be obtained by creating an DarkSky account.
This value is **REQUIRED**
+| `lat` | The geo coordinate latitude.
This value is **REQUIRED**
+| `lon` | The geo coordinate longitude.
This value is **REQUIRED**
+
+### Weather.gov options
+
+| Option | Description
+| ---------------------------- | -----------
+| `apiBase` | The weather.gov base URL.
**Possible value:** `'https://api.weather.gov/points/'`
This value is **REQUIRED**
+| `weatherEndpoint` | The weather.gov API endPoint.
**Possible values:** `/forecast` for forecast and `/forecast/hourly` for current.
This value is **REQUIRED**
+| `lat` | The geo coordinate latitude.
This value is **REQUIRED**
+| `lon` | The geo coordinate longitude.
This value is **REQUIRED**
+
+### UK Met Office options
+
+| Option | Description
+| ---------------------------- | -----------
+| `apiBase` | The UKMO base URL.
**Possible value:** `'http://datapoint.metoffice.gov.uk/public/data/val/wxfcs/all/json/'`
This value is **REQUIRED**
+| `locationId` | The UKMO API location code.
**Possible values:** `322942`
This value is **REQUIRED**
+| `apiKey` | The [UK Met Office](https://www.metoffice.gov.uk/datapoint/getting-started) API key, which can be obtained by creating an UKMO Datapoint account.
This value is **REQUIRED**
+
+## API Provider Development
+
+If you want to add another API provider checkout the [Guide](providers).
diff --git a/modules/default/weather/current.njk b/modules/default/weather/current.njk
new file mode 100755
index 00000000..33dac07a
--- /dev/null
+++ b/modules/default/weather/current.njk
@@ -0,0 +1,80 @@
+{% if current %}
+ {% if not config.onlyTemp %}
+
+
+
+ {% if config.useBeaufort %}
+ {{ current.beaufortWindSpeed() | round }}
+ {% else %}
+ {{ current.windSpeed | round }}
+ {% endif %}
+ {% if config.showWindDirection %}
+
+ {% if config.showWindDirectionAsArrow %}
+
+ {% else %}
+ {{ current.cardinalWindDirection() | translate }}
+ {% endif %}
+
+
+ {% endif %}
+
+ {% if config.showHumidity and current.humidity %}
+ {{ current.humidity | decimalSymbol }}
+ {% endif %}
+
+
+ {% if current.nextSunAction() === "sunset" %}
+ {{ current.sunset | formatTime }}
+ {% else %}
+ {{ current.sunrise | formatTime }}
+ {% endif %}
+
+
+ {% endif %}
+
+
+
+ {{ current.temperature | roundValue | unit("temperature") | decimalSymbol }}
+
+
+
+ {% if config.showIndoorTemperature and indoor.temperature %}
+
+
+
+ {{ indoor.temperature | roundValue | unit("temperature") | decimalSymbol }}
+
+
+ {% endif %}
+ {% if config.showIndoorHumidity and indoor.humidity %}
+
+
+
+ {{ indoor.humidity | roundValue | unit("humidity") | decimalSymbol }}
+
+
+ {% endif %}
+
+ {% if (config.showFeelsLike or config.showPrecipitationAmount) and not config.onlyTemp %}
+
+ {% if config.showFeelsLike %}
+
+ {{ "FEELS" | translate }} {{ current.feelsLike() | roundValue | unit("temperature") | decimalSymbol }}
+
+ {% endif %}
+ {% if config.showPrecipitationAmount %}
+
+ {{ "PRECIP" | translate }} {{ current.precipitation | unit("precip") }}
+
+ {% endif %}
+
+ {% endif %}
+{% else %}
+
+ {{ "LOADING" | translate | safe }}
+
+{% endif %}
+
+
+
diff --git a/modules/default/weather/current.png b/modules/default/weather/current.png
new file mode 100644
index 00000000..de6c5a39
Binary files /dev/null and b/modules/default/weather/current.png differ
diff --git a/modules/default/weather/forecast.njk b/modules/default/weather/forecast.njk
new file mode 100644
index 00000000..fed0e85c
--- /dev/null
+++ b/modules/default/weather/forecast.njk
@@ -0,0 +1,32 @@
+{% if forecast %}
+ {% set numSteps = forecast | calcNumSteps %}
+ {% set currentStep = 0 %}
+
+ {% set forecast = forecast.slice(0, numSteps) %}
+ {% for f in forecast %}
+
+ {{ f.date.format('ddd') }}
+
+
+ {{ f.maxTemperature | roundValue | unit("temperature") }}
+
+
+ {{ f.minTemperature | roundValue | unit("temperature") }}
+
+ {% if config.showPrecipitationAmount %}
+
+ {{ f.precipitation | unit("precip") }}
+
+ {% endif %}
+
+ {% set currentStep = currentStep + 1 %}
+ {% endfor %}
+
+{% else %}
+
+ {{ "LOADING" | translate | safe }}
+
+{% endif %}
+
+
+
diff --git a/modules/default/weather/forecast.png b/modules/default/weather/forecast.png
new file mode 100644
index 00000000..1afd3191
Binary files /dev/null and b/modules/default/weather/forecast.png differ
diff --git a/modules/default/weather/providers/README.md b/modules/default/weather/providers/README.md
new file mode 100755
index 00000000..dad9ed49
--- /dev/null
+++ b/modules/default/weather/providers/README.md
@@ -0,0 +1,133 @@
+# MagicMirror² Weather Module Weather Provider Development Documentation
+
+This document describes the way to develop your own MagicMirror² weather module weather provider.
+
+Table of Contents:
+
+- The weather provider file: yourprovider.js
+ - [Weather provider methods to implement](#weather-provider-methods-to-implement)
+ - [Weather Provider instance methods](#weather-provider-instance-methods)
+ - [WeatherObject](#weatherobject)
+
+---
+
+## The weather provider file: yourprovider.js
+
+This is the script in which the weather provider will be defined. In it's most simple form, the weather provider must implement the following:
+
+````javascript
+WeatherProvider.register("yourprovider", {
+ providerName: "YourProvider",
+
+ fetchCurrentWeather() {},
+
+ fetchWeatherForecast() {}
+});
+````
+
+### Weather provider methods to implement
+
+#### `fetchCurrentWeather()`
+
+This method is called when the weather module tries to fetch the current weather of your provider. The implementation of this method is required.
+The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise.
+After the response is processed, the current weather information (as a [WeatherObject](#weatherobject)) needs to be set with `this.setCurrentWeather(currentWeather);`.
+It will then automatically refresh the module DOM with the new data.
+
+#### `fetchWeatherForecast()`
+
+This method is called when the weather module tries to fetch the weather weather of your provider. The implementation of this method is required.
+The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise.
+After the response is processed, the weather forecast information (as an array of [WeatherObject](#weatherobject)s) needs to be set with `this.setCurrentWeather(forecast);`.
+It will then automatically refresh the module DOM with the new data.
+
+### Weather Provider instance methods
+
+#### `init()`
+
+Called when a weather provider is initialized.
+
+#### `setConfig(config)`
+
+Called to set the config, this config is the same as the weather module's config.
+
+#### `start()`
+
+Called when the weather provider is about to start.
+
+#### `currentWeather()`
+
+This returns a WeatherDay object for the current weather.
+
+#### `weatherForecast()`
+
+This returns an array of WeatherDay objects for the weather forecast.
+
+#### `fetchedLocation()`
+
+This returns the name of the fetched location or an empty string.
+
+#### `setCurrentWeather(currentWeatherObject)`
+
+Set the currentWeather and notify the delegate that new information is available.
+
+#### `setWeatherForecast(weatherForecastArray)`
+
+Set the weatherForecastArray and notify the delegate that new information is available.
+
+#### `setFetchedLocation(name)`
+
+Set the fetched location name.
+
+#### `updateAvailable()`
+
+Notify the delegate that new weather is available.
+
+#### `fetchData(url, method, data)`
+
+A convenience function to make requests. It returns a promise.
+
+### WeatherObject
+
+| Property | Type | Value/Unit |
+| --- | --- | --- |
+| units | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` |
+| tempUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` |
+| windUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` |
+| date | `object` | [Moment.js](https://momentjs.com/) object of the time/date. |
+| windSpeed |`number` | Metric: `meter/second`
Imperial: `miles/hour` |
+| windDirection |`number` | Direction of the wind in degrees. |
+| sunrise |`object` | [Moment.js](https://momentjs.com/) object of sunrise. |
+| sunset |`object` | [Moment.js](https://momentjs.com/) object of sunset. |
+| temperature | `number` | Current temperature |
+| minTemperature | `number` | Lowest temperature of the day. |
+| maxTemperature | `number` | Highest temperature of the day. |
+| weatherType | `string` | Icon name of the weather type.
Possible values: [WeatherIcons](https://www.npmjs.com/package/weathericons) |
+| humidity | `number` | Percentage of humidity |
+| rain | `number` | Metric: `millimeters`
Imperial: `inches` |
+| snow | `number` | Metric: `millimeters`
Imperial: `inches` |
+| precipitation | `number` | Metric: `millimeters`
Imperial: `inches`
UK Met Office provider: `percent` |
+
+#### Current weather
+
+For the current weather object the following properties are required:
+
+- humidity
+- sunrise
+- sunset
+- temperature
+- units
+- weatherType
+- windDirection
+- windSpeed
+
+#### Weather forecast
+
+For the forecast weather object the following properties are required:
+
+- date
+- maxTemperature
+- minTemperature
+- rain
+- units
+- weatherType
diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js
new file mode 100755
index 00000000..b24c4794
--- /dev/null
+++ b/modules/default/weather/providers/darksky.js
@@ -0,0 +1,124 @@
+/* global WeatherProvider, WeatherDay */
+
+/* Magic Mirror
+ * Module: Weather
+ * Provider: Dark Sky
+ *
+ * By Nicholas Hubbard https://github.com/nhubbard
+ * MIT Licensed
+ *
+ * This class is a provider for Dark Sky.
+ * Note that the Dark Sky API does not provide rainfall. Instead it provides snowfall and precipitation probability
+ */
+WeatherProvider.register("darksky", {
+ // Set the name of the provider.
+ // Not strictly required, but helps for debugging.
+ providerName: "Dark Sky",
+
+ units: {
+ imperial: 'us',
+ metric: 'si'
+ },
+
+ fetchCurrentWeather() {
+ this.fetchData(this.getUrl())
+ .then(data => {
+ if(!data || !data.currently || typeof data.currently.temperature === "undefined") {
+ // No usable data?
+ return;
+ }
+
+ const currentWeather = this.generateWeatherDayFromCurrentWeather(data);
+ this.setCurrentWeather(currentWeather);
+ }).catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+ fetchWeatherForecast() {
+ this.fetchData(this.getUrl())
+ .then(data => {
+ if(!data || !data.daily || !data.daily.data.length) {
+ // No usable data?
+ return;
+ }
+
+ const forecast = this.generateWeatherObjectsFromForecast(data.daily.data);
+ this.setWeatherForecast(forecast);
+ }).catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+ // Create a URL from the config and base URL.
+ getUrl() {
+ const units = this.units[this.config.units] || "auto";
+ return `${this.config.apiBase}${this.config.weatherEndpoint}/${this.config.apiKey}/${this.config.lat},${this.config.lon}?units=${units}&lang=${this.config.lang}`;
+ },
+
+ // Implement WeatherDay generator.
+ generateWeatherDayFromCurrentWeather(currentWeatherData) {
+ const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ currentWeather.date = moment();
+ currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity);
+ currentWeather.temperature = parseFloat(currentWeatherData.currently.temperature);
+ currentWeather.windSpeed = parseFloat(currentWeatherData.currently.windSpeed);
+ currentWeather.windDirection = currentWeatherData.currently.windBearing;
+ currentWeather.weatherType = this.convertWeatherType(currentWeatherData.currently.icon);
+ currentWeather.sunrise = moment(currentWeatherData.daily.data[0].sunriseTime, "X");
+ currentWeather.sunset = moment(currentWeatherData.daily.data[0].sunsetTime, "X");
+
+ return currentWeather;
+ },
+
+ generateWeatherObjectsFromForecast(forecasts) {
+ const days = [];
+
+ for (const forecast of forecasts) {
+ const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ weather.date = moment(forecast.time, "X");
+ weather.minTemperature = forecast.temperatureMin;
+ weather.maxTemperature = forecast.temperatureMax;
+ weather.weatherType = this.convertWeatherType(forecast.icon);
+ weather.snow = 0;
+
+ // The API will return centimeters if units is 'si' and will return inches for 'us'
+ // Note that the Dark Sky API does not provide rainfall. Instead it provides snowfall and precipitation probability
+ if (forecast.hasOwnProperty("precipAccumulation")) {
+ if (this.config.units === "imperial" && !isNaN(forecast.precipAccumulation)) {
+ weather.snow = forecast.precipAccumulation;
+ } else if (!isNaN(forecast.precipAccumulation)) {
+ weather.snow = forecast.precipAccumulation * 10;
+ }
+ }
+
+ weather.precipitation = weather.snow;
+
+ days.push(weather);
+ }
+
+ return days;
+ },
+
+ // Map icons from Dark Sky to our icons.
+ convertWeatherType(weatherType) {
+ const weatherTypes = {
+ "clear-day": "day-sunny",
+ "clear-night": "night-clear",
+ "rain": "rain",
+ "snow": "snow",
+ "sleet": "snow",
+ "wind": "wind",
+ "fog": "fog",
+ "cloudy": "cloudy",
+ "partly-cloudy-day": "day-cloudy",
+ "partly-cloudy-night": "night-cloudy"
+ };
+
+ return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null;
+ }
+});
diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js
new file mode 100755
index 00000000..e99dc476
--- /dev/null
+++ b/modules/default/weather/providers/openweathermap.js
@@ -0,0 +1,283 @@
+/* global WeatherProvider, WeatherObject */
+
+/* Magic Mirror
+ * Module: Weather
+ *
+ * By Michael Teeuw http://michaelteeuw.nl
+ * MIT Licensed.
+ *
+ * This class is the blueprint for a weather provider.
+ */
+
+WeatherProvider.register("openweathermap", {
+
+ // Set the name of the provider.
+ // This isn't strictly necessary, since it will fallback to the provider identifier
+ // But for debugging (and future alerts) it would be nice to have the real name.
+ providerName: "OpenWeatherMap",
+
+ // Overwrite the fetchCurrentWeather method.
+ fetchCurrentWeather() {
+ this.fetchData(this.getUrl())
+ .then(data => {
+ if (!data || !data.main || typeof data.main.temp === "undefined") {
+ // Did not receive usable new data.
+ // Maybe this needs a better check?
+ return;
+ }
+
+ this.setFetchedLocation(`${data.name}, ${data.sys.country}`);
+
+ const currentWeather = this.generateWeatherObjectFromCurrentWeather(data);
+ this.setCurrentWeather(currentWeather);
+ })
+ .catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+ // Overwrite the fetchCurrentWeather method.
+ fetchWeatherForecast() {
+ this.fetchData(this.getUrl())
+ .then(data => {
+ if (!data || !data.list || !data.list.length) {
+ // Did not receive usable new data.
+ // Maybe this needs a better check?
+ return;
+ }
+
+ this.setFetchedLocation(`${data.city.name}, ${data.city.country}`);
+
+ const forecast = this.generateWeatherObjectsFromForecast(data.list);
+ this.setWeatherForecast(forecast);
+ })
+ .catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+ /** OpenWeatherMap Specific Methods - These are not part of the default provider methods */
+ /*
+ * Gets the complete url for the request
+ */
+ getUrl() {
+ return this.config.apiBase + this.config.apiVersion + this.config.weatherEndpoint + this.getParams();
+ },
+
+ /*
+ * Generate a WeatherObject based on currentWeatherInformation
+ */
+ generateWeatherObjectFromCurrentWeather(currentWeatherData) {
+ const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ currentWeather.humidity = currentWeatherData.main.humidity;
+ currentWeather.temperature = currentWeatherData.main.temp;
+ currentWeather.windSpeed = currentWeatherData.wind.speed;
+ currentWeather.windDirection = currentWeatherData.wind.deg;
+ currentWeather.weatherType = this.convertWeatherType(currentWeatherData.weather[0].icon);
+ currentWeather.sunrise = moment(currentWeatherData.sys.sunrise, "X");
+ currentWeather.sunset = moment(currentWeatherData.sys.sunset, "X");
+
+ return currentWeather;
+ },
+
+ /*
+ * Generate WeatherObjects based on forecast information
+ */
+ generateWeatherObjectsFromForecast(forecasts) {
+
+ if (this.config.weatherEndpoint === "/forecast") {
+ return this.fetchForecastHourly(forecasts);
+ } else if (this.config.weatherEndpoint === "/forecast/daily") {
+ return this.fetchForecastDaily(forecasts);
+ }
+ // if weatherEndpoint does not match forecast or forecast/daily, what should be returned?
+ const days = [new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits)];
+ return days;
+ },
+
+ /*
+ * fetch forecast information for 3-hourly forecast (available for free subscription).
+ */
+ fetchForecastHourly(forecasts) {
+ // initial variable declaration
+ const days = [];
+ // variables for temperature range and rain
+ let minTemp = [];
+ let maxTemp = [];
+ let rain = 0;
+ let snow = 0;
+ // variable for date
+ let date = "";
+ let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ for (const forecast of forecasts) {
+
+ if (date !== moment(forecast.dt, "X").format("YYYY-MM-DD")) {
+ // calculate minimum/maximum temperature, specify rain amount
+ weather.minTemperature = Math.min.apply(null, minTemp);
+ weather.maxTemperature = Math.max.apply(null, maxTemp);
+ weather.rain = rain;
+ weather.snow = snow;
+ weather.precipitation = weather.rain + weather.snow;
+ // push weather information to days array
+ days.push(weather);
+ // create new weather-object
+ weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ minTemp = [];
+ maxTemp = [];
+ rain = 0;
+ snow = 0;
+
+ // set new date
+ date = moment(forecast.dt, "X").format("YYYY-MM-DD");
+
+ // specify date
+ weather.date = moment(forecast.dt, "X");
+
+ // If the first value of today is later than 17:00, we have an icon at least!
+ weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
+
+ }
+
+ if (moment(forecast.dt, "X").format("H") >= 8 && moment(forecast.dt, "X").format("H") <= 17) {
+ weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
+ }
+
+ // the same day as before
+ // add values from forecast to corresponding variables
+ minTemp.push(forecast.main.temp_min);
+ maxTemp.push(forecast.main.temp_max);
+
+ if (forecast.hasOwnProperty("rain")) {
+ if (this.config.units === "imperial" && !isNaN(forecast.rain["3h"])) {
+ rain += forecast.rain["3h"] / 25.4;
+ } else if (!isNaN(forecast.rain["3h"])) {
+ rain += forecast.rain["3h"];
+ }
+ }
+
+ if (forecast.hasOwnProperty("snow")) {
+ if (this.config.units === "imperial" && !isNaN(forecast.snow["3h"])) {
+ snow += forecast.snow["3h"] / 25.4;
+ } else if (!isNaN(forecast.snow["3h"])) {
+ snow += forecast.snow["3h"];
+ }
+ }
+ }
+
+ // last day
+ // calculate minimum/maximum temperature, specify rain amount
+ weather.minTemperature = Math.min.apply(null, minTemp);
+ weather.maxTemperature = Math.max.apply(null, maxTemp);
+ weather.rain = rain;
+ weather.snow = snow;
+ weather.precipitation = weather.rain + weather.snow;
+ // push weather information to days array
+ days.push(weather);
+ return days.slice(1);
+ },
+
+ /*
+ * fetch forecast information for daily forecast (available for paid subscription or old apiKey).
+ */
+ fetchForecastDaily(forecasts) {
+ // initial variable declaration
+ const days = [];
+
+ for (const forecast of forecasts) {
+ const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ weather.date = moment(forecast.dt, "X");
+ weather.minTemperature = forecast.temp.min;
+ weather.maxTemperature = forecast.temp.max;
+ weather.weatherType = this.convertWeatherType(forecast.weather[0].icon);
+ weather.rain = 0;
+ weather.snow = 0;
+
+ // forecast.rain not available if amount is zero
+ // The API always returns in millimeters
+ if (forecast.hasOwnProperty("rain")) {
+ if (this.config.units === "imperial" && !isNaN(forecast.rain)) {
+ weather.rain = forecast.rain / 25.4;
+ } else if (!isNaN(forecast.rain)) {
+ weather.rain = forecast.rain;
+ }
+ }
+
+ // forecast.snow not available if amount is zero
+ // The API always returns in millimeters
+ if (forecast.hasOwnProperty("snow")) {
+ if (this.config.units === "imperial" && !isNaN(forecast.snow)) {
+ weather.snow = forecast.snow / 25.4;
+ } else if (!isNaN(forecast.snow)) {
+ weather.snow = forecast.snow;
+ }
+ }
+
+ weather.precipitation = weather.rain + weather.snow;
+
+ days.push(weather);
+ }
+
+ return days;
+ },
+
+ /*
+ * Convert the OpenWeatherMap icons to a more usable name.
+ */
+ convertWeatherType(weatherType) {
+ const weatherTypes = {
+ "01d": "day-sunny",
+ "02d": "day-cloudy",
+ "03d": "cloudy",
+ "04d": "cloudy-windy",
+ "09d": "showers",
+ "10d": "rain",
+ "11d": "thunderstorm",
+ "13d": "snow",
+ "50d": "fog",
+ "01n": "night-clear",
+ "02n": "night-cloudy",
+ "03n": "night-cloudy",
+ "04n": "night-cloudy",
+ "09n": "night-showers",
+ "10n": "night-rain",
+ "11n": "night-thunderstorm",
+ "13n": "night-snow",
+ "50n": "night-alt-cloudy-windy"
+ };
+
+ return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null;
+ },
+
+ /* getParams(compliments)
+ * Generates an url with api parameters based on the config.
+ *
+ * return String - URL params.
+ */
+ getParams() {
+ let params = "?";
+ if(this.config.locationID) {
+ params += "id=" + this.config.locationID;
+ } else if(this.config.location) {
+ params += "q=" + this.config.location;
+ } else if (this.firstEvent && this.firstEvent.geo) {
+ params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon;
+ } else if (this.firstEvent && this.firstEvent.location) {
+ params += "q=" + this.firstEvent.location;
+ } else {
+ this.hide(this.config.animationSpeed, {lockString:this.identifier});
+ return;
+ }
+
+ params += "&units=" + this.config.units;
+ params += "&lang=" + this.config.lang;
+ params += "&APPID=" + this.config.apiKey;
+
+ return params;
+ }
+});
diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js
new file mode 100755
index 00000000..47785b3b
--- /dev/null
+++ b/modules/default/weather/providers/ukmetoffice.js
@@ -0,0 +1,264 @@
+/* global WeatherProvider, WeatherObject */
+
+/* Magic Mirror
+ * Module: Weather
+ *
+ * By Malcolm Oakes https://github.com/maloakes
+ * MIT Licensed.
+ *
+ * This class is a provider for UK Met Office Datapoint.
+ */
+
+
+WeatherProvider.register("ukmetoffice", {
+
+ // Set the name of the provider.
+ // This isn't strictly necessary, since it will fallback to the provider identifier
+ // But for debugging (and future alerts) it would be nice to have the real name.
+ providerName: "UK Met Office",
+
+ units: {
+ imperial: "us",
+ metric: "si"
+ },
+
+ // Overwrite the fetchCurrentWeather method.
+ fetchCurrentWeather() {
+ this.fetchData(this.getUrl("3hourly"))
+ .then(data => {
+ if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location ||
+ !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length == 0) {
+ // Did not receive usable new data.
+ // Maybe this needs a better check?
+ return;
+ }
+
+ this.setFetchedLocation(`${data.SiteRep.DV.Location.name}, ${data.SiteRep.DV.Location.country}`);
+
+ const currentWeather = this.generateWeatherObjectFromCurrentWeather(data);
+ this.setCurrentWeather(currentWeather);
+ })
+ .catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+ // Overwrite the fetchCurrentWeather method.
+ fetchWeatherForecast() {
+ this.fetchData(this.getUrl("daily"))
+ .then(data => {
+ if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location ||
+ !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length == 0) {
+ // Did not receive usable new data.
+ // Maybe this needs a better check?
+ return;
+ }
+
+ this.setFetchedLocation(`${data.SiteRep.DV.Location.name}, ${data.SiteRep.DV.Location.country}`);
+
+ const forecast = this.generateWeatherObjectsFromForecast(data);
+ this.setWeatherForecast(forecast);
+ })
+ .catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+
+
+ /** UK Met Office Specific Methods - These are not part of the default provider methods */
+ /*
+ * Gets the complete url for the request
+ */
+ getUrl(forecastType) {
+ return this.config.apiBase + this.config.locationID + this.getParams(forecastType);
+ },
+
+ /*
+ * Generate a WeatherObject based on currentWeatherInformation
+ */
+ generateWeatherObjectFromCurrentWeather(currentWeatherData) {
+ const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ // data times are always UTC
+ let nowUtc = moment.utc()
+ let midnightUtc = nowUtc.clone().startOf("day")
+ let timeInMins = nowUtc.diff(midnightUtc, "minutes");
+
+ // loop round each of the (5) periods, look for today (the first period may be yesterday)
+ for (i in currentWeatherData.SiteRep.DV.Location.Period) {
+ let periodDate = moment.utc(currentWeatherData.SiteRep.DV.Location.Period[i].value.substr(0,10), "YYYY-MM-DD")
+
+ // ignore if period is before today
+ if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) {
+
+ // check this is the period we want, after today the diff will be -ve
+ if (moment().diff(periodDate, "minutes") > 0) {
+ // loop round the reports looking for the one we are in
+ // $ value specifies the time in minutes-of-the-day: 0, 180, 360,...1260
+ for (j in currentWeatherData.SiteRep.DV.Location.Period[i].Rep){
+ let p = currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].$;
+ if (timeInMins >= p && timeInMins-180 < p) {
+ // finally got the one we want, so populate weather object
+ currentWeather.humidity = currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].H;
+ currentWeather.temperature = this.convertTemp(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].T);
+ currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].F);
+ currentWeather.precipitation = parseInt(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].Pp);
+ currentWeather.windSpeed = this.convertWindSpeed(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].S);
+ currentWeather.windDirection = this.convertWindDirection(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].D);
+ currentWeather.weatherType = this.convertWeatherType(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].W);
+ }
+ }
+ }
+ }
+ }
+
+ // determine the sunrise/sunset times - not supplied in UK Met Office data
+ let times = this.calcAstroData(currentWeatherData.SiteRep.DV.Location)
+ currentWeather.sunrise = times[0];
+ currentWeather.sunset = times[1];
+
+ return currentWeather;
+ },
+
+ /*
+ * Generate WeatherObjects based on forecast information
+ */
+ generateWeatherObjectsFromForecast(forecasts) {
+
+ const days = [];
+
+ // loop round the (5) periods getting the data
+ // for each period array, Day is [0], Night is [1]
+ for (j in forecasts.SiteRep.DV.Location.Period) {
+ const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ // data times are always UTC
+ dateStr = forecasts.SiteRep.DV.Location.Period[j].value
+ let periodDate = moment.utc(dateStr.substr(0,10), "YYYY-MM-DD")
+
+ // ignore if period is before today
+ if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) {
+ // populate the weather object
+ weather.date = moment.utc(dateStr.substr(0,10), "YYYY-MM-DD");
+ weather.minTemperature = this.convertTemp(forecasts.SiteRep.DV.Location.Period[j].Rep[1].Nm);
+ weather.maxTemperature = this.convertTemp(forecasts.SiteRep.DV.Location.Period[j].Rep[0].Dm);
+ weather.weatherType = this.convertWeatherType(forecasts.SiteRep.DV.Location.Period[j].Rep[0].W);
+ weather.precipitation = parseInt(forecasts.SiteRep.DV.Location.Period[j].Rep[0].PPd);
+
+ days.push(weather);
+ }
+ }
+
+ return days;
+ },
+
+ /*
+ * calculate the astronomical data
+ */
+ calcAstroData(location) {
+ const sunTimes = [];
+
+ // determine the sunrise/sunset times
+ let times = SunCalc.getTimes(new Date(), location.lat, location.lon);
+ sunTimes.push(moment(times.sunrise, "X"));
+ sunTimes.push(moment(times.sunset, "X"));
+
+ return sunTimes;
+ },
+
+ /*
+ * Convert the Met Office icons to a more usable name.
+ */
+ convertWeatherType(weatherType) {
+ const weatherTypes = {
+ 0: "night-clear",
+ 1: "day-sunny",
+ 2: "night-alt-cloudy",
+ 3: "day-cloudy",
+ 5: "fog",
+ 6: "fog",
+ 7: "cloudy",
+ 8: "cloud",
+ 9: "night-sprinkle",
+ 10: "day-sprinkle",
+ 11: "raindrops",
+ 12: "sprinkle",
+ 13: "night-alt-showers",
+ 14: "day-showers",
+ 15: "rain",
+ 16: "night-alt-sleet",
+ 17: "day-sleet",
+ 18: "sleet",
+ 19: "night-alt-hail",
+ 20: "day-hail",
+ 21: "hail",
+ 22: "night-alt-snow",
+ 23: "day-snow",
+ 24: "snow",
+ 25: "night-alt-snow",
+ 26: "day-snow",
+ 27: "snow",
+ 28: "night-alt-thunderstorm",
+ 29: "day-thunderstorm",
+ 30: "thunderstorm"
+ };
+
+ return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null;
+ },
+
+ /*
+ * Convert temp (from degrees C) if required
+ */
+ convertTemp(tempInC) {
+ return this.tempUnits === "imperial" ? tempInC * 9 / 5 + 32 : tempInC;
+ },
+
+ /*
+ * Convert wind speed (from mph) if required
+ */
+ convertWindSpeed(windInMph) {
+ return this.windUnits === "metric" ? windInMph * 2.23694 : windInMph;
+ },
+
+ /*
+ * Convert the wind direction cardinal to value
+ */
+ convertWindDirection(windDirection) {
+ const windCardinals = {
+ "N": 0,
+ "NNE": 22,
+ "NE": 45,
+ "ENE": 67,
+ "E": 90,
+ "ESE": 112,
+ "SE": 135,
+ "SSE": 157,
+ "S": 180,
+ "SSW": 202,
+ "SW": 225,
+ "WSW": 247,
+ "W": 270,
+ "WNW": 292,
+ "NW": 315,
+ "NNW": 337
+ };
+
+ return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null;
+ },
+
+ /*
+ * Generates an url with api parameters based on the config.
+ *
+ * return String - URL params.
+ */
+ getParams(forecastType) {
+ let params = "?";
+ params += "res=" + forecastType;
+ params += "&key=" + this.config.apiKey;
+
+ return params;
+ }
+});
diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js
new file mode 100755
index 00000000..74d95522
--- /dev/null
+++ b/modules/default/weather/providers/weathergov.js
@@ -0,0 +1,264 @@
+/* global WeatherProvider, WeatherObject */
+
+/* Magic Mirror
+ * Module: Weather
+ * Provider: weather.gov
+ *
+ * By Vince Peri
+ * MIT Licensed.
+ *
+ * This class is a provider for weather.gov.
+ * Note that this is only for US locations (lat and lon) and does not require an API key
+ * Since it is free, there are some items missing - like sunrise, sunset, humidity, etc.
+ */
+
+WeatherProvider.register("weathergov", {
+
+ // Set the name of the provider.
+ // This isn't strictly necessary, since it will fallback to the provider identifier
+ // But for debugging (and future alerts) it would be nice to have the real name.
+ providerName: "Weather.gov",
+
+ // Overwrite the fetchCurrentWeather method.
+ fetchCurrentWeather() {
+ this.fetchData(this.getUrl())
+ .then(data => {
+ if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) {
+ // Did not receive usable new data.
+ // Maybe this needs a better check?
+ return;
+ }
+
+ const currentWeather = this.generateWeatherObjectFromCurrentWeather(data.properties.periods[0]);
+ this.setCurrentWeather(currentWeather);
+ })
+ .catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+ // Overwrite the fetchCurrentWeather method.
+ fetchWeatherForecast() {
+ this.fetchData(this.getUrl())
+ .then(data => {
+ if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) {
+ // Did not receive usable new data.
+ // Maybe this needs a better check?
+ return;
+ }
+
+ const forecast = this.generateWeatherObjectsFromForecast(data.properties.periods);
+ this.setWeatherForecast(forecast);
+ })
+ .catch(function(request) {
+ Log.error("Could not load data ... ", request);
+ })
+ .finally(() => this.updateAvailable())
+ },
+
+ /** Weather.gov Specific Methods - These are not part of the default provider methods */
+ /*
+ * Gets the complete url for the request
+ */
+ getUrl() {
+ return this.config.apiBase + this.config.lat + "," + this.config.lon + this.config.weatherEndpoint;
+ },
+
+ /*
+ * Generate a WeatherObject based on currentWeatherInformation
+ */
+ generateWeatherObjectFromCurrentWeather(currentWeatherData) {
+ const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ currentWeather.temperature = currentWeatherData.temperature;
+ currentWeather.windSpeed = currentWeatherData.windSpeed.split(" ", 1);
+ currentWeather.windDirection = this.convertWindDirection(currentWeatherData.windDirection);
+ currentWeather.weatherType = this.convertWeatherType(currentWeatherData.shortForecast, currentWeatherData.isDaytime);
+
+ // determine the sunrise/sunset times - not supplied in weather.gov data
+ let times = this.calcAstroData(this.config.lat, this.config.lon)
+ currentWeather.sunrise = times[0];
+ currentWeather.sunset = times[1];
+
+ return currentWeather;
+ },
+
+ /*
+ * Generate WeatherObjects based on forecast information
+ */
+ generateWeatherObjectsFromForecast(forecasts) {
+ return this.fetchForecastDaily(forecasts);
+ },
+
+ /*
+ * fetch forecast information for daily forecast.
+ */
+ fetchForecastDaily(forecasts) {
+ // initial variable declaration
+ const days = [];
+ // variables for temperature range and rain
+ let minTemp = [];
+ let maxTemp = [];
+ // variable for date
+ let date = "";
+ let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+ weather.precipitation = 0;
+
+ for (const forecast of forecasts) {
+
+ if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) {
+
+ // calculate minimum/maximum temperature, specify rain amount
+ weather.minTemperature = Math.min.apply(null, minTemp);
+ weather.maxTemperature = Math.max.apply(null, maxTemp);
+
+ // push weather information to days array
+ days.push(weather);
+ // create new weather-object
+ weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits);
+
+ minTemp = [];
+ maxTemp = [];
+ weather.precipitation = 0;
+
+ // set new date
+ date = moment(forecast.startTime).format("YYYY-MM-DD");
+
+ // specify date
+ weather.date = moment(forecast.startTime);
+
+ // If the first value of today is later than 17:00, we have an icon at least!
+ weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime);
+ }
+
+ if (moment(forecast.startTime).format("H") >= 8 && moment(forecast.startTime).format("H") <= 17) {
+ weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime);
+ }
+
+ // the same day as before
+ // add values from forecast to corresponding variables
+ minTemp.push(forecast.temperature);
+ maxTemp.push(forecast.temperature);
+ }
+
+ // last day
+ // calculate minimum/maximum temperature
+ weather.minTemperature = Math.min.apply(null, minTemp);
+ weather.maxTemperature = Math.max.apply(null, maxTemp);
+
+ // push weather information to days array
+ days.push(weather);
+ return days.slice(1);
+ },
+
+ /*
+ * Calculate the astronomical data
+ */
+ calcAstroData(lat, lon) {
+ const sunTimes = [];
+
+ // determine the sunrise/sunset times
+ let times = SunCalc.getTimes(new Date(), lat, lon);
+ sunTimes.push(moment(times.sunrise, "X"));
+ sunTimes.push(moment(times.sunset, "X"));
+
+ return sunTimes;
+ },
+
+ /*
+ * Convert the icons to a more usable name.
+ */
+ convertWeatherType(weatherType, isDaytime) {
+ //https://w1.weather.gov/xml/current_obs/weather.php
+ // There are way too many types to create, so lets just look for certain strings
+
+ if (weatherType.includes("Cloudy") || weatherType.includes("Partly")) {
+ if (isDaytime) {
+ return "day-cloudy";
+ }
+
+ return "night-cloudy";
+ } else if (weatherType.includes("Overcast")) {
+ if (isDaytime) {
+ return "cloudy";
+ }
+
+ return "night-cloudy";
+ } else if (weatherType.includes("Freezing") || weatherType.includes("Ice")) {
+ return "rain-mix";
+ } else if (weatherType.includes("Snow")) {
+ if (isDaytime) {
+ return "snow";
+ }
+
+ return "night-snow";
+ } else if (weatherType.includes("Thunderstorm")) {
+ if (isDaytime) {
+ return "thunderstorm";
+ }
+
+ return "night-thunderstorm";
+ } else if (weatherType.includes("Showers")) {
+ if (isDaytime) {
+ return "showers";
+ }
+
+ return "night-showers";
+ } else if (weatherType.includes("Rain") || weatherType.includes("Drizzle")) {
+ if (isDaytime) {
+ return "rain";
+ }
+
+ return "night-rain";
+ } else if (weatherType.includes("Breezy") || weatherType.includes("Windy")) {
+ if (isDaytime) {
+ return "cloudy-windy";
+ }
+
+ return "night-alt-cloudy-windy";
+ } else if (weatherType.includes("Fair") || weatherType.includes("Clear") || weatherType.includes("Few") || weatherType.includes("Sunny")) {
+ if (isDaytime) {
+ return "day-sunny";
+ }
+
+ return "night-clear";
+ } else if (weatherType.includes("Dust") || weatherType.includes("Sand")) {
+ return "dust";
+ } else if (weatherType.includes("Fog")) {
+ return "fog";
+ } else if (weatherType.includes("Smoke")) {
+ return "smoke";
+ } else if (weatherType.includes("Haze")) {
+ return "day-haze";
+ }
+
+ return null;
+ },
+
+ /*
+ Convert the direction into Degrees
+ */
+ convertWindDirection(windDirection) {
+ const windCardinals = {
+ "N": 0,
+ "NNE": 22,
+ "NE": 45,
+ "ENE": 67,
+ "E": 90,
+ "ESE": 112,
+ "SE": 135,
+ "SSE": 157,
+ "S": 180,
+ "SSW": 202,
+ "SW": 225,
+ "WSW": 247,
+ "W": 270,
+ "WNW": 292,
+ "NW": 315,
+ "NNW": 337
+ };
+
+ return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null;
+ }
+});
diff --git a/modules/default/weather/weather.css b/modules/default/weather/weather.css
new file mode 100644
index 00000000..639ce7a9
--- /dev/null
+++ b/modules/default/weather/weather.css
@@ -0,0 +1,49 @@
+.weather .weathericon,
+.weather .fa-home {
+ font-size: 75%;
+ line-height: 65px;
+ display: inline-block;
+ -ms-transform: translate(0, -3px); /* IE 9 */
+ -webkit-transform: translate(0, -3px); /* Safari */
+ transform: translate(0, -3px);
+}
+
+.weather .humidityIcon {
+ padding-right: 4px;
+}
+
+.weather .humidity-padding {
+ padding-bottom: 6px;
+}
+
+.weather .day {
+ padding-left: 0;
+ padding-right: 25px;
+}
+
+.weather .weather-icon {
+ padding-right: 30px;
+ text-align: center;
+}
+
+.weather .min-temp {
+ padding-left: 20px;
+ padding-right: 0;
+}
+
+.weather .precipitation {
+ padding-left: 20px;
+ padding-right: 0;
+}
+
+.weather tr .weathericon {
+ line-height: 25px;
+}
+
+.weather tr.colored .min-temp {
+ color: #bcddff;
+}
+
+.weather tr.colored .max-temp {
+ color: #ff8e99;
+}
diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js
new file mode 100755
index 00000000..868316d9
--- /dev/null
+++ b/modules/default/weather/weather.js
@@ -0,0 +1,255 @@
+/* global Module, WeatherProvider */
+
+/* Magic Mirror
+ * Module: Weather
+ *
+ * By Michael Teeuw http://michaelteeuw.nl
+ * MIT Licensed.
+ */
+
+Module.register("weather",{
+ // Default module config.
+ defaults: {
+ updateInterval: 10 * 60 * 1000,
+ weatherProvider: "openweathermap",
+ roundTemp: false,
+ type: "current", //current, forecast
+
+ location: false,
+ locationID: false,
+ appid: "",
+ units: config.units,
+
+ tempUnits: config.units,
+ windUnits: config.units,
+
+ updateInterval: 10 * 60 * 1000, // every 10 minutes
+ animationSpeed: 1000,
+ timeFormat: config.timeFormat,
+ showPeriod: true,
+ showPeriodUpper: false,
+ showWindDirection: true,
+ showWindDirectionAsArrow: false,
+ useBeaufort: true,
+ lang: config.language,
+ showHumidity: false,
+ degreeLabel: false,
+ decimalSymbol: ".",
+ showIndoorTemperature: false,
+ showIndoorHumidity: false,
+ maxNumberOfDays: 5,
+ fade: true,
+ fadePoint: 0.25, // Start on 1/4th of the list.
+
+ initialLoadDelay: 0, // 0 seconds delay
+ retryDelay: 2500,
+
+ apiVersion: "2.5",
+ apiBase: "http://api.openweathermap.org/data/",
+ weatherEndpoint: "/weather",
+
+ appendLocationNameToHeader: true,
+ calendarClass: "calendar",
+ tableClass: "small",
+
+ onlyTemp: false,
+ showPrecipitationAmount: false,
+ colored: false,
+ showFeelsLike: true
+ },
+
+ // Module properties.
+ weatherProvider: null,
+
+ // Define required scripts.
+ getStyles: function() {
+ return ["font-awesome.css", "weather-icons.css", "weather.css"];
+ },
+
+ // Return the scripts that are necessary for the weather module.
+ getScripts: function () {
+ return [
+ "moment.js",
+ "weatherprovider.js",
+ "weatherobject.js",
+ "suncalc.js",
+ this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")
+ ];
+ },
+
+ // Override getHeader method.
+ getHeader: function() {
+ if (this.config.appendLocationNameToHeader && this.data.header !== undefined && this.weatherProvider) {
+ return this.data.header + " " + this.weatherProvider.fetchedLocation();
+ }
+
+ return this.data.header;
+ },
+
+ // Start the weather module.
+ start: function () {
+ moment.locale(this.config.lang);
+
+ // Initialize the weather provider.
+ this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this);
+
+ // Let the weather provider know we are starting.
+ this.weatherProvider.start();
+
+ // Add custom filters
+ this.addFilters();
+
+ // Schedule the first update.
+ this.scheduleUpdate(this.config.initialLoadDelay);
+ },
+
+ // Override notification handler.
+ notificationReceived: function(notification, payload, sender) {
+ if (notification === "CALENDAR_EVENTS") {
+ var senderClasses = sender.data.classes.toLowerCase().split(" ");
+ if (senderClasses.indexOf(this.config.calendarClass.toLowerCase()) !== -1) {
+ this.firstEvent = false;
+
+ for (var e in payload) {
+ var event = payload[e];
+ if (event.location || event.geo) {
+ this.firstEvent = event;
+ //Log.log("First upcoming event with location: ", event);
+ break;
+ }
+ }
+ }
+ } else if (notification === "INDOOR_TEMPERATURE") {
+ this.indoorTemperature = this.roundValue(payload);
+ this.updateDom(300);
+ } else if (notification === "INDOOR_HUMIDITY") {
+ this.indoorHumidity = this.roundValue(payload);
+ this.updateDom(300);
+ }
+ },
+
+ // Select the template depending on the display type.
+ getTemplate: function () {
+ return `${this.config.type.toLowerCase()}.njk`;
+ },
+
+ // Add all the data to the template.
+ getTemplateData: function () {
+ return {
+ config: this.config,
+ current: this.weatherProvider.currentWeather(),
+ forecast: this.weatherProvider.weatherForecast(),
+ indoor: {
+ humidity: this.indoorHumidity,
+ temperature: this.indoorTemperature
+ }
+ };
+ },
+
+ // What to do when the weather provider has new information available?
+ updateAvailable: function() {
+ Log.log("New weather information available.");
+ this.updateDom(0);
+ this.scheduleUpdate();
+ },
+
+ scheduleUpdate: function(delay = null) {
+ var nextLoad = this.config.updateInterval;
+ if (delay !== null && delay >= 0) {
+ nextLoad = delay;
+ }
+
+ setTimeout(() => {
+ if (this.config.type === "forecast") {
+ this.weatherProvider.fetchWeatherForecast();
+ } else {
+ this.weatherProvider.fetchCurrentWeather();
+ }
+ }, nextLoad);
+ },
+
+ roundValue: function(temperature) {
+ var decimals = this.config.roundTemp ? 0 : 1;
+ return parseFloat(temperature).toFixed(decimals);
+ },
+
+ addFilters() {
+ this.nunjucksEnvironment().addFilter("formatTime", function(date) {
+ date = moment(date);
+
+ if (this.config.timeFormat !== 24) {
+ if (this.config.showPeriod) {
+ if (this.config.showPeriodUpper) {
+ return date.format("h:mm A");
+ } else {
+ return date.format("h:mm a");
+ }
+ } else {
+ return date.format("h:mm");
+ }
+ }
+
+ return date.format("HH:mm");
+ }.bind(this));
+
+ this.nunjucksEnvironment().addFilter("unit", function (value, type) {
+ if (type === "temperature") {
+ if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") {
+ value += "°";
+ }
+ if (this.config.degreeLabel) {
+ if (this.config.tempUnits === "metric") {
+ value += "C";
+ } else if (this.config.tempUnits === "imperial") {
+ value += "F";
+ } else {
+ value += "K";
+ }
+ }
+ } else if (type === "precip") {
+ if (isNaN(value) || value === 0 || value.toFixed(2) === "0.00") {
+ value = "";
+ } else {
+ if (this.config.weatherProvider === "ukmetoffice") {
+ value += "%";
+ } else {
+ value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`;
+ }
+ }
+ } else if (type === "humidity") {
+ value += "%";
+ }
+
+ return value;
+ }.bind(this));
+
+ this.nunjucksEnvironment().addFilter("roundValue", function(value) {
+ return this.roundValue(value);
+ }.bind(this));
+
+ this.nunjucksEnvironment().addFilter("decimalSymbol", function(value) {
+ return value.toString().replace(/\./g, this.config.decimalSymbol);
+ }.bind(this));
+
+ this.nunjucksEnvironment().addFilter("calcNumSteps", function(forecast) {
+ return Math.min(forecast.length, this.config.maxNumberOfDays);
+ }.bind(this));
+
+ this.nunjucksEnvironment().addFilter("opacity", function(currentStep, numSteps) {
+ if (this.config.fade && this.config.fadePoint < 1) {
+ if (this.config.fadePoint < 0) {
+ this.config.fadePoint = 0;
+ }
+ var startingPoint = numSteps * this.config.fadePoint;
+ var numFadesteps = numSteps - startingPoint;
+ if (currentStep >= startingPoint) {
+ return 1 - (currentStep - startingPoint) / numFadesteps;
+ } else {
+ return 1;
+ }
+ } else {
+ return 1;
+ }
+ }.bind(this));
+ }
+});
diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js
new file mode 100755
index 00000000..ed455537
--- /dev/null
+++ b/modules/default/weather/weatherobject.js
@@ -0,0 +1,110 @@
+/* global Class */
+
+/* Magic Mirror
+ * Module: Weather
+ *
+ * By Michael Teeuw http://michaelteeuw.nl
+ * MIT Licensed.
+ *
+ * This class is the blueprint for a day which includes weather information.
+ */
+
+// Currently this is focused on the information which is necessary for the current weather.
+// As soon as we start implementing the forecast, mode properties will be added.
+
+class WeatherObject {
+ constructor(units, tempUnits, windUnits) {
+
+ this.units = units;
+ this.tempUnits = tempUnits;
+ this.windUnits = windUnits;
+ this.date = null;
+ this.windSpeed = null;
+ this.windDirection = null;
+ this.sunrise = null;
+ this.sunset = null;
+ this.temperature = null;
+ this.minTemperature = null;
+ this.maxTemperature = null;
+ this.weatherType = null;
+ this.humidity = null;
+ this.rain = null;
+ this.snow = null;
+ this.precipitation = null;
+ this.feelsLikeTemp = null;
+
+ }
+
+ cardinalWindDirection() {
+ if (this.windDirection > 11.25 && this.windDirection <= 33.75){
+ return "NNE";
+ } else if (this.windDirection > 33.75 && this.windDirection <= 56.25) {
+ return "NE";
+ } else if (this.windDirection > 56.25 && this.windDirection <= 78.75) {
+ return "ENE";
+ } else if (this.windDirection > 78.75 && this.windDirection <= 101.25) {
+ return "E";
+ } else if (this.windDirection > 101.25 && this.windDirection <= 123.75) {
+ return "ESE";
+ } else if (this.windDirection > 123.75 && this.windDirection <= 146.25) {
+ return "SE";
+ } else if (this.windDirection > 146.25 && this.windDirection <= 168.75) {
+ return "SSE";
+ } else if (this.windDirection > 168.75 && this.windDirection <= 191.25) {
+ return "S";
+ } else if (this.windDirection > 191.25 && this.windDirection <= 213.75) {
+ return "SSW";
+ } else if (this.windDirection > 213.75 && this.windDirection <= 236.25) {
+ return "SW";
+ } else if (this.windDirection > 236.25 && this.windDirection <= 258.75) {
+ return "WSW";
+ } else if (this.windDirection > 258.75 && this.windDirection <= 281.25) {
+ return "W";
+ } else if (this.windDirection > 281.25 && this.windDirection <= 303.75) {
+ return "WNW";
+ } else if (this.windDirection > 303.75 && this.windDirection <= 326.25) {
+ return "NW";
+ } else if (this.windDirection > 326.25 && this.windDirection <= 348.75) {
+ return "NNW";
+ } else {
+ return "N";
+ }
+ }
+
+ beaufortWindSpeed() {
+ const windInKmh = (this.windUnits === "imperial") ? this.windSpeed * 1.609344 : this.windSpeed * 60 * 60 / 1000;
+ const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000];
+ for (const [index, speed] of speeds.entries()) {
+ if (speed > windInKmh) {
+ return index;
+ }
+ }
+ return 12;
+ }
+
+ nextSunAction() {
+ return moment().isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise";
+ }
+
+ feelsLike() {
+ if (this.feelsLikeTemp) {
+ return this.feelsLikeTemp;
+ }
+ const windInMph = (this.windUnits === "imperial") ? this.windSpeed : this.windSpeed * 2.23694;
+ const tempInF = this.tempUnits === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32;
+ let feelsLike = tempInF;
+
+ if (windInMph > 3 && tempInF < 50) {
+ feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16));
+ } else if (tempInF > 80 && this.humidity > 40) {
+ feelsLike = -42.379 + 2.04901523 * tempInF + 10.14333127 * this.humidity
+ - 0.22475541 * tempInF * this.humidity - 6.83783 * Math.pow(10, -3) * tempInF * tempInF
+ - 5.481717 * Math.pow(10, -2) * this.humidity * this.humidity
+ + 1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity
+ + 8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity
+ - 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity;
+ }
+
+ return this.tempUnits === "imperial" ? feelsLike : (feelsLike - 32) * 5 / 9;
+ }
+}
diff --git a/modules/default/weather/weatherprovider.js b/modules/default/weather/weatherprovider.js
new file mode 100644
index 00000000..1789b95c
--- /dev/null
+++ b/modules/default/weather/weatherprovider.js
@@ -0,0 +1,148 @@
+/* global Class */
+
+/* Magic Mirror
+ * Module: Weather
+ *
+ * By Michael Teeuw http://michaelteeuw.nl
+ * MIT Licensed.
+ *
+ * This class is the blueprint for a weather provider.
+ */
+
+/**
+ * Base BluePrint for the WeatherProvider
+ */
+var WeatherProvider = Class.extend({
+ // Weather Provider Properties
+ providerName: null,
+
+ // The following properties have accestor methods.
+ // Try to not access them directly.
+ currentWeatherObject: null,
+ weatherForecastArray: null,
+ fetchedLocationName: null,
+
+ // The following properties will be set automatically.
+ // You do not need to overwrite these properties.
+ config: null,
+ delegate: null,
+ providerIdentifier: null,
+
+ // Weather Provider Methods
+ // All the following methods can be overwritten, although most are good as they are.
+
+ // Called when a weather provider is initialized.
+ init: function(config) {
+ this.config = config;
+ Log.info(`Weather provider: ${this.providerName} initialized.`);
+ },
+
+ // Called to set the config, this config is the same as the weather module's config.
+ setConfig: function(config) {
+ this.config = config;
+ Log.info(`Weather provider: ${this.providerName} config set.`, this.config);
+ },
+
+ // Called when the weather provider is about to start.
+ start: function() {
+ Log.info(`Weather provider: ${this.providerName} started.`);
+ },
+
+ // This method should start the API request to fetch the current weather.
+ // This method should definitely be overwritten in the provider.
+ fetchCurrentWeather: function() {
+ Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchCurrentWeather method.`);
+ },
+
+ // This method should start the API request to fetch the weather forecast.
+ // This method should definitely be overwritten in the provider.
+ fetchWeatherForecast: function() {
+ Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchWeatherForecast method.`);
+ },
+
+ // This returns a WeatherDay object for the current weather.
+ currentWeather: function() {
+ return this.currentWeatherObject;
+ },
+
+ // This returns an array of WeatherDay objects for the weather forecast.
+ weatherForecast: function() {
+ return this.weatherForecastArray;
+ },
+
+ // This returns the name of the fetched location or an empty string.
+ fetchedLocation: function() {
+ return this.fetchedLocationName || "";
+ },
+
+ // Set the currentWeather and notify the delegate that new information is available.
+ setCurrentWeather: function(currentWeatherObject) {
+ // We should check here if we are passing a WeatherDay
+ this.currentWeatherObject = currentWeatherObject;
+ },
+
+ // Set the weatherForecastArray and notify the delegate that new information is available.
+ setWeatherForecast: function(weatherForecastArray) {
+ // We should check here if we are passing a WeatherDay
+ this.weatherForecastArray = weatherForecastArray;
+ },
+
+ // Set the fetched location name.
+ setFetchedLocation: function(name) {
+ this.fetchedLocationName = name;
+ },
+
+ // Notify the delegate that new weather is available.
+ updateAvailable: function() {
+ this.delegate.updateAvailable(this);
+ },
+
+ // A convenience function to make requests. It returns a promise.
+ fetchData: function(url, method = "GET", data = null) {
+ return new Promise(function(resolve, reject) {
+ var request = new XMLHttpRequest();
+ request.open(method, url, true);
+ request.onreadystatechange = function() {
+ if (this.readyState === 4) {
+ if (this.status === 200) {
+ resolve(JSON.parse(this.response));
+ } else {
+ reject(request);
+ }
+ }
+ };
+ request.send();
+ });
+ }
+});
+
+/**
+ * Collection of registered weather providers.
+ */
+WeatherProvider.providers = [];
+
+/**
+ * Static method to register a new weather provider.
+ */
+WeatherProvider.register = function(providerIdentifier, providerDetails) {
+ WeatherProvider.providers[providerIdentifier.toLowerCase()] = WeatherProvider.extend(providerDetails);
+};
+
+/**
+ * Static method to initialize a new weather provider.
+ */
+WeatherProvider.initialize = function(providerIdentifier, delegate) {
+ providerIdentifier = providerIdentifier.toLowerCase();
+
+ var provider = new WeatherProvider.providers[providerIdentifier]();
+
+ provider.delegate = delegate;
+ provider.setConfig(delegate.config);
+
+ provider.providerIdentifier = providerIdentifier;
+ if (!provider.providerName) {
+ provider.providerName = providerIdentifier;
+ }
+
+ return provider;
+};
diff --git a/modules/default/weatherforecast/README.md b/modules/default/weatherforecast/README.md
index 3568f7de..a75cb984 100644
--- a/modules/default/weatherforecast/README.md
+++ b/modules/default/weatherforecast/README.md
@@ -2,6 +2,11 @@
The `weatherforecast` module is one of the default modules of the MagicMirror.
This module displays the weather forecast for the coming week, including an an icon to display the current conditions, the minimum temperature and the maximum temperature.
+## Screenshots
+
+- 5 day forecast
+
+
## Using the module
To use this module, add it to the modules array in the `config/config.js` file:
@@ -14,7 +19,7 @@ modules: [
config: {
// See 'Configuration options' for more information.
location: "Amsterdam,Netherlands",
- locationID: "", //Location ID from http://openweathermap.org/help/city_list.txt
+ locationID: "", //Location ID from http://bulk.openweathermap.org/sample/city.list.json.gz
appid: "abcde12345abcde12345abcde12345ab" //openweathermap.org API key.
}
}
@@ -28,15 +33,16 @@ The following properties can be configured:
| Option | Description
| ---------------------------- | -----------
| `location` | The location used for weather information.
**Example:** `'Amsterdam,Netherlands'`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
-| `locationID` | Location ID from [OpenWeatherMap](http://openweathermap.org/help/city_list.txt) **This will override anything you put in location.**
Leave blank if you want to use location.
**Example:** `1234567`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
+| `locationID` | Location ID from [OpenWeatherMap](https://openweathermap.org/find) **This will override anything you put in location.**
Leave blank if you want to use location.
**Example:** `1234567`
**Default value:** `false`
**Note:** When the `location` and `locationID` are both not set, the location will be based on the information provided by the calendar module. The first upcoming event with location data will be used.
| `appid` | The [OpenWeatherMap](https://home.openweathermap.org) API key, which can be obtained by creating an OpenWeatherMap account.
This value is **REQUIRED**
| `units` | What units to use. Specified by config.js
**Possible values:** `config.units` = Specified by config.js, `default` = Kelvin, `metric` = Celsius, `imperial` =Fahrenheit
**Default value:** `config.units`
| `roundTemp` | Round temperature values to nearest integer.
**Possible values:** `true` (round to integer) or `false` (display exact value with decimal point)
**Default value:** `false`
| `maxNumberOfDays` | How many days of forecast to return. Specified by config.js
**Possible values:** `1` - `16`
**Default value:** `7` (7 days)
This value is optional. By default the weatherforecast module will return 7 days.
| `showRainAmount` | Should the predicted rain amount be displayed?
**Possible values:** `true` or `false`
**Default value:** `false`
This value is optional. By default the weatherforecast module will not display the predicted amount of rain.
| `updateInterval` | How often does the content needs to be fetched? (Milliseconds)
**Possible values:** `1000` - `86400000`
**Default value:** `600000` (10 minutes)
-| `animationSpeed` | Speed of the update animation. (Milliseconds)
**Possible values:**`0` - `5000`
**Default value:** `1000` (1 second)
+| `animationSpeed` | Speed of the update animation. (Milliseconds)
**Possible values:** `0` - `5000`
**Default value:** `1000` (1 second)
| `lang` | The language of the days.
**Possible values:** `en`, `nl`, `ru`, etc ...
**Default value:** uses value of _config.language_
+| `decimalSymbol` | The decimal symbol to use.
**Possible values:** `.`, `,` or any other symbol.
**Default value:** `.`
| `fade` | Fade the future events to black. (Gradient)
**Possible values:** `true` or `false`
**Default value:** `true`
| `fadePoint` | Where to start fade?
**Possible values:** `0` (top of the list) - `1` (bottom of list)
**Default value:** `0.25`
| `initialLoadDelay` | The initial delay before loading. If you have multiple modules that use the same API key, you might want to delay one of the requests. (Milliseconds)
**Possible values:** `1000` - `5000`
**Default value:** `2500` (2.5 seconds delay. This delay is used to keep the OpenWeather API happy.)
@@ -45,9 +51,11 @@ The following properties can be configured:
| `apiBase` | The OpenWeatherMap base URL.
**Default value:** `'http://api.openweathermap.org/data/'`
| `forecastEndpoint` | The OpenWeatherMap API endPoint.
**Default value:** `'forecast/daily'`
| `appendLocationNameToHeader` | If set to `true`, the returned location name will be appended to the header of the module, if the header is enabled. This is mainly intresting when using calender based weather.
**Default value:** `true`
-| `calendarClass` | The class for the calender module to base the event based weather information on.
**Default value:** `'calendar'`
+| `calendarClass` | The class for the calendar module to base the event based weather information on.
**Default value:** `'calendar'`
+| `tableClass` | Name of the classes issued from `main.css`.
**Possible values:** xsmall, small, medium, large, xlarge.
**Default value:** _small._
| `iconTable` | The conversion table to convert the weather conditions to weather-icons.
**Default value:** view table below
- `colored` | If set 'colored' to true the min-temp get a blue tone and the max-temp get a red tone.
**Default value:** `'false'`
+| `colored` | If set `colored` to `true` the min-temp gets a blue tone and the max-temp gets a red tone.
**Default value:** `'false'`
+| `scale ` | If set to `true` the module will display `C` for Celsius degrees and `F` for Fahrenheit degrees after the number, based on the value of the `units` option, otherwise only the ° character is displayed.
**Default value:** `false`
#### Default Icon Table
````javascript
diff --git a/modules/default/weatherforecast/forecast_screenshot.png b/modules/default/weatherforecast/forecast_screenshot.png
new file mode 100644
index 00000000..b9022adf
Binary files /dev/null and b/modules/default/weatherforecast/forecast_screenshot.png differ
diff --git a/modules/default/weatherforecast/weatherforecast.css b/modules/default/weatherforecast/weatherforecast.css
index 85d65685..21be13b7 100644
--- a/modules/default/weatherforecast/weatherforecast.css
+++ b/modules/default/weatherforecast/weatherforecast.css
@@ -19,9 +19,9 @@
}
.weatherforecast tr.colored .min-temp {
- color: #BCDDFF;
+ color: #BCDDFF;
}
.weatherforecast tr.colored .max-temp {
- color: #FF8E99;
+ color: #FF8E99;
}
diff --git a/modules/default/weatherforecast/weatherforecast.js b/modules/default/weatherforecast/weatherforecast.js
index b8321b17..b6b57d8c 100644
--- a/modules/default/weatherforecast/weatherforecast.js
+++ b/modules/default/weatherforecast/weatherforecast.js
@@ -21,19 +21,22 @@ Module.register("weatherforecast",{
animationSpeed: 1000,
timeFormat: config.timeFormat,
lang: config.language,
+ decimalSymbol: ".",
fade: true,
fadePoint: 0.25, // Start on 1/4th of the list.
colored: false,
+ scale: false,
initialLoadDelay: 2500, // 2.5 seconds delay. This delay is used to keep the OpenWeather API happy.
retryDelay: 2500,
apiVersion: "2.5",
- apiBase: "http://api.openweathermap.org/data/",
+ apiBase: "https://api.openweathermap.org/data/",
forecastEndpoint: "forecast/daily",
appendLocationNameToHeader: true,
calendarClass: "calendar",
+ tableClass: "small",
roundTemp: false,
@@ -63,7 +66,7 @@ Module.register("weatherforecast",{
firstEvent: false,
// create a variable to hold the location name based on the API result.
- fetchedLocatioName: "",
+ fetchedLocationName: "",
// Define required scripts.
getScripts: function() {
@@ -79,7 +82,7 @@ Module.register("weatherforecast",{
getTranslations: function() {
// The translations for the default modules are defined in the core translation files.
// Therefor we can just return false. Otherwise we should have returned a dictionary.
- // If you're trying to build yiur own module including translations, check out the documentation.
+ // If you're trying to build your own module including translations, check out the documentation.
return false;
},
@@ -115,7 +118,7 @@ Module.register("weatherforecast",{
}
var table = document.createElement("table");
- table.className = "small";
+ table.className = this.config.tableClass;
for (var f in this.forecast) {
var forecast = this.forecast[f];
@@ -139,13 +142,35 @@ Module.register("weatherforecast",{
icon.className = "wi weathericon " + forecast.icon;
iconCell.appendChild(icon);
+ var degreeLabel = "";
+ if (this.config.units === "metric" || this.config.units === "imperial") {
+ degreeLabel += "°";
+ }
+ if(this.config.scale) {
+ switch(this.config.units) {
+ case "metric":
+ degreeLabel += "C";
+ break;
+ case "imperial":
+ degreeLabel += "F";
+ break;
+ case "default":
+ degreeLabel = "K";
+ break;
+ }
+ }
+
+ if (this.config.decimalSymbol === "" || this.config.decimalSymbol === " ") {
+ this.config.decimalSymbol = ".";
+ }
+
var maxTempCell = document.createElement("td");
- maxTempCell.innerHTML = forecast.maxTemp;
+ maxTempCell.innerHTML = forecast.maxTemp.replace(".", this.config.decimalSymbol) + degreeLabel;
maxTempCell.className = "align-right bright max-temp";
row.appendChild(maxTempCell);
var minTempCell = document.createElement("td");
- minTempCell.innerHTML = forecast.minTemp;
+ minTempCell.innerHTML = forecast.minTemp.replace(".", this.config.decimalSymbol) + degreeLabel;
minTempCell.className = "align-right min-temp";
row.appendChild(minTempCell);
@@ -155,7 +180,7 @@ Module.register("weatherforecast",{
rainCell.innerHTML = "";
} else {
if(config.units !== "imperial") {
- rainCell.innerHTML = forecast.rain + " mm";
+ rainCell.innerHTML = parseFloat(forecast.rain).toFixed(1) + " mm";
} else {
rainCell.innerHTML = (parseFloat(forecast.rain) / 25.4).toFixed(2) + " in";
}
@@ -175,7 +200,6 @@ Module.register("weatherforecast",{
row.style.opacity = 1 - (1 / steps * currentStep);
}
}
-
}
return table;
@@ -184,7 +208,7 @@ Module.register("weatherforecast",{
// Override getHeader method.
getHeader: function() {
if (this.config.appendLocationNameToHeader) {
- return this.data.header + " " + this.fetchedLocatioName;
+ return this.data.header + " " + this.fetchedLocationName;
}
return this.data.header;
@@ -200,10 +224,9 @@ Module.register("weatherforecast",{
if (notification === "CALENDAR_EVENTS") {
var senderClasses = sender.data.classes.toLowerCase().split(" ");
if (senderClasses.indexOf(this.config.calendarClass.toLowerCase()) !== -1) {
- var lastEvent = this.firstEvent;
this.firstEvent = false;
- for (e in payload) {
+ for (var e in payload) {
var event = payload[e];
if (event.location || event.geo) {
this.firstEvent = event;
@@ -217,7 +240,7 @@ Module.register("weatherforecast",{
/* updateWeather(compliments)
* Requests new data from openweather.org.
- * Calls processWeather on succesfull response.
+ * Calls processWeather on successful response.
*/
updateWeather: function() {
if (this.config.appid === "") {
@@ -238,7 +261,11 @@ Module.register("weatherforecast",{
} else if (this.status === 401) {
self.updateDom(self.config.animationSpeed);
- Log.error(self.name + ": Incorrect APPID.");
+ if (self.config.forecastEndpoint === "forecast/daily") {
+ self.config.forecastEndpoint = "forecast";
+ Log.warn(self.name + ": Your AppID does not support long term forecasts. Switching to fallback endpoint.");
+ }
+
retry = true;
} else {
Log.error(self.name + ": Could not load weather.");
@@ -264,7 +291,7 @@ Module.register("weatherforecast",{
} else if(this.config.location) {
params += "q=" + this.config.location;
} else if (this.firstEvent && this.firstEvent.geo) {
- params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon
+ params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon;
} else if (this.firstEvent && this.firstEvent.location) {
params += "q=" + this.firstEvent.location;
} else {
@@ -274,38 +301,80 @@ Module.register("weatherforecast",{
params += "&units=" + this.config.units;
params += "&lang=" + this.config.lang;
- /*
- * Submit a specific number of days to forecast, between 1 to 16 days.
- * The OpenWeatherMap API properly handles values outside of the 1 - 16 range and returns 7 days by default.
- * This is simply being pedantic and doing it ourselves.
- */
- params += "&cnt=" + (((this.config.maxNumberOfDays < 1) || (this.config.maxNumberOfDays > 16)) ? 7 : this.config.maxNumberOfDays);
params += "&APPID=" + this.config.appid;
return params;
},
+ /*
+ * parserDataWeather(data)
+ *
+ * Use the parse to keep the same struct between daily and forecast Endpoint
+ * from Openweather
+ *
+ */
+ parserDataWeather: function(data) {
+ if (data.hasOwnProperty("main")) {
+ data["temp"] = {"min": data.main.temp_min, "max": data.main.temp_max};
+ }
+ return data;
+ },
+
/* processWeather(data)
* Uses the received data to set the various values.
*
* argument data object - Weather information received form openweather.org.
*/
processWeather: function(data) {
- this.fetchedLocatioName = data.city.name + ", " + data.city.country;
+ this.fetchedLocationName = data.city.name + ", " + data.city.country;
this.forecast = [];
+ var lastDay = null;
+ var forecastData = {};
+
for (var i = 0, count = data.list.length; i < count; i++) {
var forecast = data.list[i];
- this.forecast.push({
+ this.parserDataWeather(forecast); // hack issue #1017
- day: moment(forecast.dt, "X").format("ddd"),
- icon: this.config.iconTable[forecast.weather[0].icon],
- maxTemp: this.roundValue(forecast.temp.max),
- minTemp: this.roundValue(forecast.temp.min),
- rain: this.roundValue(forecast.rain)
+ var day;
+ var hour;
+ if(!!forecast.dt_txt) {
+ day = moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss").format("ddd");
+ hour = moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss").format("H");
+ } else {
+ day = moment(forecast.dt, "X").format("ddd");
+ hour = moment(forecast.dt, "X").format("H");
+ }
- });
+ if (day !== lastDay) {
+ var forecastData = {
+ day: day,
+ icon: this.config.iconTable[forecast.weather[0].icon],
+ maxTemp: this.roundValue(forecast.temp.max),
+ minTemp: this.roundValue(forecast.temp.min),
+ rain: forecast.rain
+ };
+
+ this.forecast.push(forecastData);
+ lastDay = day;
+
+ // Stop processing when maxNumberOfDays is reached
+ if (this.forecast.length === this.config.maxNumberOfDays) {
+ break;
+ }
+ } else {
+ //Log.log("Compare max: ", forecast.temp.max, parseFloat(forecastData.maxTemp));
+ forecastData.maxTemp = forecast.temp.max > parseFloat(forecastData.maxTemp) ? this.roundValue(forecast.temp.max) : forecastData.maxTemp;
+ //Log.log("Compare min: ", forecast.temp.min, parseFloat(forecastData.minTemp));
+ forecastData.minTemp = forecast.temp.min < parseFloat(forecastData.minTemp) ? this.roundValue(forecast.temp.min) : forecastData.minTemp;
+
+ // Since we don't want an icon from the start of the day (in the middle of the night)
+ // we update the icon as long as it's somewhere during the day.
+ if (hour >= 8 && hour <= 17) {
+ forecastData.icon = this.config.iconTable[forecast.weather[0].icon];
+ }
+ }
}
//Log.log(this.forecast);
@@ -335,6 +404,10 @@ Module.register("weatherforecast",{
/* ms2Beaufort(ms)
* Converts m2 to beaufort (windspeed).
*
+ * see:
+ * http://www.spc.noaa.gov/faq/tornado/beaufort.html
+ * https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale
+ *
* argument ms number - Windspeed in m/s.
*
* return number - Windspeed in beaufort.
@@ -356,7 +429,7 @@ Module.register("weatherforecast",{
*
* argument temperature number - Temperature.
*
- * return number - Rounded Temperature.
+ * return string - Rounded Temperature.
*/
roundValue: function(temperature) {
var decimals = this.config.roundTemp ? 0 : 1;
diff --git a/modules/node_modules/node_helper/index.js b/modules/node_modules/node_helper/index.js
index 37c3e2cb..92931140 100644
--- a/modules/node_modules/node_helper/index.js
+++ b/modules/node_modules/node_helper/index.js
@@ -23,6 +23,16 @@ NodeHelper = Class.extend({
console.log("Starting module helper: " + this.name);
},
+ /* stop()
+ * Called when the MagicMirror server receives a `SIGINT`
+ * Close any open connections, stop any sub-processes and
+ * gracefully exit the module.
+ *
+ */
+ stop: function() {
+ console.log("Stopping module helper: " + this.name);
+ },
+
/* socketNotificationReceived(notification, payload)
* This method is called when a socket notification arrives.
*
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 00000000..17b8ce12
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,8560 @@
+{
+ "name": "magicmirror",
+ "version": "2.9.0-develop",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@babel/code-frame": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
+ "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
+ "dev": true,
+ "requires": {
+ "@babel/highlight": "^7.0.0"
+ }
+ },
+ "@babel/core": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz",
+ "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/generator": "^7.4.4",
+ "@babel/helpers": "^7.4.4",
+ "@babel/parser": "^7.4.5",
+ "@babel/template": "^7.4.4",
+ "@babel/traverse": "^7.4.5",
+ "@babel/types": "^7.4.4",
+ "convert-source-map": "^1.1.0",
+ "debug": "^4.1.0",
+ "json5": "^2.1.0",
+ "lodash": "^4.17.11",
+ "resolve": "^1.3.2",
+ "semver": "^5.4.1",
+ "source-map": "^0.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "json5": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz",
+ "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.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
+ }
+ }
+ },
+ "@babel/generator": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz",
+ "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.4.4",
+ "jsesc": "^2.5.1",
+ "lodash": "^4.17.11",
+ "source-map": "^0.5.0",
+ "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=",
+ "dev": true
+ }
+ }
+ },
+ "@babel/helper-function-name": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz",
+ "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==",
+ "dev": true,
+ "requires": {
+ "@babel/helper-get-function-arity": "^7.0.0",
+ "@babel/template": "^7.1.0",
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@babel/helper-get-function-arity": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz",
+ "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.0.0"
+ }
+ },
+ "@babel/helper-split-export-declaration": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz",
+ "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==",
+ "dev": true,
+ "requires": {
+ "@babel/types": "^7.4.4"
+ }
+ },
+ "@babel/helpers": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz",
+ "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==",
+ "dev": true,
+ "requires": {
+ "@babel/template": "^7.4.4",
+ "@babel/traverse": "^7.4.4",
+ "@babel/types": "^7.4.4"
+ }
+ },
+ "@babel/highlight": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
+ "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.0",
+ "esutils": "^2.0.2",
+ "js-tokens": "^4.0.0"
+ }
+ },
+ "@babel/parser": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz",
+ "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==",
+ "dev": true
+ },
+ "@babel/template": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz",
+ "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/parser": "^7.4.4",
+ "@babel/types": "^7.4.4"
+ }
+ },
+ "@babel/traverse": {
+ "version": "7.4.5",
+ "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz",
+ "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "@babel/generator": "^7.4.4",
+ "@babel/helper-function-name": "^7.1.0",
+ "@babel/helper-split-export-declaration": "^7.4.4",
+ "@babel/parser": "^7.4.5",
+ "@babel/types": "^7.4.4",
+ "debug": "^4.1.0",
+ "globals": "^11.1.0",
+ "lodash": "^4.17.11"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "@babel/types": {
+ "version": "7.4.4",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz",
+ "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2",
+ "lodash": "^4.17.11",
+ "to-fast-properties": "^2.0.0"
+ }
+ },
+ "@mrmlnc/readdir-enhanced": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz",
+ "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==",
+ "dev": true,
+ "requires": {
+ "call-me-maybe": "^1.0.1",
+ "glob-to-regexp": "^0.3.0"
+ }
+ },
+ "@nodelib/fs.stat": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz",
+ "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==",
+ "dev": true
+ },
+ "@octokit/rest": {
+ "version": "15.18.1",
+ "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.1.tgz",
+ "integrity": "sha512-g2tecjp2TEtYV8bKAFvfQtu+W29HM7ektmWmw8zrMy9/XCKDEYRErR2YvvhN9+IxkLC4O3lDqYP4b6WgsL6Utw==",
+ "dev": true,
+ "requires": {
+ "before-after-hook": "^1.1.0",
+ "btoa-lite": "^1.0.0",
+ "debug": "^3.1.0",
+ "http-proxy-agent": "^2.1.0",
+ "https-proxy-agent": "^2.2.0",
+ "lodash": "^4.17.4",
+ "node-fetch": "^2.1.1",
+ "universal-user-agent": "^2.0.0",
+ "url-template": "^2.0.8"
+ }
+ },
+ "@types/events": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/@types/events/-/events-3.0.0.tgz",
+ "integrity": "sha512-EaObqwIvayI5a8dCzhFrjKzVwKLxjoG9T6Ppd5CEo07LRKfQ8Yokw54r5+Wq7FaBQ+yXRvQAYPrHwya1/UFt9g==",
+ "dev": true
+ },
+ "@types/glob": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.1.tgz",
+ "integrity": "sha512-1Bh06cbWJUHMC97acuD6UMG29nMt0Aqz1vF3guLfG+kHHJhy3AyohZFFxYk2f7Q1SQIrNwvncxAE0N/9s70F2w==",
+ "dev": true,
+ "requires": {
+ "@types/events": "*",
+ "@types/minimatch": "*",
+ "@types/node": "*"
+ }
+ },
+ "@types/minimatch": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+ "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+ "dev": true
+ },
+ "@types/node": {
+ "version": "8.10.49",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-8.10.49.tgz",
+ "integrity": "sha512-YX30JVx0PvSmJ3Eqr74fYLGeBxD+C7vIL20ek+GGGLJeUbVYRUW3EzyAXpIRA0K8c8o0UWqR/GwEFYiFoz1T8w=="
+ },
+ "@types/unist": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.3.tgz",
+ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==",
+ "dev": true
+ },
+ "@types/vfile": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz",
+ "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/unist": "*",
+ "@types/vfile-message": "*"
+ }
+ },
+ "@types/vfile-message": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-1.0.1.tgz",
+ "integrity": "sha512-mlGER3Aqmq7bqR1tTTIVHq8KSAFFRyGbrxuM8C/H82g6k7r2fS+IMEkIu3D7JHzG10NvPdR8DNx0jr0pwpp4dA==",
+ "dev": true,
+ "requires": {
+ "@types/node": "*",
+ "@types/unist": "*"
+ }
+ },
+ "JSV": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz",
+ "integrity": "sha1-0Hf2glVx+CEy+d/67Vh7QCn+/1c=",
+ "dev": true
+ },
+ "abab": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.0.tgz",
+ "integrity": "sha512-sY5AXXVZv4Y1VACTtR11UJCPHHudgY5i26Qj5TypE6DKlIApbwb5uqhXcJ5UUGbvZNRh7EeIoW+LrJumBsKp7w==",
+ "dev": true
+ },
+ "abbrev": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz",
+ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==",
+ "dev": true
+ },
+ "accepts": {
+ "version": "1.3.7",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz",
+ "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==",
+ "requires": {
+ "mime-types": "~2.1.24",
+ "negotiator": "0.6.2"
+ }
+ },
+ "acorn": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz",
+ "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==",
+ "dev": true
+ },
+ "acorn-globals": {
+ "version": "4.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-4.3.2.tgz",
+ "integrity": "sha512-BbzvZhVtZP+Bs1J1HcwrQe8ycfO0wStkSGxuul3He3GkHOIZ6eTqOkPuw9IP1X3+IkOo4wiJmwkobzXYz4wewQ==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.0.1",
+ "acorn-walk": "^6.0.1"
+ }
+ },
+ "acorn-jsx": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz",
+ "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==",
+ "dev": true
+ },
+ "acorn-walk": {
+ "version": "6.1.1",
+ "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-6.1.1.tgz",
+ "integrity": "sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw==",
+ "dev": true
+ },
+ "after": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
+ "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
+ },
+ "agent-base": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.2.1.tgz",
+ "integrity": "sha512-JVwXMr9nHYTUXsBFKUqhJwvlcYU/blreOEUkhNR2eXZIvwd+c+o5V4MgDPKWnMS/56awN3TRzIP+KoPn+roQtg==",
+ "dev": true,
+ "requires": {
+ "es6-promisify": "^5.0.0"
+ }
+ },
+ "ajv": {
+ "version": "6.10.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
+ "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
+ "requires": {
+ "fast-deep-equal": "^2.0.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-escapes": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz",
+ "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==",
+ "dev": true
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8="
+ },
+ "ansi-styles": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+ "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+ "dev": true,
+ "requires": {
+ "color-convert": "^1.9.0"
+ }
+ },
+ "apache-crypt": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.1.tgz",
+ "integrity": "sha1-1vxyqm0n2ZyVqU/RiNcx7v/6Zjw=",
+ "dev": true,
+ "requires": {
+ "unix-crypt-td-js": "^1.0.0"
+ }
+ },
+ "apache-md5": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.2.tgz",
+ "integrity": "sha1-7klza2ObTxCLbp5ibG2pkwa0FpI=",
+ "dev": true
+ },
+ "archiver": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/archiver/-/archiver-2.1.1.tgz",
+ "integrity": "sha1-/2YrSnggFJSj7lRNOjP+dJZQnrw=",
+ "dev": true,
+ "requires": {
+ "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",
+ "zip-stream": "^1.2.0"
+ },
+ "dependencies": {
+ "async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+ "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "archiver-utils": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/archiver-utils/-/archiver-utils-1.3.0.tgz",
+ "integrity": "sha1-5QtMCccL89aA4y/xt5lOn52JUXQ=",
+ "dev": true,
+ "requires": {
+ "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"
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "argparse": {
+ "version": "1.0.10",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
+ "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "~1.0.2"
+ },
+ "dependencies": {
+ "sprintf-js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
+ "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
+ "dev": true
+ }
+ }
+ },
+ "arr-diff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz",
+ "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=",
+ "dev": true
+ },
+ "arr-flatten": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz",
+ "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==",
+ "dev": true
+ },
+ "arr-union": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz",
+ "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=",
+ "dev": true
+ },
+ "array-equal": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz",
+ "integrity": "sha1-jCpe8kcv2ep0KwTHenUJO6J1fJM=",
+ "dev": true
+ },
+ "array-find-index": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz",
+ "integrity": "sha1-3wEKoSh+Fku9pvlyOwqWoexBh6E="
+ },
+ "array-flatten": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
+ "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
+ },
+ "array-union": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz",
+ "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=",
+ "dev": true,
+ "requires": {
+ "array-uniq": "^1.0.1"
+ }
+ },
+ "array-uniq": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz",
+ "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=",
+ "dev": true
+ },
+ "array-unique": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz",
+ "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=",
+ "dev": true
+ },
+ "arraybuffer.slice": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
+ "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
+ },
+ "arrify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz",
+ "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
+ "dev": true
+ },
+ "asn1": {
+ "version": "0.2.4",
+ "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
+ "integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
+ "requires": {
+ "safer-buffer": "~2.1.0"
+ }
+ },
+ "assert-plus": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
+ "integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU="
+ },
+ "assertion-error": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz",
+ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==",
+ "dev": true
+ },
+ "assign-symbols": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz",
+ "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=",
+ "dev": true
+ },
+ "astral-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz",
+ "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==",
+ "dev": true
+ },
+ "async": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz",
+ "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
+ "dev": true
+ },
+ "async-limiter": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
+ "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
+ },
+ "asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k="
+ },
+ "atob": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz",
+ "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==",
+ "dev": true
+ },
+ "autoprefixer": {
+ "version": "9.6.0",
+ "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.6.0.tgz",
+ "integrity": "sha512-kuip9YilBqhirhHEGHaBTZKXL//xxGnzvsD0FtBQa6z+A69qZD6s/BAX9VzDF1i9VKDquTJDQaPLSEhOnL6FvQ==",
+ "dev": true,
+ "requires": {
+ "browserslist": "^4.6.1",
+ "caniuse-lite": "^1.0.30000971",
+ "chalk": "^2.4.2",
+ "normalize-range": "^0.1.2",
+ "num2fraction": "^1.2.2",
+ "postcss": "^7.0.16",
+ "postcss-value-parser": "^3.3.1"
+ }
+ },
+ "aws-sign2": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
+ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg="
+ },
+ "aws4": {
+ "version": "1.8.0",
+ "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
+ "integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ=="
+ },
+ "babel-polyfill": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-polyfill/-/babel-polyfill-6.26.0.tgz",
+ "integrity": "sha1-N5k3q8Z9eJWXCtxiHyhM2WbPIVM=",
+ "dev": true,
+ "requires": {
+ "babel-runtime": "^6.26.0",
+ "core-js": "^2.5.0",
+ "regenerator-runtime": "^0.10.5"
+ }
+ },
+ "babel-runtime": {
+ "version": "6.26.0",
+ "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz",
+ "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=",
+ "dev": true,
+ "requires": {
+ "core-js": "^2.4.0",
+ "regenerator-runtime": "^0.11.0"
+ },
+ "dependencies": {
+ "regenerator-runtime": {
+ "version": "0.11.1",
+ "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz",
+ "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==",
+ "dev": true
+ }
+ }
+ },
+ "backo2": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
+ "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
+ },
+ "bail": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.4.tgz",
+ "integrity": "sha512-S8vuDB4w6YpRhICUDET3guPlQpaJl7od94tpZ0Fvnyp+MKW/HyDTcRDck+29C9g+d/qQHnddRH3+94kZdrW0Ww==",
+ "dev": true
+ },
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "base": {
+ "version": "0.11.2",
+ "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz",
+ "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==",
+ "dev": true,
+ "requires": {
+ "cache-base": "^1.0.1",
+ "class-utils": "^0.3.5",
+ "component-emitter": "^1.2.1",
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.1",
+ "mixin-deep": "^1.2.0",
+ "pascalcase": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "base64-arraybuffer": {
+ "version": "0.1.5",
+ "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
+ "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
+ },
+ "base64-js": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.0.tgz",
+ "integrity": "sha512-ccav/yGvoa80BQDljCxsmmQ3Xvx60/UpBIij5QN21W3wBi/hhIC9OoO+KLpu9IJTS9j4DRVJ3aDDF9cMSoa2lw==",
+ "dev": true
+ },
+ "base64id": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
+ "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
+ },
+ "bcrypt-pbkdf": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
+ "integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
+ "requires": {
+ "tweetnacl": "^0.14.3"
+ }
+ },
+ "bcryptjs": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz",
+ "integrity": "sha1-mrVie5PmBiH/fNrF2pczAn3x0Ms=",
+ "dev": true
+ },
+ "before-after-hook": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/before-after-hook/-/before-after-hook-1.4.0.tgz",
+ "integrity": "sha512-l5r9ir56nda3qu14nAXIlyq1MmUSs0meCIaFAh8HwkFwP1F8eToOuS3ah2VAHHcY04jaYD7FpJC5JTXHYRbkzg==",
+ "dev": true
+ },
+ "better-assert": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
+ "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
+ "requires": {
+ "callsite": "1.0.0"
+ }
+ },
+ "bl": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/bl/-/bl-1.2.2.tgz",
+ "integrity": "sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA==",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.3.5",
+ "safe-buffer": "^5.1.1"
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "blob": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.5.tgz",
+ "integrity": "sha512-gaqbzQPqOoamawKg0LGVd7SzLgXS+JH61oWprSLH+P+abTczqJbhTR8CmJ2u9/bUYNmHTGJx/UEmn6doAvvuig=="
+ },
+ "body-parser": {
+ "version": "1.19.0",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz",
+ "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==",
+ "requires": {
+ "bytes": "3.1.0",
+ "content-type": "~1.0.4",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "on-finished": "~2.3.0",
+ "qs": "6.7.0",
+ "raw-body": "2.4.0",
+ "type-is": "~1.6.17"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ }
+ }
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "dev": true,
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "2.3.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz",
+ "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==",
+ "dev": true,
+ "requires": {
+ "arr-flatten": "^1.1.0",
+ "array-unique": "^0.3.2",
+ "extend-shallow": "^2.0.1",
+ "fill-range": "^4.0.0",
+ "isobject": "^3.0.1",
+ "repeat-element": "^1.1.2",
+ "snapdragon": "^0.8.1",
+ "snapdragon-node": "^2.0.1",
+ "split-string": "^3.0.2",
+ "to-regex": "^3.0.1"
+ }
+ },
+ "browser-process-hrtime": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-0.1.3.tgz",
+ "integrity": "sha512-bRFnI4NnjO6cnyLmOV/7PVoDEMJChlcfN0z4s1YMBY989/SvlfMI1lgCnkFUs53e9gQF+w7qu7XdllSTiSl8Aw==",
+ "dev": true
+ },
+ "browser-stdout": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz",
+ "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=",
+ "dev": true
+ },
+ "browserslist": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.2.tgz",
+ "integrity": "sha512-2neU/V0giQy9h3XMPwLhEY3+Ao0uHSwHvU8Q1Ea6AgLVL1sXbX3dzPrJ8NWe5Hi4PoTkCYXOtVR9rfRLI0J/8Q==",
+ "dev": true,
+ "requires": {
+ "caniuse-lite": "^1.0.30000974",
+ "electron-to-chromium": "^1.3.150",
+ "node-releases": "^1.1.23"
+ }
+ },
+ "btoa-lite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/btoa-lite/-/btoa-lite-1.0.0.tgz",
+ "integrity": "sha1-M3dm2hWAEhD92VbCLpxokaudAzc=",
+ "dev": true
+ },
+ "buffer": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.2.1.tgz",
+ "integrity": "sha512-c+Ko0loDaFfuPWiL02ls9Xd3GO3cPVmUobQ6t3rXNUk304u6hGq+8N/kFi+QEIKhzK3uwolVhLzszmfLmMLnqg==",
+ "dev": true,
+ "requires": {
+ "base64-js": "^1.0.2",
+ "ieee754": "^1.1.4"
+ }
+ },
+ "buffer-alloc": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc/-/buffer-alloc-1.2.0.tgz",
+ "integrity": "sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow==",
+ "dev": true,
+ "requires": {
+ "buffer-alloc-unsafe": "^1.1.0",
+ "buffer-fill": "^1.0.0"
+ }
+ },
+ "buffer-alloc-unsafe": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz",
+ "integrity": "sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg==",
+ "dev": true
+ },
+ "buffer-crc32": {
+ "version": "0.2.13",
+ "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
+ "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=",
+ "dev": true
+ },
+ "buffer-equal-constant-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz",
+ "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=",
+ "dev": true
+ },
+ "buffer-fill": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/buffer-fill/-/buffer-fill-1.0.0.tgz",
+ "integrity": "sha1-+PeLdniYiO858gXNY39o5wISKyw=",
+ "dev": true
+ },
+ "buffer-from": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
+ "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
+ },
+ "bytes": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz",
+ "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg=="
+ },
+ "cache-base": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz",
+ "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==",
+ "dev": true,
+ "requires": {
+ "collection-visit": "^1.0.0",
+ "component-emitter": "^1.2.1",
+ "get-value": "^2.0.6",
+ "has-value": "^1.0.0",
+ "isobject": "^3.0.1",
+ "set-value": "^2.0.0",
+ "to-object-path": "^0.3.0",
+ "union-value": "^1.0.0",
+ "unset-value": "^1.0.0"
+ }
+ },
+ "call-me-maybe": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz",
+ "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=",
+ "dev": true
+ },
+ "caller-callsite": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz",
+ "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=",
+ "dev": true,
+ "requires": {
+ "callsites": "^2.0.0"
+ },
+ "dependencies": {
+ "callsites": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz",
+ "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=",
+ "dev": true
+ }
+ }
+ },
+ "caller-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz",
+ "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=",
+ "dev": true,
+ "requires": {
+ "caller-callsite": "^2.0.0"
+ }
+ },
+ "callsite": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
+ "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
+ },
+ "callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true
+ },
+ "camelcase": {
+ "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",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-2.1.0.tgz",
+ "integrity": "sha1-MIvur/3ygRkFHvodkyITyRuPkuc=",
+ "requires": {
+ "camelcase": "^2.0.0",
+ "map-obj": "^1.0.0"
+ }
+ },
+ "camelize": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.0.tgz",
+ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs="
+ },
+ "caniuse-lite": {
+ "version": "1.0.30000974",
+ "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz",
+ "integrity": "sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww==",
+ "dev": true
+ },
+ "caseless": {
+ "version": "0.12.0",
+ "resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
+ "integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw="
+ },
+ "ccount": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.4.tgz",
+ "integrity": "sha512-fpZ81yYfzentuieinmGnphk0pLkOTMm6MZdVqwd77ROvhko6iujLNGrHH5E7utq3ygWklwfmwuG+A7P+NpqT6w==",
+ "dev": true
+ },
+ "chai": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz",
+ "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==",
+ "dev": true,
+ "requires": {
+ "assertion-error": "^1.1.0",
+ "check-error": "^1.0.2",
+ "deep-eql": "^3.0.1",
+ "get-func-name": "^2.0.0",
+ "pathval": "^1.1.0",
+ "type-detect": "^4.0.5"
+ }
+ },
+ "chai-as-promised": {
+ "version": "7.1.1",
+ "resolved": "https://registry.npmjs.org/chai-as-promised/-/chai-as-promised-7.1.1.tgz",
+ "integrity": "sha512-azL6xMoi+uxu6z4rhWQ1jbdUhOMhis2PvscD/xjLqNMkv3BPPp2JyyuTHOrf9BOosGpNQ11v6BKv/g57RXbiaA==",
+ "dev": true,
+ "requires": {
+ "check-error": "^1.0.2"
+ }
+ },
+ "chalk": {
+ "version": "2.4.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+ "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.1",
+ "escape-string-regexp": "^1.0.5",
+ "supports-color": "^5.3.0"
+ }
+ },
+ "character-entities": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz",
+ "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==",
+ "dev": true
+ },
+ "character-entities-html4": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.3.tgz",
+ "integrity": "sha512-SwnyZ7jQBCRHELk9zf2CN5AnGEc2nA+uKMZLHvcqhpPprjkYhiLn0DywMHgN5ttFZuITMATbh68M6VIVKwJbcg==",
+ "dev": true
+ },
+ "character-entities-legacy": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.3.tgz",
+ "integrity": "sha512-YAxUpPoPwxYFsslbdKkhrGnXAtXoHNgYjlBM3WMXkWGTl5RsY3QmOyhwAgL8Nxm9l5LBThXGawxKPn68y6/fww==",
+ "dev": true
+ },
+ "character-reference-invalid": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.3.tgz",
+ "integrity": "sha512-VOq6PRzQBam/8Jm6XBGk2fNEnHXAdGd6go0rtd4weAGECBamHDwwCQSOT12TACIYUZegUXnV6xBXqUssijtxIg==",
+ "dev": true
+ },
+ "chardet": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
+ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
+ "dev": true
+ },
+ "check-error": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz",
+ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
+ "dev": true
+ },
+ "clarinet": {
+ "version": "0.12.3",
+ "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.3.tgz",
+ "integrity": "sha512-Vdv6MsBQWppWUCe/5EGa6JSYln0coSK98NsLAAbdqM3uTXmySZoGQXAMDgOAOlf5wjSIdeHVx9jhjkXOVDvoIA=="
+ },
+ "class-utils": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz",
+ "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==",
+ "dev": true,
+ "requires": {
+ "arr-union": "^3.1.0",
+ "define-property": "^0.2.5",
+ "isobject": "^3.0.0",
+ "static-extend": "^0.1.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ }
+ }
+ },
+ "cli": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/cli/-/cli-1.0.1.tgz",
+ "integrity": "sha1-IoF1NPJL+klQw01TLUjsvGIbjBQ=",
+ "dev": true,
+ "requires": {
+ "exit": "0.1.2",
+ "glob": "^7.1.1"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "cli-cursor": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz",
+ "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=",
+ "dev": true,
+ "requires": {
+ "restore-cursor": "^2.0.0"
+ }
+ },
+ "cli-width": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz",
+ "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=",
+ "dev": true
+ },
+ "cliui": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz",
+ "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==",
+ "dev": true,
+ "requires": {
+ "string-width": "^2.1.1",
+ "strip-ansi": "^4.0.0",
+ "wrap-ansi": "^2.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "clone-regexp": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz",
+ "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==",
+ "dev": true,
+ "requires": {
+ "is-regexp": "^2.0.0"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c="
+ },
+ "coffeescript": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz",
+ "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=",
+ "dev": true
+ },
+ "collapse-white-space": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.5.tgz",
+ "integrity": "sha512-703bOOmytCYAX9cXYqoikYIx6twmFCXsnzRQheBcTG3nzKYBR4P/+wkYeH+Mvj7qUz8zZDtdyzbxfnEi/kYzRQ==",
+ "dev": true
+ },
+ "collection-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz",
+ "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=",
+ "dev": true,
+ "requires": {
+ "map-visit": "^1.0.0",
+ "object-visit": "^1.0.0"
+ }
+ },
+ "color-convert": {
+ "version": "1.9.3",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
+ "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
+ "dev": true,
+ "requires": {
+ "color-name": "1.1.3"
+ }
+ },
+ "color-name": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
+ "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
+ "dev": true
+ },
+ "colors": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
+ "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg=="
+ },
+ "combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "requires": {
+ "delayed-stream": "~1.0.0"
+ }
+ },
+ "commander": {
+ "version": "2.20.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
+ "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
+ "dev": true
+ },
+ "component-bind": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
+ "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
+ },
+ "component-emitter": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
+ "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
+ },
+ "component-inherit": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
+ "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
+ },
+ "compress-commons": {
+ "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.1",
+ "crc32-stream": "^2.0.0",
+ "normalize-path": "^2.0.0",
+ "readable-stream": "^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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "concat-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz",
+ "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==",
+ "requires": {
+ "buffer-from": "^1.0.0",
+ "inherits": "^2.0.3",
+ "readable-stream": "^2.2.2",
+ "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.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.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"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "console-browserify": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz",
+ "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=",
+ "dev": true,
+ "requires": {
+ "date-now": "^0.1.4"
+ }
+ },
+ "content-disposition": {
+ "version": "0.5.3",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz",
+ "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==",
+ "requires": {
+ "safe-buffer": "5.1.2"
+ }
+ },
+ "content-security-policy-builder": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/content-security-policy-builder/-/content-security-policy-builder-2.0.0.tgz",
+ "integrity": "sha512-j+Nhmj1yfZAikJLImCvPJFE29x/UuBi+/MWqggGGc515JKaZrjuei2RhULJmy0MsstW3E3htl002bwmBNMKr7w=="
+ },
+ "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=="
+ },
+ "convert-source-map": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz",
+ "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.1"
+ }
+ },
+ "cookie": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
+ "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
+ },
+ "cookie-signature": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
+ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
+ },
+ "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.6.9",
+ "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz",
+ "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==",
+ "dev": true
+ },
+ "core-util-is": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
+ "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac="
+ },
+ "cosmiconfig": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz",
+ "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==",
+ "dev": true,
+ "requires": {
+ "import-fresh": "^2.0.0",
+ "is-directory": "^0.3.1",
+ "js-yaml": "^3.13.1",
+ "parse-json": "^4.0.0"
+ },
+ "dependencies": {
+ "import-fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz",
+ "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=",
+ "dev": true,
+ "requires": {
+ "caller-path": "^2.0.0",
+ "resolve-from": "^3.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "resolve-from": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz",
+ "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=",
+ "dev": true
+ }
+ }
+ },
+ "crc": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz",
+ "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==",
+ "dev": true,
+ "requires": {
+ "buffer": "^5.1.0"
+ }
+ },
+ "crc32-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/crc32-stream/-/crc32-stream-2.0.0.tgz",
+ "integrity": "sha1-483TtN8xaN10494/u8t7KX/pCPQ=",
+ "dev": true,
+ "requires": {
+ "crc": "^3.4.4",
+ "readable-stream": "^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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "cross-spawn": {
+ "version": "6.0.5",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz",
+ "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==",
+ "dev": true,
+ "requires": {
+ "nice-try": "^1.0.4",
+ "path-key": "^2.0.1",
+ "semver": "^5.5.0",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "css": {
+ "version": "2.2.4",
+ "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz",
+ "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "source-map": "^0.6.1",
+ "source-map-resolve": "^0.5.2",
+ "urix": "^0.1.0"
+ }
+ },
+ "css-parse": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/css-parse/-/css-parse-2.0.0.tgz",
+ "integrity": "sha1-pGjuZnwW2BzPBcWMONKpfHgNv9Q=",
+ "dev": true,
+ "requires": {
+ "css": "^2.0.0"
+ }
+ },
+ "css-value": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/css-value/-/css-value-0.0.1.tgz",
+ "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=",
+ "dev": true
+ },
+ "cssom": {
+ "version": "0.3.6",
+ "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.6.tgz",
+ "integrity": "sha512-DtUeseGk9/GBW0hl0vVPpU22iHL6YB5BUX7ml1hB+GMpo0NX5G4voX3kdWiMSEguFtcW3Vh3djqNF4aIe6ne0A==",
+ "dev": true
+ },
+ "cssstyle": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-1.2.2.tgz",
+ "integrity": "sha512-43wY3kl1CVQSvL7wUY1qXkxVGkStjpkDmVjiIKX8R97uhajy8Bybay78uOtqvh7Q5GK75dNPfW0geWjE6qQQow==",
+ "dev": true,
+ "requires": {
+ "cssom": "0.3.x"
+ }
+ },
+ "current-week-number": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/current-week-number/-/current-week-number-1.0.7.tgz",
+ "integrity": "sha1-VnJ4rrX+WN7LFQuayGT5Pc5O2XI=",
+ "dev": true
+ },
+ "currently-unhandled": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz",
+ "integrity": "sha1-mI3zP+qxke95mmE2nddsF635V+o=",
+ "requires": {
+ "array-find-index": "^1.0.1"
+ }
+ },
+ "danger": {
+ "version": "3.9.0",
+ "resolved": "https://registry.npmjs.org/danger/-/danger-3.9.0.tgz",
+ "integrity": "sha512-alFPZBK/ceTkEzjzrz1LOhi30Zn/2ZTLtBTUpqPhAEIV7G3CbjWYmZJdxnZtjW4cCh6UjHIgzyhMK6+MmnZP5g==",
+ "dev": true,
+ "requires": {
+ "@octokit/rest": "^15.9.5",
+ "babel-polyfill": "^6.23.0",
+ "chalk": "^2.3.0",
+ "commander": "^2.13.0",
+ "debug": "^3.1.0",
+ "get-stdin": "^6.0.0",
+ "https-proxy-agent": "^2.2.1",
+ "hyperlinker": "^1.0.0",
+ "jsome": "^2.3.25",
+ "json5": "^1.0.0",
+ "jsonpointer": "^4.0.1",
+ "jsonwebtoken": "^8.2.1",
+ "lodash.find": "^4.6.0",
+ "lodash.includes": "^4.3.0",
+ "lodash.isobject": "^3.0.2",
+ "lodash.keys": "^4.0.8",
+ "node-cleanup": "^2.1.2",
+ "node-fetch": "^2.1.2",
+ "p-limit": "^1.2.0",
+ "parse-diff": "^0.4.2",
+ "parse-git-config": "^2.0.2",
+ "parse-github-url": "^1.0.2",
+ "parse-link-header": "^1.0.1",
+ "pinpoint": "^1.1.0",
+ "readline-sync": "^1.4.9",
+ "require-from-string": "^2.0.2",
+ "rfc6902": "^2.2.2",
+ "supports-hyperlinks": "^1.0.1",
+ "vm2": "^3.6.0",
+ "voca": "^1.4.0"
+ },
+ "dependencies": {
+ "get-stdin": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz",
+ "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==",
+ "dev": true
+ }
+ }
+ },
+ "dashdash": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
+ "integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
+ "requires": {
+ "assert-plus": "^1.0.0"
+ }
+ },
+ "dasherize": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dasherize/-/dasherize-2.0.0.tgz",
+ "integrity": "sha1-bYCcnNDPe7iVLYD8hPoT1H3bEwg="
+ },
+ "data-urls": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-1.1.0.tgz",
+ "integrity": "sha512-YTWYI9se1P55u58gL5GkQHW4P6VJBJ5iBT+B5a7i2Tjadhv52paJG0qHX4A0OR6/t52odI64KP2YvFpkDOi3eQ==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "whatwg-mimetype": "^2.2.0",
+ "whatwg-url": "^7.0.0"
+ },
+ "dependencies": {
+ "whatwg-url": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-7.0.0.tgz",
+ "integrity": "sha512-37GeVSIJ3kn1JgKyjiYNmSLP1yzbpb29jdmwBSgkD9h40/hyrR/OifpVUndji3tmwGgD8qpw7iQu3RSbCrBpsQ==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ }
+ }
+ },
+ "date-now": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz",
+ "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=",
+ "dev": true
+ },
+ "date-time": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz",
+ "integrity": "sha1-GIdtC9pMGf5w3Tv0sDTygbEqQLY=",
+ "dev": true,
+ "requires": {
+ "time-zone": "^0.1.0"
+ }
+ },
+ "dateformat": {
+ "version": "1.0.12",
+ "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz",
+ "integrity": "sha1-nxJLZ1lMk3/3BpMuSmQsyo27/uk=",
+ "dev": true,
+ "requires": {
+ "get-stdin": "^4.0.1",
+ "meow": "^3.3.0"
+ }
+ },
+ "debug": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz",
+ "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
+ },
+ "decamelize-keys": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz",
+ "integrity": "sha1-0XGoeTMlKAfrPLYdwcFEXQeN8tk=",
+ "dev": true,
+ "requires": {
+ "decamelize": "^1.1.0",
+ "map-obj": "^1.0.0"
+ }
+ },
+ "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
+ },
+ "deep-eql": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz",
+ "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==",
+ "dev": true,
+ "requires": {
+ "type-detect": "^4.0.0"
+ }
+ },
+ "deep-extend": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
+ "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA=="
+ },
+ "deep-is": {
+ "version": "0.1.3",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz",
+ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=",
+ "dev": true
+ },
+ "deepmerge": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz",
+ "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ==",
+ "dev": true
+ },
+ "define-property": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz",
+ "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.2",
+ "isobject": "^3.0.1"
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk="
+ },
+ "depd": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
+ "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
+ },
+ "destroy": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
+ "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
+ },
+ "dev-null": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/dev-null/-/dev-null-0.1.1.tgz",
+ "integrity": "sha1-WiBc48Ky73e2I41roXnrdMag6Bg=",
+ "dev": true
+ },
+ "diff": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz",
+ "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==",
+ "dev": true
+ },
+ "dir-glob": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz",
+ "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==",
+ "dev": true,
+ "requires": {
+ "path-type": "^3.0.0"
+ },
+ "dependencies": {
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ }
+ },
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "dns-prefetch-control": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/dns-prefetch-control/-/dns-prefetch-control-0.1.0.tgz",
+ "integrity": "sha1-YN20V3dOF48flBXwyrsOhbCzALI="
+ },
+ "doctrine": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
+ "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
+ "dev": true,
+ "requires": {
+ "esutils": "^2.0.2"
+ }
+ },
+ "dom-serializer": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz",
+ "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.0",
+ "entities": "^1.1.1"
+ }
+ },
+ "domelementtype": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz",
+ "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==",
+ "dev": true
+ },
+ "domexception": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/domexception/-/domexception-1.0.1.tgz",
+ "integrity": "sha512-raigMkn7CJNNo6Ihro1fzG7wr3fHuYVytzquZKX5n0yizGsTcYgzdIUwj1X9pK0VvjeihV+XiclP+DjwbsSKug==",
+ "dev": true,
+ "requires": {
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "domhandler": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz",
+ "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1"
+ }
+ },
+ "domutils": {
+ "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",
+ "domelementtype": "1"
+ }
+ },
+ "dont-sniff-mimetype": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.0.0.tgz",
+ "integrity": "sha1-WTKJDcn04vGeXrAqIAJuXl78j1g="
+ },
+ "dot-prop": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-4.2.0.tgz",
+ "integrity": "sha512-tUMXrxlExSW6U2EXiiKGSBVdYgtV8qlHL+C10TsW4PURY/ic+eaysnSkwB4kA/mBlCyy/IKDJ+Lc3wbWeaXtuQ==",
+ "dev": true,
+ "requires": {
+ "is-obj": "^1.0.0"
+ }
+ },
+ "ecc-jsbn": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
+ "integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
+ "requires": {
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.1.0"
+ }
+ },
+ "ecdsa-sig-formatter": {
+ "version": "1.0.11",
+ "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz",
+ "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
+ },
+ "ejs": {
+ "version": "2.5.9",
+ "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.5.9.tgz",
+ "integrity": "sha512-GJCAeDBKfREgkBtgrYSf9hQy9kTb3helv0zGdzqhM7iAkW8FA/ZF97VQDbwFiwIT8MQLLOe5VlPZOEvZAqtUAQ==",
+ "dev": true
+ },
+ "electron": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/electron/-/electron-3.1.10.tgz",
+ "integrity": "sha512-IORdmdD5gWHmp3ffa+ZRD9kESJwdmQz8carDTeza6+W76dG447AUn7GmKk4cun31bLYTKb56D8pPhxa9S7kOZQ==",
+ "requires": {
+ "@types/node": "^8.0.24",
+ "electron-download": "^4.1.0",
+ "extract-zip": "^1.0.3"
+ }
+ },
+ "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"
+ }
+ },
+ "electron-download": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/electron-download/-/electron-download-4.1.1.tgz",
+ "integrity": "sha512-FjEWG9Jb/ppK/2zToP+U5dds114fM1ZOJqMAR4aXXL5CvyPE9fiqBK/9YcwC9poIFQTEJk/EM/zyRwziziRZrg==",
+ "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"
+ }
+ },
+ "electron-to-chromium": {
+ "version": "1.3.159",
+ "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.159.tgz",
+ "integrity": "sha512-bhiEr8/A97GUBcUzNb9MFNhzQOjakbKmEKBEAa6UMY45zG2e8PM63LOgAPXEJE9bQiaQH6nOdYiYf8X821tZjQ==",
+ "dev": true
+ },
+ "emoji-regex": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz",
+ "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==",
+ "dev": true
+ },
+ "encodeurl": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
+ "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
+ },
+ "end-of-stream": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz",
+ "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==",
+ "dev": true,
+ "requires": {
+ "once": "^1.4.0"
+ }
+ },
+ "engine.io": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.3.2.tgz",
+ "integrity": "sha512-AsaA9KG7cWPXWHp5FvHdDWY3AMWeZ8x+2pUVLcn71qE5AtAzgGbxuclOytygskw8XGmiQafTmnI9Bix3uihu2w==",
+ "requires": {
+ "accepts": "~1.3.4",
+ "base64id": "1.0.0",
+ "cookie": "0.3.1",
+ "debug": "~3.1.0",
+ "engine.io-parser": "~2.1.0",
+ "ws": "~6.1.0"
+ },
+ "dependencies": {
+ "cookie": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
+ "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
+ },
+ "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"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "engine.io-client": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.3.2.tgz",
+ "integrity": "sha512-y0CPINnhMvPuwtqXfsGuWE8BB66+B6wTtCofQDRecMQPYX3MYUZXFNKDhdrSe3EVjgOu4V3rxdeqN/Tr91IgbQ==",
+ "requires": {
+ "component-emitter": "1.2.1",
+ "component-inherit": "0.0.3",
+ "debug": "~3.1.0",
+ "engine.io-parser": "~2.1.1",
+ "has-cors": "1.1.0",
+ "indexof": "0.0.1",
+ "parseqs": "0.0.5",
+ "parseuri": "0.0.5",
+ "ws": "~6.1.0",
+ "xmlhttprequest-ssl": "~1.5.4",
+ "yeast": "0.1.2"
+ },
+ "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"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "engine.io-parser": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.3.tgz",
+ "integrity": "sha512-6HXPre2O4Houl7c4g7Ic/XzPnHBvaEmN90vtRO9uLmwtRqQmTOw0QMevL1TOfL2Cpu1VzsaTmMotQgMdkzGkVA==",
+ "requires": {
+ "after": "0.8.2",
+ "arraybuffer.slice": "~0.0.7",
+ "base64-arraybuffer": "0.1.5",
+ "blob": "0.0.5",
+ "has-binary2": "~1.0.2"
+ }
+ },
+ "entities": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz",
+ "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==",
+ "dev": true
+ },
+ "env-paths": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-1.0.0.tgz",
+ "integrity": "sha1-QWgTO0K7BcOKNbGuQ5fIKYqzaeA="
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "es6-promise": {
+ "version": "4.2.6",
+ "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.6.tgz",
+ "integrity": "sha512-aRVgGdnmW2OiySVPUC9e6m+plolMAJKjZnQlCwNSuK5yQ0JN61DZSO1X1Ufd1foqWRAlig0rhduTCHe7sVtK5Q==",
+ "dev": true
+ },
+ "es6-promisify": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
+ "integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
+ "dev": true,
+ "requires": {
+ "es6-promise": "^4.0.3"
+ }
+ },
+ "escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
+ },
+ "escape-string-regexp": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
+ "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
+ "dev": true
+ },
+ "escodegen": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-1.11.1.tgz",
+ "integrity": "sha512-JwiqFD9KdGVVpeuRa68yU3zZnBEOcPs0nKW7wZzXky8Z7tffdYUHbe11bPCV5jYlK6DVdKLWLm0f5I/QlL0Kmw==",
+ "dev": true,
+ "requires": {
+ "esprima": "^3.1.3",
+ "estraverse": "^4.2.0",
+ "esutils": "^2.0.2",
+ "optionator": "^0.8.1",
+ "source-map": "~0.6.1"
+ },
+ "dependencies": {
+ "esprima": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz",
+ "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=",
+ "dev": true
+ }
+ }
+ },
+ "eslint": {
+ "version": "5.16.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz",
+ "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==",
+ "dev": true,
+ "requires": {
+ "@babel/code-frame": "^7.0.0",
+ "ajv": "^6.9.1",
+ "chalk": "^2.1.0",
+ "cross-spawn": "^6.0.5",
+ "debug": "^4.0.1",
+ "doctrine": "^3.0.0",
+ "eslint-scope": "^4.0.3",
+ "eslint-utils": "^1.3.1",
+ "eslint-visitor-keys": "^1.0.0",
+ "espree": "^5.0.1",
+ "esquery": "^1.0.1",
+ "esutils": "^2.0.2",
+ "file-entry-cache": "^5.0.1",
+ "functional-red-black-tree": "^1.0.1",
+ "glob": "^7.1.2",
+ "globals": "^11.7.0",
+ "ignore": "^4.0.6",
+ "import-fresh": "^3.0.0",
+ "imurmurhash": "^0.1.4",
+ "inquirer": "^6.2.2",
+ "js-yaml": "^3.13.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "levn": "^0.3.0",
+ "lodash": "^4.17.11",
+ "minimatch": "^3.0.4",
+ "mkdirp": "^0.5.1",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.8.2",
+ "path-is-inside": "^1.0.2",
+ "progress": "^2.0.0",
+ "regexpp": "^2.0.1",
+ "semver": "^5.5.1",
+ "strip-ansi": "^4.0.0",
+ "strip-json-comments": "^2.0.1",
+ "table": "^5.2.3",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "eslint-scope": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz",
+ "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==",
+ "dev": true,
+ "requires": {
+ "esrecurse": "^4.1.0",
+ "estraverse": "^4.1.1"
+ }
+ },
+ "eslint-utils": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz",
+ "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==",
+ "dev": true
+ },
+ "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==",
+ "dev": true
+ },
+ "espree": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz",
+ "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==",
+ "dev": true,
+ "requires": {
+ "acorn": "^6.0.7",
+ "acorn-jsx": "^5.0.0",
+ "eslint-visitor-keys": "^1.0.0"
+ }
+ },
+ "esprima": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
+ "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
+ "dev": true
+ },
+ "esquery": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz",
+ "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.0.0"
+ }
+ },
+ "esrecurse": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz",
+ "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==",
+ "dev": true,
+ "requires": {
+ "estraverse": "^4.1.0"
+ }
+ },
+ "estraverse": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz",
+ "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=",
+ "dev": true
+ },
+ "esutils": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
+ "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
+ "dev": true
+ },
+ "etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
+ },
+ "eventemitter2": {
+ "version": "0.4.14",
+ "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz",
+ "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=",
+ "dev": true
+ },
+ "eventyoshi": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/eventyoshi/-/eventyoshi-0.2.1.tgz",
+ "integrity": "sha512-74HGaBn3Okqlv+mLFBRgqAgG5X8FvmHzrAZcJ7SG8nZZiLgRR2or0kJrkJ3GT5NncQDwHYh/sO7Cpzne+Ep2LA=="
+ },
+ "execa": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz",
+ "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^6.0.0",
+ "get-stream": "^4.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "execall": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz",
+ "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==",
+ "dev": true,
+ "requires": {
+ "clone-regexp": "^2.1.0"
+ }
+ },
+ "exit": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz",
+ "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=",
+ "dev": true
+ },
+ "expand-brackets": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz",
+ "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=",
+ "dev": true,
+ "requires": {
+ "debug": "^2.3.3",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "posix-character-classes": "^0.1.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=",
+ "dev": true,
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "expect-ct": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/expect-ct/-/expect-ct-0.2.0.tgz",
+ "integrity": "sha512-6SK3MG/Bbhm8MsgyJAylg+ucIOU71/FzyFalcfu5nY19dH8y/z0tBJU0wrNBXD4B27EoQtqPF/9wqH0iYAd04g=="
+ },
+ "express": {
+ "version": "4.17.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz",
+ "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==",
+ "requires": {
+ "accepts": "~1.3.7",
+ "array-flatten": "1.1.1",
+ "body-parser": "1.19.0",
+ "content-disposition": "0.5.3",
+ "content-type": "~1.0.4",
+ "cookie": "0.4.0",
+ "cookie-signature": "1.0.6",
+ "debug": "2.6.9",
+ "depd": "~1.1.2",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "etag": "~1.8.1",
+ "finalhandler": "~1.1.2",
+ "fresh": "0.5.2",
+ "merge-descriptors": "1.0.1",
+ "methods": "~1.1.2",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "path-to-regexp": "0.1.7",
+ "proxy-addr": "~2.0.5",
+ "qs": "6.7.0",
+ "range-parser": "~1.2.1",
+ "safe-buffer": "5.1.2",
+ "send": "0.17.1",
+ "serve-static": "1.14.1",
+ "setprototypeof": "1.1.1",
+ "statuses": "~1.5.0",
+ "type-is": "~1.6.18",
+ "utils-merge": "1.0.1",
+ "vary": "~1.1.2"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ },
+ "qs": {
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz",
+ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ=="
+ }
+ }
+ },
+ "express-ipfilter": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.0.1.tgz",
+ "integrity": "sha512-Jhrk7fC6FEql57icWzmiUuPRpx2Cryp+XEjo1tSbEeiRlpBIAdthreHIoTJGsqUEatmoLNLE8JHYn/T7SVAKog==",
+ "requires": {
+ "ip": "~1.1.0",
+ "lodash": "^4.17.11",
+ "proxy-addr": "^2.0.4",
+ "range_check": "^1.2.0"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "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"
+ }
+ },
+ "external-editor": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz",
+ "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.7.0",
+ "iconv-lite": "^0.4.24",
+ "tmp": "^0.0.33"
+ }
+ },
+ "extglob": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz",
+ "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==",
+ "dev": true,
+ "requires": {
+ "array-unique": "^0.3.2",
+ "define-property": "^1.0.0",
+ "expand-brackets": "^2.1.4",
+ "extend-shallow": "^2.0.1",
+ "fragment-cache": "^0.2.1",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "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.7",
+ "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz",
+ "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=",
+ "requires": {
+ "concat-stream": "1.6.2",
+ "debug": "2.6.9",
+ "mkdirp": "0.5.1",
+ "yauzl": "2.4.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "extsprintf": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
+ "integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU="
+ },
+ "fast-deep-equal": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
+ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk="
+ },
+ "fast-glob": {
+ "version": "2.2.7",
+ "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz",
+ "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==",
+ "dev": true,
+ "requires": {
+ "@mrmlnc/readdir-enhanced": "^2.2.1",
+ "@nodelib/fs.stat": "^1.1.2",
+ "glob-parent": "^3.1.0",
+ "is-glob": "^4.0.0",
+ "merge2": "^1.2.3",
+ "micromatch": "^3.1.10"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "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"
+ }
+ },
+ "micromatch": {
+ "version": "3.1.10",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz",
+ "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "braces": "^2.3.1",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "extglob": "^2.0.4",
+ "fragment-cache": "^0.2.1",
+ "kind-of": "^6.0.2",
+ "nanomatch": "^1.2.9",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.2"
+ }
+ }
+ }
+ },
+ "fast-json-stable-stringify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
+ "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I="
+ },
+ "fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=",
+ "dev": true
+ },
+ "fd-slicer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz",
+ "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=",
+ "requires": {
+ "pend": "~1.2.0"
+ }
+ },
+ "feature-policy": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/feature-policy/-/feature-policy-0.3.0.tgz",
+ "integrity": "sha512-ZtijOTFN7TzCujt1fnNhfWPFPSHeZkesff9AXZj+UEjYBynWNUIYpC87Ve4wHzyexQsImicLu7WsC2LHq7/xrQ=="
+ },
+ "feedme": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/feedme/-/feedme-1.2.0.tgz",
+ "integrity": "sha512-GNaewCsb6eWTgWqvxnGCYm6MkYrRSlXyqNhJRbdX7ku2Ubks3Vlg0cveea+gnK3mYh4pjfMQpzWpYyFl2RvILw==",
+ "requires": {
+ "clarinet": "^0.12.0",
+ "eventyoshi": "^0.2.0",
+ "sax": "^1.0.0"
+ }
+ },
+ "figures": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz",
+ "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5"
+ }
+ },
+ "file-entry-cache": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz",
+ "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==",
+ "dev": true,
+ "requires": {
+ "flat-cache": "^2.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz",
+ "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1",
+ "to-regex-range": "^2.1.0"
+ }
+ },
+ "finalhandler": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz",
+ "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==",
+ "requires": {
+ "debug": "2.6.9",
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "on-finished": "~2.3.0",
+ "parseurl": "~1.3.3",
+ "statuses": "~1.5.0",
+ "unpipe": "~1.0.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha1-ay6YIrGizgpgq2TWEOzK1TyyTQ8=",
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ },
+ "dependencies": {
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha1-D+tsZPD8UY2adU3V77YscCJ2H0s=",
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ }
+ }
+ },
+ "findup-sync": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz",
+ "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=",
+ "dev": true,
+ "requires": {
+ "glob": "~5.0.0"
+ },
+ "dependencies": {
+ "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"
+ }
+ }
+ }
+ },
+ "flat-cache": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz",
+ "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==",
+ "dev": true,
+ "requires": {
+ "flatted": "^2.0.0",
+ "rimraf": "2.6.3",
+ "write": "1.0.3"
+ }
+ },
+ "flatted": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz",
+ "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==",
+ "dev": true
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=",
+ "dev": true
+ },
+ "forever-agent": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
+ "integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE="
+ },
+ "form-data": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
+ "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
+ "requires": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.6",
+ "mime-types": "^2.1.12"
+ }
+ },
+ "forwarded": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
+ "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
+ },
+ "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"
+ }
+ },
+ "frameguard": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/frameguard/-/frameguard-3.1.0.tgz",
+ "integrity": "sha512-TxgSKM+7LTA6sidjOiSZK9wxY0ffMPY3Wta//MqwmX0nZuEHc8QrkV8Fh3ZhMJeiH+Uyh/tcaarImRy8u77O7g=="
+ },
+ "fresh": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
+ "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
+ },
+ "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==",
+ "dev": true
+ },
+ "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": "4.0.3",
+ "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+ "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
+ "dev": true
+ },
+ "functional-red-black-tree": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz",
+ "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
+ "dev": true
+ },
+ "gaze": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/gaze/-/gaze-1.1.3.tgz",
+ "integrity": "sha512-BRdNm8hbWzFzWHERTrejLqwHDfS4GibPoq5wjTPIoJHoBtKGPg3xAFfxmM+9ztbXelxcf2hwQcaz1PtmFeue8g==",
+ "dev": true,
+ "requires": {
+ "globule": "^1.0.0"
+ }
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==",
+ "dev": true
+ },
+ "get-func-name": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz",
+ "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
+ "dev": true
+ },
+ "get-stdin": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-4.0.1.tgz",
+ "integrity": "sha1-uWjGsKBDhDJJAui/Gl3zJXmkUP4="
+ },
+ "get-stream": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
+ "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==",
+ "dev": true,
+ "requires": {
+ "pump": "^3.0.0"
+ }
+ },
+ "get-value": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz",
+ "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=",
+ "dev": true
+ },
+ "getobject": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz",
+ "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=",
+ "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"
+ }
+ },
+ "git-config-path": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/git-config-path/-/git-config-path-1.0.1.tgz",
+ "integrity": "sha1-bTP37WPbDQ4RgTFQO6s6ykfVRmQ=",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "fs-exists-sync": "^0.1.0",
+ "homedir-polyfill": "^1.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz",
+ "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.2",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "glob-parent": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz",
+ "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=",
+ "dev": true,
+ "requires": {
+ "is-glob": "^3.1.0",
+ "path-dirname": "^1.0.0"
+ },
+ "dependencies": {
+ "is-glob": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz",
+ "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.0"
+ }
+ }
+ }
+ },
+ "glob-to-regexp": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz",
+ "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=",
+ "dev": true
+ },
+ "global-modules": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz",
+ "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==",
+ "dev": true,
+ "requires": {
+ "global-prefix": "^3.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz",
+ "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==",
+ "dev": true,
+ "requires": {
+ "ini": "^1.3.5",
+ "kind-of": "^6.0.2",
+ "which": "^1.3.1"
+ }
+ },
+ "globals": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz",
+ "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==",
+ "dev": true
+ },
+ "globby": {
+ "version": "9.2.0",
+ "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz",
+ "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==",
+ "dev": true,
+ "requires": {
+ "@types/glob": "^7.1.1",
+ "array-union": "^1.0.2",
+ "dir-glob": "^2.2.2",
+ "fast-glob": "^2.2.6",
+ "glob": "^7.1.3",
+ "ignore": "^4.0.3",
+ "pify": "^4.0.1",
+ "slash": "^2.0.0"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "slash": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz",
+ "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==",
+ "dev": true
+ }
+ }
+ },
+ "globjoin": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz",
+ "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=",
+ "dev": true
+ },
+ "globule": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/globule/-/globule-1.2.1.tgz",
+ "integrity": "sha512-g7QtgWF4uYSL5/dn71WxubOrS7JVGCnFPEnoeChJmBnyR9Mw8nGoEwOgJL/RC2Te0WhbsEUCejfH8SZNJ+adYQ==",
+ "dev": true,
+ "requires": {
+ "glob": "~7.1.1",
+ "lodash": "~4.17.10",
+ "minimatch": "~3.0.2"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "gonzales-pe": {
+ "version": "4.2.4",
+ "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.2.4.tgz",
+ "integrity": "sha512-v0Ts/8IsSbh9n1OJRnSfa7Nlxi4AkXIsWB6vPept8FDbL4bXn3FNuxjYtO/nmBGu7GDkL9MFeGebeSu6l55EPQ==",
+ "dev": true,
+ "requires": {
+ "minimist": "1.1.x"
+ },
+ "dependencies": {
+ "minimist": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz",
+ "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=",
+ "dev": true
+ }
+ }
+ },
+ "graceful-fs": {
+ "version": "4.1.15",
+ "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz",
+ "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA=="
+ },
+ "grapheme-splitter": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
+ "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
+ "dev": true
+ },
+ "growl": {
+ "version": "1.10.3",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz",
+ "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==",
+ "dev": true
+ },
+ "grunt": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.4.tgz",
+ "integrity": "sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==",
+ "dev": true,
+ "requires": {
+ "coffeescript": "~1.10.0",
+ "dateformat": "~1.0.12",
+ "eventemitter2": "~0.4.13",
+ "exit": "~0.1.1",
+ "findup-sync": "~0.3.0",
+ "glob": "~7.0.0",
+ "grunt-cli": "~1.2.0",
+ "grunt-known-options": "~1.1.0",
+ "grunt-legacy-log": "~2.0.0",
+ "grunt-legacy-util": "~1.1.1",
+ "iconv-lite": "~0.4.13",
+ "js-yaml": "~3.13.0",
+ "minimatch": "~3.0.2",
+ "mkdirp": "~0.5.1",
+ "nopt": "~3.0.6",
+ "path-is-absolute": "~1.0.0",
+ "rimraf": "~2.6.2"
+ },
+ "dependencies": {
+ "grunt-cli": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz",
+ "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=",
+ "dev": true,
+ "requires": {
+ "findup-sync": "~0.3.0",
+ "grunt-known-options": "~1.1.0",
+ "nopt": "~3.0.6",
+ "resolve": "~1.1.0"
+ }
+ },
+ "resolve": {
+ "version": "1.1.7",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz",
+ "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-eslint": {
+ "version": "21.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-21.1.0.tgz",
+ "integrity": "sha512-TN1C4BV947eUB/XrROUQ/QFTufWgH6wdfaxhlfmpjE70bFTp5q+Q2LgIZ5Y//+Rn1BWrXmm44sxegijNN6WR/A==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.1.0",
+ "eslint": "^5.16.0"
+ }
+ },
+ "grunt-jsonlint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/grunt-jsonlint/-/grunt-jsonlint-1.1.0.tgz",
+ "integrity": "sha1-ox7pckCu4/NDyiY8Rb1TIGMSfbI=",
+ "dev": true,
+ "requires": {
+ "jsonlint": "1.6.2",
+ "strip-json-comments": "^2.0.0"
+ }
+ },
+ "grunt-known-options": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz",
+ "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==",
+ "dev": true
+ },
+ "grunt-legacy-log": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz",
+ "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==",
+ "dev": true,
+ "requires": {
+ "colors": "~1.1.2",
+ "grunt-legacy-log-utils": "~2.0.0",
+ "hooker": "~0.2.3",
+ "lodash": "~4.17.5"
+ },
+ "dependencies": {
+ "colors": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz",
+ "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=",
+ "dev": true
+ }
+ }
+ },
+ "grunt-legacy-log-utils": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz",
+ "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==",
+ "dev": true,
+ "requires": {
+ "chalk": "~2.4.1",
+ "lodash": "~4.17.10"
+ }
+ },
+ "grunt-legacy-util": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz",
+ "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==",
+ "dev": true,
+ "requires": {
+ "async": "~1.5.2",
+ "exit": "~0.1.1",
+ "getobject": "~0.1.0",
+ "hooker": "~0.2.3",
+ "lodash": "~4.17.10",
+ "underscore.string": "~3.3.4",
+ "which": "~1.3.0"
+ }
+ },
+ "grunt-markdownlint": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/grunt-markdownlint/-/grunt-markdownlint-2.5.0.tgz",
+ "integrity": "sha512-UXp69SktIu0aM5rLPpfFAhGU80ioorRUB76YiqZGi4xxRJBUundLYm0/p9XnpHJw8LOkXWvtCoALecaMc1aTWw==",
+ "dev": true,
+ "requires": {
+ "markdownlint": "^0.15.0"
+ }
+ },
+ "grunt-stylelint": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.11.0.tgz",
+ "integrity": "sha512-/6LOPh8ftRS70tKa676ZrGG+eNCQQHJPH5QWe4gmzdW+K3Ud0YwbmUe1Bly3x9ymfllNTCALRmMJoV9xEh9RFA==",
+ "dev": true,
+ "requires": {
+ "chalk": "2.4.2"
+ }
+ },
+ "grunt-yamllint": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/grunt-yamllint/-/grunt-yamllint-0.3.0.tgz",
+ "integrity": "sha1-EAP3n5uluSMVedOOr8M/awmNdPM=",
+ "dev": true,
+ "requires": {
+ "async": "^2.1.5",
+ "chalk": "^1.1.3",
+ "js-yaml": "^3.8.1"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "async": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/async/-/async-2.6.2.tgz",
+ "integrity": "sha512-H1qVYh1MYhEEFLsP97cVKqCGo7KfCyTt6uEWqsTBr9SO84oK9Uwbyd/yCW+6rKJLHksBNUVWZDAjfS+Ccx0Bbg==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz",
+ "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
+ "dev": true
+ }
+ }
+ },
+ "har-schema": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
+ "integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI="
+ },
+ "har-validator": {
+ "version": "5.1.3",
+ "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
+ "integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
+ "requires": {
+ "ajv": "^6.5.5",
+ "har-schema": "^2.0.0"
+ }
+ },
+ "has-ansi": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz",
+ "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "has-binary2": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.3.tgz",
+ "integrity": "sha512-G1LWKhDSvhGeAQ8mPVQlqNcOB2sJdwATtZKl2pDKKHfpf/rYj24lkinxf69blJbnsvtqqNU+L3SL50vzZhXOnw==",
+ "requires": {
+ "isarray": "2.0.1"
+ },
+ "dependencies": {
+ "isarray": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+ "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
+ }
+ }
+ },
+ "has-color": {
+ "version": "0.1.7",
+ "resolved": "https://registry.npmjs.org/has-color/-/has-color-0.1.7.tgz",
+ "integrity": "sha1-ZxRKUmDDT8PMpnfQQdr1L+e3iy8=",
+ "dev": true
+ },
+ "has-cors": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
+ "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
+ },
+ "has-flag": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
+ "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
+ "dev": true
+ },
+ "has-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"
+ }
+ }
+ }
+ },
+ "he": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
+ "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
+ "dev": true
+ },
+ "helmet": {
+ "version": "3.18.0",
+ "resolved": "https://registry.npmjs.org/helmet/-/helmet-3.18.0.tgz",
+ "integrity": "sha512-TsKlGE5UVkV0NiQ4PllV9EVfZklPjyzcMEMjWlyI/8S6epqgRT+4s4GHVgc25x0TixsKvp3L7c91HQQt5l0+QA==",
+ "requires": {
+ "depd": "2.0.0",
+ "dns-prefetch-control": "0.1.0",
+ "dont-sniff-mimetype": "1.0.0",
+ "expect-ct": "0.2.0",
+ "feature-policy": "0.3.0",
+ "frameguard": "3.1.0",
+ "helmet-crossdomain": "0.3.0",
+ "helmet-csp": "2.7.1",
+ "hide-powered-by": "1.0.0",
+ "hpkp": "2.0.0",
+ "hsts": "2.2.0",
+ "ienoopen": "1.1.0",
+ "nocache": "2.1.0",
+ "referrer-policy": "1.2.0",
+ "x-xss-protection": "1.1.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ }
+ }
+ },
+ "helmet-crossdomain": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/helmet-crossdomain/-/helmet-crossdomain-0.3.0.tgz",
+ "integrity": "sha512-YiXhj0E35nC4Na5EPE4mTfoXMf9JTGpN4OtB4aLqShKuH9d2HNaJX5MQoglO6STVka0uMsHyG5lCut5Kzsy7Lg=="
+ },
+ "helmet-csp": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/helmet-csp/-/helmet-csp-2.7.1.tgz",
+ "integrity": "sha512-sCHwywg4daQ2mY0YYwXSZRsgcCeerUwxMwNixGA7aMLkVmPTYBl7gJoZDHOZyXkqPrtuDT3s2B1A+RLI7WxSdQ==",
+ "requires": {
+ "camelize": "1.0.0",
+ "content-security-policy-builder": "2.0.0",
+ "dasherize": "2.0.0",
+ "platform": "1.3.5"
+ }
+ },
+ "hide-powered-by": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hide-powered-by/-/hide-powered-by-1.0.0.tgz",
+ "integrity": "sha1-SoWtZYgfYoV/xwr3F0oRhNzM4ys="
+ },
+ "homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "dev": true,
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "hooker": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz",
+ "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=",
+ "dev": true
+ },
+ "hosted-git-info": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz",
+ "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w=="
+ },
+ "hpkp": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/hpkp/-/hpkp-2.0.0.tgz",
+ "integrity": "sha1-EOFCJk52IVpdMMROxD3mTe5tFnI="
+ },
+ "hsts": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/hsts/-/hsts-2.2.0.tgz",
+ "integrity": "sha512-ToaTnQ2TbJkochoVcdXYm4HOCliNozlviNsg+X2XQLQvZNI/kCHR9rZxVYpJB3UPcHz80PgxRyWQ7PdU1r+VBQ==",
+ "requires": {
+ "depd": "2.0.0"
+ },
+ "dependencies": {
+ "depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+ }
+ }
+ },
+ "html-encoding-sniffer": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz",
+ "integrity": "sha512-71lZziiDnsuabfdYiUeWdCVyKuqwWi23L8YeIgV9jSSZHCtb6wB1BKWooH7L3tn4/FuZJMVWyNaIDr4RGmaSYw==",
+ "dev": true,
+ "requires": {
+ "whatwg-encoding": "^1.0.1"
+ }
+ },
+ "html-tags": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.0.0.tgz",
+ "integrity": "sha512-xiXEBjihaNI+VZ2mKEoI5ZPxqUsevTKM+aeeJ/W4KAg2deGE35minmCJMn51BvwJZmiHaeAxrb2LAS0yZJxuuA==",
+ "dev": true
+ },
+ "htmlparser2": {
+ "version": "3.8.3",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.8.3.tgz",
+ "integrity": "sha1-mWwosZFRaovoZQGn15dX5ccMEGg=",
+ "dev": true,
+ "requires": {
+ "domelementtype": "1",
+ "domhandler": "2.3",
+ "domutils": "1.5",
+ "entities": "1.0",
+ "readable-stream": "1.1"
+ },
+ "dependencies": {
+ "entities": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-1.0.0.tgz",
+ "integrity": "sha1-sph6o4ITR/zeZCsk/fyeT7cSvyY=",
+ "dev": true
+ }
+ }
+ },
+ "http-auth": {
+ "version": "3.2.3",
+ "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.2.3.tgz",
+ "integrity": "sha1-Y2hCtx1uHyyY26Ca9UQXof74thw=",
+ "dev": true,
+ "requires": {
+ "apache-crypt": "^1.1.2",
+ "apache-md5": "^1.0.6",
+ "bcryptjs": "^2.3.0",
+ "uuid": "^3.0.0"
+ }
+ },
+ "http-errors": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz",
+ "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==",
+ "requires": {
+ "depd": "~1.1.2",
+ "inherits": "2.0.3",
+ "setprototypeof": "1.1.1",
+ "statuses": ">= 1.5.0 < 2",
+ "toidentifier": "1.0.0"
+ }
+ },
+ "http-proxy-agent": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
+ "integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
+ "dev": true,
+ "requires": {
+ "agent-base": "4",
+ "debug": "3.1.0"
+ },
+ "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"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ }
+ }
+ },
+ "http-signature": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
+ "integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "jsprim": "^1.2.2",
+ "sshpk": "^1.7.0"
+ }
+ },
+ "https-proxy-agent": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
+ "integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
+ "dev": true,
+ "requires": {
+ "agent-base": "^4.1.0",
+ "debug": "^3.1.0"
+ }
+ },
+ "hyperlinker": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz",
+ "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==",
+ "dev": true
+ },
+ "iconv-lite": {
+ "version": "0.4.24",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
+ "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3"
+ }
+ },
+ "ieee754": {
+ "version": "1.1.13",
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
+ "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==",
+ "dev": true
+ },
+ "ienoopen": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/ienoopen/-/ienoopen-1.1.0.tgz",
+ "integrity": "sha512-MFs36e/ca6ohEKtinTJ5VvAJ6oDRAYFdYXweUnGY9L9vcoqFOU4n2ZhmJ0C4z/cwGZ3YIQRSB3XZ1+ghZkY5NQ=="
+ },
+ "ignore": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz",
+ "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==",
+ "dev": true
+ },
+ "import-fresh": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz",
+ "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==",
+ "dev": true,
+ "requires": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ }
+ },
+ "import-lazy": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz",
+ "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==",
+ "dev": true
+ },
+ "imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-2.1.0.tgz",
+ "integrity": "sha1-ji1INIdCEhtKghi3oTfppSBJ3IA=",
+ "requires": {
+ "repeating": "^2.0.0"
+ }
+ },
+ "indexes-of": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz",
+ "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=",
+ "dev": true
+ },
+ "indexof": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
+ "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
+ "dev": true,
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
+ "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
+ },
+ "ini": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz",
+ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw=="
+ },
+ "inquirer": {
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz",
+ "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.2.0",
+ "chalk": "^2.4.2",
+ "cli-cursor": "^2.1.0",
+ "cli-width": "^2.0.0",
+ "external-editor": "^3.0.3",
+ "figures": "^2.0.0",
+ "lodash": "^4.17.11",
+ "mute-stream": "0.0.7",
+ "run-async": "^2.2.0",
+ "rxjs": "^6.4.0",
+ "string-width": "^2.1.0",
+ "strip-ansi": "^5.1.0",
+ "through": "^2.3.6"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz",
+ "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "dependencies": {
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ }
+ }
+ }
+ }
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha1-EEqOSqym09jNFXqO+L+rLXo//bY=",
+ "dev": true
+ },
+ "ip": {
+ "version": "1.1.5",
+ "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz",
+ "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo="
+ },
+ "ip6": {
+ "version": "0.0.4",
+ "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.0.4.tgz",
+ "integrity": "sha1-RMWp23njnUBSAbTXjROzhw5I2zE="
+ },
+ "ipaddr.js": {
+ "version": "1.9.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.0.tgz",
+ "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA=="
+ },
+ "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-alphabetical": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz",
+ "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==",
+ "dev": true
+ },
+ "is-alphanumeric": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz",
+ "integrity": "sha1-Spzvcdr0wAHB2B1j0UDPU/1oifQ=",
+ "dev": true
+ },
+ "is-alphanumerical": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.3.tgz",
+ "integrity": "sha512-A1IGAPO5AW9vSh7omxIlOGwIqEvpW/TA+DksVOPM5ODuxKlZS09+TEM1E3275lJqO2oJ38vDpeAL3DCIiHE6eA==",
+ "dev": true,
+ "requires": {
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0="
+ },
+ "is-buffer": {
+ "version": "1.1.6",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz",
+ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
+ "dev": true
+ },
+ "is-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-decimal": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz",
+ "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==",
+ "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-directory": {
+ "version": "0.3.1",
+ "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz",
+ "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=",
+ "dev": true
+ },
+ "is-extendable": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz",
+ "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=",
+ "dev": true
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=",
+ "dev": true
+ },
+ "is-finite": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz",
+ "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz",
+ "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==",
+ "dev": true,
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-hexadecimal": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.3.tgz",
+ "integrity": "sha512-zxQ9//Q3D/34poZf8fiy3m3XVpbQc7ren15iKqrTtLPwkPD/t3Scy9Imp63FujULGxuK0ZlCwoo5xNpktFgbOA==",
+ "dev": true
+ },
+ "is-number": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz",
+ "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "is-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-1.0.1.tgz",
+ "integrity": "sha1-PkcprB9f3gJc19g6iW2rn09n2w8=",
+ "dev": true
+ },
+ "is-plain-obj": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz",
+ "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=",
+ "dev": true
+ },
+ "is-plain-object": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz",
+ "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "is-promise": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz",
+ "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=",
+ "dev": true
+ },
+ "is-regexp": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz",
+ "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==",
+ "dev": true
+ },
+ "is-stream": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz",
+ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=",
+ "dev": true
+ },
+ "is-typedarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
+ "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo="
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI="
+ },
+ "is-whitespace-character": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.3.tgz",
+ "integrity": "sha512-SNPgMLz9JzPccD3nPctcj8sZlX9DAMJSKH8bP7Z6bohCwuNgX8xbWr1eTAYXX9Vpi/aSn8Y1akL9WgM3t43YNQ==",
+ "dev": true
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==",
+ "dev": true
+ },
+ "is-word-character": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.3.tgz",
+ "integrity": "sha512-0wfcrFgOOOBdgRNT9H33xe6Zi6yhX/uoc4U8NBZGeQQB0ctU1dnlNTyL9JM2646bHDTpsDm1Brb3VPoCIMrd/A==",
+ "dev": true
+ },
+ "isarray": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz",
+ "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=",
+ "dev": true
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=",
+ "dev": true
+ },
+ "isstream": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
+ "integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo="
+ },
+ "js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true
+ },
+ "js-yaml": {
+ "version": "3.13.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
+ "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "esprima": "^4.0.0"
+ }
+ },
+ "jsbn": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
+ "integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM="
+ },
+ "jsdom": {
+ "version": "11.12.0",
+ "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-11.12.0.tgz",
+ "integrity": "sha512-y8Px43oyiBM13Zc1z780FrfNLJCXTL40EWlty/LXUtcjykRBNgLlCjWXpfSPBl2iv+N7koQN+dvqszHZgT/Fjw==",
+ "dev": true,
+ "requires": {
+ "abab": "^2.0.0",
+ "acorn": "^5.5.3",
+ "acorn-globals": "^4.1.0",
+ "array-equal": "^1.0.0",
+ "cssom": ">= 0.3.2 < 0.4.0",
+ "cssstyle": "^1.0.0",
+ "data-urls": "^1.0.0",
+ "domexception": "^1.0.1",
+ "escodegen": "^1.9.1",
+ "html-encoding-sniffer": "^1.0.2",
+ "left-pad": "^1.3.0",
+ "nwsapi": "^2.0.7",
+ "parse5": "4.0.0",
+ "pn": "^1.1.0",
+ "request": "^2.87.0",
+ "request-promise-native": "^1.0.5",
+ "sax": "^1.2.4",
+ "symbol-tree": "^3.2.2",
+ "tough-cookie": "^2.3.4",
+ "w3c-hr-time": "^1.0.1",
+ "webidl-conversions": "^4.0.2",
+ "whatwg-encoding": "^1.0.3",
+ "whatwg-mimetype": "^2.1.0",
+ "whatwg-url": "^6.4.1",
+ "ws": "^5.2.0",
+ "xml-name-validator": "^3.0.0"
+ },
+ "dependencies": {
+ "acorn": {
+ "version": "5.7.3",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-5.7.3.tgz",
+ "integrity": "sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==",
+ "dev": true
+ },
+ "ws": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-5.2.2.tgz",
+ "integrity": "sha512-jaHFD6PFv6UgoIVda6qZllptQsMlDEJkTQcybzzXDYM1XO9Y8em691FGMPmM46WGyLU4z9KMgQN+qrux/nhlHA==",
+ "dev": true,
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ }
+ }
+ },
+ "jsesc": {
+ "version": "2.5.2",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz",
+ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==",
+ "dev": true
+ },
+ "jshint": {
+ "version": "2.10.2",
+ "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.10.2.tgz",
+ "integrity": "sha512-e7KZgCSXMJxznE/4WULzybCMNXNAd/bf5TSrvVEq78Q/K8ZwFpmBqQeDtNiHc3l49nV4E/+YeHU/JZjSUIrLAA==",
+ "dev": true,
+ "requires": {
+ "cli": "~1.0.0",
+ "console-browserify": "1.1.x",
+ "exit": "0.1.x",
+ "htmlparser2": "3.8.x",
+ "lodash": "~4.17.11",
+ "minimatch": "~3.0.2",
+ "shelljs": "0.3.x",
+ "strip-json-comments": "1.0.x"
+ },
+ "dependencies": {
+ "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
+ }
+ }
+ },
+ "jsome": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/jsome/-/jsome-2.5.0.tgz",
+ "integrity": "sha1-XkF+70NB/+uD7ov6kmWzbVb+Se0=",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.3.0",
+ "json-stringify-safe": "^5.0.1",
+ "yargs": "^11.0.0"
+ }
+ },
+ "json-parse-better-errors": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz",
+ "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==",
+ "dev": true
+ },
+ "json-schema": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
+ "integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM="
+ },
+ "json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg=="
+ },
+ "json-stable-stringify-without-jsonify": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
+ "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=",
+ "dev": true
+ },
+ "json-stringify-safe": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
+ "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus="
+ },
+ "json5": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz",
+ "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==",
+ "dev": true,
+ "requires": {
+ "minimist": "^1.2.0"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "jsonlint": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/jsonlint/-/jsonlint-1.6.2.tgz",
+ "integrity": "sha1-VzcEUIX1XrRVxosf9OvAG9UOiDA=",
+ "dev": true,
+ "requires": {
+ "JSV": ">= 4.0.x",
+ "nomnom": ">= 1.5.x"
+ }
+ },
+ "jsonpointer": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/jsonpointer/-/jsonpointer-4.0.1.tgz",
+ "integrity": "sha1-T9kss04OnbPInIYi7PUfm5eMbLk=",
+ "dev": true
+ },
+ "jsonwebtoken": {
+ "version": "8.5.1",
+ "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz",
+ "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==",
+ "dev": true,
+ "requires": {
+ "jws": "^3.2.2",
+ "lodash.includes": "^4.3.0",
+ "lodash.isboolean": "^3.0.3",
+ "lodash.isinteger": "^4.0.4",
+ "lodash.isnumber": "^3.0.3",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.isstring": "^4.0.1",
+ "lodash.once": "^4.0.0",
+ "ms": "^2.1.1",
+ "semver": "^5.6.0"
+ }
+ },
+ "jsprim": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
+ "integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
+ "requires": {
+ "assert-plus": "1.0.0",
+ "extsprintf": "1.3.0",
+ "json-schema": "0.2.3",
+ "verror": "1.10.0"
+ }
+ },
+ "jwa": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz",
+ "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==",
+ "dev": true,
+ "requires": {
+ "buffer-equal-constant-time": "1.0.1",
+ "ecdsa-sig-formatter": "1.0.11",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "jws": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz",
+ "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==",
+ "dev": true,
+ "requires": {
+ "jwa": "^1.4.1",
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz",
+ "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==",
+ "dev": true
+ },
+ "known-css-properties": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.14.0.tgz",
+ "integrity": "sha512-P+0a/gBzLgVlCnK8I7VcD0yuYJscmWn66wH9tlKsQnmVdg689tLEmziwB9PuazZYLkcm07fvWOKCJJqI55sD5Q==",
+ "dev": true
+ },
+ "lazystream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz",
+ "integrity": "sha1-9plf4PggOS9hOWvolGJAe7dxaOQ=",
+ "dev": true,
+ "requires": {
+ "readable-stream": "^2.0.5"
+ },
+ "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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha1-MIrMr6C8SDo4Z7S28rlQYlHRuDU=",
+ "dev": true,
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "left-pad": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/left-pad/-/left-pad-1.3.0.tgz",
+ "integrity": "sha512-XI5MPzVNApjAyhQzphX8BkmKsKUxD4LdyK24iZeQGinBN9yTQT3bFlCBy/aVx2HrNcqQGsdot8ghrjyrvMCoEA==",
+ "dev": true
+ },
+ "leven": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
+ "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
+ "dev": true
+ },
+ "levn": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz",
+ "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2"
+ }
+ },
+ "linkify-it": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.1.0.tgz",
+ "integrity": "sha512-4REs8/062kV2DSHxNfq5183zrqXMl7WP0WzABH9IeJI+NLm429FgE1PDecltYfnOoFDFlZGh2T8PfZn0r+GTRg==",
+ "dev": true,
+ "requires": {
+ "uc.micro": "^1.0.1"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha1-lWkFcI1YtLq0wiYbBPWfMcmTdMA=",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ }
+ },
+ "locate-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz",
+ "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=",
+ "dev": true,
+ "requires": {
+ "p-locate": "^2.0.0",
+ "path-exists": "^3.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.11",
+ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz",
+ "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg=="
+ },
+ "lodash.find": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz",
+ "integrity": "sha1-ywcE1Hq3F4n/oN6Ll92Sb7iLE7E=",
+ "dev": true
+ },
+ "lodash.includes": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz",
+ "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=",
+ "dev": true
+ },
+ "lodash.isboolean": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz",
+ "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=",
+ "dev": true
+ },
+ "lodash.isinteger": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz",
+ "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=",
+ "dev": true
+ },
+ "lodash.isnumber": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz",
+ "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=",
+ "dev": true
+ },
+ "lodash.isobject": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/lodash.isobject/-/lodash.isobject-3.0.2.tgz",
+ "integrity": "sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=",
+ "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": "4.2.0",
+ "resolved": "https://registry.npmjs.org/lodash.keys/-/lodash.keys-4.2.0.tgz",
+ "integrity": "sha1-oIYCrBLk+4P5H8H7ejYKTZujUgU=",
+ "dev": true
+ },
+ "lodash.once": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
+ "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=",
+ "dev": true
+ },
+ "lodash.sortby": {
+ "version": "4.7.0",
+ "resolved": "https://registry.npmjs.org/lodash.sortby/-/lodash.sortby-4.7.0.tgz",
+ "integrity": "sha1-7dFMgk4sycHgsKG0K7UhBRakJDg=",
+ "dev": true
+ },
+ "log-symbols": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-3.0.0.tgz",
+ "integrity": "sha512-dSkNGuI7iG3mfvDzUuYZyvk5dD9ocYCYzNU6CYDE6+Xqd+gwme6Z00NS3dUh8mq/73HaEtT7m6W+yUPtU6BZnQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2"
+ }
+ },
+ "longest-streak": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.3.tgz",
+ "integrity": "sha512-9lz5IVdpwsKLMzQi0MQ+oD9EA0mIGcWYP7jXMTZVXP8D42PwuAk+M/HBFYQoxt1G5OR8m7aSIgb1UymfWGBWEw==",
+ "dev": true
+ },
+ "loud-rejection": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz",
+ "integrity": "sha1-W0b4AUft7leIcPCG0Eghz5mOVR8=",
+ "requires": {
+ "currently-unhandled": "^0.4.1",
+ "signal-exit": "^3.0.0"
+ }
+ },
+ "lru-cache": {
+ "version": "4.1.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz",
+ "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==",
+ "dev": true,
+ "requires": {
+ "pseudomap": "^1.0.2",
+ "yallist": "^2.1.2"
+ }
+ },
+ "luxon": {
+ "version": "1.16.0",
+ "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.16.0.tgz",
+ "integrity": "sha512-qaqB+JwpGwtl7UbIXng3A/l4W/ySBr8drQvwtMLZBMiLD2V+0fEnPWMrs+UjnIy9PsktazQaKvwDUCLzoWz0Hw==",
+ "optional": true
+ },
+ "macos-release": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/macos-release/-/macos-release-2.2.0.tgz",
+ "integrity": "sha512-iV2IDxZaX8dIcM7fG6cI46uNmHUxHE4yN+Z8tKHAW1TBPMZDIKHf/3L+YnOuj/FK9il14UaVdHmiQ1tsi90ltA==",
+ "dev": true
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=",
+ "dev": true
+ },
+ "map-obj": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz",
+ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0="
+ },
+ "map-visit": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz",
+ "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=",
+ "dev": true,
+ "requires": {
+ "object-visit": "^1.0.0"
+ }
+ },
+ "markdown-escapes": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.3.tgz",
+ "integrity": "sha512-XUi5HJhhV5R74k8/0H2oCbCiYf/u4cO/rX8tnGkRvrqhsr5BRNU6Mg0yt/8UIx1iIS8220BNJsDb7XnILhLepw==",
+ "dev": true
+ },
+ "markdown-it": {
+ "version": "8.4.2",
+ "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-8.4.2.tgz",
+ "integrity": "sha512-GcRz3AWTqSUphY3vsUqQSFMbgR38a4Lh3GWlHRh/7MRwz8mcu9n2IO7HOh+bXHrR9kOPDl5RNCaEsrneb+xhHQ==",
+ "dev": true,
+ "requires": {
+ "argparse": "^1.0.7",
+ "entities": "~1.1.1",
+ "linkify-it": "^2.0.0",
+ "mdurl": "^1.0.1",
+ "uc.micro": "^1.0.5"
+ }
+ },
+ "markdown-table": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz",
+ "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==",
+ "dev": true
+ },
+ "markdownlint": {
+ "version": "0.15.0",
+ "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.15.0.tgz",
+ "integrity": "sha512-sNcrSrUgpNbTQX6rPIMd+RI9rAryGTEbDI9VFpcFyijlC5g8gpkma49k5p98yFLdNbdcB3VW69UJ0smxvTVw6g==",
+ "dev": true,
+ "requires": {
+ "markdown-it": "8.4.2"
+ }
+ },
+ "mathml-tag-names": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.1.tgz",
+ "integrity": "sha512-pWB896KPGSGkp1XtyzRBftpTzwSOL0Gfk0wLvxt4f2mgzjY19o0LxJ3U25vNWTzsh7da+KTbuXQoQ3lOJZ8WHw==",
+ "dev": true
+ },
+ "mdast-util-compact": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.3.tgz",
+ "integrity": "sha512-nRiU5GpNy62rZppDKbLwhhtw5DXoFMqw9UNZFmlPsNaQCZ//WLjGKUwWMdJrUH+Se7UvtO2gXtAMe0g/N+eI5w==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ }
+ },
+ "mdurl": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz",
+ "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=",
+ "dev": true
+ },
+ "media-typer": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
+ "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
+ },
+ "mem": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/mem/-/mem-1.1.0.tgz",
+ "integrity": "sha1-Xt1StIXKHZAP5kiVUFOZoN+kX3Y=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "meow": {
+ "version": "3.7.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-3.7.0.tgz",
+ "integrity": "sha1-cstmi0JSKCkKu/qFaJJYcwioAfs=",
+ "requires": {
+ "camelcase-keys": "^2.0.0",
+ "decamelize": "^1.1.2",
+ "loud-rejection": "^1.0.0",
+ "map-obj": "^1.0.1",
+ "minimist": "^1.1.3",
+ "normalize-package-data": "^2.3.4",
+ "object-assign": "^4.0.1",
+ "read-pkg-up": "^1.0.1",
+ "redent": "^1.0.0",
+ "trim-newlines": "^1.0.0"
+ }
+ },
+ "merge-descriptors": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
+ "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
+ },
+ "merge2": {
+ "version": "1.2.3",
+ "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.2.3.tgz",
+ "integrity": "sha512-gdUU1Fwj5ep4kplwcmftruWofEFt6lfpkkr3h860CXbAB9c3hGb55EOL2ali0Td5oebvW0E1+3Sr+Ur7XfKpRA==",
+ "dev": true
+ },
+ "methods": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
+ "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
+ },
+ "micromatch": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.2.tgz",
+ "integrity": "sha512-y7FpHSbMUMoyPbYUSzO6PaZ6FyRnQOpHuKwbo1G+Knck95XVU4QAiKdGEnj5wwoS7PlOgthX/09u5iFJ+aYf5Q==",
+ "dev": true,
+ "requires": {
+ "braces": "^3.0.1",
+ "picomatch": "^2.0.5"
+ },
+ "dependencies": {
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "dev": true,
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "dev": true,
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
+ "dev": true
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "dev": true,
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ }
+ }
+ },
+ "mime": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
+ "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg=="
+ },
+ "mime-db": {
+ "version": "1.40.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
+ "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA=="
+ },
+ "mime-types": {
+ "version": "2.1.24",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
+ "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
+ "requires": {
+ "mime-db": "1.40.0"
+ }
+ },
+ "mimic-fn": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz",
+ "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+ "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ="
+ },
+ "minimist-options": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz",
+ "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==",
+ "dev": true,
+ "requires": {
+ "arrify": "^1.0.1",
+ "is-plain-obj": "^1.1.0"
+ }
+ },
+ "mixin-deep": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz",
+ "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==",
+ "dev": true,
+ "requires": {
+ "for-in": "^1.0.2",
+ "is-extendable": "^1.0.1"
+ },
+ "dependencies": {
+ "is-extendable": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz",
+ "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==",
+ "dev": true,
+ "requires": {
+ "is-plain-object": "^2.0.4"
+ }
+ }
+ }
+ },
+ "mkdirp": {
+ "version": "0.5.1",
+ "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
+ "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
+ "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="
+ }
+ }
+ },
+ "mocha": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz",
+ "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==",
+ "dev": true,
+ "requires": {
+ "browser-stdout": "1.3.0",
+ "commander": "2.11.0",
+ "debug": "3.1.0",
+ "diff": "3.3.1",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.2",
+ "growl": "1.10.3",
+ "he": "1.1.1",
+ "mkdirp": "0.5.1",
+ "supports-color": "4.4.0"
+ },
+ "dependencies": {
+ "commander": {
+ "version": "2.11.0",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz",
+ "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==",
+ "dev": true
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "mocha-each": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mocha-each/-/mocha-each-1.2.0.tgz",
+ "integrity": "sha512-WVNx7Rovf7ebZq5XSlhXqenuyN3xS1InqKYvdR544/mQkMoSfTLhT5iehXyK0xCvxx90QIltU6KojKh3Ptz7mA==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "^1.0.3"
+ }
+ },
+ "mocha-logger": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/mocha-logger/-/mocha-logger-1.0.6.tgz",
+ "integrity": "sha512-D7Z3r1RkyaJOnlgokODdzt9p4ut0m3DVzEKp3r3tgeXIpdxp54z049Vc0EEh5hkhudfRN0dfUD10Fcj2WuOO3w==",
+ "dev": true,
+ "requires": {
+ "mocha": "^5.1.1"
+ },
+ "dependencies": {
+ "browser-stdout": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
+ "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
+ "dev": true
+ },
+ "commander": {
+ "version": "2.15.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
+ "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
+ "dev": true
+ },
+ "debug": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+ "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "diff": {
+ "version": "3.5.0",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
+ "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
+ "dev": true
+ },
+ "glob": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
+ "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "growl": {
+ "version": "1.10.5",
+ "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
+ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
+ "dev": true
+ },
+ "mocha": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
+ "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
+ "dev": true,
+ "requires": {
+ "browser-stdout": "1.3.1",
+ "commander": "2.15.1",
+ "debug": "3.1.0",
+ "diff": "3.5.0",
+ "escape-string-regexp": "1.0.5",
+ "glob": "7.1.2",
+ "growl": "1.10.5",
+ "he": "1.1.1",
+ "minimatch": "3.0.4",
+ "mkdirp": "0.5.1",
+ "supports-color": "5.4.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "supports-color": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
+ "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "moment": {
+ "version": "2.24.0",
+ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz",
+ "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg=="
+ },
+ "ms": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz",
+ "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg=="
+ },
+ "mute-stream": {
+ "version": "0.0.7",
+ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
+ "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
+ "dev": true
+ },
+ "nanomatch": {
+ "version": "1.2.13",
+ "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz",
+ "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==",
+ "dev": true,
+ "requires": {
+ "arr-diff": "^4.0.0",
+ "array-unique": "^0.3.2",
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "fragment-cache": "^0.2.1",
+ "is-windows": "^1.0.2",
+ "kind-of": "^6.0.2",
+ "object.pick": "^1.3.0",
+ "regex-not": "^1.0.0",
+ "snapdragon": "^0.8.1",
+ "to-regex": "^3.0.1"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=",
+ "dev": true
+ },
+ "negotiator": {
+ "version": "0.6.2",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz",
+ "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw=="
+ },
+ "nice-try": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz",
+ "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==",
+ "dev": true
+ },
+ "nocache": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/nocache/-/nocache-2.1.0.tgz",
+ "integrity": "sha512-0L9FvHG3nfnnmaEQPjT9xhfN4ISk0A8/2j4M37Np4mcDesJjHgEUfgPhdCyZuFI954tjokaIj/A3NdpFNdEh4Q=="
+ },
+ "node-cleanup": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/node-cleanup/-/node-cleanup-2.1.2.tgz",
+ "integrity": "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=",
+ "dev": true
+ },
+ "node-fetch": {
+ "version": "2.6.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz",
+ "integrity": "sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==",
+ "dev": true
+ },
+ "node-releases": {
+ "version": "1.1.23",
+ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.23.tgz",
+ "integrity": "sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w==",
+ "dev": true,
+ "requires": {
+ "semver": "^5.3.0"
+ }
+ },
+ "nomnom": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/nomnom/-/nomnom-1.8.1.tgz",
+ "integrity": "sha1-IVH3Ikcrp55Qp2/BJbuMjy5Nwqc=",
+ "dev": true,
+ "requires": {
+ "chalk": "~0.4.0",
+ "underscore": "~1.6.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-1.0.0.tgz",
+ "integrity": "sha1-yxAt8cVvUSPquLZ817mAJ6AnkXg=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-0.4.0.tgz",
+ "integrity": "sha1-UZmj3c0MHv4jvAjBsCewYXbgxk8=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "~1.0.0",
+ "has-color": "~0.1.0",
+ "strip-ansi": "~0.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-0.1.1.tgz",
+ "integrity": "sha1-OeipjQRNFQZgq+SmgIrPcLt7yZE=",
+ "dev": true
+ }
+ }
+ },
+ "nopt": {
+ "version": "3.0.6",
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz",
+ "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=",
+ "dev": true,
+ "requires": {
+ "abbrev": "1"
+ }
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "normalize-path": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz",
+ "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=",
+ "dev": true,
+ "requires": {
+ "remove-trailing-separator": "^1.0.1"
+ }
+ },
+ "normalize-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",
+ "integrity": "sha1-0LFF62kRicY6eNIB3E/bEpPvDAM=",
+ "dev": true
+ },
+ "npm-install-package": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/npm-install-package/-/npm-install-package-2.1.0.tgz",
+ "integrity": "sha1-1+/jz816sAYUuJbqUxGdyaslkSU=",
+ "dev": true
+ },
+ "npm-run-path": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz",
+ "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=",
+ "dev": true,
+ "requires": {
+ "path-key": "^2.0.0"
+ }
+ },
+ "nugget": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/nugget/-/nugget-2.0.1.tgz",
+ "integrity": "sha1-IBCVpIfhrTYIGzQy+jytpPjQcbA=",
+ "requires": {
+ "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": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "num2fraction": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz",
+ "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=",
+ "dev": true
+ },
+ "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="
+ },
+ "nwsapi": {
+ "version": "2.1.4",
+ "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.1.4.tgz",
+ "integrity": "sha512-iGfd9Y6SFdTNldEy2L0GUhcarIutFmk+MPWIn9dmj8NMIup03G08uUF2KGbbmv/Ux4RT0VZJoP/sVbWA6d/VIw==",
+ "dev": true
+ },
+ "oauth-sign": {
+ "version": "0.9.0",
+ "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
+ "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ=="
+ },
+ "object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM="
+ },
+ "object-component": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
+ "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
+ },
+ "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-keys": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-0.4.0.tgz",
+ "integrity": "sha1-KKaq50KN0sOpLz2V8hM13SBOAzY="
+ },
+ "object-visit": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz",
+ "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=",
+ "dev": true,
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "on-finished": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
+ "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
+ "requires": {
+ "ee-first": "1.1.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
+ "dev": true,
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz",
+ "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=",
+ "dev": true,
+ "requires": {
+ "mimic-fn": "^1.0.0"
+ }
+ },
+ "optimist": {
+ "version": "0.6.1",
+ "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz",
+ "integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
+ "dev": true,
+ "requires": {
+ "minimist": "~0.0.1",
+ "wordwrap": "~0.0.2"
+ },
+ "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",
+ "integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
+ "dev": true
+ }
+ }
+ },
+ "optionator": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz",
+ "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=",
+ "dev": true,
+ "requires": {
+ "deep-is": "~0.1.3",
+ "fast-levenshtein": "~2.0.4",
+ "levn": "~0.3.0",
+ "prelude-ls": "~1.1.2",
+ "type-check": "~0.3.2",
+ "wordwrap": "~1.0.0"
+ }
+ },
+ "os-locale": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-2.1.0.tgz",
+ "integrity": "sha512-3sslG3zJbEYcaC4YVAvDorjGxc7tv6KVATnLPZONiljsUncvihe9BQoVCEs0RZ1kmf4Hk9OBqlZfJZWI4GanKA==",
+ "dev": true,
+ "requires": {
+ "execa": "^0.7.0",
+ "lcid": "^1.0.0",
+ "mem": "^1.1.0"
+ },
+ "dependencies": {
+ "cross-spawn": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz",
+ "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=",
+ "dev": true,
+ "requires": {
+ "lru-cache": "^4.0.1",
+ "shebang-command": "^1.2.0",
+ "which": "^1.2.9"
+ }
+ },
+ "execa": {
+ "version": "0.7.0",
+ "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz",
+ "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=",
+ "dev": true,
+ "requires": {
+ "cross-spawn": "^5.0.1",
+ "get-stream": "^3.0.0",
+ "is-stream": "^1.1.0",
+ "npm-run-path": "^2.0.0",
+ "p-finally": "^1.0.0",
+ "signal-exit": "^3.0.0",
+ "strip-eof": "^1.0.0"
+ }
+ },
+ "get-stream": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz",
+ "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=",
+ "dev": true
+ }
+ }
+ },
+ "os-name": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/os-name/-/os-name-3.1.0.tgz",
+ "integrity": "sha512-h8L+8aNjNcMpo/mAIBPn5PXCM16iyPGjHNWo6U1YO8sJTMHtEtyczI6QJnLoplswm6goopQkqc7OAnjhWcugVg==",
+ "dev": true,
+ "requires": {
+ "macos-release": "^2.2.0",
+ "windows-release": "^3.1.0"
+ }
+ },
+ "os-tmpdir": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
+ "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=",
+ "dev": true
+ },
+ "p-finally": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz",
+ "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=",
+ "dev": true
+ },
+ "p-limit": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz",
+ "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==",
+ "dev": true,
+ "requires": {
+ "p-try": "^1.0.0"
+ }
+ },
+ "p-locate": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz",
+ "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=",
+ "dev": true,
+ "requires": {
+ "p-limit": "^1.1.0"
+ }
+ },
+ "p-try": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz",
+ "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=",
+ "dev": true
+ },
+ "parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "requires": {
+ "callsites": "^3.0.0"
+ }
+ },
+ "parse-diff": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/parse-diff/-/parse-diff-0.4.2.tgz",
+ "integrity": "sha512-YYQzII66NqysdPgDVxzbdwNXMv5Ww562JSZSXZ4RIPoolzD7yqA4crgD8swrs+JNcvjoZMKMiT4kGcLYvf6IoA==",
+ "dev": true
+ },
+ "parse-entities": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz",
+ "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==",
+ "dev": true,
+ "requires": {
+ "character-entities": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "character-reference-invalid": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "parse-git-config": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/parse-git-config/-/parse-git-config-2.0.3.tgz",
+ "integrity": "sha512-Js7ueMZOVSZ3tP8C7E3KZiHv6QQl7lnJ+OkbxoaFazzSa2KyEHqApfGbU3XboUgUnq4ZuUmskUpYKTNx01fm5A==",
+ "dev": true,
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "git-config-path": "^1.0.1",
+ "ini": "^1.3.5"
+ }
+ },
+ "parse-github-url": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/parse-github-url/-/parse-github-url-1.0.2.tgz",
+ "integrity": "sha512-kgBf6avCbO3Cn6+RnzRGLkUsv4ZVqv/VfAYkRsyBcgkshNvVBkRn1FEZcW0Jb+npXQWm2vHPnnOqFteZxRRGNw==",
+ "dev": true
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=",
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "parse-link-header": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.1.tgz",
+ "integrity": "sha1-vt/g0hGK64S+deewJUGeyKYRQKc=",
+ "dev": true,
+ "requires": {
+ "xtend": "~4.0.1"
+ },
+ "dependencies": {
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ }
+ }
+ },
+ "parse-ms": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz",
+ "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=",
+ "dev": true
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
+ "dev": true
+ },
+ "parse5": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-4.0.0.tgz",
+ "integrity": "sha512-VrZ7eOd3T1Fk4XWNXMgiGBK/z0MG48BWG2uQNU4I72fkQuKUTZpl+u9k+CxEG0twMVzSmXEEz12z5Fnw1jIQFA==",
+ "dev": true
+ },
+ "parseqs": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
+ "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
+ "requires": {
+ "better-assert": "~1.0.0"
+ }
+ },
+ "parseuri": {
+ "version": "0.0.5",
+ "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
+ "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
+ "requires": {
+ "better-assert": "~1.0.0"
+ }
+ },
+ "parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ=="
+ },
+ "pascalcase": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz",
+ "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
+ "dev": true
+ },
+ "path-dirname": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz",
+ "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=",
+ "dev": true
+ },
+ "path-exists": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz",
+ "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU="
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
+ "dev": true
+ },
+ "path-is-inside": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz",
+ "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=",
+ "dev": true
+ },
+ "path-key": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz",
+ "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=",
+ "dev": true
+ },
+ "path-parse": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
+ "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw=="
+ },
+ "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="
+ },
+ "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.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "pathval": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz",
+ "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=",
+ "dev": true
+ },
+ "pend": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
+ "integrity": "sha1-elfrVQpng/kRUzH89GY9XI4AelA="
+ },
+ "performance-now": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
+ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns="
+ },
+ "picomatch": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.0.7.tgz",
+ "integrity": "sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA==",
+ "dev": true
+ },
+ "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.0"
+ }
+ },
+ "pinpoint": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pinpoint/-/pinpoint-1.1.0.tgz",
+ "integrity": "sha1-DPd1eml38b9/ajIge3CeN3OI6HQ=",
+ "dev": true
+ },
+ "platform": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.5.tgz",
+ "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q=="
+ },
+ "plur": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz",
+ "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=",
+ "dev": true
+ },
+ "pn": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/pn/-/pn-1.1.0.tgz",
+ "integrity": "sha512-2qHaIQr2VLRFoxe2nASzsV6ef4yOOH+Fi9FBOVH6cqeSgUnoyySPZkxzLuzd+RYOQTRpROA0ztTMqxROKSb/nA==",
+ "dev": true
+ },
+ "posix-character-classes": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz",
+ "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=",
+ "dev": true
+ },
+ "postcss": {
+ "version": "7.0.17",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.17.tgz",
+ "integrity": "sha512-546ZowA+KZ3OasvQZHsbuEpysvwTZNGJv9EfyCQdsIDltPSWHAeTQ5fQy/Npi2ZDtLI3zs7Ps/p6wThErhm9fQ==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.2",
+ "source-map": "^0.6.1",
+ "supports-color": "^6.1.0"
+ },
+ "dependencies": {
+ "supports-color": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz",
+ "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ }
+ }
+ },
+ "postcss-html": {
+ "version": "0.36.0",
+ "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz",
+ "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==",
+ "dev": true,
+ "requires": {
+ "htmlparser2": "^3.10.0"
+ },
+ "dependencies": {
+ "htmlparser2": {
+ "version": "3.10.1",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz",
+ "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==",
+ "dev": true,
+ "requires": {
+ "domelementtype": "^1.3.1",
+ "domhandler": "^2.3.0",
+ "domutils": "^1.5.1",
+ "entities": "^1.1.1",
+ "inherits": "^2.0.1",
+ "readable-stream": "^3.1.1"
+ }
+ },
+ "readable-stream": {
+ "version": "3.4.0",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.4.0.tgz",
+ "integrity": "sha512-jItXPLmrSR8jmTRmRWJXCnGJsfy85mB3Wd/uINMXA65yrnFo0cPClFIUWzo2najVNSl+mx7/4W8ttlLWJe99pQ==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.3",
+ "string_decoder": "^1.1.1",
+ "util-deprecate": "^1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.2.0.tgz",
+ "integrity": "sha512-6YqyX6ZWEYguAxgZzHGL7SsCeGx3V2TtOTqZz1xSTSWnqsbWwbptafNyvf/ACquZUXV3DANr5BDIwNYe1mN42w==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ },
+ "postcss-jsx": {
+ "version": "0.36.1",
+ "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.1.tgz",
+ "integrity": "sha512-xaZpy01YR7ijsFUtu5rViYCFHurFIPHir+faiOQp8g/NfTfWqZCKDhKrydQZ4d8WlSAmVdXGwLjpFbsNUI26Sw==",
+ "dev": true,
+ "requires": {
+ "@babel/core": ">=7.2.2"
+ }
+ },
+ "postcss-less": {
+ "version": "3.1.4",
+ "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz",
+ "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.14"
+ }
+ },
+ "postcss-markdown": {
+ "version": "0.36.0",
+ "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz",
+ "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==",
+ "dev": true,
+ "requires": {
+ "remark": "^10.0.1",
+ "unist-util-find-all-after": "^1.0.2"
+ }
+ },
+ "postcss-media-query-parser": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz",
+ "integrity": "sha1-J7Ocb02U+Bsac7j3Y1HGCeXO8kQ=",
+ "dev": true
+ },
+ "postcss-reporter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz",
+ "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.4.1",
+ "lodash": "^4.17.11",
+ "log-symbols": "^2.2.0",
+ "postcss": "^7.0.7"
+ },
+ "dependencies": {
+ "log-symbols": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz",
+ "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==",
+ "dev": true,
+ "requires": {
+ "chalk": "^2.0.1"
+ }
+ }
+ }
+ },
+ "postcss-resolve-nested-selector": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz",
+ "integrity": "sha1-Kcy8fDfe36wwTp//C/FZaz9qDk4=",
+ "dev": true
+ },
+ "postcss-safe-parser": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.1.tgz",
+ "integrity": "sha512-xZsFA3uX8MO3yAda03QrG3/Eg1LN3EPfjjf07vke/46HERLZyHrTsQ9E1r1w1W//fWEhtYNndo2hQplN2cVpCQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-sass": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz",
+ "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==",
+ "dev": true,
+ "requires": {
+ "gonzales-pe": "^4.2.3",
+ "postcss": "^7.0.1"
+ }
+ },
+ "postcss-scss": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.0.0.tgz",
+ "integrity": "sha512-um9zdGKaDZirMm+kZFKKVsnKPF7zF7qBAtIfTSnZXD1jZ0JNZIxdB6TxQOjCnlSzLRInVl2v3YdBh/M881C4ug==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.0"
+ }
+ },
+ "postcss-selector-parser": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.1.tgz",
+ "integrity": "sha1-T4dfSvsMllc9XPTXQBGu4lCn6GU=",
+ "dev": true,
+ "requires": {
+ "dot-prop": "^4.1.1",
+ "indexes-of": "^1.0.1",
+ "uniq": "^1.0.1"
+ }
+ },
+ "postcss-syntax": {
+ "version": "0.36.2",
+ "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz",
+ "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==",
+ "dev": true
+ },
+ "postcss-value-parser": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz",
+ "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==",
+ "dev": true
+ },
+ "prelude-ls": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz",
+ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=",
+ "dev": true
+ },
+ "pretty-bytes": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz",
+ "integrity": "sha1-CiLoIQYJrTVUL4yNXSFZr/B1HIQ=",
+ "requires": {
+ "get-stdin": "^4.0.1",
+ "meow": "^3.1.0"
+ }
+ },
+ "pretty-ms": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz",
+ "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=",
+ "dev": true,
+ "requires": {
+ "is-finite": "^1.0.1",
+ "parse-ms": "^1.0.0",
+ "plur": "^1.0.0"
+ }
+ },
+ "process-nextick-args": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz",
+ "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw=="
+ },
+ "progress": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz",
+ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==",
+ "dev": true
+ },
+ "progress-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/progress-stream/-/progress-stream-1.2.0.tgz",
+ "integrity": "sha1-LNPP6jO6OonJwSHsM0er6asSX3c=",
+ "requires": {
+ "speedometer": "~0.1.2",
+ "through2": "~0.2.3"
+ }
+ },
+ "proxy-addr": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.5.tgz",
+ "integrity": "sha512-t/7RxHXPH6cJtP0pRG6smSr9QJidhB+3kXu0KgXnbGYMgzEnUxRQ4/LDdfOwZEMyIh3/xHb8PX3t+lfL9z+YVQ==",
+ "requires": {
+ "forwarded": "~0.1.2",
+ "ipaddr.js": "1.9.0"
+ }
+ },
+ "pseudomap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz",
+ "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=",
+ "dev": true
+ },
+ "psl": {
+ "version": "1.1.32",
+ "resolved": "https://registry.npmjs.org/psl/-/psl-1.1.32.tgz",
+ "integrity": "sha512-MHACAkHpihU/REGGPLj4sEfc/XKW2bheigvHO1dUqjaKigMp1C8+WLQYRGgeKFMsw5PMfegZcaN8IDXK/cD0+g=="
+ },
+ "pump": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
+ "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+ "dev": true,
+ "requires": {
+ "end-of-stream": "^1.1.0",
+ "once": "^1.3.1"
+ }
+ },
+ "punycode": {
+ "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.1",
+ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz",
+ "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=",
+ "dev": true
+ },
+ "qs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
+ "integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA=="
+ },
+ "querystring": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz",
+ "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=",
+ "dev": true
+ },
+ "quick-lru": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz",
+ "integrity": "sha1-Q2CxfGETatOAeDl/8RQW4Ybc+7g=",
+ "dev": true
+ },
+ "range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg=="
+ },
+ "range_check": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/range_check/-/range_check-1.4.0.tgz",
+ "integrity": "sha1-zYfHrGLEC6nfabhwPGBPYMN0hjU=",
+ "requires": {
+ "ip6": "0.0.4",
+ "ipaddr.js": "1.2"
+ },
+ "dependencies": {
+ "ipaddr.js": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.2.0.tgz",
+ "integrity": "sha1-irpJyRknmVhb3WQ+DMtQ6K53e6Q="
+ }
+ }
+ },
+ "raw-body": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz",
+ "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==",
+ "requires": {
+ "bytes": "3.1.0",
+ "http-errors": "1.7.2",
+ "iconv-lite": "0.4.24",
+ "unpipe": "1.0.0"
+ }
+ },
+ "rc": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
+ "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
+ "requires": {
+ "deep-extend": "^0.6.0",
+ "ini": "~1.3.0",
+ "minimist": "^1.2.0",
+ "strip-json-comments": "~2.0.1"
+ }
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha1-9f+qXs0pyzHAR0vKfXVra7KePyg=",
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha1-nWPBMnbAZZGNV/ACpX9AobZD+wI=",
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ }
+ },
+ "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.0",
+ "inherits": "~2.0.1",
+ "isarray": "0.0.1",
+ "string_decoder": "~0.10.x"
+ }
+ },
+ "readline-sync": {
+ "version": "1.4.9",
+ "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.9.tgz",
+ "integrity": "sha1-PtqOZfI80qF+YTAbHwADOWr17No=",
+ "dev": true
+ },
+ "redent": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-1.0.0.tgz",
+ "integrity": "sha1-z5Fqsf1fHxbfsggi3W7H9zDCr94=",
+ "requires": {
+ "indent-string": "^2.1.0",
+ "strip-indent": "^1.0.1"
+ }
+ },
+ "referrer-policy": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/referrer-policy/-/referrer-policy-1.2.0.tgz",
+ "integrity": "sha512-LgQJIuS6nAy1Jd88DCQRemyE3mS+ispwlqMk3b0yjZ257fI1v9c+/p6SD5gP5FGyXUIgrNOAfmyioHwZtYv2VA=="
+ },
+ "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
+ },
+ "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"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "regexpp": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz",
+ "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==",
+ "dev": true
+ },
+ "remark": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz",
+ "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==",
+ "dev": true,
+ "requires": {
+ "remark-parse": "^6.0.0",
+ "remark-stringify": "^6.0.0",
+ "unified": "^7.0.0"
+ }
+ },
+ "remark-parse": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz",
+ "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==",
+ "dev": true,
+ "requires": {
+ "collapse-white-space": "^1.0.2",
+ "is-alphabetical": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "is-word-character": "^1.0.0",
+ "markdown-escapes": "^1.0.0",
+ "parse-entities": "^1.1.0",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "trim": "0.0.1",
+ "trim-trailing-lines": "^1.0.0",
+ "unherit": "^1.0.4",
+ "unist-util-remove-position": "^1.0.0",
+ "vfile-location": "^2.0.0",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ }
+ }
+ },
+ "remark-stringify": {
+ "version": "6.0.4",
+ "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz",
+ "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==",
+ "dev": true,
+ "requires": {
+ "ccount": "^1.0.0",
+ "is-alphanumeric": "^1.0.0",
+ "is-decimal": "^1.0.0",
+ "is-whitespace-character": "^1.0.0",
+ "longest-streak": "^2.0.1",
+ "markdown-escapes": "^1.0.0",
+ "markdown-table": "^1.1.0",
+ "mdast-util-compact": "^1.0.0",
+ "parse-entities": "^1.0.2",
+ "repeat-string": "^1.5.4",
+ "state-toggle": "^1.0.0",
+ "stringify-entities": "^1.0.1",
+ "unherit": "^1.0.4",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ }
+ }
+ },
+ "remove-trailing-separator": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz",
+ "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=",
+ "dev": true
+ },
+ "repeat-element": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz",
+ "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==",
+ "dev": true
+ },
+ "repeat-string": {
+ "version": "1.6.1",
+ "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz",
+ "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
+ "dev": true
+ },
+ "repeating": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz",
+ "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=",
+ "requires": {
+ "is-finite": "^1.0.0"
+ }
+ },
+ "replace-ext": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz",
+ "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=",
+ "dev": true
+ },
+ "request": {
+ "version": "2.88.0",
+ "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
+ "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
+ "requires": {
+ "aws-sign2": "~0.7.0",
+ "aws4": "^1.8.0",
+ "caseless": "~0.12.0",
+ "combined-stream": "~1.0.6",
+ "extend": "~3.0.2",
+ "forever-agent": "~0.6.1",
+ "form-data": "~2.3.2",
+ "har-validator": "~5.1.0",
+ "http-signature": "~1.2.0",
+ "is-typedarray": "~1.0.0",
+ "isstream": "~0.1.2",
+ "json-stringify-safe": "~5.0.1",
+ "mime-types": "~2.1.19",
+ "oauth-sign": "~0.9.0",
+ "performance-now": "^2.1.0",
+ "qs": "~6.5.2",
+ "safe-buffer": "^5.1.2",
+ "tough-cookie": "~2.4.3",
+ "tunnel-agent": "^0.6.0",
+ "uuid": "^3.3.2"
+ }
+ },
+ "request-promise-core": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/request-promise-core/-/request-promise-core-1.1.2.tgz",
+ "integrity": "sha512-UHYyq1MO8GsefGEt7EprS8UrXsm1TxEvFUX1IMTuSLU2Rh7fTIdFtl8xD7JiEYiWU2dl+NYAjCTksTehQUxPag==",
+ "dev": true,
+ "requires": {
+ "lodash": "^4.17.11"
+ }
+ },
+ "request-promise-native": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmjs.org/request-promise-native/-/request-promise-native-1.0.7.tgz",
+ "integrity": "sha512-rIMnbBdgNViL37nZ1b3L/VfPOpSi0TqVDQPAvO6U14lMzOLrt5nilxCQqtDKhZeDiW0/hkCXGoQjhgJd/tCh6w==",
+ "dev": true,
+ "requires": {
+ "request-promise-core": "1.1.2",
+ "stealthy-require": "^1.1.1",
+ "tough-cookie": "^2.3.3"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=",
+ "dev": true
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
+ "dev": true
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=",
+ "dev": true
+ },
+ "resolve": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz",
+ "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==",
+ "requires": {
+ "path-parse": "^1.0.6"
+ }
+ },
+ "resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true
+ },
+ "resolve-url": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz",
+ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=",
+ "dev": true
+ },
+ "restore-cursor": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz",
+ "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=",
+ "dev": true,
+ "requires": {
+ "onetime": "^2.0.0",
+ "signal-exit": "^3.0.2"
+ }
+ },
+ "ret": {
+ "version": "0.1.15",
+ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
+ "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==",
+ "dev": true
+ },
+ "rfc6902": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/rfc6902/-/rfc6902-2.4.0.tgz",
+ "integrity": "sha512-Oof0+ZGIey7+U2kIU51Ao2YUjgkik6iFwyKNIRzNnl9DD/WnaxQnp21iUwBlkbqrRkxuE/DGPRroLzYjj/ngMA==",
+ "dev": true
+ },
+ "rgb2hex": {
+ "version": "0.1.9",
+ "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.1.9.tgz",
+ "integrity": "sha512-32iuQzhOjyT+cv9aAFRBJ19JgHwzQwbjUhH3Fj2sWW2EEGAW8fpFrDFP5ndoKDxJaLO06x1hE3kyuIFrUQtybQ==",
+ "dev": true
+ },
+ "rimraf": {
+ "version": "2.6.3",
+ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
+ "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==",
+ "dev": true,
+ "requires": {
+ "glob": "^7.1.3"
+ },
+ "dependencies": {
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ }
+ }
+ },
+ "rrule": {
+ "version": "2.6.2",
+ "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.2.tgz",
+ "integrity": "sha512-xL38CM1zOYOIp4OO8hdD6zHH5UdR9siHMvPiv+CCSh7o0LYJ0owg87QcFW7GXJ0PfpLBHjanEMvvBjJxbRhAcQ==",
+ "requires": {
+ "luxon": "^1.3.3",
+ "tslib": "^1.9.0"
+ }
+ },
+ "rrule-alt": {
+ "version": "2.2.8",
+ "resolved": "https://registry.npmjs.org/rrule-alt/-/rrule-alt-2.2.8.tgz",
+ "integrity": "sha1-oxC23Gy8yKEA5Vgj+T9ia9QbFoA="
+ },
+ "run-async": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz",
+ "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=",
+ "dev": true,
+ "requires": {
+ "is-promise": "^2.1.0"
+ }
+ },
+ "rx-lite": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz",
+ "integrity": "sha1-Cx4Rr4vESDbwSmQH6S2kJGe3lEQ=",
+ "dev": true
+ },
+ "rx-lite-aggregates": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz",
+ "integrity": "sha1-dTuHqJoRyVRnxKwWJsTvxOBcZ74=",
+ "dev": true,
+ "requires": {
+ "rx-lite": "*"
+ }
+ },
+ "rxjs": {
+ "version": "6.5.2",
+ "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz",
+ "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==",
+ "dev": true,
+ "requires": {
+ "tslib": "^1.9.0"
+ }
+ },
+ "safe-buffer": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
+ },
+ "safe-regex": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
+ "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=",
+ "dev": true,
+ "requires": {
+ "ret": "~0.1.10"
+ }
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "sax": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
+ "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
+ },
+ "semver": {
+ "version": "5.7.0",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
+ "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
+ },
+ "send": {
+ "version": "0.17.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz",
+ "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==",
+ "requires": {
+ "debug": "2.6.9",
+ "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.7.2",
+ "mime": "1.6.0",
+ "ms": "2.1.1",
+ "on-finished": "~2.3.0",
+ "range-parser": "~1.2.1",
+ "statuses": "~1.5.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ },
+ "dependencies": {
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ }
+ }
+ },
+ "serve-static": {
+ "version": "1.14.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz",
+ "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==",
+ "requires": {
+ "encodeurl": "~1.0.2",
+ "escape-html": "~1.0.3",
+ "parseurl": "~1.3.3",
+ "send": "0.17.1"
+ }
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=",
+ "dev": true
+ },
+ "set-value": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz",
+ "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^2.0.1",
+ "is-extendable": "^0.1.1",
+ "is-plain-object": "^2.0.3",
+ "split-string": "^3.0.1"
+ }
+ },
+ "setprototypeof": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz",
+ "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw=="
+ },
+ "shebang-command": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz",
+ "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=",
+ "dev": true,
+ "requires": {
+ "shebang-regex": "^1.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz",
+ "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=",
+ "dev": true
+ },
+ "shelljs": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/shelljs/-/shelljs-0.3.0.tgz",
+ "integrity": "sha1-NZbmMHp4FUT1kfN9phg2DzHbV7E=",
+ "dev": true
+ },
+ "signal-exit": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz",
+ "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0="
+ },
+ "simple-git": {
+ "version": "1.113.0",
+ "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-1.113.0.tgz",
+ "integrity": "sha512-i9WVsrK2u0G/cASI9nh7voxOk9mhanWY9eGtWBDSYql6m49Yk5/Fan6uZsDr/xmzv8n+eQ8ahKCoEr8cvU3h+g==",
+ "requires": {
+ "debug": "^4.0.1"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "single-line-log": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/single-line-log/-/single-line-log-1.1.2.tgz",
+ "integrity": "sha1-wvg/Jzo+GhbtsJlWYdoO1e8DM2Q=",
+ "requires": {
+ "string-width": "^1.0.1"
+ }
+ },
+ "slash": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
+ "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+ "dev": true
+ },
+ "slice-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz",
+ "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^3.2.0",
+ "astral-regex": "^1.0.0",
+ "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=",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz",
+ "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==",
+ "dev": true,
+ "requires": {
+ "base": "^0.11.1",
+ "debug": "^2.2.0",
+ "define-property": "^0.2.5",
+ "extend-shallow": "^2.0.1",
+ "map-cache": "^0.2.2",
+ "source-map": "^0.5.6",
+ "source-map-resolve": "^0.5.0",
+ "use": "^3.1.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "dev": true,
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "define-property": {
+ "version": "0.2.5",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz",
+ "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^0.1.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
+ "dev": true
+ },
+ "source-map": {
+ "version": "0.5.7",
+ "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
+ "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
+ "dev": true
+ }
+ }
+ },
+ "snapdragon-node": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz",
+ "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^1.0.0",
+ "isobject": "^3.0.0",
+ "snapdragon-util": "^3.0.1"
+ },
+ "dependencies": {
+ "define-property": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz",
+ "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=",
+ "dev": true,
+ "requires": {
+ "is-descriptor": "^1.0.0"
+ }
+ },
+ "is-accessor-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz",
+ "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-data-descriptor": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz",
+ "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^6.0.0"
+ }
+ },
+ "is-descriptor": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz",
+ "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==",
+ "dev": true,
+ "requires": {
+ "is-accessor-descriptor": "^1.0.0",
+ "is-data-descriptor": "^1.0.0",
+ "kind-of": "^6.0.2"
+ }
+ }
+ }
+ },
+ "snapdragon-util": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz",
+ "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.2.0"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "socket.io": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.2.0.tgz",
+ "integrity": "sha512-wxXrIuZ8AILcn+f1B4ez4hJTPG24iNgxBBDaJfT6MsyOhVYiTXWexGoPkd87ktJG8kQEcL/NBvRi64+9k4Kc0w==",
+ "requires": {
+ "debug": "~4.1.0",
+ "engine.io": "~3.3.1",
+ "has-binary2": "~1.0.2",
+ "socket.io-adapter": "~1.1.0",
+ "socket.io-client": "2.2.0",
+ "socket.io-parser": "~3.3.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ }
+ }
+ },
+ "socket.io-adapter": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz",
+ "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs="
+ },
+ "socket.io-client": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.2.0.tgz",
+ "integrity": "sha512-56ZrkTDbdTLmBIyfFYesgOxsjcLnwAKoN4CiPyTVkMQj3zTUh0QAx3GbvIvLpFEOvQWu92yyWICxB0u7wkVbYA==",
+ "requires": {
+ "backo2": "1.0.2",
+ "base64-arraybuffer": "0.1.5",
+ "component-bind": "1.0.0",
+ "component-emitter": "1.2.1",
+ "debug": "~3.1.0",
+ "engine.io-client": "~3.3.1",
+ "has-binary2": "~1.0.2",
+ "has-cors": "1.1.0",
+ "indexof": "0.0.1",
+ "object-component": "0.0.3",
+ "parseqs": "0.0.5",
+ "parseuri": "0.0.5",
+ "socket.io-parser": "~3.3.0",
+ "to-array": "0.1.4"
+ },
+ "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"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "socket.io-parser": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.3.0.tgz",
+ "integrity": "sha512-hczmV6bDgdaEbVqhAeVMM/jfUfzuEZHsQg6eOmLgJht6G3mPKMxYm75w2+qhAQZ+4X+1+ATZ+QFKeOZD5riHng==",
+ "requires": {
+ "component-emitter": "1.2.1",
+ "debug": "~3.1.0",
+ "isarray": "2.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"
+ }
+ },
+ "isarray": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
+ "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "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-resolve": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz",
+ "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==",
+ "dev": true,
+ "requires": {
+ "atob": "^2.1.1",
+ "decode-uri-component": "^0.2.0",
+ "resolve-url": "^0.2.1",
+ "source-map-url": "^0.4.0",
+ "urix": "^0.1.0"
+ }
+ },
+ "source-map-url": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz",
+ "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=",
+ "dev": true
+ },
+ "spdx-correct": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz",
+ "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==",
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz",
+ "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA=="
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz",
+ "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==",
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz",
+ "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA=="
+ },
+ "specificity": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz",
+ "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==",
+ "dev": true
+ },
+ "spectron": {
+ "version": "3.8.0",
+ "resolved": "https://registry.npmjs.org/spectron/-/spectron-3.8.0.tgz",
+ "integrity": "sha512-fQ7gFp6UuEaONjXFLifLeIUI022pOsm3b+NFAm696r2umUkSZ9IbnEgHwrvBX+pJ3QUDyCEs5bPHUieYU7FvaQ==",
+ "dev": true,
+ "requires": {
+ "dev-null": "^0.1.1",
+ "electron-chromedriver": "~1.8.0",
+ "request": "^2.81.0",
+ "split": "^1.0.0",
+ "webdriverio": "^4.8.0"
+ }
+ },
+ "speedometer": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/speedometer/-/speedometer-0.1.4.tgz",
+ "integrity": "sha1-mHbb0qFp0xFUAtSObqYynIgWpQ0="
+ },
+ "split": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/split/-/split-1.0.1.tgz",
+ "integrity": "sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==",
+ "dev": true,
+ "requires": {
+ "through": "2"
+ }
+ },
+ "split-string": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz",
+ "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==",
+ "dev": true,
+ "requires": {
+ "extend-shallow": "^3.0.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "sprintf-js": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz",
+ "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==",
+ "dev": true
+ },
+ "sshpk": {
+ "version": "1.16.1",
+ "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
+ "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
+ "requires": {
+ "asn1": "~0.2.3",
+ "assert-plus": "^1.0.0",
+ "bcrypt-pbkdf": "^1.0.0",
+ "dashdash": "^1.12.0",
+ "ecc-jsbn": "~0.1.1",
+ "getpass": "^0.1.1",
+ "jsbn": "~0.1.0",
+ "safer-buffer": "^2.0.2",
+ "tweetnacl": "~0.14.0"
+ }
+ },
+ "state-toggle": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.2.tgz",
+ "integrity": "sha512-8LpelPGR0qQM4PnfLiplOQNJcIN1/r2Gy0xKB2zKnIW2YzPMt2sR4I/+gtPjhN7Svh9kw+zqEg2SFwpBO9iNiw==",
+ "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.5.0",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz",
+ "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow="
+ },
+ "stealthy-require": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/stealthy-require/-/stealthy-require-1.1.1.tgz",
+ "integrity": "sha1-NbCYdbT/SfJqd35QmzCQoyJr8ks=",
+ "dev": true
+ },
+ "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.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "string_decoder": {
+ "version": "0.10.31",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz",
+ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ="
+ },
+ "stringify-entities": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz",
+ "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==",
+ "dev": true,
+ "requires": {
+ "character-entities-html4": "^1.0.0",
+ "character-entities-legacy": "^1.0.0",
+ "is-alphanumerical": "^1.0.0",
+ "is-hexadecimal": "^1.0.0"
+ }
+ },
+ "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"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha1-YhmoVhZSBJHzV4i9vxRHqZx+aw4=",
+ "requires": {
+ "is-utf8": "^0.2.0"
+ }
+ },
+ "strip-eof": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz",
+ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz",
+ "integrity": "sha1-DHlipq3vp7vUrDZkYKY4VSrhoKI=",
+ "requires": {
+ "get-stdin": "^4.0.1"
+ }
+ },
+ "strip-json-comments": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
+ "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo="
+ },
+ "style-search": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz",
+ "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=",
+ "dev": true
+ },
+ "stylelint": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-10.1.0.tgz",
+ "integrity": "sha512-OmlUXrgzEMLQYj1JPTpyZPR9G4bl0StidfHnGJEMpdiQ0JyTq0MPg1xkHk1/xVJ2rTPESyJCDWjG8Kbpoo7Kuw==",
+ "dev": true,
+ "requires": {
+ "autoprefixer": "^9.5.1",
+ "balanced-match": "^1.0.0",
+ "chalk": "^2.4.2",
+ "cosmiconfig": "^5.2.0",
+ "debug": "^4.1.1",
+ "execall": "^2.0.0",
+ "file-entry-cache": "^5.0.1",
+ "get-stdin": "^7.0.0",
+ "global-modules": "^2.0.0",
+ "globby": "^9.2.0",
+ "globjoin": "^0.1.4",
+ "html-tags": "^3.0.0",
+ "ignore": "^5.0.6",
+ "import-lazy": "^4.0.0",
+ "imurmurhash": "^0.1.4",
+ "known-css-properties": "^0.14.0",
+ "leven": "^3.1.0",
+ "lodash": "^4.17.11",
+ "log-symbols": "^3.0.0",
+ "mathml-tag-names": "^2.1.0",
+ "meow": "^5.0.0",
+ "micromatch": "^4.0.0",
+ "normalize-selector": "^0.2.0",
+ "pify": "^4.0.1",
+ "postcss": "^7.0.14",
+ "postcss-html": "^0.36.0",
+ "postcss-jsx": "^0.36.1",
+ "postcss-less": "^3.1.4",
+ "postcss-markdown": "^0.36.0",
+ "postcss-media-query-parser": "^0.2.3",
+ "postcss-reporter": "^6.0.1",
+ "postcss-resolve-nested-selector": "^0.1.1",
+ "postcss-safe-parser": "^4.0.1",
+ "postcss-sass": "^0.3.5",
+ "postcss-scss": "^2.0.0",
+ "postcss-selector-parser": "^3.1.0",
+ "postcss-syntax": "^0.36.2",
+ "postcss-value-parser": "^3.3.1",
+ "resolve-from": "^5.0.0",
+ "signal-exit": "^3.0.2",
+ "slash": "^3.0.0",
+ "specificity": "^0.4.1",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^5.2.0",
+ "style-search": "^0.1.0",
+ "sugarss": "^2.0.0",
+ "svg-tags": "^1.0.0",
+ "table": "^5.2.3"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "dev": true
+ },
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ },
+ "camelcase-keys": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz",
+ "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0",
+ "map-obj": "^2.0.0",
+ "quick-lru": "^1.0.0"
+ }
+ },
+ "debug": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+ "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+ "dev": true,
+ "requires": {
+ "ms": "^2.1.1"
+ }
+ },
+ "emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "get-stdin": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz",
+ "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==",
+ "dev": true
+ },
+ "ignore": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.2.tgz",
+ "integrity": "sha512-vdqWBp7MyzdmHkkRWV5nY+PfGRbYbahfuvsBCh277tq+w9zyNi7h5CYJCK0kmzti9kU+O/cB7sE8HvKv6aXAKQ==",
+ "dev": true
+ },
+ "indent-string": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz",
+ "integrity": "sha1-Sl/W0nzDMvN+VBmlBNu4NxBckok=",
+ "dev": true
+ },
+ "is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true
+ },
+ "load-json-file": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz",
+ "integrity": "sha1-L19Fq5HjMhYjT9U62rZo607AmTs=",
+ "dev": true,
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^4.0.0",
+ "pify": "^3.0.0",
+ "strip-bom": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "map-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz",
+ "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=",
+ "dev": true
+ },
+ "meow": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz",
+ "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==",
+ "dev": true,
+ "requires": {
+ "camelcase-keys": "^4.0.0",
+ "decamelize-keys": "^1.0.0",
+ "loud-rejection": "^1.0.0",
+ "minimist-options": "^3.0.1",
+ "normalize-package-data": "^2.3.4",
+ "read-pkg-up": "^3.0.0",
+ "redent": "^2.0.0",
+ "trim-newlines": "^2.0.0",
+ "yargs-parser": "^10.0.0"
+ }
+ },
+ "parse-json": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz",
+ "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=",
+ "dev": true,
+ "requires": {
+ "error-ex": "^1.3.1",
+ "json-parse-better-errors": "^1.0.1"
+ }
+ },
+ "path-type": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz",
+ "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==",
+ "dev": true,
+ "requires": {
+ "pify": "^3.0.0"
+ },
+ "dependencies": {
+ "pify": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz",
+ "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=",
+ "dev": true
+ }
+ }
+ },
+ "pify": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz",
+ "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==",
+ "dev": true
+ },
+ "read-pkg": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
+ "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=",
+ "dev": true,
+ "requires": {
+ "load-json-file": "^4.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^3.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz",
+ "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=",
+ "dev": true,
+ "requires": {
+ "find-up": "^2.0.0",
+ "read-pkg": "^3.0.0"
+ }
+ },
+ "redent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz",
+ "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=",
+ "dev": true,
+ "requires": {
+ "indent-string": "^3.0.0",
+ "strip-indent": "^2.0.0"
+ }
+ },
+ "resolve-from": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true
+ },
+ "string-width": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.1.0.tgz",
+ "integrity": "sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^5.2.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ },
+ "strip-bom": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
+ "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=",
+ "dev": true
+ },
+ "strip-indent": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz",
+ "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=",
+ "dev": true
+ },
+ "trim-newlines": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz",
+ "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=",
+ "dev": true
+ },
+ "yargs-parser": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz",
+ "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ }
+ }
+ }
+ },
+ "stylelint-config-recommended": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-2.2.0.tgz",
+ "integrity": "sha512-bZ+d4RiNEfmoR74KZtCKmsABdBJr4iXRiCso+6LtMJPw5rd/KnxUWTxht7TbafrTJK1YRjNgnN0iVZaJfc3xJA==",
+ "dev": true
+ },
+ "stylelint-config-standard": {
+ "version": "18.3.0",
+ "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-18.3.0.tgz",
+ "integrity": "sha512-Tdc/TFeddjjy64LvjPau9SsfVRexmTFqUhnMBrzz07J4p2dVQtmpncRF/o8yZn8ugA3Ut43E6o1GtjX80TFytw==",
+ "dev": true,
+ "requires": {
+ "stylelint-config-recommended": "^2.2.0"
+ }
+ },
+ "sugarss": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz",
+ "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==",
+ "dev": true,
+ "requires": {
+ "postcss": "^7.0.2"
+ }
+ },
+ "sumchecker": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-2.0.2.tgz",
+ "integrity": "sha1-D0LBDl0F2l1C7qPlbDOZo31sWz4=",
+ "requires": {
+ "debug": "^2.2.0"
+ },
+ "dependencies": {
+ "debug": {
+ "version": "2.6.9",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
+ "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
+ "requires": {
+ "ms": "2.0.0"
+ }
+ },
+ "ms": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
+ "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
+ }
+ }
+ },
+ "supports-color": {
+ "version": "5.5.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^3.0.0"
+ }
+ },
+ "supports-hyperlinks": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-1.0.1.tgz",
+ "integrity": "sha512-HHi5kVSefKaJkGYXbDuKbUGRVxqnWGn3J2e39CYcNJEfWciGq2zYtOhXLTlvrOZW1QU7VX67w7fMmWafHX9Pfw==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^2.0.0",
+ "supports-color": "^5.0.0"
+ },
+ "dependencies": {
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ }
+ }
+ },
+ "svg-tags": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz",
+ "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=",
+ "dev": true
+ },
+ "symbol-tree": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.2.tgz",
+ "integrity": "sha1-rifbOPZgp64uHDt9G8KQgZuFGeY=",
+ "dev": true
+ },
+ "table": {
+ "version": "5.4.0",
+ "resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz",
+ "integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==",
+ "dev": true,
+ "requires": {
+ "ajv": "^6.9.1",
+ "lodash": "^4.17.11",
+ "slice-ansi": "^2.1.0",
+ "string-width": "^3.0.0"
+ },
+ "dependencies": {
+ "ansi-regex": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+ "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+ "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": "3.1.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+ "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+ "dev": true,
+ "requires": {
+ "emoji-regex": "^7.0.1",
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^5.1.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+ "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^4.1.0"
+ }
+ }
+ }
+ },
+ "tar-stream": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-1.6.2.tgz",
+ "integrity": "sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A==",
+ "dev": true,
+ "requires": {
+ "bl": "^1.0.0",
+ "buffer-alloc": "^1.2.0",
+ "end-of-stream": "^1.0.0",
+ "fs-constants": "^1.0.0",
+ "readable-stream": "^2.3.0",
+ "to-buffer": "^1.1.1",
+ "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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ },
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ }
+ }
+ },
+ "text-table": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
+ "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=",
+ "dev": true
+ },
+ "throttleit": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-0.0.2.tgz",
+ "integrity": "sha1-z+34jmDADdlpe2H90qg0OptoDq8="
+ },
+ "through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=",
+ "dev": true
+ },
+ "through2": {
+ "version": "0.2.3",
+ "resolved": "https://registry.npmjs.org/through2/-/through2-0.2.3.tgz",
+ "integrity": "sha1-6zKE2k6jEbbMis42U3SKUqvyWj8=",
+ "requires": {
+ "readable-stream": "~1.1.9",
+ "xtend": "~2.1.1"
+ }
+ },
+ "time-grunt": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-2.0.0.tgz",
+ "integrity": "sha512-iQD2AeDYCAJrsPC/eUsfYZD9UT7TuBOmUIgFV5zeTQgRk6yLJKoc3aYR0gusJ0m+bG13B6qrDZ0SwPLe0/htHw==",
+ "dev": true,
+ "requires": {
+ "chalk": "^1.0.0",
+ "date-time": "^1.1.0",
+ "figures": "^1.0.0",
+ "hooker": "^0.2.3",
+ "number-is-nan": "^1.0.0",
+ "pretty-ms": "^2.1.0",
+ "text-table": "^0.2.0"
+ },
+ "dependencies": {
+ "ansi-styles": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz",
+ "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
+ "dev": true
+ },
+ "chalk": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz",
+ "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
+ "dev": true,
+ "requires": {
+ "ansi-styles": "^2.2.1",
+ "escape-string-regexp": "^1.0.2",
+ "has-ansi": "^2.0.0",
+ "strip-ansi": "^3.0.0",
+ "supports-color": "^2.0.0"
+ }
+ },
+ "figures": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz",
+ "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=",
+ "dev": true,
+ "requires": {
+ "escape-string-regexp": "^1.0.5",
+ "object-assign": "^4.1.0"
+ }
+ },
+ "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
+ }
+ }
+ },
+ "time-zone": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz",
+ "integrity": "sha1-Sncotqwo2w4Aj1FAQ/1VW9VXO0Y=",
+ "dev": true
+ },
+ "tmp": {
+ "version": "0.0.33",
+ "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
+ "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
+ "dev": true,
+ "requires": {
+ "os-tmpdir": "~1.0.2"
+ }
+ },
+ "to-array": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
+ "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
+ },
+ "to-buffer": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/to-buffer/-/to-buffer-1.1.1.tgz",
+ "integrity": "sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg==",
+ "dev": true
+ },
+ "to-fast-properties": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz",
+ "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=",
+ "dev": true
+ },
+ "to-object-path": {
+ "version": "0.3.0",
+ "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz",
+ "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=",
+ "dev": true,
+ "requires": {
+ "kind-of": "^3.0.2"
+ },
+ "dependencies": {
+ "kind-of": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz",
+ "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^1.1.5"
+ }
+ }
+ }
+ },
+ "to-regex": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz",
+ "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==",
+ "dev": true,
+ "requires": {
+ "define-property": "^2.0.2",
+ "extend-shallow": "^3.0.2",
+ "regex-not": "^1.0.2",
+ "safe-regex": "^1.1.0"
+ },
+ "dependencies": {
+ "extend-shallow": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz",
+ "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=",
+ "dev": true,
+ "requires": {
+ "assign-symbols": "^1.0.0",
+ "is-extendable": "^1.0.1"
+ }
+ },
+ "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"
+ }
+ }
+ }
+ },
+ "to-regex-range": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz",
+ "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=",
+ "dev": true,
+ "requires": {
+ "is-number": "^3.0.0",
+ "repeat-string": "^1.6.1"
+ }
+ },
+ "toidentifier": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz",
+ "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw=="
+ },
+ "tough-cookie": {
+ "version": "2.4.3",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
+ "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
+ "requires": {
+ "psl": "^1.1.24",
+ "punycode": "^1.4.1"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
+ "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4="
+ }
+ }
+ },
+ "tr46": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-1.0.1.tgz",
+ "integrity": "sha1-qLE/1r/SSJUZZ0zN5VujaTtwbQk=",
+ "dev": true,
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "trim": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz",
+ "integrity": "sha1-WFhUf2spB1fulczMZm+1AITEYN0=",
+ "dev": true
+ },
+ "trim-newlines": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-1.0.0.tgz",
+ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM="
+ },
+ "trim-right": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz",
+ "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=",
+ "dev": true
+ },
+ "trim-trailing-lines": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.2.tgz",
+ "integrity": "sha512-MUjYItdrqqj2zpcHFTkMa9WAv4JHTI6gnRQGPFLrt5L9a6tRMiDnIqYl8JBvu2d2Tc3lWJKQwlGCp0K8AvCM+Q==",
+ "dev": true
+ },
+ "trough": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz",
+ "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==",
+ "dev": true
+ },
+ "tslib": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz",
+ "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ=="
+ },
+ "tunnel-agent": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
+ "integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
+ "requires": {
+ "safe-buffer": "^5.0.1"
+ }
+ },
+ "tweetnacl": {
+ "version": "0.14.5",
+ "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
+ "integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q="
+ },
+ "type-check": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz",
+ "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=",
+ "dev": true,
+ "requires": {
+ "prelude-ls": "~1.1.2"
+ }
+ },
+ "type-detect": {
+ "version": "4.0.8",
+ "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz",
+ "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==",
+ "dev": true
+ },
+ "type-is": {
+ "version": "1.6.18",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
+ "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==",
+ "requires": {
+ "media-typer": "0.3.0",
+ "mime-types": "~2.1.24"
+ }
+ },
+ "typedarray": {
+ "version": "0.0.6",
+ "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz",
+ "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c="
+ },
+ "uc.micro": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz",
+ "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==",
+ "dev": true
+ },
+ "underscore": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.6.0.tgz",
+ "integrity": "sha1-izixDKze9jM3uLJOT/htRa6lKag=",
+ "dev": true
+ },
+ "underscore.string": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz",
+ "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==",
+ "dev": true,
+ "requires": {
+ "sprintf-js": "^1.0.3",
+ "util-deprecate": "^1.0.2"
+ }
+ },
+ "unherit": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz",
+ "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==",
+ "dev": true,
+ "requires": {
+ "inherits": "^2.0.1",
+ "xtend": "^4.0.1"
+ },
+ "dependencies": {
+ "xtend": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.1.tgz",
+ "integrity": "sha1-pcbVMr5lbiPbgg77lDofBJmNY68=",
+ "dev": true
+ }
+ }
+ },
+ "unified": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz",
+ "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==",
+ "dev": true,
+ "requires": {
+ "@types/unist": "^2.0.0",
+ "@types/vfile": "^3.0.0",
+ "bail": "^1.0.0",
+ "extend": "^3.0.0",
+ "is-plain-obj": "^1.1.0",
+ "trough": "^1.0.0",
+ "vfile": "^3.0.0",
+ "x-is-string": "^0.1.0"
+ }
+ },
+ "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": {
+ "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",
+ "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz",
+ "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=",
+ "dev": true
+ },
+ "unist-util-find-all-after": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.4.tgz",
+ "integrity": "sha512-CaxvMjTd+yF93BKLJvZnEfqdM7fgEACsIpQqz8vIj9CJnUb9VpyymFS3tg6TCtgrF7vfCJBF5jbT2Ox9CBRYRQ==",
+ "dev": true,
+ "requires": {
+ "unist-util-is": "^3.0.0"
+ }
+ },
+ "unist-util-is": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz",
+ "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==",
+ "dev": true
+ },
+ "unist-util-remove-position": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.3.tgz",
+ "integrity": "sha512-CtszTlOjP2sBGYc2zcKA/CvNdTdEs3ozbiJ63IPBxh8iZg42SCCb8m04f8z2+V1aSk5a7BxbZKEdoDjadmBkWA==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit": "^1.1.0"
+ }
+ },
+ "unist-util-stringify-position": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz",
+ "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==",
+ "dev": true
+ },
+ "unist-util-visit": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz",
+ "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==",
+ "dev": true,
+ "requires": {
+ "unist-util-visit-parents": "^2.0.0"
+ }
+ },
+ "unist-util-visit-parents": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz",
+ "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==",
+ "dev": true,
+ "requires": {
+ "unist-util-is": "^3.0.0"
+ }
+ },
+ "universal-user-agent": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/universal-user-agent/-/universal-user-agent-2.1.0.tgz",
+ "integrity": "sha512-8itiX7G05Tu3mGDTdNY2fB4KJ8MgZLS54RdG6PkkfwMAavrXu1mV/lls/GABx9O3Rw4PnTtasxrvbMQoBYY92Q==",
+ "dev": true,
+ "requires": {
+ "os-name": "^3.0.0"
+ }
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
+ },
+ "unix-crypt-td-js": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.0.0.tgz",
+ "integrity": "sha1-HAgkFQSBvHoB1J6Y8exmjYJBLzs=",
+ "dev": true
+ },
+ "unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
+ },
+ "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
+ },
+ "isarray": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
+ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=",
+ "dev": true
+ }
+ }
+ },
+ "uri-js": {
+ "version": "4.2.2",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
+ "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "urix": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz",
+ "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=",
+ "dev": true
+ },
+ "url": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz",
+ "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=",
+ "dev": true,
+ "requires": {
+ "punycode": "1.3.2",
+ "querystring": "0.2.0"
+ },
+ "dependencies": {
+ "punycode": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz",
+ "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=",
+ "dev": true
+ }
+ }
+ },
+ "url-template": {
+ "version": "2.0.8",
+ "resolved": "https://registry.npmjs.org/url-template/-/url-template-2.0.8.tgz",
+ "integrity": "sha1-/FZaPMy/93MMd19WQflVV5FDnyE=",
+ "dev": true
+ },
+ "use": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz",
+ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==",
+ "dev": true
+ },
+ "util-deprecate": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
+ "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8="
+ },
+ "utils-merge": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
+ "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
+ },
+ "uuid": {
+ "version": "3.3.2",
+ "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
+ "integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA=="
+ },
+ "valid-url": {
+ "version": "1.0.9",
+ "resolved": "https://registry.npmjs.org/valid-url/-/valid-url-1.0.9.tgz",
+ "integrity": "sha1-HBRHm0DxOXp1eC8RXkCGRHQzogA="
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
+ },
+ "verror": {
+ "version": "1.10.0",
+ "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
+ "integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
+ "requires": {
+ "assert-plus": "^1.0.0",
+ "core-util-is": "1.0.2",
+ "extsprintf": "^1.2.0"
+ }
+ },
+ "vfile": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz",
+ "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==",
+ "dev": true,
+ "requires": {
+ "is-buffer": "^2.0.0",
+ "replace-ext": "1.0.0",
+ "unist-util-stringify-position": "^1.0.0",
+ "vfile-message": "^1.0.0"
+ },
+ "dependencies": {
+ "is-buffer": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz",
+ "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==",
+ "dev": true
+ }
+ }
+ },
+ "vfile-location": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.5.tgz",
+ "integrity": "sha512-Pa1ey0OzYBkLPxPZI3d9E+S4BmvfVwNAAXrrqGbwTVXWaX2p9kM1zZ+n35UtVM06shmWKH4RPRN8KI80qE3wNQ==",
+ "dev": true
+ },
+ "vfile-message": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz",
+ "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==",
+ "dev": true,
+ "requires": {
+ "unist-util-stringify-position": "^1.1.1"
+ }
+ },
+ "vm2": {
+ "version": "3.8.1",
+ "resolved": "https://registry.npmjs.org/vm2/-/vm2-3.8.1.tgz",
+ "integrity": "sha512-ecR1+KFuP7KK2hpo8ItamW0F9pq4dJOd4o+r6OWvAsx2eXGPshP6uKE24qepGshT8v+TF0jpnzugFJak42LuZQ==",
+ "dev": true
+ },
+ "voca": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/voca/-/voca-1.4.0.tgz",
+ "integrity": "sha512-8Xz4H3vhYRGbFupLtl6dHwMx0ojUcjt0HYkqZ9oBCfipd/5mD7Md58m2/dq7uPuZU/0T3Gb1m66KS9jn+I+14Q==",
+ "dev": true
+ },
+ "w3c-hr-time": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz",
+ "integrity": "sha1-gqwr/2PZUOqeMYmlimViX+3xkEU=",
+ "dev": true,
+ "requires": {
+ "browser-process-hrtime": "^0.1.2"
+ }
+ },
+ "wdio-dot-reporter": {
+ "version": "0.0.10",
+ "resolved": "https://registry.npmjs.org/wdio-dot-reporter/-/wdio-dot-reporter-0.0.10.tgz",
+ "integrity": "sha512-A0TCk2JdZEn3M1DSG9YYbNRcGdx/YRw19lTiRpgwzH4qqWkO/oRDZRmi3Snn4L2j54KKTfPalBhlOtc8fojVgg==",
+ "dev": true
+ },
+ "webdriverio": {
+ "version": "4.14.4",
+ "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-4.14.4.tgz",
+ "integrity": "sha512-Knp2vzuzP5c5ybgLu+zTwy/l1Gh0bRP4zAr8NWcrStbuomm9Krn9oRF0rZucT6AyORpXinETzmeowFwIoo7mNA==",
+ "dev": true,
+ "requires": {
+ "archiver": "~2.1.0",
+ "babel-runtime": "^6.26.0",
+ "css-parse": "^2.0.0",
+ "css-value": "~0.0.1",
+ "deepmerge": "~2.0.1",
+ "ejs": "~2.5.6",
+ "gaze": "~1.1.2",
+ "glob": "~7.1.1",
+ "grapheme-splitter": "^1.0.2",
+ "inquirer": "~3.3.0",
+ "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.83.0",
+ "rgb2hex": "^0.1.9",
+ "safe-buffer": "~5.1.1",
+ "supports-color": "~5.0.0",
+ "url": "~0.11.0",
+ "wdio-dot-reporter": "~0.0.8",
+ "wgxpath": "~1.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
+ },
+ "chardet": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz",
+ "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=",
+ "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==",
+ "dev": true,
+ "requires": {
+ "chardet": "^0.4.0",
+ "iconv-lite": "^0.4.17",
+ "tmp": "^0.0.33"
+ }
+ },
+ "glob": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
+ "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
+ "dev": true,
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "has-flag": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-2.0.0.tgz",
+ "integrity": "sha1-6CB68cx7MNRGzHC3NLXovhj4jVE=",
+ "dev": true
+ },
+ "inquirer": {
+ "version": "3.3.0",
+ "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-3.3.0.tgz",
+ "integrity": "sha512-h+xtnyk4EwKvFWHrUYsWErEVR+igKtLdchu+o0Z1RL7VU/jVMFbYir2bp6bAj8efFNxWqHX0dIss6fJQ+/+qeQ==",
+ "dev": true,
+ "requires": {
+ "ansi-escapes": "^3.0.0",
+ "chalk": "^2.0.0",
+ "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.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"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ },
+ "supports-color": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.0.1.tgz",
+ "integrity": "sha512-7FQGOlSQ+AQxBNXJpVDj8efTA/FtyB5wcNE1omXXJ0cq6jm1jjDwuROlYDbnzHqdNPqliWFhcioCWSyav+xBnA==",
+ "dev": true,
+ "requires": {
+ "has-flag": "^2.0.0"
+ }
+ }
+ }
+ },
+ "webidl-conversions": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz",
+ "integrity": "sha512-YQ+BmxuTgd6UXZW3+ICGfyqRyHXVlD5GtQr5+qjiNW7bF0cqrzX500HVXPBOvgXb5YnzDd+h0zqyv61KUD7+Sg==",
+ "dev": true
+ },
+ "wgxpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wgxpath/-/wgxpath-1.0.0.tgz",
+ "integrity": "sha1-7vikudVYzEla06mit1FZfs2a9pA=",
+ "dev": true
+ },
+ "whatwg-encoding": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz",
+ "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==",
+ "dev": true,
+ "requires": {
+ "iconv-lite": "0.4.24"
+ }
+ },
+ "whatwg-mimetype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz",
+ "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==",
+ "dev": true
+ },
+ "whatwg-url": {
+ "version": "6.5.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-6.5.0.tgz",
+ "integrity": "sha512-rhRZRqx/TLJQWUpQ6bmrt2UV4f0HCQ463yQuONJqC6fO2VoEb1pTYddbe59SkYq87aoM5A3bdhMZiUiVws+fzQ==",
+ "dev": true,
+ "requires": {
+ "lodash.sortby": "^4.7.0",
+ "tr46": "^1.0.1",
+ "webidl-conversions": "^4.0.2"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "dev": true,
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz",
+ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=",
+ "dev": true
+ },
+ "windows-release": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz",
+ "integrity": "sha512-QTlz2hKLrdqukrsapKsINzqMgOUpQW268eJ0OaOpJN32h272waxR9fkB9VoWRtK7uKHG5EHJcTXQBD8XZVJkFA==",
+ "dev": true,
+ "requires": {
+ "execa": "^1.0.0"
+ }
+ },
+ "wordwrap": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz",
+ "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=",
+ "dev": true
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=",
+ "dev": true,
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
+ "dev": true
+ },
+ "write": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz",
+ "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==",
+ "dev": true,
+ "requires": {
+ "mkdirp": "^0.5.1"
+ }
+ },
+ "ws": {
+ "version": "6.1.4",
+ "resolved": "https://registry.npmjs.org/ws/-/ws-6.1.4.tgz",
+ "integrity": "sha512-eqZfL+NE/YQc1/ZynhojeV8q+H050oR8AZ2uIev7RU10svA9ZnJUddHcOUZTJLinZ9yEfdA2kSATS2qZK5fhJA==",
+ "requires": {
+ "async-limiter": "~1.0.0"
+ }
+ },
+ "x-is-string": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz",
+ "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=",
+ "dev": true
+ },
+ "x-xss-protection": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.1.0.tgz",
+ "integrity": "sha512-rx3GzJlgEeZ08MIcDsU2vY2B1QEriUKJTSiNHHUIem6eg9pzVOr2TL3Y4Pd6TMAM5D5azGjcxqI62piITBDHVg=="
+ },
+ "xml-name-validator": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz",
+ "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==",
+ "dev": true
+ },
+ "xmlhttprequest-ssl": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
+ "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
+ },
+ "xtend": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/xtend/-/xtend-2.1.2.tgz",
+ "integrity": "sha1-bv7MKk2tjmlixJAbM3znuoe10os=",
+ "requires": {
+ "object-keys": "~0.4.0"
+ }
+ },
+ "y18n": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-3.2.1.tgz",
+ "integrity": "sha1-bRX7qITAhnnA136I53WegR4H+kE=",
+ "dev": true
+ },
+ "yallist": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz",
+ "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=",
+ "dev": true
+ },
+ "yargs": {
+ "version": "11.1.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz",
+ "integrity": "sha512-NwW69J42EsCSanF8kyn5upxvjp5ds+t3+udGBeTbFnERA+lF541DDpMawzo4z6W/QrzNM18D+BPMiOBibnFV5A==",
+ "dev": true,
+ "requires": {
+ "cliui": "^4.0.0",
+ "decamelize": "^1.1.1",
+ "find-up": "^2.1.0",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^2.0.0",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^2.0.0",
+ "which-module": "^2.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^9.0.2"
+ },
+ "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
+ },
+ "find-up": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz",
+ "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=",
+ "dev": true,
+ "requires": {
+ "locate-path": "^2.0.0"
+ }
+ },
+ "is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+ "dev": true
+ },
+ "string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "dev": true,
+ "requires": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=",
+ "dev": true,
+ "requires": {
+ "ansi-regex": "^3.0.0"
+ }
+ }
+ }
+ },
+ "yargs-parser": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-9.0.2.tgz",
+ "integrity": "sha1-nM9qQ0YP5O1Aqbto9I1DuKaMwHc=",
+ "dev": true,
+ "requires": {
+ "camelcase": "^4.1.0"
+ },
+ "dependencies": {
+ "camelcase": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz",
+ "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=",
+ "dev": true
+ }
+ }
+ },
+ "yauzl": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz",
+ "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=",
+ "requires": {
+ "fd-slicer": "~1.0.1"
+ }
+ },
+ "yeast": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
+ "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
+ },
+ "zip-stream": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/zip-stream/-/zip-stream-1.2.0.tgz",
+ "integrity": "sha1-qLxF9MG0lpnGuQGYuqyqzbzUugQ=",
+ "dev": true,
+ "requires": {
+ "archiver-utils": "^1.3.0",
+ "compress-commons": "^1.2.0",
+ "lodash": "^4.8.0",
+ "readable-stream": "^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.6",
+ "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz",
+ "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==",
+ "dev": true,
+ "requires": {
+ "core-util-is": "~1.0.0",
+ "inherits": "~2.0.3",
+ "isarray": "~1.0.0",
+ "process-nextick-args": "~2.0.0",
+ "safe-buffer": "~5.1.1",
+ "string_decoder": "~1.1.1",
+ "util-deprecate": "~1.0.1"
+ }
+ },
+ "string_decoder": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
+ "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
+ "dev": true,
+ "requires": {
+ "safe-buffer": "~5.1.0"
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 8157fed8..1f7e7402 100644
--- a/package.json
+++ b/package.json
@@ -1,16 +1,18 @@
{
"name": "magicmirror",
- "version": "2.1.2-dev",
+ "version": "2.9.0-develop",
"description": "The open source modular smart mirror platform.",
"main": "js/electron.js",
"scripts": {
"start": "sh run-start.sh",
"install": "cd vendor && npm install",
- "postinstall": "sh installers/postinstall/postinstall.sh",
+ "install-fonts": "cd fonts && npm install",
+ "postinstall": "sh installers/postinstall/postinstall.sh && npm run install-fonts",
"test": "NODE_ENV=test ./node_modules/mocha/bin/mocha tests --recursive",
"test:unit": "NODE_ENV=test ./node_modules/mocha/bin/mocha tests/unit --recursive",
"test:e2e": "NODE_ENV=test ./node_modules/mocha/bin/mocha tests/e2e --recursive",
- "config:check": "node tests/configs/check_config.js"
+ "config:check": "node tests/configs/check_config.js",
+ "lint": "grunt"
},
"repository": {
"type": "git",
@@ -32,36 +34,41 @@
},
"homepage": "https://magicmirror.builders",
"devDependencies": {
- "chai": "^3.5.0",
- "chai-as-promised": "^6.0.0",
+ "chai": "^4.1.2",
+ "chai-as-promised": "^7.1.1",
+ "current-week-number": "^1.0.7",
+ "danger": "^3.1.3",
"grunt": "latest",
"grunt-eslint": "latest",
"grunt-jsonlint": "latest",
- "grunt-markdownlint": "^1.0.13",
+ "grunt-markdownlint": "latest",
"grunt-stylelint": "latest",
"grunt-yamllint": "latest",
- "http-auth": "^3.1.3",
- "jshint": "^2.9.4",
- "mocha": "^3.2.0",
- "spectron": "^3.4.1",
+ "http-auth": "^3.2.3",
+ "jsdom": "^11.6.2",
+ "jshint": "^2.10.2",
+ "mocha": "^4.1.0",
+ "mocha-each": "^1.1.0",
+ "mocha-logger": "^1.0.6",
+ "spectron": "^3.8.0",
+ "stylelint": "latest",
"stylelint-config-standard": "latest",
"time-grunt": "latest"
},
"dependencies": {
- "body-parser": "^1.17.1",
"colors": "^1.1.2",
- "electron": "^1.4.7",
- "express": "^4.14.0",
- "express-ipfilter": "latest",
+ "electron": "^3.0.13",
+ "express": "^4.16.2",
+ "express-ipfilter": "^1.0.1",
"feedme": "latest",
- "helmet": "^3.1.0",
+ "helmet": "^3.9.0",
"iconv-lite": "latest",
"moment": "latest",
- "request": "^2.78.0",
- "rrule-alt": "^2.2.3",
- "simple-git": "^1.62.0",
- "socket.io": "^1.7.3",
- "valid-url": "latest",
- "walk": "latest"
+ "request": "^2.88.0",
+ "rrule": "^2.6.2",
+ "rrule-alt": "^2.2.8",
+ "simple-git": "^1.85.0",
+ "socket.io": "^2.1.1",
+ "valid-url": "latest"
}
}
diff --git a/run-start.sh b/run-start.sh
index a039ec4d..6fc19b51 100644
--- a/run-start.sh
+++ b/run-start.sh
@@ -1,4 +1,4 @@
if [ -z "$DISPLAY" ]; then #If not set DISPLAY is SSH remote or tty
- export DISPLAY=:0 # Set by defaul display
+ export DISPLAY=:0 # Set by default display
fi
electron js/electron.js $1
diff --git a/serveronly/index.js b/serveronly/index.js
index ccd4c294..3b8013ef 100644
--- a/serveronly/index.js
+++ b/serveronly/index.js
@@ -1,6 +1,5 @@
var app = require("../js/app.js");
app.start(function(config) {
- console.log("");
var bindAddress = config.address ? config.address : "localhost";
- console.log("Ready to go! Please point your browser to: http://" + bindAddress + ":" + config.port);
+ console.log("\nReady to go! Please point your browser to: http://" + bindAddress + ":" + config.port);
});
diff --git a/tests/configs/check_config.js b/tests/configs/check_config.js
index fa294761..03a275bf 100644
--- a/tests/configs/check_config.js
+++ b/tests/configs/check_config.js
@@ -14,11 +14,9 @@ var path = require("path");
var fs = require("fs");
var Utils = require(__dirname + "/../../js/utils.js");
-if (process.env.NODE_ENV == "test") {return 0};
-
/* getConfigFile()
* Return string with path of configuration file
- * Check if set by enviroment variable MM_CONFIG_FILE
+ * Check if set by environment variable MM_CONFIG_FILE
*/
function getConfigFile() {
// FIXME: This function should be in core. Do you want refactor me ;) ?, be good!
@@ -30,37 +28,43 @@ function getConfigFile() {
return configFileName;
}
-var configFileName = getConfigFile();
-// Check if file is present
-if (fs.existsSync(configFileName) === false) {
- console.error(Utils.colors.error("File not found: "), configFileName);
- return;
-}
-// check permision
-try {
- fs.accessSync(configFileName, fs.F_OK);
-} catch (e) {
- console.log(Utils.colors.error(e));
- return;
-}
-
-// Validate syntax of the configuration file.
-// In case the there errors show messages and
-// return
-console.info(Utils.colors.info("Checking file... ", configFileName));
- // I'm not sure if all ever is utf-8
-fs.readFile(configFileName, "utf-8", function(err, data) {
- if (err) {throw err;}
- v.JSHINT(data); // Parser by jshint
-
- if (v.JSHINT.errors.length == 0) {
- console.log("Your configuration file don't containt syntax error :)");
- return true;
- } else {
- errors = v.JSHINT.data().errors;
- for (idx in errors) {
- error = errors[idx];
- console.log("Line", error.line, "col", error.character, error.reason);
- }
+function checkConfigFile() {
+ var configFileName = getConfigFile();
+ // Check if file is present
+ if (fs.existsSync(configFileName) === false) {
+ console.error(Utils.colors.error("File not found: "), configFileName);
+ return;
}
-});
+ // check permission
+ try {
+ fs.accessSync(configFileName, fs.F_OK);
+ } catch (e) {
+ console.log(Utils.colors.error(e));
+ return;
+ }
+
+ // Validate syntax of the configuration file.
+ // In case the there errors show messages and
+ // return
+ console.info(Utils.colors.info("Checking file... ", configFileName));
+ // I'm not sure if all ever is utf-8
+ fs.readFile(configFileName, "utf-8", function (err, data) {
+ if (err) { throw err; }
+ v.JSHINT(data); // Parser by jshint
+
+ if (v.JSHINT.errors.length === 0) {
+ console.log("Your configuration file doesn't contain syntax errors :)");
+ return true;
+ } else {
+ errors = v.JSHINT.data().errors;
+ for (var idx in errors) {
+ error = errors[idx];
+ console.log("Line", error.line, "col", error.character, error.reason);
+ }
+ }
+ });
+}
+
+if (process.env.NODE_ENV !== "test") {
+ checkConfigFile();
+}
diff --git a/tests/configs/data/StripComments.json b/tests/configs/data/StripComments.json
new file mode 100644
index 00000000..62d5d618
--- /dev/null
+++ b/tests/configs/data/StripComments.json
@@ -0,0 +1,13 @@
+{
+ // Escaped
+ "FOO\"BAR": "Today",
+
+ /*
+ * The following lines
+ * represent cardinal directions
+ */
+ "N": "N",
+ "E": "E",
+ "S": "S",
+ "W": "W"
+}
diff --git a/tests/configs/data/TranslationTest.json b/tests/configs/data/TranslationTest.json
new file mode 100644
index 00000000..bbb13845
--- /dev/null
+++ b/tests/configs/data/TranslationTest.json
@@ -0,0 +1,33 @@
+{
+ "LOADING": "Loading …",
+
+ "TODAY": "Today",
+ "TOMORROW": "Tomorrow",
+ "DAYAFTERTOMORROW": "In 2 days",
+ "RUNNING": "Ends in",
+ "EMPTY": "No upcoming events.",
+
+ "WEEK": "Week {weekNumber}",
+
+ "N": "N",
+ "NNE": "NNE",
+ "NE": "NE",
+ "ENE": "ENE",
+ "E": "E",
+ "ESE": "ESE",
+ "SE": "SE",
+ "SSE": "SSE",
+ "S": "S",
+ "SSW": "SSW",
+ "SW": "SW",
+ "WSW": "WSW",
+ "W": "W",
+ "WNW": "WNW",
+ "NW": "NW",
+ "NNW": "NNW",
+
+ "UPDATE_NOTIFICATION": "MagicMirror² update available.",
+ "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.",
+ "UPDATE_INFO_SINGLE": "The current installation is COMMIT_COUNT commit behind on the BRANCH_NAME branch.",
+ "UPDATE_INFO_MULTIPLE": "The current installation is COMMIT_COUNT commits behind on the BRANCH_NAME branch."
+}
diff --git a/tests/configs/data/en.json b/tests/configs/data/en.json
new file mode 100644
index 00000000..bbb13845
--- /dev/null
+++ b/tests/configs/data/en.json
@@ -0,0 +1,33 @@
+{
+ "LOADING": "Loading …",
+
+ "TODAY": "Today",
+ "TOMORROW": "Tomorrow",
+ "DAYAFTERTOMORROW": "In 2 days",
+ "RUNNING": "Ends in",
+ "EMPTY": "No upcoming events.",
+
+ "WEEK": "Week {weekNumber}",
+
+ "N": "N",
+ "NNE": "NNE",
+ "NE": "NE",
+ "ENE": "ENE",
+ "E": "E",
+ "ESE": "ESE",
+ "SE": "SE",
+ "SSE": "SSE",
+ "S": "S",
+ "SSW": "SSW",
+ "SW": "SW",
+ "WSW": "WSW",
+ "W": "W",
+ "WNW": "WNW",
+ "NW": "NW",
+ "NNW": "NNW",
+
+ "UPDATE_NOTIFICATION": "MagicMirror² update available.",
+ "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.",
+ "UPDATE_INFO_SINGLE": "The current installation is COMMIT_COUNT commit behind on the BRANCH_NAME branch.",
+ "UPDATE_INFO_MULTIPLE": "The current installation is COMMIT_COUNT commits behind on the BRANCH_NAME branch."
+}
diff --git a/tests/configs/env.js b/tests/configs/env.js
index 252934d7..ef244c39 100644
--- a/tests/configs/env.js
+++ b/tests/configs/env.js
@@ -1,4 +1,4 @@
-/* Magic Mirror Test config sample enviroment
+/* Magic Mirror Test config sample environment
*
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
diff --git a/tests/configs/modules/clock/es/clock_showWeek.js b/tests/configs/modules/clock/es/clock_showWeek.js
new file mode 100644
index 00000000..29550f04
--- /dev/null
+++ b/tests/configs/modules/clock/es/clock_showWeek.js
@@ -0,0 +1,38 @@
+
+/* Magic Mirror
+ *
+ * Test config for default clock module
+ * Language es for showWeek feature
+ *
+ * By Rodrigo Ramírez Norambuena
+ * https://rodrigoramirez.com
+ *
+ * MIT Licensed.
+ */
+
+var config = {
+ port: 8080,
+ ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
+
+ language: "es",
+ timeFormat: 12,
+ units: "metric",
+ electronOptions: {
+ webPreferences: {
+ nodeIntegration: true,
+ },
+ },
+
+ modules: [
+ {
+ module: "clock",
+ position: "middle_center",
+ config: {
+ showWeek: true
+ }
+ }
+ ]
+};
+
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {module.exports = config;}
diff --git a/tests/configs/modules/helloworld/helloworld_default.js b/tests/configs/modules/helloworld/helloworld_default.js
new file mode 100644
index 00000000..710000f0
--- /dev/null
+++ b/tests/configs/modules/helloworld/helloworld_default.js
@@ -0,0 +1,31 @@
+/* Magic Mirror
+ *
+ * Test config sample module hello world default config
+ *
+ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
+ * MIT Licensed.
+ */
+
+var config = {
+ port: 8080,
+ ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
+
+ language: "en",
+ timeFormat: 24,
+ units: "metric",
+ electronOptions: {
+ webPreferences: {
+ nodeIntegration: true,
+ },
+ },
+
+ modules: [
+ {
+ module: "helloworld",
+ position: "bottom_bar"
+ }
+ ]
+};
+
+/*************** DO NOT EDIT THE LINE BELOW ***************/
+if (typeof module !== "undefined") {module.exports = config;}
diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js
index 60e6dd04..d56fab91 100644
--- a/tests/configs/modules/positions.js
+++ b/tests/configs/modules/positions.js
@@ -6,7 +6,6 @@
* MIT Licensed.
*/
-
var config = {
port: 8080,
ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"],
diff --git a/tests/configs/port_8090.js b/tests/configs/port_8090.js
index 6646dff7..d1dc546f 100644
--- a/tests/configs/port_8090.js
+++ b/tests/configs/port_8090.js
@@ -1,4 +1,4 @@
-/* Magic Mirror Test config sample enviroment set por 8090
+/* Magic Mirror Test config sample environment set port 8090
*
* By Rodrigo Ramírez Norambuena https://rodrigoramirez.com
* MIT Licensed.
diff --git a/tests/e2e/dev_console.js b/tests/e2e/dev_console.js
index b430e9e4..42f8ac99 100644
--- a/tests/e2e/dev_console.js
+++ b/tests/e2e/dev_console.js
@@ -1,50 +1,60 @@
-const Application = require("spectron").Application;
-const path = require("path");
-const chai = require("chai");
-const expect = chai.expect;
-const chaiAsPromised = require("chai-as-promised");
+const helpers = require("./global-setup");
+const expect = require("chai").expect;
-var electronPath = path.join(__dirname, "../../", "node_modules", ".bin", "electron");
+const describe = global.describe;
+const it = global.it;
-if (process.platform === "win32") {
- electronPath += ".cmd";
-}
+describe("Development console tests", function() {
+ // This tests fail and crash another tests
+ // Suspect problem with window focus
+ // FIXME
+ return false;
-var appPath = path.join(__dirname, "../../js/electron.js");
+ helpers.setupTimeout(this);
-var app = new Application({
- path: electronPath
-});
-
-global.before(function () {
- chai.should();
- chai.use(chaiAsPromised);
-});
-
-describe("Argument 'dev'", function () {
- this.timeout(20000);
+ var app = null;
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/env.js";
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
+ describe("Without 'dev' commandline argument", function() {
+ before(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
+ });
- it("should not open dev console when absent", function () {
- app.args = [appPath];
+ after(function() {
+ return helpers.stopApplication(app);
+ });
- return app.start().then(function() {
+ it("should not open dev console when absent", function() {
return expect(app.browserWindow.isDevToolsOpened()).to.eventually.equal(false);
});
});
- it("should open dev console when provided", function () {
- app.args = [appPath, "dev"];
+ describe("With 'dev' commandline argument", function() {
+ before(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js", "dev"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
+ });
- return app.start().then(function() {
+ after(function() {
+ return helpers.stopApplication(app);
+ });
+
+ it("should open dev console when provided", function() {
return expect(app.browserWindow.isDevToolsOpened()).to.eventually.equal(true);
});
});
diff --git a/tests/e2e/env_spec.js b/tests/e2e/env_spec.js
index 202bd5e4..73784e96 100644
--- a/tests/e2e/env_spec.js
+++ b/tests/e2e/env_spec.js
@@ -1,47 +1,67 @@
-const globalSetup = require("./global-setup");
-const app = globalSetup.app;
+const helpers = require("./global-setup");
const request = require("request");
-const chai = require("chai");
-const expect = chai.expect;
+const expect = require("chai").expect;
-describe("Electron app environment", function () {
- this.timeout(20000);
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
+
+describe("Electron app environment", function() {
+ helpers.setupTimeout(this);
+
+ var app = null;
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/env.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
+ beforeEach(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
+ afterEach(function() {
+ return helpers.stopApplication(app);
});
- it("is set to open new app window", function () {
- return app.client.waitUntilWindowLoaded()
- .getWindowCount().should.eventually.equal(1);
+ it("should open a browserwindow", function() {
+ return app.client
+ .waitUntilWindowLoaded()
+ // .browserWindow.focus()
+ .getWindowCount()
+ .should.eventually.equal(1)
+ .browserWindow.isMinimized()
+ .should.eventually.be.false.browserWindow.isDevToolsOpened()
+ .should.eventually.be.false.browserWindow.isVisible()
+ .should.eventually.be.true.browserWindow.isFocused()
+ .should.eventually.be.true.browserWindow.getBounds()
+ .should.eventually.have.property("width")
+ .and.be.above(0)
+ .browserWindow.getBounds()
+ .should.eventually.have.property("height")
+ .and.be.above(0)
+ .browserWindow.getTitle()
+ .should.eventually.equal("MagicMirror²");
});
- it("sets correct window title", function () {
- return app.client.waitUntilWindowLoaded()
- .getTitle().should.eventually.equal("Magic Mirror");
- });
-
- it("get request from http://localhost:8080 should return 200", function (done) {
- request.get("http://localhost:8080", function (err, res, body) {
+ it("get request from http://localhost:8080 should return 200", function(done) {
+ request.get("http://localhost:8080", function(err, res, body) {
expect(res.statusCode).to.equal(200);
done();
});
});
- it("get request from http://localhost:8080/nothing should return 404", function (done) {
- request.get("http://localhost:8080/nothing", function (err, res, body) {
+ it("get request from http://localhost:8080/nothing should return 404", function(done) {
+ request.get("http://localhost:8080/nothing", function(err, res, body) {
expect(res.statusCode).to.equal(404);
done();
});
});
-
});
diff --git a/tests/e2e/fonts.js b/tests/e2e/fonts.js
new file mode 100644
index 00000000..7df36ad8
--- /dev/null
+++ b/tests/e2e/fonts.js
@@ -0,0 +1,47 @@
+const helpers = require("./global-setup");
+const request = require("request");
+const expect = require("chai").expect;
+const forEach = require("mocha-each");
+
+const describe = global.describe;
+
+describe("All font files from roboto.css should be downloadable", function() {
+ helpers.setupTimeout(this);
+
+ var fontFiles = [];
+ // Statements below filters out all 'url' lines in the CSS file
+ var fileContent = require("fs").readFileSync(__dirname + "/../../fonts/roboto.css", "utf8");
+ var regex = /\burl\(['"]([^'"]+)['"]\)/g;
+ var match = regex.exec(fileContent);
+ while (match !== null) {
+ // Push 1st match group onto fontFiles stack
+ fontFiles.push(match[1]);
+ // Find the next one
+ match = regex.exec(fileContent);
+ }
+
+ before(function() {
+ // Set config sample for use in test
+ process.env.MM_CONFIG_FILE = "tests/configs/without_modules.js";
+
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
+ });
+
+ after(function() {
+ return helpers.stopApplication(app);
+ });
+
+ forEach(fontFiles).it("should return 200 HTTP code for file '%s'", (fontFile, done) => {
+ var fontUrl = "http://localhost:8080/fonts/" + fontFile;
+ request.get(fontUrl, function(err, res, body) {
+ expect(res.statusCode).to.equal(200);
+ done();
+ });
+ });
+});
diff --git a/tests/e2e/global-setup.js b/tests/e2e/global-setup.js
index 7b94ec40..c4b170fe 100644
--- a/tests/e2e/global-setup.js
+++ b/tests/e2e/global-setup.js
@@ -9,26 +9,53 @@
*/
const Application = require("spectron").Application;
-const path = require("path");
+const assert = require("assert");
const chai = require("chai");
const chaiAsPromised = require("chai-as-promised");
+const path = require("path");
-var electronPath = path.join(__dirname, "../../", "node_modules", ".bin", "electron");
-
-if (process.platform === "win32") {
- electronPath += ".cmd";
-}
-
-var appPath = path.join(__dirname, "../../js/electron.js");
-
-var app = new Application({
- path: electronPath,
- args: [appPath]
-});
-
-global.before(function () {
+global.before(function() {
chai.should();
chai.use(chaiAsPromised);
});
-exports.app = app;
+exports.getElectronPath = function() {
+ var electronPath = path.join(__dirname, "..", "..", "node_modules", ".bin", "electron");
+ if (process.platform === "win32") {
+ electronPath += ".cmd";
+ }
+ return electronPath;
+};
+
+// Set timeout - if this is run within Travis, increase timeout
+exports.setupTimeout = function(test) {
+ if (process.env.CI) {
+ test.timeout(30000);
+ } else {
+ test.timeout(10000);
+ }
+};
+
+exports.startApplication = function(options) {
+ options.path = exports.getElectronPath();
+ if (process.env.CI) {
+ options.startTimeout = 30000;
+ }
+
+ var app = new Application(options);
+ return app.start().then(function() {
+ assert.equal(app.isRunning(), true);
+ chaiAsPromised.transferPromiseness = app.transferPromiseness;
+ return app;
+ });
+};
+
+exports.stopApplication = function(app) {
+ if (!app || !app.isRunning()) {
+ return;
+ }
+
+ return app.stop().then(function() {
+ assert.equal(app.isRunning(), false);
+ });
+};
diff --git a/tests/e2e/ipWhistlist_spec.js b/tests/e2e/ipWhistlist_spec.js
index 46fc4cff..c544465e 100644
--- a/tests/e2e/ipWhistlist_spec.js
+++ b/tests/e2e/ipWhistlist_spec.js
@@ -1,24 +1,29 @@
-const globalSetup = require("./global-setup");
-const app = globalSetup.app;
+const helpers = require("./global-setup");
const request = require("request");
-const chai = require("chai");
-const expect = chai.expect;
+const expect = require("chai").expect;
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
describe("ipWhitelist directive configuration", function () {
+ helpers.setupTimeout(this);
- this.timeout(20000);
+ var app = null;
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
+ beforeEach(function () {
+ return helpers.startApplication({
+ args: ["js/electron.js"]
+ }).then(function (startedApp) { app = startedApp; });
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
+ afterEach(function () {
+ return helpers.stopApplication(app);
});
describe("Set ipWhitelist without access", function () {
- before(function() {
+ before(function () {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/noIpWhiteList.js";
});
@@ -31,7 +36,7 @@ describe("ipWhitelist directive configuration", function () {
});
describe("Set ipWhitelist []", function () {
- before(function() {
+ before(function () {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/empty_ipWhiteList.js";
});
diff --git a/tests/e2e/modules/calendar_spec.js b/tests/e2e/modules/calendar_spec.js
index c701ed3c..beeba148 100644
--- a/tests/e2e/modules/calendar_spec.js
+++ b/tests/e2e/modules/calendar_spec.js
@@ -1,19 +1,28 @@
-const globalSetup = require("../global-setup");
-const serverBasicAuth = require("../../servers/basic-auth.js");
-const app = globalSetup.app;
-const chai = require("chai");
-const expect = chai.expect;
+const helpers = require("../global-setup");
+const serverBasicAuth = require("../../servers/basic-auth.js");
-describe("Calendar module", function () {
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
- this.timeout(20000);
+describe("Calendar module", function() {
+ helpers.setupTimeout(this);
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
+ var app = null;
+
+ beforeEach(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
+ afterEach(function() {
+ return helpers.stopApplication(app);
});
describe("Default configuration", function() {
@@ -22,12 +31,11 @@ describe("Calendar module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/default.js";
});
- it("Should return TestEvents", function () {
+ it("Should return TestEvents", function() {
return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000);
});
});
-
describe("Basic auth", function() {
before(function() {
serverBasicAuth.listen(8010);
@@ -35,12 +43,15 @@ describe("Calendar module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/basic-auth.js";
});
- it("Should return TestEvents", function () {
+ after(function(done) {
+ serverBasicAuth.close(done());
+ });
+
+ it("Should return TestEvents", function() {
return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000);
});
});
-
describe("Basic auth by default", function() {
before(function() {
serverBasicAuth.listen(8011);
@@ -48,19 +59,27 @@ describe("Calendar module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/auth-default.js";
});
- it("Should return TestEvents", function () {
+ after(function(done) {
+ serverBasicAuth.close(done());
+ });
+
+ it("Should return TestEvents", function() {
return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000);
});
});
- describe("Basic auth backward compatibilty configuration", function() {
+ describe("Basic auth backward compatibility configuration: DEPRECATED", function() {
before(function() {
serverBasicAuth.listen(8012);
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/old-basic-auth.js";
});
- it("Should return TestEvents", function () {
+ after(function(done) {
+ serverBasicAuth.close(done());
+ });
+
+ it("Should return TestEvents", function() {
return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000);
});
});
@@ -72,10 +91,12 @@ describe("Calendar module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/fail-basic-auth.js";
});
- it("Should return No upcoming events", function () {
+ after(function(done) {
+ serverBasicAuth.close(done());
+ });
+
+ it("Should return No upcoming events", function() {
return app.client.waitUntilTextExists(".calendar", "No upcoming events.", 10000);
});
});
-
-
});
diff --git a/tests/e2e/modules/clock_es_spec.js b/tests/e2e/modules/clock_es_spec.js
index f90263cf..7ad4ae64 100644
--- a/tests/e2e/modules/clock_es_spec.js
+++ b/tests/e2e/modules/clock_es_spec.js
@@ -1,8 +1,28 @@
-const globalSetup = require("../global-setup");
-const app = globalSetup.app;
+const helpers = require("../global-setup");
-describe("Clock set to spanish language module", function () {
- this.timeout(20000);
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
+
+describe("Clock set to spanish language module", function() {
+ helpers.setupTimeout(this);
+
+ var app = null;
+
+ beforeEach(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
+ });
+
+ afterEach(function() {
+ return helpers.stopApplication(app);
+ });
describe("with default 24hr clock config", function() {
before(function() {
@@ -10,24 +30,14 @@ describe("Clock set to spanish language module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_24hr.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
- it("shows date with correct format", function () {
+ it("shows date with correct format", function() {
const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .date").should.eventually.match(dateRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 24hr format", function() {
- const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .time").should.eventually.match(timeRegex);
+ const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/;
+ return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex);
});
});
@@ -37,24 +47,14 @@ describe("Clock set to spanish language module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_12hr.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
- it("shows date with correct format", function () {
+ it("shows date with correct format", function() {
const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .date").should.eventually.match(dateRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 12hr format", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .time").should.eventually.match(timeRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex);
});
});
@@ -64,18 +64,22 @@ describe("Clock set to spanish language module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showPeriodUpper.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
it("shows 12hr time with upper case AM/PM", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/;
+ return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex);
+ });
+ });
+
+ describe("with showWeek config enabled", function() {
+ before(function() {
+ // Set config sample for use in test
+ process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showWeek.js";
+ });
+
+ it("shows week with correct format", function() {
+ const weekRegex = /^Semana [0-9]{1,2}$/;
return app.client.waitUntilWindowLoaded()
- .getText(".clock .time").should.eventually.match(timeRegex);
+ .getText(".clock .week").should.eventually.match(weekRegex);
});
});
});
diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js
index a24b38d6..be4ef0e3 100644
--- a/tests/e2e/modules/clock_spec.js
+++ b/tests/e2e/modules/clock_spec.js
@@ -1,8 +1,28 @@
-const globalSetup = require("../global-setup");
-const app = globalSetup.app;
+const helpers = require("../global-setup");
-describe("Clock module", function () {
- this.timeout(20000);
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
+
+describe("Clock module", function() {
+ helpers.setupTimeout(this);
+
+ var app = null;
+
+ beforeEach(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
+ });
+
+ afterEach(function() {
+ return helpers.stopApplication(app);
+ });
describe("with default 24hr clock config", function() {
before(function() {
@@ -10,24 +30,14 @@ describe("Clock module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_24hr.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
- it("shows date with correct format", function () {
+ it("shows date with correct format", function() {
const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .date").should.eventually.match(dateRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 24hr format", function() {
- const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .time").should.eventually.match(timeRegex);
+ const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/;
+ return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex);
});
});
@@ -37,24 +47,14 @@ describe("Clock module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_12hr.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
- it("shows date with correct format", function () {
+ it("shows date with correct format", function() {
const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .date").should.eventually.match(dateRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex);
});
it("shows time in 12hr format", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .time").should.eventually.match(timeRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex);
});
});
@@ -64,18 +64,9 @@ describe("Clock module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showPeriodUpper.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
it("shows 12hr time with upper case AM/PM", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .time").should.eventually.match(timeRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex);
});
});
@@ -85,18 +76,9 @@ describe("Clock module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_displaySeconds_false.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
it("shows 12hr time without seconds am/pm", function() {
const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .time").should.eventually.match(timeRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex);
});
});
@@ -106,19 +88,17 @@ describe("Clock module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showWeek.js";
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
-
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
-
it("shows week with correct format", function() {
const weekRegex = /^Week [0-9]{1,2}$/;
- return app.client.waitUntilWindowLoaded()
- .getText(".clock .week").should.eventually.match(weekRegex);
+ return app.client.waitUntilWindowLoaded().getText(".clock .week").should.eventually.match(weekRegex);
+ });
+
+ it("shows week with correct number of week of year", function() {
+ it("FIXME: if the day is a sunday this not match");
+ // const currentWeekNumber = require("current-week-number")();
+ // const weekToShow = "Week " + currentWeekNumber;
+ // return app.client.waitUntilWindowLoaded()
+ // .getText(".clock .week").should.eventually.equal(weekToShow);
});
});
-
});
diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js
index 0dd2c411..35529b19 100644
--- a/tests/e2e/modules/compliments_spec.js
+++ b/tests/e2e/modules/compliments_spec.js
@@ -1,77 +1,78 @@
-const globalSetup = require("../global-setup");
-const app = globalSetup.app;
-const chai = require("chai");
-const expect = chai.expect;
+const helpers = require("../global-setup");
+const expect = require("chai").expect;
-describe("Compliments module", function () {
- this.timeout(20000);
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
+describe("Compliments module", function() {
+ helpers.setupTimeout(this);
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
+ var app = null;
+
+ beforeEach(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
+ afterEach(function() {
+ return helpers.stopApplication(app);
});
-
describe("parts of days", function() {
-
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_parts_day.js";
});
- it("if Morning compliments for that part of day", function () {
+ it("if Morning compliments for that part of day", function() {
var hour = new Date().getHours();
if (hour >= 3 && hour < 12) {
// if morning check
- return app.client.waitUntilWindowLoaded()
- .getText(".compliments").then(function (text) {
- expect(text).to.be.oneOf(["Hi", "Good Morning", "Morning test"]);
- })
+ return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) {
+ expect(text).to.be.oneOf(["Hi", "Good Morning", "Morning test"]);
+ });
}
});
- it("if Afternoon show Compliments for that part of day", function () {
+ it("if Afternoon show Compliments for that part of day", function() {
var hour = new Date().getHours();
if (hour >= 12 && hour < 17) {
// if morning check
- return app.client.waitUntilWindowLoaded()
- .getText(".compliments").then(function (text) {
- expect(text).to.be.oneOf(["Hello", "Good Afternoon", "Afternoon test"]);
- })
+ return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) {
+ expect(text).to.be.oneOf(["Hello", "Good Afternoon", "Afternoon test"]);
+ });
}
});
- it("if Evening show Compliments for that part of day", function () {
+ it("if Evening show Compliments for that part of day", function() {
var hour = new Date().getHours();
if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) {
// if evening check
- return app.client.waitUntilWindowLoaded()
- .getText(".compliments").then(function (text) {
- expect(text).to.be.oneOf(["Hello There", "Good Evening", "Evening test"]);
- })
+ return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) {
+ expect(text).to.be.oneOf(["Hello There", "Good Evening", "Evening test"]);
+ });
}
});
-
});
-
describe("Feature anytime in compliments module", function() {
-
describe("Set anytime and empty compliments for morning, evening and afternoon ", function() {
before(function() {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_anytime.js";
});
- it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function () {
- return app.client.waitUntilWindowLoaded()
- .getText(".compliments").then(function (text) {
- expect(text).to.be.oneOf(["Anytime here"]);
- })
+ it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function() {
+ return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) {
+ expect(text).to.be.oneOf(["Anytime here"]);
+ });
});
});
@@ -81,15 +82,11 @@ describe("Compliments module", function () {
process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_only_anytime.js";
});
- it("Show anytime compliments", function () {
- return app.client.waitUntilWindowLoaded()
- .getText(".compliments").then(function (text) {
- expect(text).to.be.oneOf(["Anytime here"]);
- })
+ it("Show anytime compliments", function() {
+ return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) {
+ expect(text).to.be.oneOf(["Anytime here"]);
+ });
});
});
-
-
});
-
});
diff --git a/tests/e2e/modules/helloworld_spec.js b/tests/e2e/modules/helloworld_spec.js
index f956effb..a59e2ae4 100644
--- a/tests/e2e/modules/helloworld_spec.js
+++ b/tests/e2e/modules/helloworld_spec.js
@@ -1,24 +1,50 @@
-const globalSetup = require("../global-setup");
-const app = globalSetup.app;
+const helpers = require("../global-setup");
-describe("Test helloworld module", function () {
- this.timeout(20000);
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
- before(function() {
- // Set config sample for use in test
- process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld.js";
+describe("Test helloworld module", function() {
+ helpers.setupTimeout(this);
+
+ var app = null;
+
+ beforeEach(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
});
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
+ afterEach(function() {
+ return helpers.stopApplication(app);
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
+ describe("helloworld set config text", function () {
+ before(function() {
+ // Set config sample for use in test
+ process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld.js";
+ });
+
+ it("Test message helloworld module", function () {
+ return app.client.waitUntilWindowLoaded()
+ .getText(".helloworld").should.eventually.equal("Test HelloWorld Module");
+ });
});
- it("Test message helloworld module", function () {
- return app.client.waitUntilWindowLoaded()
- .getText(".helloworld").should.eventually.equal("Test HelloWorld Module");
+ describe("helloworld default config text", function () {
+ before(function() {
+ // Set config sample for use in test
+ process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld_default.js";
+ });
+
+ it("Test message helloworld module", function () {
+ return app.client.waitUntilWindowLoaded()
+ .getText(".helloworld").should.eventually.equal("Hello World!");
+ });
});
});
diff --git a/tests/e2e/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js
index 049d1a2a..88cb8c3e 100644
--- a/tests/e2e/modules/newsfeed_spec.js
+++ b/tests/e2e/modules/newsfeed_spec.js
@@ -1,27 +1,35 @@
-const globalSetup = require("../global-setup");
-const app = globalSetup.app;
-const chai = require("chai");
-const expect = chai.expect;
+const helpers = require("../global-setup");
-describe("Newsfeed module", function () {
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
- this.timeout(20000);
+describe("Newsfeed module", function() {
+ helpers.setupTimeout(this);
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
+ var app = null;
+
+ beforeEach(function() {
+ return helpers
+ .startApplication({
+ args: ["js/electron.js"]
+ })
+ .then(function(startedApp) {
+ app = startedApp;
+ });
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
+ afterEach(function() {
+ return helpers.stopApplication(app);
});
describe("Default configuration", function() {
-
before(function() {
process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/default.js";
});
- it("show title newsfeed", function () {
+ it("show title newsfeed", function() {
return app.client.waitUntilTextExists(".newsfeed .small", "Rodrigo Ramirez Blog", 10000).should.be.fulfilled;
});
});
diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js
index a781388a..40399680 100644
--- a/tests/e2e/modules_position_spec.js
+++ b/tests/e2e/modules_position_spec.js
@@ -1,26 +1,25 @@
-const globalSetup = require("./global-setup");
-const app = globalSetup.app;
-const chai = require("chai");
-const expect = chai.expect;
+const helpers = require("./global-setup");
+
+const describe = global.describe;
+const it = global.it;
describe("Position of modules", function () {
- this.timeout(20000);
+ helpers.setupTimeout(this);
+ var app = null;
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
- });
+ describe("Using helloworld", function () {
- afterEach(function (done) {
- app.stop().then(function() { done(); });
- });
+ after(function () {
+ return helpers.stopApplication(app);
+ });
-
- describe("Using helloworld", function() {
-
- before(function() {
+ before(function () {
// Set config sample for use in test
process.env.MM_CONFIG_FILE = "tests/configs/modules/positions.js";
+ return helpers.startApplication({
+ args: ["js/electron.js"]
+ }).then(function (startedApp) { app = startedApp; });
});
var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third",
@@ -32,11 +31,10 @@ describe("Position of modules", function () {
for (idx in positions) {
position = positions[idx];
className = position.replace("_", ".");
- it("show text in " + position , function () {
+ it("show text in " + position, function () {
return app.client.waitUntilWindowLoaded()
.getText("." + className).should.eventually.equal("Text in " + position);
});
}
});
-
});
diff --git a/tests/e2e/port_config.js b/tests/e2e/port_config.js
index 44c6b498..41f50e75 100644
--- a/tests/e2e/port_config.js
+++ b/tests/e2e/port_config.js
@@ -1,27 +1,33 @@
-const globalSetup = require("./global-setup");
-const app = globalSetup.app;
+const helpers = require("./global-setup");
const request = require("request");
-const chai = require("chai");
-const expect = chai.expect;
+const expect = require("chai").expect;
+const describe = global.describe;
+const it = global.it;
+const beforeEach = global.beforeEach;
+const afterEach = global.afterEach;
describe("port directive configuration", function () {
+ helpers.setupTimeout(this);
- this.timeout(20000);
+ var app = null;
- beforeEach(function (done) {
- app.start().then(function() { done(); } );
+ beforeEach(function () {
+ return helpers.startApplication({
+ args: ["js/electron.js"]
+ }).then(function (startedApp) { app = startedApp; });
});
- afterEach(function (done) {
- app.stop().then(function() { done(); });
+ afterEach(function () {
+ return helpers.stopApplication(app);
});
describe("Set port 8090", function () {
- before(function() {
+ before(function () {
// Set config sample for use in this test
process.env.MM_CONFIG_FILE = "tests/configs/port_8090.js";
});
+
it("should return 200", function (done) {
request.get("http://localhost:8090", function (err, res, body) {
expect(res.statusCode).to.equal(200);
@@ -30,16 +36,17 @@ describe("port directive configuration", function () {
});
});
- describe("Set port 8100 on enviroment variable MM_PORT", function () {
- before(function() {
+ describe("Set port 8100 on environment variable MM_PORT", function () {
+ before(function () {
process.env.MM_PORT = 8100;
// Set config sample for use in this test
process.env.MM_CONFIG_FILE = "tests/configs/port_8090.js";
});
- after(function(){
+ after(function () {
delete process.env.MM_PORT;
});
+
it("should return 200", function (done) {
request.get("http://localhost:8100", function (err, res, body) {
expect(res.statusCode).to.equal(200);
@@ -47,5 +54,4 @@ describe("port directive configuration", function () {
});
});
});
-
});
diff --git a/tests/e2e/translations_spec.js b/tests/e2e/translations_spec.js
new file mode 100644
index 00000000..e589689e
--- /dev/null
+++ b/tests/e2e/translations_spec.js
@@ -0,0 +1,128 @@
+const fs = require("fs");
+const path = require("path");
+const chai = require("chai");
+const expect = chai.expect;
+const mlog = require("mocha-logger");
+const translations = require("../../translations/translations.js");
+const helmet = require("helmet");
+const {JSDOM} = require("jsdom");
+const express = require("express");
+
+describe("Translations", function() {
+ let server;
+
+ before(function() {
+ const app = express();
+ app.use(helmet());
+ app.use(function (req, res, next) {
+ res.header("Access-Control-Allow-Origin", "*");
+ next();
+ });
+ app.use("/translations", express.static(path.join(__dirname, "..", "..", "translations")));
+
+ server = app.listen(3000);
+ });
+
+ after(function() {
+ server.close();
+ });
+
+ it("should have a translation file in the specified path", function() {
+ for(let language in translations) {
+ const file = fs.statSync(translations[language]);
+ expect(file.isFile()).to.be.equal(true);
+ }
+ });
+
+ const mmm = {
+ name: "TranslationTest",
+ file(file) {
+ return `http://localhost:3000/${file}`;
+ }
+ };
+
+ describe("Parsing language files through the Translator class", function() {
+ for(let language in translations) {
+ it(`should parse ${language}`, function(done) {
+ const dom = new JSDOM(`\
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+ \
+