From 2b511b67c3392e9a42c02df13c106ffd2416b744 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Wed, 1 Jan 2020 22:21:55 +0100 Subject: [PATCH 001/104] Prepare for 2.11.0 --- CHANGELOG.md | 16 +++++++++++++--- package-lock.json | 2 +- package.json | 2 +- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66d87893..9ec4cbb2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,18 @@ This project adheres to [Semantic Versioning](http://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core. +## [2.11.0] - Unreleased (Develop Branch) + +*This release is scheduled to be released on 2020-04-01.* + +### Added +### Updated +### Fixed + ## [2.10.0] - 2020-01-01 +Special thanks to @sdetweil for all his great contributions! + ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. ### Added @@ -27,9 +37,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fixed issue in weatherforecast module where predicted amount of rain was not using the decimal symbol specified in config.js. - Module header now updates correctly, if a module need to dynamically show/hide its header based on a condition. - Fix handling of config.js for serverOnly mode commented out. -- Fixed issue in calendar module where the debug script didn't work correctly with authentication -- Fixed issue that some full day events were not correctly recognized as such -- Display full day events lasting multiple days as happening today instead of some days ago if they are still ongoing +- Fixed issue in calendar module where the debug script didn't work correctly with authentication. +- Fixed issue that some full day events were not correctly recognized as such. +- Display full day events lasting multiple days as happening today instead of some days ago if they are still ongoing. ## [2.9.0] - 2019-10-01 diff --git a/package-lock.json b/package-lock.json index edcd68f5..757d0d52 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.10.0", + "version": "2.11.0-develop", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 91e4e8a1..0aca57bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.10.0", + "version": "2.11.0-develop", "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { From 10d5529f7927775e9da917a832a495e781051244 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sami=20M=C3=A4kinen?= Date: Thu, 2 Jan 2020 00:04:59 +0200 Subject: [PATCH 002/104] Add missing translations for fi --- CHANGELOG.md | 3 +++ translations/fi.json | 5 ++++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ec4cbb2..222af8cb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). *This release is scheduled to be released on 2020-04-01.* ### Added + +- Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". + ### Updated ### Fixed diff --git a/translations/fi.json b/translations/fi.json index 495439c1..c731d973 100644 --- a/translations/fi.json +++ b/translations/fi.json @@ -28,6 +28,9 @@ "UPDATE_NOTIFICATION": "MagicMirror² päivitys saatavilla.", "UPDATE_NOTIFICATION_MODULE": "Päivitys saatavilla moduulille {MODULE_NAME}.", + "UPDATE_INFO_SINGLE": "Nykyasennus on {COMMIT_COUNT} muutoksen jäljessä {BRANCH_NAME} haaraan nähden.", + "UPDATE_INFO_MULTIPLE": "Nykyasennus on {COMMIT_COUNT} muutosta jäljessä {BRANCH_NAME} haaraan nähden.", - "FEELS": "Tuntuu kuin" + "FEELS": "Tuntuu kuin", + "PRECIP": "Sateen todennäköisyys" } From 94ff8a9b047cdf6eef34e307d7eddad365a5f2a5 Mon Sep 17 00:00:00 2001 From: HeikoGr Date: Thu, 2 Jan 2020 14:15:24 +0000 Subject: [PATCH 003/104] force declaration of public ip adress in config file (ISSUE #1852) --- config/config.js.sample | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/config.js.sample b/config/config.js.sample index 115e2dd2..3b3bb71e 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -12,8 +12,8 @@ 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" + // - "0.0.0.0", "::" to listen on any interface + // Default, when address config is left out or empty, 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 : From 760995773e6595e6bbd22b2e62da2db9f572d606 Mon Sep 17 00:00:00 2001 From: HeikoGr Date: Thu, 2 Jan 2020 16:04:38 +0100 Subject: [PATCH 004/104] Update CHANGELOG.md --- CHANGELOG.md | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 66d87893..b8b0902a 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,8 +5,19 @@ This project adheres to [Semantic Versioning](http://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core. +## [2.11.0] - Unreleased (Develop Branch) + +*This release is scheduled to be released on 2020-04-01.* + +### Added +### Updated +### Fixed +- Force declaration of public ip adress in config file (ISSUE #1852) + ## [2.10.0] - 2020-01-01 +Special thanks to @sdetweil for all his great contributions! + ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. ### Added @@ -27,9 +38,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fixed issue in weatherforecast module where predicted amount of rain was not using the decimal symbol specified in config.js. - Module header now updates correctly, if a module need to dynamically show/hide its header based on a condition. - Fix handling of config.js for serverOnly mode commented out. -- Fixed issue in calendar module where the debug script didn't work correctly with authentication -- Fixed issue that some full day events were not correctly recognized as such -- Display full day events lasting multiple days as happening today instead of some days ago if they are still ongoing +- Fixed issue in calendar module where the debug script didn't work correctly with authentication. +- Fixed issue that some full day events were not correctly recognized as such. +- Display full day events lasting multiple days as happening today instead of some days ago if they are still ongoing. ## [2.9.0] - 2019-10-01 From 20a9150ea32dad387abb3a4a005daffaac58d580 Mon Sep 17 00:00:00 2001 From: Karsten Hassel Date: Fri, 3 Jan 2020 19:12:02 +0100 Subject: [PATCH 005/104] fix run-start.sh: if running in docker-container, just start electron, see #1859 --- CHANGELOG.md | 1 + run-start.sh | 124 +++++++++++++++++++++++++++------------------------ 2 files changed, 67 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e65fc767..e212d352 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) +- Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) ### Updated diff --git a/run-start.sh b/run-start.sh index 95d776cd..f4c2d4e3 100755 --- a/run-start.sh +++ b/run-start.sh @@ -2,66 +2,74 @@ # use bash instead of sh ./untrack-css.sh -if [ -z "$DISPLAY" ]; then #If not set DISPLAY is SSH remote or tty - export DISPLAY=:0 # Set by default display -fi -# get the processor architecture -arch=$(uname -m) -false='false' +if grep docker /proc/1/cgroup -qa; then + # if running in docker, only start electron -# get the config option, if any -# only check non comment lines -serveronly=$(grep -v '^\s//' config/config.js | grep -i serveronly: | awk '{print tolower($2)}' | tr -d ,\"\') -# set default if not defined in config -serveronly=${serveronly:-false} -# check for xwindows running -xorg=$(pgrep Xorg) -#check for macOS -mac=$(uname) -# -# if the user requested serveronly OR -# electron support for armv6l has been dropped OR -# system is in text mode -# -if [ "$serveronly." != "false." -o "$arch" == "armv6l" ] || [ "$xorg." == "." -a $mac != 'Darwin' ]; then + electron js/electron.js $1; +else + # not running in docker - # if user explicitly configured to run server only (no ui local) - # OR there is no xwindows running, so no support for browser graphics - if [ "$serveronly." == "true." -o "$xorg." == "." ]; then - # start server mode, - node serveronly - else - # start the server in the background - # wait for server to be ready - # need bash for this - exec 3< <(node serveronly) + if [ -z "$DISPLAY" ]; then #If not set DISPLAY is SSH remote or tty + export DISPLAY=:0 # Set by default display + fi + # get the processor architecture + arch=$(uname -m) + false='false' - # Read the output of server line by line until one line 'point your browser' - while read line; do - case "$line" in - *point\ your\ browser*) - echo $line - break - ;; - *) - echo $line - #sleep .25 - ;; - esac - done <&3 + # get the config option, if any + # only check non comment lines + serveronly=$(grep -v '^\s//' config/config.js | grep -i serveronly: | awk '{print tolower($2)}' | tr -d ,\"\') + # set default if not defined in config + serveronly=${serveronly:-false} + # check for xwindows running + xorg=$(pgrep Xorg) + #check for macOS + mac=$(uname) + # + # if the user requested serveronly OR + # electron support for armv6l has been dropped OR + # system is in text mode + # + if [ "$serveronly." != "false." -o "$arch" == "armv6l" ] || [ "$xorg." == "." -a $mac != 'Darwin' ]; then - # Close the file descriptor - exec 3<&- + # if user explicitly configured to run server only (no ui local) + # OR there is no xwindows running, so no support for browser graphics + if [ "$serveronly." == "true." -o "$xorg." == "." ]; then + # start server mode, + node serveronly + else + # start the server in the background + # wait for server to be ready + # need bash for this + exec 3< <(node serveronly) - # lets use chrome to display here now - # get the server port address from the ready message - port=$(echo $line | awk -F\: '{print $4}') - # start chromium - echo "Starting chromium browser now, have patience, it takes a minute" - chromium-browser -noerrdialogs -kiosk -start_maximized --disable-infobars --app=http://localhost:$port --ignore-certificate-errors-spki-list --ignore-ssl-errors --ignore-certificate-errors 2>/dev/null - exit - fi -else - # we can use electron directly - electron js/electron.js $1; -fi + # Read the output of server line by line until one line 'point your browser' + while read line; do + case "$line" in + *point\ your\ browser*) + echo $line + break + ;; + *) + echo $line + #sleep .25 + ;; + esac + done <&3 + + # Close the file descriptor + exec 3<&- + + # lets use chrome to display here now + # get the server port address from the ready message + port=$(echo $line | awk -F\: '{print $4}') + # start chromium + echo "Starting chromium browser now, have patience, it takes a minute" + chromium-browser -noerrdialogs -kiosk -start_maximized --disable-infobars --app=http://localhost:$port --ignore-certificate-errors-spki-list --ignore-ssl-errors --ignore-certificate-errors 2>/dev/null + exit + fi + else + # we can use electron directly + electron js/electron.js $1; + fi +fi \ No newline at end of file From eea8b4dfbf882c7fb02519eb6dc1205ab6c08aac Mon Sep 17 00:00:00 2001 From: Shahrukh Khan Date: Wed, 8 Jan 2020 18:10:36 +0500 Subject: [PATCH 006/104] Update README.md Remove extra two "of" words --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 8c0342a1..2fcd93f9 100644 --- a/README.md +++ b/README.md @@ -223,7 +223,7 @@ A real Manifesto is still to be written. Till then, Michael's response on [one o > "... I started this project as an ultimate starter project for Raspberry Pi enthusiasts. As a matter of fact, for most of the contributors, the MagicMirror project is the first open source project they ever contributed to. This is one of the reasons why the MagicMirror project is featured in several RasPi magazines. > ->The project has a lot of opportunities for improvement. We could use a powerful framework like Vue to ramp up the development speed. We could use SASS for better/easier css implementations. We could make it an NPM installable package. And as you say, we could bundle it up. The big downside of of of these changes is that it over complicates things: a user no longer will be able to open just one file and make a small modification and see how it works out. +>The project has a lot of opportunities for improvement. We could use a powerful framework like Vue to ramp up the development speed. We could use SASS for better/easier css implementations. We could make it an NPM installable package. And as you say, we could bundle it up. The big downside of these changes is that it over complicates things: a user no longer will be able to open just one file and make a small modification and see how it works out. > >Of course, a bundled version can be complimentary to the regular un-bundled version. And I'm sure a lot of (new) users will opt for the bundled version. But this means those users won't be motivated to take a peek under the hood. They will just remain 'users'. They won't become contributors, and worse: they won't be motivated to take their first steps in software development. > From 1152689f3474d68fc634c3703b2b9c58d74feb7d Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sun, 12 Jan 2020 13:01:56 +0100 Subject: [PATCH 007/104] Remove docs and link to docs.magicmirror.builders. --- CHANGELOG.md | 1 + modules/README.md | 721 ------------------ modules/default/alert/README.md | 63 +- modules/default/calendar/README.md | 105 +-- modules/default/clock/README.md | 54 +- modules/default/clock/clock_screenshot.png | Bin 30525 -> 0 bytes modules/default/compliments/README.md | 148 +--- .../compliments/compliments_screenshot.png | Bin 26157 -> 0 bytes modules/default/currentweather/README.md | 86 +-- .../currentweather/weather_screenshot.png | Bin 38566 -> 0 bytes modules/default/helloworld/README.md | 23 +- modules/default/newsfeed/README.md | 104 +-- .../default/newsfeed/newsfeed_screenshot.png | Bin 45375 -> 0 bytes modules/default/updatenotification/README.md | 24 +- modules/default/weather/README.md | 117 +-- modules/default/weather/current.png | Bin 8141 -> 0 bytes modules/default/weather/forecast.png | Bin 16385 -> 0 bytes modules/default/weatherforecast/README.md | 79 +- .../weatherforecast/forecast_screenshot.png | Bin 86206 -> 0 bytes 19 files changed, 11 insertions(+), 1514 deletions(-) delete mode 100644 modules/README.md delete mode 100644 modules/default/clock/clock_screenshot.png delete mode 100644 modules/default/compliments/compliments_screenshot.png delete mode 100644 modules/default/currentweather/weather_screenshot.png delete mode 100644 modules/default/newsfeed/newsfeed_screenshot.png delete mode 100644 modules/default/weather/current.png delete mode 100644 modules/default/weather/forecast.png delete mode 100644 modules/default/weatherforecast/forecast_screenshot.png diff --git a/CHANGELOG.md b/CHANGELOG.md index b94f9e59..f7ad78cf 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) ### Updated +- Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). ## [2.10.1] - 2020-01-10 diff --git a/modules/README.md b/modules/README.md deleted file mode 100644 index 3d292738..00000000 --- a/modules/README.md +++ /dev/null @@ -1,721 +0,0 @@ -# MagicMirror² Module Development Documentation - -This document describes the way to develop your own MagicMirror² modules. - -Table of Contents: - -- Module structure - - Files - -- The Core module file: modulename.js - - Available module instance properties - - Subclassable module methods - - Module instance methods - - Visibility locking - -- The Node Helper: node_helper.js - - Available module instance properties - - Subclassable module methods - - Module instance methods - -- MagicMirror Helper Methods - - Module Selection - -- MagicMirror Logger - ---- - - -## General Advice - -As MagicMirror has gained huge popularity, so has the number of available modules. For new users and developers alike, it is very time consuming to navigate around the various repositories in order to find out what exactly a certain modules does, how it looks and what it depends on. Unfortunately, this information is rarely available, nor easily obtained without having to install it first. -Therefore **we highly recommend you to include the following information in your README file.** - -- A high quality screenshot of your working module -- A short, one sentence, clear description what it does (duh!) -- What external API's it depends upon, including web links to those -- Whether the API/request require a key and the user limitations of those. (Is it free?) - -Surely this also help you get better recognition and feedback for your work. - -## Module structure - -All modules are loaded in the `modules` folder. The default modules are grouped together in the `modules/default` folder. Your module should be placed in a subfolder of `modules`. Note that any file or folder your create in the `modules` folder will be ignored by git, allowing you to upgrade the MagicMirror² without the loss of your files. - -A module can be placed in one single folder. Or multiple modules can be grouped in a subfolder. Note that name of the module must be unique. Even when a module with a similar name is placed in a different folder, they can't be loaded at the same time. - -### Files -- **modulename/modulename.js** - This is your core module script. -- **modulename/node_helper.js** - This is an optional helper that will be loaded by the node script. The node helper and module script can communicate with each other using an integrated socket system. -- **modulename/public** - Any files in this folder can be accessed via the browser on `/modulename/filename.ext`. -- **modulename/anyfileorfolder** Any other file or folder in the module folder can be used by the core module script. For example: *modulename/css/modulename.css* would be a good path for your additional module styles. - -## The Core module file: modulename.js -This is the script in which the module will be defined. This script is required in order for the module to be used. In it's most simple form, the core module file must contain: -````javascript -Module.register("modulename",{}); -```` -Of course, the above module would not do anything fancy, so it's good to look at one of the simplest modules: **helloworld**: - -````javascript -//helloworld.js: - -Module.register("helloworld",{ - // Default module config. - defaults: { - text: "Hello World!" - }, - - // Override dom generator. - getDom: function() { - var wrapper = document.createElement("div"); - wrapper.innerHTML = this.config.text; - return wrapper; - } -}); -```` - -As you can see, the `Module.register()` method takes two arguments: the name of the module and an object with the module properties. - -### Available module instance properties -After the module is initialized, the module instance has a few available module properties: - -| Instance Property | Type | Description | -|:----------------- |:---- |:----------- | -| `this.name` | String | The name of the module. | -| `this.identifier` | String | This is a unique identifier for the module instance. | -| `this.hidden` | Boolean | This represents if the module is currently hidden (faded away). | -| `this.config` | Boolean | The configuration of the module instance as set in the user's `config.js` file. This config will also contain the module's defaults if these properties are not over-written by the user config. | -| `this.data` | Object | The data object contain additional metadata about the module instance. (See below) | - - -The `this.data` data object contain the following metadata: -- `data.classes` - The classes which are added to the module dom wrapper. -- `data.file` - The filename of the core module file. -- `data.path` - The path of the module folder. -- `data.header` - The header added to the module. -- `data.position` - The position in which the instance will be shown. - - -#### `defaults: {}` -Any properties defined in the defaults object, will be merged with the module config as defined in the user's config.js file. This is the best place to set your modules' configuration defaults. Any of the module configuration properties can be accessed using `this.config.propertyName`, but more about that later. - -#### `requiresVersion:` - -*Introduced in version: 2.1.0.* - -A string that defines the minimum version of the MagicMirror framework. If it is set, the system compares the required version with the users version. If the version of the user is out of date, it won't run the module. Make sure to also set this value in the Node helper. - -**Note:** Since this check is introduced in version 2.1.0, this check will not be run in older versions. Keep this in mind if you get issue reports on your module. - -Example: -````javascript -requiresVersion: "2.1.0", -```` - -### Subclassable module methods - -#### `init()` -This method is called when a module gets instantiated. In most cases you do not need to subclass this method. - -#### `loaded(callback)` - -*Introduced in version: 2.1.1.* - -This method is called when a module is loaded. Subsequent modules in the config are not yet loaded. The `callback` function MUST be called when the module is done loading. In most cases you do not need to subclass this method. - -**Example:** -````javascript -loaded: function(callback) { - this.finishLoading(); - Log.log(this.name + ' is loaded!'); - callback(); -} -```` - -#### `start()` -This method is called when all modules are loaded and the system is ready to boot up. Keep in mind that the dom object for the module is not yet created. The start method is a perfect place to define any additional module properties: - -**Example:** -````javascript -start: function() { - this.mySpecialProperty = "So much wow!"; - Log.log(this.name + ' is started!'); -} -```` - -#### `getScripts()` -**Should return: Array** - -The getScripts method is called to request any additional scripts that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.js')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder. - -**Example:** -````javascript -getScripts: function() { - return [ - 'script.js', // will try to load it from the vendor folder, otherwise it will load is from the module folder. - 'moment.js', // this file is available in the vendor folder, so it doesn't need to be available in the module folder. - this.file('anotherfile.js'), // this file will be loaded straight from the module folder. - 'https://code.jquery.com/jquery-2.2.3.min.js', // this file will be loaded from the jquery servers. - ] -} - -```` -**Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore, it's advised not to use any external urls. - - -#### `getStyles()` -**Should return: Array** - -The getStyles method is called to request any additional stylesheets that need to be loaded. This method should therefore return an array with strings. If you want to return a full path to a file in the module folder, use the `this.file('filename.css')` method. In all cases the loader will only load a file once. It even checks if the file is available in the default vendor folder. - -**Example:** -````javascript -getStyles: function() { - return [ - 'script.css', // will try to load it from the vendor folder, otherwise it will load is from the module folder. - 'font-awesome.css', // this file is available in the vendor folder, so it doesn't need to be available in the module folder. - this.file('anotherfile.css'), // this file will be loaded straight from the module folder. - 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css', // this file will be loaded from the bootstrapcdn servers. - ] -} - -```` -**Note:** If a file can not be loaded, the boot up of the mirror will stall. Therefore, it's advised not to use any external URLs. - -#### `getTranslations()` -**Should return: Dictionary** - -The getTranslations method is called to request translation files that need to be loaded. This method should therefore return a dictionary with the files to load, identified by the country's short name. - -If the module does not have any module specific translations, the function can just be omitted or return `false`. - -**Example:** -````javascript -getTranslations: function() { - return { - en: "translations/en.json", - de: "translations/de.json" - } -} - -```` - -#### `getDom()` -**Should return:** Dom Object - -Whenever the MagicMirror needs to update the information on screen (because it starts, or because your module asked a refresh using `this.updateDom()`), the system calls the getDom method. This method should therefore return a dom object. - -**Example:** -````javascript -getDom: function() { - var wrapper = document.createElement("div"); - wrapper.innerHTML = 'Hello world!'; - return wrapper; -} - -```` - -#### `getHeader()` -**Should return:** String - -Whenever the MagicMirror needs to update the information on screen (because it starts, or because your module asked a refresh using `this.updateDom()`), the system calls the getHeader method to retrieve the module's header. This method should therefor return a string. If this method is not subclassed, this function will return the user's configured header. - -If you want to use the original user's configured header, reference `this.data.header`. - -**NOTE:** If the user did not configure a default header, no header will be displayed and thus this method will not be called. - -**Example:** -````javascript -getHeader: function() { - return this.data.header + ' Foo Bar'; -} - -```` - -#### `notificationReceived(notification, payload, sender)` - -That MagicMirror core has the ability to send notifications to modules. Or even better: the modules have the possibility to send notifications to other modules. When this module is called, it has 3 arguments: - -- `notification` - String - The notification identifier. -- `payload` - AnyType - The payload of a notification. -- `sender` - Module - The sender of the notification. If this argument is `undefined`, the sender of the notification is the core system. - -**Example:** -````javascript -notificationReceived: function(notification, payload, sender) { - if (sender) { - Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name); - } else { - Log.log(this.name + " received a system notification: " + notification); - } -} -```` - -**Note:** the system sends three notifications when starting up. These notifications could come in handy! - - -- `ALL_MODULES_STARTED` - All modules are started. You can now send notifications to other modules. -- `DOM_OBJECTS_CREATED` - All dom objects are created. The system is now ready to perform visual changes. -- `MODULE_DOM_CREATED` - This module's dom has been fully loaded. You can now access your module's dom objects. - - -#### `socketNotificationReceived: function(notification, payload)` -When using a node_helper, the node helper can send your module notifications. When this module is called, it has 2 arguments: - -- `notification` - String - The notification identifier. -- `payload` - AnyType - The payload of a notification. - -**Note 1:** When a node helper sends a notification, all modules of that module type receive the same notifications.
-**Note 2:** The socket connection is established as soon as the module sends its first message using [sendSocketNotification](#thissendsocketnotificationnotification-payload). - -**Example:** -````javascript -socketNotificationReceived: function(notification, payload) { - Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); -}, -```` - -#### `suspend()` -When a module is hidden (using the `module.hide()` method), the `suspend()` method will be called. By subclassing this method you can perform tasks like halting the update timers. - -#### `resume()` -When a module is requested to be shown (using the `module.show()` method), the `resume()` method will be called. By subclassing this method you can perform tasks restarting the update timers. - - -### Module instance methods - -Each module instance has some handy methods which can be helpful building your module. - - -#### `this.file(filename)` -***filename* String** - The name of the file you want to create the path for.
-**Returns String** - -If you want to create a path to a file in your module folder, use the `file()` method. It returns the path to the filename given as the attribute. Is method comes in handy when configuring the [getScripts](#getscripts) and [getStyles](#getstyles) methods. - -#### `this.updateDom(speed)` -***speed* Number** - Optional. Animation speed in milliseconds.
- -Whenever your module need to be updated, call the `updateDom(speed)` method. It requests the MagicMirror core to update its dom object. If you define the speed, the content update will be animated, but only if the content will really change. - -As an example: the clock modules calls this method every second: - -````javascript -... -start: function() { - var self = this; - setInterval(function() { - self.updateDom(); // no speed defined, so it updates instantly. - }, 1000); //perform every 1000 milliseconds. -}, -... -```` - -#### `this.sendNotification(notification, payload)` -***notification* String** - The notification identifier.
-***payload* AnyType** - Optional. A notification payload.
- -If you want to send a notification to all other modules, use the `sendNotification(notification, payload)`. All other modules will receive the message via the [notificationReceived](#notificationreceivednotification-payload-sender) method. In that case, the sender is automatically set to the instance calling the sendNotification method. - -**Example:** -````javascript -this.sendNotification('MYMODULE_READY_FOR_ACTION', {foo:bar}); -```` - -#### `this.sendSocketNotification(notification, payload)` -***notification* String** - The notification identifier.
-***payload* AnyType** - Optional. A notification payload.
- -If you want to send a notification to the node_helper, use the `sendSocketNotification(notification, payload)`. Only the node_helper of this module will receive the socket notification. - -**Example:** -````javascript -this.sendSocketNotification('SET_CONFIG', this.config); -```` - -#### `this.hide(speed, callback, options)` -***speed* Number** - Optional (Required when setting callback or options), The speed of the hide animation in milliseconds. -***callback* Function** - Optional, The callback after the hide animation is finished. -***options* Function** - Optional, Object with additional options for the hide action (see below). (*Introduced in version: 2.1.0.*) - -To hide a module, you can call the `hide(speed, callback)` method. You can call the hide method on the module instance itself using `this.hide()`, but of course you can also hide another module using `anOtherModule.hide()`. - -Possible configurable options: - -- `lockString` - String - When setting lock string, the module can not be shown without passing the correct lockstring. This way (multiple) modules can prevent a module from showing. It's considered best practice to use your modules identifier as the locksString: `this.identifier`. See *visibility locking* below. - - -**Note 1:** If the hide animation is cancelled, for instance because the show method is called before the hide animation was finished, the callback will not be called.
-**Note 2:** If the hide animation is hijacked (an other method calls hide on the same module), the callback will not be called.
-**Note 3:** If the dom is not yet created, the hide method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender). - - -#### `this.show(speed, callback, options)` -***speed* Number** - Optional (Required when setting callback or options), The speed of the show animation in milliseconds. -***callback* Function** - Optional, The callback after the show animation is finished. -***options* Function** - Optional, Object with additional options for the show action (see below). (*Introduced in version: 2.1.0.*) - -To show a module, you can call the `show(speed, callback)` method. You can call the show method on the module instance itself using `this.show()`, but of course you can also show another module using `anOtherModule.show()`. - -Possible configurable options: - -- `lockString` - String - When setting lock string, the module can not be shown without passing the correct lockstring. This way (multiple) modules can prevent a module from showing. See *visibility locking* below. -- `force` - Boolean - When setting the force tag to `true`, the locking mechanism will be overwritten. Use this option with caution. It's considered best practice to let the usage of the force option be use- configurable. See *visibility locking* below. - -**Note 1:** If the show animation is canceled, for instance because the hide method is called before the show animation was finished, the callback will not be called.
-**Note 2:** If the show animation is hijacked (an other method calls show on the same module), the callback will not be called.
-**Note 3:** If the dom is not yet created, the show method won't work. Wait for the `DOM_OBJECTS_CREATED` [notification](#notificationreceivednotification-payload-sender). - -#### Visibility locking - -(*Introduced in version: 2.1.0.*) - -Visibility locking helps the module system to prevent unwanted hide/show actions. The following scenario explains the concept: - -**Module B asks module A to hide:** -````javascript -moduleA.hide(0, {lockString: "module_b_identifier"}); -```` -Module A is now hidden, and has an lock array with the following strings: -````javascript -moduleA.lockStrings == ["module_b_identifier"] -moduleA.hidden == true -```` -**Module C asks module A to hide:** -````javascript -moduleA.hide(0, {lockString: "module_c_identifier"}); -```` -Module A is now hidden, and has an lock array with the following strings: -````javascript -moduleA.lockStrings == ["module_b_identifier", "module_c_identifier"] -moduleA.hidden == true -```` -**Module B asks module A to show:** -````javascript -moduleA.show(0, {lockString: "module_b_identifier"}); -```` -The lockString will be removed from moduleA’s locks array, but since there still is an other lock string available, the module remains hidden: -````javascript -moduleA.lockStrings == ["module_c_identifier"] -moduleA.hidden == true -```` -**Module C asks module A to show:** -````javascript -moduleA.show(0, {lockString: "module_c_identifier"}); -```` -The lockString will be removed from moduleA’s locks array, and since this will result in an empty lock array, the module will be visible: -````javascript -moduleA.lockStrings == [] -moduleA.hidden == false -```` - -**Note:** The locking mechanism can be overwritten by using the force tag: -````javascript -moduleA.show(0, {force: true}); -```` -This will reset the lockstring array, and will show the module. -````javascript -moduleA.lockStrings == [] -moduleA.hidden == false -```` - -Use this `force` method with caution. See `show()` method for more information. - - - -#### `this.translate(identifier)` -***identifier* String** - Identifier of the string that should be translated. - -The Magic Mirror contains a convenience wrapper for `l18n`. You can use this to automatically serve different translations for your modules based on the user's `language` configuration. - -If no translation is found, a fallback will be used. The fallback sequence is as follows: -- 1. Translation as defined in module translation file of the user's preferred language. -- 2. Translation as defined in core translation file of the user's preferred language. -- 3. Translation as defined in module translation file of the fallback language (the first defined module translation file). -- 4. Translation as defined in core translation file of the fallback language (the first defined core translation file). -- 5. The key (identifier) of the translation. - -When adding translations to your module, it's a good idea to see if an appropriate translation is already available in the [core translation files](https://github.com/MichMich/MagicMirror/tree/master/translations). This way, your module can benefit from the existing translations. - -**Example:** -````javascript -this.translate("INFO") //Will return a translated string for the identifier INFO -```` - -**Example json file:** -````javascript -{ - "INFO": "Really important information!" -} -```` - -**Note:** although comments are officially not supported in JSON files, MagicMirror allows it by stripping the comments before parsing the JSON file. Comments in translation files could help other translators. - -##### `this.translate(identifier, variables)` -***identifier* String** - Identifier of the string that should be translated. -***variables* Object** - Object of variables to be used in translation. - -This improved and backwards compatible way to handle translations behaves like the normal translation function and follows the rules described above. It's recommended to use this new format for translating everywhere. It allows translator to change the word order in the sentence to be translated. - - -**Example:** -````javascript -var timeUntilEnd = moment(event.endDate, "x").fromNow(true); -this.translate("RUNNING", { "timeUntilEnd": timeUntilEnd) }); // Will return a translated string for the identifier RUNNING, replacing `{timeUntilEnd}` with the contents of the variable `timeUntilEnd` in the order that translator intended. -```` - -**Example English .json file:** -````javascript -{ - "RUNNING": "Ends in {timeUntilEnd}", -} -```` - -**Example Finnish .json file:** -````javascript -{ - "RUNNING": "Päättyy {timeUntilEnd} päästä", -} -```` - -**Note:** The *variables* Object has an special case called `fallback`. It's used to support old translations in translation files that do not have the variables in them. If you are upgrading an old module that had translations that did not support the word order, it is recommended to have the fallback layout. - -**Example:** -````javascript -var timeUntilEnd = moment(event.endDate, "x").fromNow(true); -this.translate("RUNNING", { - "fallback": this.translate("RUNNING") + " {timeUntilEnd}" - "timeUntilEnd": timeUntilEnd -)}); // Will return a translated string for the identifier RUNNING, replacing `{timeUntilEnd}` with the contents of the variable `timeUntilEnd` in the order that translator intended. (has a fallback) -```` - -**Example Swedish .json file that does not have the variable in it:** -````javascript -{ - "RUNNING": "Slutar", -} -```` -In this case the `translate`-function will not find any variables in the translation, will look for `fallback` variable and use that if possible to create the translation. - -## The Node Helper: node_helper.js - -The node helper is a Node.js script that is able to do some backend task to support your module. For every module type, only one node helper instance will be created. For example: if your MagicMirror uses two calendar modules, there will be only one calendar node helper instantiated. - -**Note:** Because there is only one node helper per module type, there is no default config available within your module. It's your task to send the desired config from your module to your node helper. - -In it's most simple form, the node_helper.js file must contain: - -````javascript -var NodeHelper = require("node_helper"); -module.exports = NodeHelper.create({}); -```` - -Of course, the above helper would not do anything useful. So with the information above, you should be able to make it a bit more sophisticated. - -### Available module instance properties - -#### `this.name` -**String** - -The name of the module - -#### `this.path` -**String** - -The path of the module - -#### `this.expressApp` -**Express App Instance** - -This is a link to the express instance. It will allow you to define extra routes. - -**Example:** -````javascript -start: function() { - this.expressApp.get('/foobar', function (req, res) { - res.send('GET request to /foobar'); - }); -} -```` - -**Note:** By default, a public path to your module's public folder will be created: -````javascript -this.expressApp.use("/" + this.name, express.static(this.path + "/public")); -```` - -#### `this.io` -**Socket IO Instance** - -This is a link to the IO instance. It will allow you to do some Socket.IO magic. In most cases you won't need this, since the Node Helper has a few convenience methods to make this simple. - - -#### `requiresVersion:` -*Introduced in version: 2.1.0.* - -A string that defines the minimum version of the MagicMirror framework. If it is set, the system compares the required version with the users version. If the version of the user is out of date, it won't run the module. - -**Note:** Since this check is introduced in version 2.1.0, this check will not be run in older versions. Keep this in mind if you get issue reports on your module. - -Example: -````javascript -requiresVersion: "2.1.0", -```` - -### Subclassable module methods - -#### `init()` -This method is called when a node helper gets instantiated. In most cases you do not need to subclass this method. - -#### `start()` -This method is called when all node helpers are loaded and the system is ready to boot up. The start method is a perfect place to define any additional module properties: - -**Example:** -````javascript -start: function() { - this.mySpecialProperty = "So much wow!"; - Log.log(this.name + ' is started!'); -} -```` - -#### `stop()` -This method is called when the MagicMirror server receives a `SIGINT` command and is shutting down. This method should include any commands needed to close any open connections, stop any sub-processes and gracefully exit the module. - -**Example:** -````javascript -stop: function() { - console.log("Shutting down MyModule"); - this.connection.close(); -} -```` - -#### `socketNotificationReceived: function(notification, payload)` -With this method, your node helper can receive notifications from your modules. When this method is called, it has 2 arguments: - -- `notification` - String - The notification identifier. -- `payload` - AnyType - The payload of a notification. - -**Note:** The socket connection is established as soon as the module sends its first message using [sendSocketNotification](thissendsocketnotificationnotification-payload). - -**Example:** -````javascript -socketNotificationReceived: function(notification, payload) { - Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); -}, -```` - -### Module instance methods - -Each node helper has some handy methods which can be helpful building your module. - -#### `this.sendSocketNotification(notification, payload)` -***notification* String** - The notification identifier.
-***payload* AnyType** - Optional. A notification payload.
- -If you want to send a notification to all your modules, use the `sendSocketNotification(notification, payload)`. Only the module of your module type will receive the socket notification. - -**Note:** Since all instances of your module will receive the notifications, it's your task to make sure the right module responds to your messages. - -**Example:** -````javascript -this.sendSocketNotification('SET_CONFIG', this.config); -```` - -## MagicMirror Helper Methods - -The core Magic Mirror object: `MM` has some handy method that will help you in controlling your and other modules. Most of the `MM` methods are available via convenience methods on the Module instance. - -### Module selection -The only additional method available for your module, is the feature to retrieve references to other modules. This can be used to hide and show other modules. - -#### `MM.getModules()` -**Returns Array** - An array with module instances.
- -To make a selection of all currently loaded module instances, run the `MM.getModules()` method. It will return an array with all currently loaded module instances. The returned array has a lot of filtering methods. See below for more info. - -**Note:** This method returns an empty array if not all modules are started yet. Wait for the `ALL_MODULES_STARTED` [notification](#notificationreceivednotification-payload-sender). - - -##### `.withClass(classnames)` -***classnames* String or Array** - The class names on which you want to filter. -**Returns Array** - An array with module instances.
- -If you want to make a selection based on one or more class names, use the withClass method on a result of the `MM.getModules()` method. The argument of the `withClass(classname)` method can be an array, or space separated string. - -**Examples:** -````javascript -var modules = MM.getModules().withClass('classname'); -var modules = MM.getModules().withClass('classname1 classname2'); -var modules = MM.getModules().withClass(['classname1','classname2']); -```` - -##### `.exceptWithClass(classnames)` -***classnames* String or Array** - The class names of the modules you want to remove from the results. -**Returns Array** - An array with module instances.
- -If you to remove some modules from a selection based on a classname, use the exceptWithClass method on a result of the `MM.getModules()` method. The argument of the `exceptWithClass(classname)` method can be an array, or space separated string. - -**Examples:** -````javascript -var modules = MM.getModules().exceptWithClass('classname'); -var modules = MM.getModules().exceptWithClass('classname1 classname2'); -var modules = MM.getModules().exceptWithClass(['classname1','classname2']); -```` - -##### `.exceptModule(module)` -***module* Module Object** - The reference to a module you want to remove from the results. -**Returns Array** - An array with module instances.
- -If you to remove a specific module instance from a selection based on a classname, use the exceptWithClass method on a result of the `MM.getModules()` method. This can be helpful if you want to select all module instances except the instance of your module. - -**Examples:** -````javascript -var modules = MM.getModules().exceptModule(this); -```` - -Of course, you can combine all of the above filters: - -**Example:** -````javascript -var modules = MM.getModules().withClass('classname1').exceptwithClass('classname2').exceptModule(aModule); -```` - -##### `.enumerate(callback)` -***callback* Function(module)** - The callback run on every instance. - -If you want to perform an action on all selected modules, you can use the `enumerate` function: - -````javascript -MM.getModules().enumerate(function(module) { - Log.log(module.name); -}); -```` - -**Example:** -To hide all modules except the your module instance, you could write something like: -````javascript -Module.register("modulename",{ - //... - notificationReceived: function(notification, payload, sender) { - if (notification === 'DOM_OBJECTS_CREATED') { - MM.getModules().exceptModule(this).enumerate(function(module) { - module.hide(1000, function() { - //Module hidden. - }); - }); - } - }, - //... -}); -```` - -## MagicMirror Logger - -The Magic Mirror contains a convenience wrapper for logging. Currently, this logger is a simple proxy to the original `console.log` methods. But it might get additional features in the future. The Loggers is currently only available in the core module file (not in the node_helper). - -**Examples:** -````javascript -Log.info('error'); -Log.log('log'); -Log.error('info'); -```` diff --git a/modules/default/alert/README.md b/modules/default/alert/README.md index 4c6e4333..3bd5d00d 100644 --- a/modules/default/alert/README.md +++ b/modules/default/alert/README.md @@ -1,65 +1,4 @@ # Module: Alert The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules. -## Usage -To use this module, add it to the modules array in the config/config.js file: - -``` -modules: [ - { - module: "alert", - config: { - // The config property is optional. - // See 'Configuration options' for more information. - } - } -] -``` - -## Configuration options - -The following properties can be configured: - - -| Option | Description -| ----------------- | ----------- -| `effect` | The animation effect to use for notifications.

**Possible values:** `scale` `slide` `genie` `jelly` `flip` `exploader` `bouncyflip`
**Default value:** `slide` -| `alert_effect` | The animation effect to use for alerts.

**Possible values:** `scale` `slide` `genie` `jelly` `flip` `exploader` `bouncyflip`
**Default value:** `jelly` -| `display_time` | Time a notification is displayed in milliseconds.

**Possible values:** `int`
**Default value:** `3500` -| `position` | Position where the notifications should be displayed.

**Possible values:** `left` `center` `right`
**Default value:** `center` -| `welcome_message` | Message shown at startup.

**Possible values:** `string` `false`
**Default value:** `false` (no message at startup) - - -## Developer notes -For notifications use: - -``` -self.sendNotification("SHOW_ALERT", {type: "notification"}); -``` -For alerts use: - -``` -self.sendNotification("SHOW_ALERT", {}); -``` - -### Notification params -| Option | Description -| ------------------ | ----------- -| `title` | The title of the notification.

**Possible values:** `text` or `html` -| `message` | The message of the notification.

**Possible values:** `text` or `html` -| `timer` (optional) | How long the notification should stay visible in ms.
If absent, the default `display_time` is used.
**Possible values:** `int` `float` - - -### Alert params -| Option | Description -| ----------------------------------------------- | ----------- -| `title` | The title of the alert.

**Possible values:** `text` or `html` -| `message` | The message of the alert.

**Possible values:** `text` or `html` -| `imageUrl` (optional) | Image to show in the alert

**Possible values:** `url` `path`
**Default value:** `none` -| `imageFA` (optional) | Font Awesome icon to show in the alert

**Possible values:** See [Font Awsome](http://fontawesome.io/icons/) website.
**Default value:** `none` -| `imageHeight` (optional even with imageUrl set) | Height of the image

**Possible values:** `intpx`
**Default value:** `80px` -| `timer` (optional) | How long the alert should stay visible in ms.
**Important:** If you do not use the `timer`, it is your duty to hide the alert by using `self.sendNotification("HIDE_ALERT");`!

**Possible values:** `int` `float`
**Default value:** `none` - -## Open Source Licenses -### [NotificationStyles](https://github.com/codrops/NotificationStyles) -See [tympanus.net](http://tympanus.net/codrops/licensing/) for license. +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). \ No newline at end of file diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index eb9324f2..fbb8bfd9 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -2,107 +2,4 @@ The `calendar` module is one of the default modules of the MagicMirror. This module displays events from a public .ical calendar. It can combine multiple calendars. -## Using the module - -To use this module, add it to the modules array in the `config/config.js` file: -````javascript -modules: [ - { - module: "calendar", - position: "top_left", // This can be any of the regions. Best results in left or right regions. - config: { - // The config property is optional. - // If no config is set, an example calendar is shown. - // See 'Configuration options' for more information. - } - } -] -```` - -## Configuration options - -The following properties can be configured: - - -| Option | Description -| ---------------------------- | ----------- -| `maximumEntries` | The maximum number of events shown. / **Possible values:** `0` - `100`
**Default value:** `10` -| `maximumNumberOfDays` | The maximum number of days in the future.

**Default value:** `365` -| `displaySymbol` | Display a symbol in front of an entry.

**Possible values:** `true` or `false`
**Default value:** `true` -| `defaultSymbol` | The default symbol.

**Possible values:** See [Font Awsome](http://fontawesome.io/icons/) website.
**Default value:** `calendar` -| `showLocation` | Whether to show event locations.

**Possible values:** `true` or `false`
**Default value:** `false` -| `maxTitleLength` | The maximum title length.

**Possible values:** `10` - `50`
**Default value:** `25` -| `wrapEvents` | Wrap event titles to multiple lines. Breaks lines at the length defined by `maxTitleLength`.

**Possible values:** `true` or `false`
**Default value:** `false` -| `maxTitleLines` | The maximum number of lines a title will wrap vertically before being cut (Only enabled if `wrapEvents` is also enabled).

**Possible values:** `0` - `10`
**Default value:** `3` -| `fetchInterval` | How often does the content needs to be fetched? (Milliseconds)

**Possible values:** `1000` - `86400000`
**Default value:** `300000` (5 minutes) -| `animationSpeed` | Speed of the update animation. (Milliseconds)

**Possible values:** `0` - `5000`
**Default value:** `2000` (2 seconds) -| `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` -| `tableClass` | Name of the classes issued from `main.css`.

**Possible values:** xsmall, small, medium, large, xlarge.
**Default value:** _small._ -| `calendars` | The list of calendars.

**Possible values:** An array, see _calendar configuration_ below.
**Default value:** _An example calendar._ -| `titleReplace` | An object of textual replacements applied to the tile of the event. This allow to remove or replace certains words in the title.

**Example:** `{'Birthday of ' : '', 'foo':'bar'}`
**Default value:** `{ "De verjaardag van ": "", "'s birthday": "" }` -| `displayRepeatingCountTitle` | Show count title for yearly repeating events (e.g. "X. Birthday", "X. Anniversary")

**Possible values:** `true` or `false`
**Default value:** `false` -| `dateFormat` | Format to use for the date of events (when using absolute dates)

**Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/)
**Default value:** `MMM Do` (e.g. Jan 18th) -| `dateEndFormat` | Format to use for the end time of events

**Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/)
**Default value:** `HH:mm` (e.g. 16:30) -| `showEnd` | Show end time of events

**Possible values:** `true` or `false`
**Default value:** `true` -| `fullDayEventDateFormat` | Format to use for the date of full day events (when using absolute dates)

**Possible values:** See [Moment.js formats](http://momentjs.com/docs/#/parsing/string-format/)
**Default value:** `MMM Do` (e.g. Jan 18th) -| `timeFormat` | Display event times as absolute dates, or relative time, or using absolute date headers with times for each event next to it

**Possible values:** `absolute` or `relative` or `dateheaders`
**Default value:** `relative` -| `showEnd` | Display the end of a date as well

**Possible values:** `true` or `false`
**Default value:** `true` -| `getRelative` | How much time (in hours) should be left until calendar events start getting relative?

**Possible values:** `0` (events stay absolute) - `48` (48 hours before the event starts)
**Default value:** `6` -| `urgency` | When using a timeFormat of `absolute`, the `urgency` setting allows you to display events within a specific time frame as `relative`. This allows events within a certain time frame to be displayed as relative (in xx days) while others are displayed as absolute dates

**Possible values:** a positive integer representing the number of days for which you want a relative date, for example `7` (for 7 days)

**Default value:** `7` -| `broadcastEvents` | If this property is set to true, the calendar will broadcast all the events to all other modules with the notification message: `CALENDAR_EVENTS`. The event objects are stored in an array and contain the following fields: `title`, `startDate`, `endDate`, `fullDayEvent`, `location` and `geo`.

**Possible values:** `true`, `false`

**Default value:** `true` -| `hidePrivate` | Hides private calendar events.

**Possible values:** `true` or `false`
**Default value:** `false` -| `hideOngoing` | Hides calendar events that have already started.

**Possible values:** `true` or `false`
**Default value:** `false` -| `excludedEvents` | An array of words / phrases from event titles that will be excluded from being shown.

Additionally advanced filter objects can be passed in. Below is the configuration for the advance filtering object.
**Required**
`filterBy` - string used to determine if filter is applied.
**Optional**
`until` - Time before an event to display it Ex: [`'3 days'`, `'2 months'`, `'1 week'`]
`caseSensitive` - By default, excludedEvents are case insensitive, set this to true to enforce case sensitivity
`regex` - set to `true` if filterBy is a regex. For those not familiar with regex it is used for pattern matching, please see [here](https://regexr.com/) for more info.

**Example:** `['Birthday', 'Hide This Event', {filterBy: 'Payment', until: '6 days', caseSensitive: true}, {filterBy: '^[0-9]{1,}.*', regex: true}]`
**Default value:** `[]` -| `broadcastPastEvents` | If this is set to true, events from the past `maximumNumberOfDays` will be included in event broadcasts
**Default value:** `false` -| `sliceMultiDayEvents` | If this is set to true, events exceeding at least one midnight will be sliced into separate events including a counter like (1/2). This is especially helpful in "dateheaders" mode. Events will be sliced at midnight, end time for all events but the last will be 23:59
**Default value:** `true` -| `nextDaysRelative ` | If this is set to true, the appointments of today and tomorrow are displayed relatively, even if the timeformat is set to absolute.
**Default value:** `false` - -### Calendar configuration - -The `calendars` property contains an array of the configured calendars. -The `colored` property gives the option for an individual color for each calendar. -The `coloredSymbolOnly` property will apply color to the symbol only, not the whole line. This is only applicable when `colored` is also enabled. - -#### Default value: -````javascript -config: { - colored: false, - coloredSymbolOnly: false, - calendars: [ - { - url: 'http://www.calendarlabs.com/templates/ical/US-Holidays.ics', - symbol: 'calendar', - auth: { - user: 'username', - pass: 'superstrongpassword', - method: 'basic' - } - }, - ], -} -```` - -#### Calendar configuration options: -| Option | Description -| --------------------- | ----------- -| `url` | The url of the calendar .ical. This property is required.

**Possible values:** Any public accessble .ical calendar. -| `symbol` | The symbol to show in front of an event. This property is optional.

**Possible values:** See [Font Awesome](http://fontawesome.io/icons/) website. To have multiple symbols you can define them in an array e.g. `["calendar", "plane"]` -| `color` | The font color of an event from this calendar. This property should be set if the config is set to colored: true.

**Possible values:** HEX, RGB or RGBA values (#efefef, rgb(242,242,242), rgba(242,242,242,0.5)). -| `repeatingCountTitle` | The count title for yearly repating events in this calendar.

**Example:** `'Birthday'` -| `maximumEntries` | The maximum number of events shown. Overrides global setting. **Possible values:** `0` - `100` -| `maximumNumberOfDays` | The maximum number of days in the future. Overrides global setting -| `name` | The name of the calendar. Included in event broadcasts as `calendarName`. -| `auth` | The object containing options for authentication against the calendar. -| `symbolClass` | Add a class to the cell of symbol. -| `titleClass` | Add a class to the title's cell. -| `timeClass` | Add a class to the time's cell. -| `broadcastPastEvents` | Whether to include past events from this calendar. Overrides global setting - - -#### Calendar authentication options: -| Option | Description -| --------------------- | ----------- -| `user` | The username for HTTP authentication. -| `pass` | The password for HTTP authentication. (If you use Bearer authentication, this should be your BearerToken.) -| `method` | Which authentication method should be used. HTTP Basic, Digest and Bearer authentication methods are supported. Basic authentication is used by default if this option is omitted. **Possible values:** `digest`, `basic`, `bearer` **Default value:** `basic` +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html). \ No newline at end of file diff --git a/modules/default/clock/README.md b/modules/default/clock/README.md index e1dc0037..1c0bdf8c 100644 --- a/modules/default/clock/README.md +++ b/modules/default/clock/README.md @@ -2,56 +2,4 @@ The `clock` module is one of the default modules of the MagicMirror. This module displays the current date and time. The information will be updated realtime. -## Screenshot - -- Current time -![Current time](clock_screenshot.png) - -## Using the module - -To use this module, add it to the modules array in the `config/config.js` file: -````javascript -modules: [ - { - module: "clock", - position: "top_left", // This can be any of the regions. - config: { - // The config property is optional. - // See 'Configuration options' for more information. - } - } -] -```` - -## Configuration options - -The following properties can be configured: - -| Option | Description -| ----------------- | ----------- -| `timeFormat` | Use 12 or 24 hour format.

**Possible values:** `12` or `24`
**Default value:** uses value of _config.timeFormat_ -| `displaySeconds` | Display seconds.

**Possible values:** `true` or `false`
**Default value:** `true` -| `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` -| `clockBold` | Remove the colon and bold the minutes to make a more modern look.

**Possible values:** `true` or `false`
**Default value:** `false` -| `showDate` | Turn off or on the Date section.

**Possible values:** `true` or `false`
**Default value:** `true` -| `showWeek` | Turn off or on the Week section.

**Possible values:** `true` or `false`
**Default value:** `false` -| `dateFormat` | Configure the date format as you like.

**Possible values:** [Docs](http://momentjs.com/docs/#/displaying/format/)
**Default value:** `"dddd, LL"` -| `displayType` | Display a digital clock, analog clock, or both together.

**Possible values:** `digital`, `analog`, or `both`
**Default value:** `digital` -| `analogSize` | **Specific to the analog clock.** Defines how large the analog display is.

**Possible values:** A positive number of pixels`
**Default value:** `200px` -| `analogFace` | **Specific to the analog clock.** Specifies which clock face to use.

**Possible values:** `simple` for a simple border, `none` for no face or border, or `face-###` (where ### is currently a value between 001 and 012, inclusive)
**Default value:** `simple` -| `secondsColor` | **Specific to the analog clock.** Specifies what color to make the 'seconds' hand.

**Possible values:** `any HTML RGB Color`
**Default value:** `#888888` -| `analogPlacement` | **Specific to the analog clock. _(requires displayType set to `'both'`)_** Specifies where the analog clock is in relation to the digital clock

**Possible values:** `top`, `right`, `bottom`, or `left`
**Default value:** `bottom` -| `analogShowDate` | **Specific to the analog clock.** If the clock is used as a separate module and set to analog only, this configures whether a date is also displayed with the clock.

**Possible values:** `false`, `top`, or `bottom`
**Default value:** `top` -| `timezone` | Specific a timezone to show clock.

**Possible examples values:** `America/New_York`, `America/Santiago`, `Etc/GMT+10`
**Default value:** `none`. See more informations about configuration value [here](https://momentjs.com/timezone/docs/#/data-formats/packed-format/) - -## Notifications - -The clock makes use of the built-in [Notification Mechanism](https://github.com/michMich/MagicMirror/wiki/notifications) to relay notifications to all modules. - -Current notifications are: - -| Notification | Description -| ----------------- | ----------- -| `CLOCK_SECOND` | A second has elapsed.
*Parameter*: second value -| `CLOCK_MINUTE` | A minute has elapsed
*Parameter*: minute value +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/clock.html). \ No newline at end of file diff --git a/modules/default/clock/clock_screenshot.png b/modules/default/clock/clock_screenshot.png deleted file mode 100644 index a1f30f572f035a6308a4cd6ec3b161d488fb85d2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 30525 zcmeFYWmH_zk~R#1Ai>==xVzK11xo_K-3jgx+#4sj69~awgEj7M!QF$?1P$;W?!7Z} z?|i?%f75IA>eF?$*512z$x{*URpij#5Wj(efk9J{m;ML?^XeW329^{F0iZPg#+-+N zL1na-l6tQoB}Mt(*}=lv)*J>#J|a04QA=$IKVUzFhK8nI9KIlAO`37~M;N}ixX=QU z0%cxrJf`~bVE!u`iM}8_eXI|TtN|>1$L3hakH!)*+5{+k>T5Kxu7AAGe9wH=S0469 z)4BJvggu-QVg6XfYGuWIhKYYWoY)%z&ykp*mR1lB^BVUXdRk{vPjckr_wR3ElJXwJ zc30g32G2B)cOibK&sF(D+ltLFlvD9Do*(Veci><)D)nk;FkmDxW;2y1aHQzE83G&O z5s()3#);m!r@CY$yv5~n;$#^tfhm43NUDGU^ZD{;+T9B3fm{V@Z7`S~SHeE22mM#`gxx2UP35l#E89k_c zrQ+DcZzr@3n#!#=oeL#F%92y>adKTBjowU7#HklPONIu_W~N}^B4=RTmw?n*`IL+6ysPgAs4qaKO8p}1;R z=(NPRvt`5VrDfWdUWSGue~q7`Tu-*>3&U6vVaKed4!5PLCG;9SPdBC1$0q$=-!yi?wA%>pi)99AaVjuM22(S$*TT#Q3Loj_xdpbw)zE;$PN$^_x0 zDXQ)};zWkpE*PTb6;kF(X^+5ThMrFn9xxd6IP276Qazu zFx|-$j~rqr8Y6n1T1!vp7yxeu1FEK&MU9bHzXEUY;^PK%P+kPOdg=w_r(#^@J&jar zcr_p%My~nvfmzPsozamH7tfoNIN$Mz=)Uqq3h+Rf;WIp;}&#lYwUx%kJyUt+S~ zEXww{j%5r=&TR6cneBe+lyBxxK#hDg#mL*jpRFQT`>#zctG5>f%U|2TD;+cZ3eoRH zAMx_E6VWJ-$y+qRy)csy>(1TVMjdCY%9zdjmAAYJHKG{Yo)}E*U@5oWO2;-1ql`Pm z@UQ_TvTnta_qjSdhO`#@oN3y#IuJ&Rk{M?`7mkP`1jr$)Tlma4ZIHVjAj4dFth-uN zZPps1cW$~@DkW6SZeF5DT;%4XT?JsRw3Zvos&wLc!ir(ScZ=hK;f9Rfl-I#jsv)PL zTLi!UMwk?|Ys9OC!53_2M85!c9Vk2bDmHj#|DXHOQ?qY_^nFsp#V-(_z^E|+(5G@ z8;F3tXMS7w0^u)>-)sMXn=M0Ro*>w+*bN0EoCGAIki!rY$=Ak+o0OZlJ{~PdXJBdS zU@IBd;4=d*&P0JIE!h?Ma(eQ&?wAx<5Ark#PNB#FiT>VEI=5WA=l}htrR1#igYgrC*9w-s6>yYwDM^X#Oex4L293&RWWvER!vr z{2}#YS;;_gQ?Y{;PX_H+T#Dq#ch(h z;)gQT5A5%&-mh2rDYVN4mm8OKO>bC@&K1uJ6gWwJS52%uEGGJq{$0DUSrMAG$IY6M z@~HzUihF8 zS3*#b`lCs*>cd$MsM4WKOv1nAiSAMDUi58)+?SZ0SQesYhaEe(+0I{-{YEKWe8Eu& zzG1RqRADAPZejGO-qD1zezNJZWzn&OZX`1?zR{umWzliOVwS%-9@7^`8%7gH4RGKR z-{YhYX(aL``l&I`c+N=9e3|jKz~%O+bFKSiQDM=(*T1(tW|=vkvEE3j`%@Q*<(F1g zji-aPdAe2eVC~dpdU7S+a%pGjuiurtV@vZw^DV>orD#+At8^n4-<4ZgKOdPeS69@x zn}shmFCm}sExAQgM_&@s5`W_T9VR-rwhmf{{CeuL>OTNag?=ZI>mW4+(V34%a$5HL zxH&ovx-XnM4tyBl9IctGS-faStiYKsnLaG#9ur*f%5h1AmeshM-kI{pv>!@(5S`Ty z{+Qd1D$6YEZ5VG@9$R6ZvkP8E^RTG0?D%J{zE-uB|~iuYpoR^twI#SPuQJ306M?XaDD*s=U< z9v~G!vtiWfokDMeexyZ-Pl&CBy?|eUhf7fpI`FHuc9eCrb94YJ4wlE8=7mh2PvYhA zFNE2$wT7*d?BVm#ADapAitzdP-u56ZBPmEjJzaekZj-mqWObw?sY$+z;|hN^pKZ4) zJ6Jgoqr;?^RxQptr|IXka34+A`f@zGpkH&g^=d1nZ#AMRHnp#bu9#lwU9o~^E@7Hh z&O$m5owdqzsM({Lv9sD6Mp`O!xp(Wm-y+KB-Iblw)kO~P&B}(j>2fpk#b~{UH%or2 z398)`VSmI?^Z4PnC+$=!;A?$ck7nJjhwp)Q^Liq#DRO@7W-k?*Tj*VsS|m1dKCYEM z#d?mXj`SsjW%J8s+34ixSo&FAer;(TLM=|+k&C+XM;G*ndTH(a#F^;Av9w=QjW`5R z!Y-mNn)}!9x@mh4p!%?^VK&i$5t9|fZ%iz}C zc&mGlx+nimCe9D}?nk3mh1N$O)35XSV^J4<-F`ur;wqNd}& zRk0nFk8VcR_tTB$l_Pwt^lSvI9guF1zH#TV%b-g+=7B0(tvimq5_ z3#*lFEOfE!T`F|jJ4&f~XfvpO(lHk|e?$mIQ{-z~A6)kIN?b2&84Jr)w z{_(<{!dNNeaGlKd42&nv`?%lui7CT9LgA@od8CX&T#oe{R_mM>H96Zv0~8G^cI__I zhrM%&I4X_VZ^YcLUC$43EdNfBiXQnk?q=;bOYN^t@EbU`PdZNRZgq+2KZz{tE&XyF zI{B#9D(CGo@H6&psxLc52e#+#)u-z@lzHkZH@&zHKWKjeNjAS1f9~oq#dgcX^3m z)#F)zy!GjZmf{L@{P*DLVzj7NRrR6BpU&6dp>IzSI)7f}f#{5Y&`XLecflCY6;@aT zciut_qr>&r-3l>)>w_1c8dAQ9DihLQdX1cQ+^sj_4HPgJP*`xlIzy&WU4T-k#~r{%tvk*LmD`^M-oH?h;4Y++N%w%%1b2%f;%GD zsFtkphU76svB3`5q-!Vg8I`Z+fbD?nD6j1T1A|Zd@`Y9SNCOaIv#r&&T(y*ygiIam z*o@5_Ow8Fl?Hqy9FfbyXLcpV)xvMdyr=6|6i;$-%^*>4o0naaFc52Fh6mhi?rPfk@ zPbuZ#Y);9`#>2)z4SGXKNh#uNW+C)ZTJ~Snfq$aZR<5p&LhS4w9v*BS+-wfcmh7B@ zf`aTET~wsv&2cCe>>Y1i1q!Oc~an);=q z|Ni`QoaUa^|I?Gb%fF@tOpyKM4Lc_r2m61w4OA6*p$fgX_B6NElD4)pw|4>h0P*v2 ziTtDd|L4vB^!RTzwg0CkmjKVd*Zj9P|Eej%{xX4oo6tYG^$#k*F3=kh_Wx!*=nXvY z20XADq}I}^>cH=-m!$zdvA~z%U%$XJXs|v9rUm#-QjnHV_k=ypM*K-8bJrifrg)$X zri7;ni47yB-VK@KgXL-{h=6_|DVz_@G~`KzTuerhmxg$ z&cmWy`@(GZB?Cc;tD8m3T!VR6YWRDSSKMPfiGqg(iNvLkPY-9AxldO`X!C9oFS3>r zzBB?j=@j)Nt~1J(7MXT@Jw`%*X4Nu>66tUL9{v9PI~e=V1dGg7+1#m`5@%?-aTw7k zOWi2;qv>>C>qQqLMOvKL(@&ky3NLHvE1R`WywbI3?(qfaxc}9Z++Ga-8i%3Zow@G2 z!C^epi}Jeh&!D><9B%9Bf&=dv&25fdLJp$J9-SSpe$@Wbu}P;* z(dxc&v7V>+azMpxzw&c>nwdFI24B0^=SX**D;Nh)(%bL?R1 zI~tv-Ir7f+^7>Pwwo@M-$t4{IlGr+7|Hc4?|4Nd~JrOireN=EitNm$=bAZ&MvU!i| zZ(q_CbV7{(;iSn>d+tO5@w8@`sZ81}#{qITI?6q<0wuvIBZOM!`upRrgFH-p@&QS2Lt(K6QjF{x&Y<}gE#GEiL zBQD(`V;7!2UfFu8^X|8**kipQa2RB+6(ykl5#WPoj3{@qyifN)YwH{E`aJ$AsqAg% z-7CS4Q-32xn(p>8h3OwO4ZO_FHEE=;qUv35xgTQ=ObcB*VG(iZvN&s%e)~f+*LS#z zy7u?!#qJcS5-9dj7U`E}(>P7H6x015G7cPog|j$mm>*}c{Drnfp^fzE*#qklzkZ6p z<4(Em`RTzs6*1TQR1n&Y!Y+Lsp6h$9ZC2ND-i?ykM_{VQAk;JPlpI$1-9@u9y{m_xCPbUcMA?ev?n*yZ5cx8a(tK3S&taDf9# zVL}}ETXoxCEPqmdQYi8%Kw}(ydY%}$-U{9yd`Bzv)=rT1e7hPY$L3{%P z1IWCg|LRl8ykKlZuak#0rDObEAG;sc)z`!1VwEgF%@sDb9+E-8HZ^JiF0^t;XKkJaR zBbha>p3a`1CRnOFU!hHGx4L(|Cg9OiH3&Gr6m`U!XRiF&z4GO#Vrbc$3?~_(Hm-3w zC5o+OaK-zq{d#w0e_`@@6T{!ivr;?11CTYD*&b`nRQhaYe~>j)yH<9~eMVTD2uIOq zv%>)qH)Mx^<5ATn&qVp}Eha$p&Q(_)`wN-H-gfYpfc>lnn|J zriuj_kQ9o)8;B}6wB0*f9x1dTT`Rsft0eZ`z^;2MxpXeI6?C>Z+2&iw&)$CZvHnZi zVCkfB85qP&Rf#0*LvRPOK!${thb#o8V+_Aj*rx(+V3W)-?g^2pk0seOimu`0Uy8fP z#ndM!zm?R`N+%kNeRtu1MSX9tHwTJpNg@Ue6vnEyS%o9g&js`T#m4q zYK=`!qEc!!3Tfm{j?67dtt_tbx&3C1Il)#j2W!d!x%?6Ifx6VFKLuB5bF!s&QQZ&) zWVztBjGZ5&3JOj@wfvx4OrJ=cdYd(Lp-U<1_y+5`)3^gex3c5ui_5Cp{9>w0c2m%S z>HU!|~camPMBuOkK=nyqN?F|UM4>yL_4B3 zupJ18n9+kST%Pw?pds6HD*|mEsv@*9Or)vtCS-m_*+b1 znjqO7(-*;WjTsmIN|;XQ%In@A>jH~*T3Rgwca6V3r_EvE6BP2*f2u9fdU;@{FE(d3 z`6hZSi2>(i_FWfGmVzMFU?-x^{R{Q0h0bWix7xjV+`mqXbwSlvKz;jL7fA! z$6!5W{rTx8%rP@z91s~Dz1Nq5GBr{3Ij3H)gL=dJ@ey%#-h<-Pfl>G0x+Ht955C6{=Z~1p zeU(S698?s@+*{nmmJ{Gpaza-5bTWBggF-vyY|GeFV>8A(&vT`zi_|WM1bH90Qb&xK zPWdsc-JAC0^|k3hY)n?z44r+v>T)6Bv~iKbBBe;kvEmzJNhxHmU?KNGOr}&r%#i1c z0g5;ie<*+1I_(IS5Quj4}2{xCLzDh>lNc?JL6v&|J6u5Df_*hTUpd^ zZ!zn)?wM%GK%Cp#BHQhk^-s~Uyldh0yVynBx-sG$36u#l26Zd{`C%a(#Vj}A3}X8B zi|0QrcHbg;Vc=;#Z!Nx0ESvOkHS~TtV_24k3{`E!(Ld#Fb7QviSVLaBe6{DJp?a!j z&1>`$8JH$Do5L5m*zRJ#%Tx`Hk9Jckz(peBi?i-#^O62IxIKbdBu8Fe_!H@q4~9Qg z6JRgc7bM%H9B`jYx$>>Lsud}lajoB`4Pj7e%%q4>;Y&NzzGh{#V9e{5Rc50OcF&L~ zB?}1{tI?z4Tr?oVUWlHYKZG{!XtNq+egO+wAW*#;`tI<3$|WL>@aL(U{##sQjn>Jt z0}7?B+I#OTM5j8hCP{h^ZE1>?^TYtH0^~$|x?~37NTfee9yieu?m9wB9Pe$T$wh@+ zOt!fjqK8lu>64g@z9w1tC?*`@in_~uGR6*Xd3gpFG5Q^t_}0A%B#8U%-84&ZT46oW4HtrHr=Ttc@&H$xm4c@wG?< zD^BDt>#st!*w!dz&TnO-tJ#}&NvXrF!`cH$%jo@|pt;K*!`v-{oP*~Gbdj=$-eoFs zIOqd+KZzgHgG(%SU0i+Ur>O%e6C##7jvYKCN{SuKK7{ZEW7_DqJx#(r)d(2ZPo>)16C&qq|vT&;RX7m+y*VvjauK;lg}c zVW~9Y^(Hq}+7+$q33m>j2uWTC%l4{38^we4*YzGCJAxr==Gd8gs98R19xF`wXHoJg zjjs||zE4E7lvn2uwYjd4zc8kM(Q>(enrH_hXpyNTL6#!Z8_dy*NOg(XOJTEdb*<7+6!h!Af z$mq`q8c+MyX@4sZd5=xH2D?MpCSG-_0AI6Y1t)7st=QsF$! zPRk~yW4XMRn@pbDj|%0Vc1E6(>yIYFX*aZ5O4l=P*`StBYpTY+1Vs7IgviP}Fys-2 z_|ujP)L;g^Z3Ys7MCWCNCq-)M>-NJAusRkQRF7jz_CG4J?p}TPmZQYuyN3tLkIRQO zM4J~@e1s}#*|uc}4)}z)*R2<|ff&b<@>VBIuEXzgSs9Q$Z+yBxSJ*TpTV65|`Y^v4 z6Dn+sJgB?hxV>d1g7r0R1ID;#-%2zH)b1vc@!=0p@;r-X}n9c)zW&olf#maaUqrI zpqNpZ1nL@?!CPJ^BD?zYHs4o#w!}2!)?|JL{Un+jBhSLb5~YlTZ>Zr6S5Sn zOm}Ab=ENXIO@JBxYOz54(yK}D0|Vur0Dh4I(Fcz-LMa`)O9e4PLFWR%=2n-&(t;GN zu*vDWEA?G3&;vqoI(AIV!l={bdh%qb`lSTctw&_)|aA=<+2Y3VuWuiNG4gYIW8*{=*Gjo9i0u`27q;tBA~m@2>pYEw9UA#Ve{@ zmh}Nw8t@txWZHnWB}Zl3*GpZKwlg84?@f^NT?r z=HP}G;()hle{EjCpJi}H(JarTL z7bP9WuI-}#LkKO2@ICt;4ahp>-~kC^kL$|KyR&g*v&=<@rw z&{`!4(qeKcuRo(v>%;5=dM*YS6A~05^9de%@6v-QKd2^qh1_IOR=elF)22Ji{segpp-Rj z6%Q=XgWtMWGT1LiYlfwj`(P=-0_OllLZN^{L$NmGIxt|-c%~K%(s9pGerL6ycsz}W zMx5lsBNW#8llrilY3GtaJTX%0hw3>+Xa9N%#Idjxd#b1cnZ)w!1B{n6iEZZb!mWg# zKKi&e)k6mDJw(CU%24h?y!m8^=a202NyhCR7?k*i=QNQ{xpvc9;3i#u6|f(_BAfQW ztrFZ?)Djyhrj#JuNLhJ`*~QS1{C)4Q>m!{j6coiAQj;y)IH!vPURojQJD@~%ZcvF~8`%R`{jNKEYtZP+dND~Vpeurc#LKVzn zj32OSpK{!CR5?{BcI~@hU7Mc5D)7++@w1H?;m+i2uX%MYG&DuAPP1`_;i&DM^!oly zfCUN{IW?Oa72Tm#jPEq+lw41kX$y0bIk{bBm1_0ZT;~4vxC1G_blgxR5E>?%u8)Nm zunWRf{4p*LH$Y2*j1b2%P=4-iN4!!i*?@GMM5`SN73hMZIJ0^fCEY`Y>@B7QI4%?X z^!(*Dh{aZ*AHsBP_U!NR2Sm(ouUG$>fGh9pv0%LPC1ysV^V(8cK1VV0XgCKp21B56 z&$_YWx-R?O)x55QXdU1pS)Pl~5Y&SomXnku`?MV$iTQZDNbT=SqV*$v>sCY92ZxxB z3R7ynmkWcF<)hd<_b2Lm5Kan9Zmd~5WwX^#0vF(Qb@^RVM92O|$Uf|#?k!8f06tv` z8@Am#LGD9->TSNj-CB)^bZ*;W5nFc{TnQOEcB{!>WZSMbn2tzHC%efoFH#Hk#>Kd} z1F@?~sW8m?PgwKg)w8>ua2TVrwwgcCy@ofrwMTK>wWXi^!8q3F=EPGalA)gu-bKhOFA@*9X7uJ<=~en732xPsSJJYqt~U~qS$C6))fGELnq{;D+t`+j2uT_$?G zEq2H8Z8RH5pHHc;Sn-7)BM|K(z#A-@s~`Dz4V)3k#0v9BKPUn@_=nwn@KBtM44q#k zQNAk6&8qt{t4is7^)96E>_l8X>{`>D%OJ6E| z0l!WY#!*g|R+#1c;43Me8F=pxJh7GMUe_+bszqqWNR_gJ#)xZL7L^84bRF8~#51IR z;DA9R3-Q$6ID96l-qub^_il6-sP_y^(&|+e(@3a7F1|f)0;awpIBwG$Pb3Mt3`m^ijEs^ zd9Hxf{cQHed_8vnKG<@E?tWnwr!{M=nedyPbF3*}BChT<&;7~>c6b379z~ zTdK@Ku`aW9;V?8uGveU;oVj>iC~Qr#(^MwaJt)Q#>{6<)nrnzM<)n3?@J?HLoj~Ik z9`e9GIFm(l%5=W+TekSsqAiA{t*(!s=(TUQ^EiCc&13_PvwRX+YtCc(0nRHz7X1gm zZ+QbOW4mhow+(=2LEv#vOJVcD*q`2Z#mzt&P$HS9*?Q&r%X@w}6@aaHDQ&KuJ!)?s zLk}G4r)0mHeyBYq-A9AdK$sdJjjE2a{W{+NuJYW>UGM~2jvP7BxUyCqnoM1}sH2T3YU<|h;2dNr6Tt-6io=xhPps5Tq z-{>VHA_sfO&hju-YZj#4#AmAPc;C%H^kq7~=&T$Ym+gg%JVX>NeTsdi=JGV1W-l|K z>hPeRvg}q_UcgF4>N|3tMDNOrys4fZ3iEtf(MK>B%D}8JhF3GEDtuBO zb}V@#Zso}_5NZL44%{dP9xGue*rBco@b&eH-0dW`CjefP2T7>}iaWZ#rU~iGocw`o z`77VpKVDghQCoAB`y5U*uW%spjRhy)P1bF4Z#47INJ!XQkGZ(NTv?IOoi$Hn;YYpd z*H*B6@kCBtU&rsN4bUpEJ1=#=u zwh0wci$~S!&`yo^_p$S7*uiopV<5_zGV>3j{4?*O5)|R(J*?cgAZB$NVDmM31lr8- zuS>%xtR0_j9)B>&Y*Alz4abujePw4I2D5DaXIC(ig|0TlzrK$E+y$BNIQvxV6i;GXNG%dt)c0$56*Ch!Y&xrLJyPTqYPutFj%wjwN`i zdKucm5_ntg0h$y@PFlFO??>|WT*D{kkDuu8ArTnsut~_-Yyy6j4Zn2I<|xC2^LR3y z;%{O?Wgx;z=*RIbxGmb|GKbeE^TSo~mzAT={yP8Bu(2LvFXnczszG8f5Q zxe!mRsBev4kA^|Rc6;n{hXes!?-9b!EX4+=YaP$7rlhQS zr=?HQe3i~8)5EP@!X_voIqxeQN!=HW5n>$53W)MMwqu25jXh6l&1F86L2nbh_Wzlh#fl=8t^E*lh; z3x>j+FTWWdiuCp&3U4_#FSLi>daY%O9HuB=MT~|uuBPOx)PsuFTFMy~1?KMbq&o_J z_2nV88tM9Ef);O@$9;p_R9#M%@Dg01J}bZ-^?-1|^Zc3sQi&nJOsABlw^f&l9uqLl zGUd@XI8XqqToLu2+v=l5W^eQFU!^vXg#)kc&eq}mWhK;bThcnauBsq~eAbQma%*t5 z#bq0??YS1IPnPXl$MpQ}c86>~#`%KY2#83c9~VoRWBF?4{`f|q=NQ=h61_`aBskgL z%XEl!KRkAGL8gbC$=6xDrNw1^*S)_!{Tr{icKA#YkzSRKvyq7GW*`z}y)JLw_d&IK znfZ}XT}#{JPcUW2|Yv#cNU)D(7cgI>ENCf{n8AL2$Tmo?X7Bosiy9Y+_ zmyM^NL{EI6WBmLf3H5z=!5Q8@IB@Ha?k!m!z&&7`?eQ@=`~do4FW3P?WnmZE)fAC{ zvTP9n`s(MXr}*a1guLgHYlnq#LhRWGw}RfQVs!vg%nYh47ukhw3Oet|OC8(k{`xO% zF*U{pS{Ro3ToDf5hmNBUPgvZ=4=gc*=}5Ct}z zH@V1$WnhoFh$kY;tSKXh6R23tazp99j~EfXK9>GM8?u^6s`lr#`&$iEM|ty526e3x zj|y~?(nGFfROQr%VY+)r3_Ub$if&{=7EqB4^%AdkT!bpg0g+DI5HSI=zuXxb4-}%& zHAFREpC%H{&zGp%y+5jobDyrSY8@92JixKXzBEIj<3XjSD#)~i0`7gfR2{;5s@&OroaS?3*4nNmXYE?q1=jG+B@A#ft?mQaKZjV%B{RdjxVC4Pa($As}fVZ z$T<#OpAQ*6dy&^rukkXaD_;q81Miatt2tg((K6>Mhi$Rp)cFpkG8OA>CvwY=>rKoP zOy8=?&2fB_UfuF9d>9<0Fqg{l<@fP!ipMV-c4+^DAD)2zaw>YmE?L#S>xTq{VMhEE zU}=DU-879)s+XANuQt&MpyRSpz-2{(t7G=_PtHFL2#-2<7L9Us!q{@r%a76HyN4jL z=Z)k;ID(UC0Veg)(q|Whq%hwpmBspIxZb}_%vDIF+a1nOKwF~oPSwR8s-^g|cv#o| z00h}Hb*R~$SU5_;ewq(W=1Gm&x1RiR)U}eP%`J?J0Tb5iGaG^ORjD|P zP4V6;BB3dO<#nsaEbrE7L2?h}pKvsFwC76!j@bPwaT-O=i|B~Av6avcn(mv!s9WMV z@mPOT%Dk1xoDComCIm}Nik#LCEi}`BBQo1ngzK5-J%J`5&(Pm`TpOir*DyzHw3!J@ z5buira#R{q+20^(n_>rZ5KvZH^;x zTPCt85ltEtu)@A5Iapn;ixGee_Kt&aamnbksA5{_{Q@pRObs&&y;duA{LiHT8*95P zpFIGX6G4YLWOL1FccO#WmCk#{Rh8|2nFW#2ZI%??l5;$5-X|Wdl!R9!OL?x@Zwzge z%be)_MPL7#*|zZ)ilyGY^3n#{Vwmf4LW8rUr-H_^Z5IMbZ4RxHt(HQyhrIb@KMNCc zX{y7(qD^IU|3>F&0#AM%EAOsCPb41dlF2V^OFQ{BOP#)$E4igEzlmaIiPsAs_@z5h z{ZX$Q&QB^nnCG9NoO0N&2)JA?T84|qf0+nEVLQ-c-ScG;&d0DDzTN!ttgURiD|BWi z*5Lg7_|=0fG(c3g`qi+2g4i|k#BsyC0Rn9(>v!20uG@BA=A91~q`t#a>H_&a%{%!~ zY+L|*pz5f|U>;w`D$h!(&S|@__V*gIRCYb-%MDI-jrJQ;(g28<7K9py6l|ZIzL`__ zP?xgdzGO`=RV-YBaIXrKf^^ktKt04@@ z{R|%o(0QgKGKKPS_eo57!p)XIB%F2e?UKNqkA~Q$0eGP^5H2xJWL@n;G)Ol&WFS!BQNRBw_QjeP4)v&W_++lJXVN$cNIOkgw(6^3_e|mT%gL zd92>|zShHWrMqTm7|ubW< zU?XFc-L}mz5>y;KB-9&c3g6WqUw7`xm5TvQ)S9Dt!&@@_t}>AMF%wK*>3kW@9uL#e z7vzO_vVD&}rRo?$ql0-jJ@3^t^*(XG^E86_k!G5zx%Qb>?Cn5^l+nO z#(3vJy$r^P>|6(r-CNMo*DFGJU+mwy62xg`X1*AdpexJVbNw!a`68qZLAvuDAiAL{ zX`AFLor@%c=|w?wzB}ZGOH%G}JY!r3*!(j0WW`UlLUX^?lMvyd$342j!ZYaiKjBTH1~>SAU=_1+%iiwVGrt-_TAR>RQ?BVG}=< zuS)0Ea(xr8T|_EHHKsQ^Hn(mPkrb?MwoFW?4%(xr@I3f-_SW8g?RY5OVrifNf2Ne> zm2DA8uIY79y1GU)5V}j`AYIfq_SqKE^S^Vy@EyXbfIDGgcGrd{=AOD)li%VZul(=_8F7zC9xa* za6I!njY|-jCIKKm@f*=}cvB{*cx4bQc#N#jyrwSSC@x|Kv9MAfn(QmmppEKN-dj=F zl`u^eWmySn_c^luS^g8SQT-P@1WRa49iIe*66A2E!-!M|zjbjj_GTs%)_*G>{>gJ; z<)0_9Kehkk)}*-yA%*Pg{qc*Qx1n8hLI21!eIJY)Lazs4FlP^8+H zuBE7n>~1PlN>IHABFj4x*&nQalIGosDicb1`WJT;)V+Aqq#lgv!NDwz5N!$~FoO<* zK_vi{5pF8v(k8P-zvz^M9_f7Em+2pcTW(!&N`9a$ynY0>=xllf?hZ+euxBeglpds) zc1(%sMtw+glp%Aq?V7HK`PkQF((?wn_l@_~4$S7V9cB?reQ%zm@1i`TwtEgOT551A zv%aRS8<+(vD8bxaRJWgZIF2v5Ej3j4%A~MriF!Zdw#znKj{Gz=QLUoRfcyEMkOuZAbfNgSYOVORLbgKwML{7a66j>>W7l5g0Qwa9u#13D3{Tk#TQ z{ps%G#Wdj=dCq<4M-ob{uD0*bW4h>BZCLj7duJ1BI48Vu_Hizo$fR?f&!0BRdW3r; zDfg|rZ_o@nKQnHp6+mBD>q27kxtoP#Oi-FsnIhH}^_|tM_R`*4wL%W7I@h7{91)`G zq5YDgoZnQp=6mz0))KRh8nnY`bV`_H=Y1;tifTFqD?6}v8x(f$46HJ{_{QMB%Nq zz9VWb-fJ8am^0UasqD!my3QGUUz5mb%s`~&^*j(qVOTt|!O`}Dm^Ck4x$;_b!bMQ} zth7|#Hyh3>RhqV;%^`-gK$4$wlUYk>TpISCkZBxbor3x1pJrr)#Tv_SR` zB?h3KdQDEZOMat9+L*P;R5H4h;K{-4f)JD36@-L1D6dtS0yuUd3|I}L;{z3?)AXHG zbM$$y;^JP(Z;+RSpC-Fcbs5y1?w6>;jhG4yvrdsnxbD$^YEN8FE)VsPkOCocMhn%( zQ-#q(2_a#T%AoK6Xb=vNDC1W2$sdufC^wdU7xy_;v2H86_-)V^;h`K)dVPq}aFWWPMW$GJ?!gk=m$>;|C$ za3*Dgf6SRzx|8pr6*?}ACJcE8WI+|v1M~f3t2tL%h=e(v7@yR*gFMl^lb|T;&C+X) zx&IeHg~t2Zqk^B_1ZGeh32$L9{ss_M8U@K2jZLMr@BmuY@KGE|9T&F#+IB};UZMNV zmUyO~b6k|Nyy~dCB-tUjBPV*{1#c(gG_ZYjr3oQKtKXO0EdqdBZ0fGcNa`?wR8nDt)H@qs z;m50)%olv@x4v8fr+lx?Py(j+l6e10czEG47f|byJz28yzXtcO}1rWld(7XLyZ~rPN#tRf|(Xj_@3@|vY z`4-I*!L#ANZXR#e`M=A>@d4PfsAj-K9z$Vo!@RemJWx^<+7@#@{E>Qn#0S`Tp)DW)BTk6EzpibO{$t&EwxZ#zWg`fs1@!k^ik?n}%>YOq z(N|<`P~WY|^1DB5jRneA0=u_eo;Q0UnoPK{%)49tuEk~r-{AwrdkUmuxK~V=48FI_ z(jiAn7OP9YE7ep*8_INhmc%9Rg{LSuO{C%Iu0x-suZjStsTJ43Z)QF=nekR-ua zQ~mybTbYSSWUuUzaO{y4%4patWR#V?9SVh{jO;jw%wx-*A%$aPk1~%Pj&(TP*ZcFm zAHVPCasPM!|LftO4jtFI-q-aS&+#f*+NR(LKXu!yE*lt_BndhrDaA=xy!4-Xgxz>~ zPXsU*Rp9>DhZNyzmOq*ecsZHIQl&G5ZYRADv367NLhE}%Fo5%rnec2epFI%!-WoUe z)G4ka*KSRJk_L3v;+WriOX#V^+XM&E?+jKFb!>!=yt^i$d z%-NNPZq9pm=j2{k1?_(82OY1@5qFhQ^q~Cy+j;;`2Uv_i;qDjYF<{)veuz;e%1?Kd zt->8nrxQ}iql5rfl1hqk$bnD0)TM$>%fV)p?TzB$QLsJJ9)Q*bJ$pG`rvTA; zy@iSFe!CK()k}HU@j$qT<))>MI4H6j0nMZ5p_saJc*8!W-OFi{i+3Hx`;3V>8YE;k ztY+D1gU;8VeS*jg*){5+!Apg%*9lyp09^V)P@Ln*&!+tWr$gX6065aAS`Q)xW0Vs| zxDC8j3`CD+qZ9}7lg&M%Qh|Hy(^rOJcG-WVjIQCmpn( z1hLti7%C#vRBrR#7%MfVX|^cEJm;CO?(IAR-aOcpL36)95qH$+Jkyz6zqXqL7V0V) z*IRCTR!2BT40!uEjv4zpoUfY5xUp?)wwM2-IJs?U&(Q~WYYskJ*r(e41U3rRBsoFb zb-$xoU&t<^anR+u=O|n!?`BrXu_7t6Zmc} zbs8GwP~C|5>Ttpbku59bomXNu*BW#G5-k#+D1eZb8wX!T*;HH>3 zIQF0IN!GZ}oa+ePMJg#E2Tx{y6z`{$RFX^5hZD9szIj=rl}os*kGQ9#uOG@jp^K6I zOqPFtqohiAket%`;fZef%Lk8*AE14(Tk3nM+zMxZJMBBd$v6+y!+v?HWXFNNdWY+G zl1uZ|HZ{ETIl?Q_?2_Aotk@}qR%GL{*^sq(gFhYFAEGK_idL_m7;ou2KUw45C%2;Qh5uA~`kRNXU0J5ny99yW_W*-_7G3wwJ}}J&=qfc{X@8Rf|C(o zcfbay^f{Vn{0by5^g`VsQRmI{iWiijAO95I(iKPKT+bnaXq^u^y~%kDT%t|_dy6eE zT25ACT)+N_?D71mY ze+Yo4#y*(=N86c$s{X0Y~~eOg=G_i^^bUF->) zA`^Q-S;_ZoW~6`1_sh#jm+I65;}o8ESaxOg$8?1 zr2Z+UUus@jhRtfV-XI^O z{ad?dZ16MpJS1DoUNWN+xb#hJa~?m01^bXdLp=2NPv`zg;wfH!z_pL6R4GaFFA_~1 z4i{UZDJ4dU83QV#WyLPPggw__ngA=IjR+Op1w_f4vZlR0$I_ayw2c5|bh;z3Ghjk) z3^5JnNtJSt;b`^bha6Puk3qKf7C9|E@XnF?rgVOsTgP1GF!(M2gMP5@;aoduKj$g% z=fhpr!V{U8N$>Shek`yu(){3XHxDwGX-x*1wn=(C{TO)i3K!0RudFV}lJO-F6O38G zac30*caOGbf5^6EcvgrWc{*qRfua7=4u}1fxkbvvXM~0Wr|l5n*{^O3t^pVf>_MOkTN$jN{igO&UZzmw%;(Y3D~^2bap z5tI@&loH;5&@cS>98H-tX|ar!<-o0#B#9_hpa^a@8D)BCbPQT8&gSK@{yYUz9KEGq zdjto)FUUSpXK7!7XRT@Zfy&JUrQnX=Al2-D+5lQs@|Hca?mq~3ot4Rw9~f6!wHZY_JwSC4(9S>Q!joYLktpbuUYG< z&IH||!apc;azAI0^SPgKEqF+s-oQK`7~Z5rD^Cx%%)mOTBG2d2-5DY&0Xlj%7iGgSFQ#LU2Csu(q1&eL4u8&NkGP~7jg zh>AGBdYAc6$NQLs0{Ro3!G&&s547kPyJMY7Dk68T)%(?l{><6d+8}={t7}Ci$@uPi z%)YkOm1}#_f7=N6Prfg^S*LC6lvy;c92v<)oO8N?z3_XsKfTH!FHFo*lfCUrv1V)5IZjSw0rW zXj?++m7hfG4+`@ea^XMx-vsxH6=a1p0Dj?v&v1$V-gn;Sf(lo$e!xLDt(6hUarZL6 zXv06r1MI=*1U<>geA1cqDh0zvrMT}G9M%>j8~9E8sT@W>a@SR%jP3iW$s^E6=tr)&{GwGN0b(Wr_x$K^=i1aF*fS1_;3&HdjcT3XMYf_k)=12YRP}OK`sR)YR7L^4MKDbvv(~c#=gk=+ z$OkSrvd;2seqxoCeT&I$wQ$qVZ-4lnsLV*v2bw{jw;_rrVCsO-sWk`u?;sp(3~P78 zPCqV9;#qt>;MQV%pY2cU5)UXn)-LZEpIR?QegX>XnEaZ_`Gd}~swWub^XWH>R~ZidF_Rr69shk=Zl z_XN#$LRUB_aFB73eFSdXD5=}_g%gq zWZhB8j25rPCY852?u{>V#t7LwrIHp7;QiC16E2mFRxKyM5e?^MH44(LUmA^WaA)0HMt*CIK3bHLrC{pqCics96OO|R zv*$pu&Y_)#^DT%3mF{Q1Z|){I+ME=3f1~-)4YO>qT)+BBTx(AA3OL{U06jU7mnEWQ;`)>=h_HJyN} zjErLWGSbF0B!uLcYY8*)#wn$7Z;?|eVDy=W&{G9TixOG}J{#mTy*|svwmk=5E$xYOtt8V!gR0{2k6x5dB{krnv%!39mi_}!4v|8UQmxEL5(6e~8zU-);5?aDjQ-M-{A9k^r%Dc*<4al*d0H^kp|a}`{wXC7U+gCMFOJp%}Y2ZaFL`1h7Su(XLnjD9ER(Z=lQ zraJ<(myB++HXAei2wnxRppV=U2vK4;O@udqo5dw)U0Z*3(75O1~ zv4)Bjfpp^g>Xct!-4}lXck?xEgVmxQ;Eu~kPe-`8zaR7`bJA%OkwUju{H4$mHcVoX zaC|=`&k#Z8vsdZ1S3MllgLbl;*Iq|7Eo8rDRcPaD0^pj)oG%oo{=Gqu5f=cJWs>V| z*0DHHwK2AIE{WT#9}c=|LXLaKBF9+YmiXTHQuBwT!29!EI^$xc)JMs!XWy8;M;{F2 zJeQmYm~Ch3b(JNc^|Hfg%+s+3ZdSl(O)XB37cfbAFAi2KYfPLUYC=3ZvOXo`zt7E2t~B?&KUJHvS_nSkf90N%movuJ_s@ zB&i_Ls+$j(0CGS5SEQ4em*#kYGcRedXaEg6N*@HF$c2@s)S5ihX{h8k{vamwgK|aD z=$pgfCzoo{NA+&4RoAhe2Hbz&fF`~}ZeE!Rk1>nwIf|aS{_)mmVM0|jSoiFKue(Yk}(S_WK?-SSi z!%J<+ddx^s3uufGmLN~xCB(f2Di794*)he7Jww!A_`}|Zp9APQZJ(19{~>d=$BIC4 zi4C`FA0;WyBg&wqHPSlh_|NP5ONeOCA(aO-g&cv?L+`ok4ZJTk$Fhmrzl8#Dzn%#Y z{CS*iP$ZkD7|KR9PQ<)hq01}H6B0FU(4{M4d7g`8RgJv-efjf+#179Ahs8dCn9n)C>`moZi6`;`QpODG>9yXFFtFKu&Ywb=qnh`;OR+c z{*0pw+N2eLlX@F2Lz8bPTgB=fmy{o;DUK!Mg4 zge|!yOR!hJAx}te%Nuw_cK1iiobsET_Y&FVhx+TBjmQfa;nSSlup)_D$3~fF@u0pXJ6WPT8B+dlp=OC%;ua(nJxu zrcIs%^MyF;>Eq9yWYiWpZGFC5w*&<8m5d=giEB0^9qf~gtK=lN6rvRmG*VJ*Kb zuX2GJYxhSWaFshb-bPeUY_U65P;TB(TG=ujP(PGhyIbU7gupFGmo8XX^mRdM&(ytc z^n?mbJ*gVXNRf72wpS2Jq>Y|mPhNavW%=qUtvdv`G;fG>otA^PkMS-ZVqSVIgN&e% z$kYVw^yQu5(I}CU(FB+V)V~;~1hzyFY{~VqN}n-fx6(bPxErF1ei-!73N*;d-Ro8> zG;R%~Ex1FlW$=MPu0iOC{G>FMZd78-z2L3r`93GdX)y0D16`xBxDJ4dbhAvEftH6> zXK7u<`#n~47(+{{6$s4CsPQc3kTY|sF$j6vx+3i8d=A>I-!oa7q{`X5Ao|BT4BX)O zeG}EEasf>RGqUhbs&c(JTUCmkp&R35$2i>?%6xtHm5N1nG*#MvZzhThHr03;YPxBwdQL#0uJYXUxWsM5d@A7|#jp_1)E zP%40t9JM|>-nE~!OU^9bqY+BWF6OveLrRJ>)z6TN1IKL6QPRLl`gbVdTXUXB2JVc5 zo3;SZ^EK3?DhG|!8}ZVQ9|BU0J^Ll6pYjKecNm#I)pa|&S!pYkw)-xCdT1skFX_c% za6)Yw9}-FQ?at!X0UiQ*BaQa=0tR4wORU<_am!Lf?C*s^`B{4=BS$nv?P!320|RFO zecQ0vf^}zPO`(IN5;gW0%9Bm-&lhV(g#gTp?QF5dmhbfggr-6dMQ$#y4AU*`J#;Ip zaZy95R&+P@h=`61$at>&oJq%+mg+YxL<=$sx6n2A-Ir^PyrH$UaVH9tHxg{%m+se) z-F)6d1p1>5moL{RhtgXXvMU-GRVvyg$f>Dhr^AECd+CnGo1oP!TJ-o+~kMCLyNmS?iImYo$$LB8FJl?+=aJcyl zba21rb={5*F5RK^6=V@v`k4ZqmlYz;bgqjhp_CF~l*S0R){e$bfG*D@x;&*f^q`;U zHia)ridKO_cz;qWR#M3djm!1!M=uwKgCRIl#`%W58a|qD>&|`dhdhn&u|KF&UC6O) z4p8@z4|@9gK+T74y0^@oda`c&155X#Bag}N^&fD3333GkF3p7MV>|GtMz!xY36*CD z*|0Ttai~v}mH5h1q!O7nw4`hHZX1TQSf3A{dP5p~$v*>nO19G0-^ule6gPD+2?AA6 zp3mN;4FR$E3FpI&{P;bsF74jamn<~2lVTfp#+qp?nIAQ7T=`h;TuzDC)ZSL_&VJks zLp@iS7x}q3qBR5>*ws=8$#G_tR#refS#Q|2)*!fi8M@Y=kIfA$ktTUAn4$D`^(cAHhcznhKSeA*JfVKE^2 z28Gng3hv`C@SD~n^NE;fsJ4=Eu|Niw?)dH`^Zl}*QZ~6VS!mS!y$&{hh565f4NUn} zjq$5Xf%~6X?vDznSaG6(iXf54gLosR+0`c+g=`rdGj^JPFDQwIvh{nh-zMh!7L7i! zJh~a^YBP0HqmK^&7QSKMYBHMYX$bFcqmC4ICX}$GkYbg}ZELw+9gSiG!{&_mOr&Bz zL`IBmG^n7B#vMcfP5R;B<&sM)NU|bQ_|=wM$#yLP$~7@{{u^cCfEY%))~4Id%J_PZ zQ=a`E?|>;U*1TABS5-kv%@9j)I{Xslj8bLoylhN{OO*Lf>_p62Hp!^ z?9ZizFi|kG`~KF`D5SalijR&Bp@dq3gj%_j(ecNS*qRO|9EhNE#YwEen4yMgF_l)Y zK!KJ+Fv;+bi`-3UN}RV_>%wix^&_5iXBw0F{W&cBZ#&5Y0F1vZh386pe(FQ&O|+Nk z!tf?!!*iO+lbRF&{lx#vaIj|1cYRs@Kx;c z(IkL0-(k9^=$Et~QE)~Ch_ix{47px^98mv~GKu#<;DRyy#?RZ;_`e-Ul_r=3?+Z4T zrGdmDd4HbC`kT|GL5*rTmDZr?2B00Gjo2pR%|N}cbqWu@mbKW+6?ea+k!N*5yDBJM zVCAP9gAJjM6QPb-`4cyJ^UD(%gT&yS08q4L*)9Q?lt>FCDQ>TfO{YwUoJ#($a=D6c z^TAk5$nhT%w*w`h4$|C)1&?#>E>AKx{RX)IXG#e>1lo@x((}ciYBnYpLj)us2>dpT zSsTf9oo$fZOjAcEhbUmSXXVmlJoD?e0G&|fSorzlbK_~rN>Q_?AJlUILDysETgsIk zQN?J&GhooL)j@7Jq1^ABZGU6PnscBcOu!}EB;tIc!nXP48ff+092>bX_cp5Jyw|Ta zgL5_KlP>O{Tip+vmZ;uh^j~ZNHA<7WkxH-N1uR~CRbVS1oHnDfGR!|jv0|1QWRDUu z5TZ0<8JC5+!Mr3JVk*|n`^66bG*FvrW;^_w+|DHF_!wTyHt@Gdb2uVJU>ll`)_IzS(laa=@t7Q?U?^7s?VfjNw*V$b7y_~mVlfYY z^t=|pfRSAXjsR1iJ3IlBqg)^vDO*EEXsc-g^J*?6^D^_LJdM{eikIrirYpyH&Q^B` zjdU7{T(qbA{pwy784gkn38tAU+<7Tg?F0v7FQcJ?!)-(py$$YZ`!6}y9%zoCneWZB z-8lH=+HEnyT1Q4_JSM(M{LpLoe>AAGLtT?#8ff12>NK86J`6D5R;pz8FYEL}bmeabTuz%K}smTx&2m_tlmZ#9MYXOe2{eyuQNnvQ+5^{7VA) z-(i%}E^RlodKkWDFWETiHr_=S)KREhTrfZ_R+P#S0QI7lqIkPDngfrvhd@iwbdUve zF&zb*H2VgtP2j_Vi^ei*{20b*JY}cLiA)q!T6EK(k7-s?L0`Z%{>hOwctO@!%-RrC zj#UW5JX`s8Wb_mc5}`;11cXE;NA|AteIMuG?W7tvCh$<=p#zj}UgH-~vSUV0xx!n% zmp(u3qSfOjp9NZpwr92+7+)|UOxI=>0=1rOu&SIsc#R3UqH(JTL5Wutd8@vj{daLC zH~|6haFo;#U~iK6ypZ)PX+@jmsi$3_s#Dai43nA<5;q0A2~LoB9i`p9oz^ErxtE>s z&^MG3SRx>SfO@8^H+g&~ph;MC00Uum z1R6_4Q(&5VRT8KPyKgakD#OtJB@%}Bld)ro_*E#f??3MscpW?2;2p!GleR?H0O0Po zfU&noqJ%lYr9tDQ0nrt8+uG7Vo&w&es+Me7dj|;?##4^Zh#+GOOQ)qGm0?mw7aZN) zGC=Ebk z-cHR5_3)4e%Idp_d8AdV8sZeF7Vd&Gf2DG8d#c6>1EygIsGpaZROL`g&D`p3@YK`X zp?X5Z<;?zz_@Qq$q55B2LQr2p4`y^O{G8^V(AD6x-JU3wI=w8#JC?aXfu!dJ03|5v z&z~RG-5F!qjh~}$Bh{Et)`IB|>w4u;(gZNLoYvk2?{Qiug@A*;8=Q-)TpC2vO2w{P ze*m*XUb{U*F?>qE&<;56@5I_uQ3KZyag-8m|9Joa=PR!K6twq!2*}!Kb<$zNSOD~U z6jy5}KJRcAc9RE4igWxx>^7LQsp;12#;o?_i-Q zy`8wqYgqW{^nBBTxb9cLBNVr2EZxzdbq>D6>IejxF-3zTB~m{iPqfj2`591PFgVYq z*XZyW1ergnOri5ree6ozANl$ZF6ysyXU&Ups3=uZ>He5t>WISjl+RAtqC~D1`vw9D~o1I~3Q0I)T0wUW8(ke(}U0_$FAI9z1o9>YoSx9j3qc&S195ky_f8a1DCo z4vByjp>#UKfxx>$a|VVrMVAz06rE~?E2?C*+-_zIh0Y&X)lu5mLx5pHbU5nsJ^GOX zJ+`WDMyC|e1Ev6}zz;Aoo5I_3%S3l_f}Q~SId*E$2lsGK0J!#_zd~gOJ39bKLm3l_ z0MhZ_7Xf1%rv^k3rbKU%ZcpU`u#H@qd2?`c7CV0B{JO-!CHg z_lqeYJMgq$|La`rk!U zQ-ifA$7&h;&lZ5+^S>MTzZ>|Ud-A_0@c-uu|GmKL1^>Zo<&gGoJn%
**Possible values:** `1000` - `86400000`
**Default value:** `30000` (30 seconds) -| `fadeSpeed` | Speed of the update animation. (Milliseconds)

**Possible values:**`0` - `5000`
**Default value:** `4000` (4 seconds) -| `compliments` | The list of compliments.

**Possible values:** An object with four arrays: `morning`, `afternoon`, `evening` and `anytime`. See _compliment configuration_ below.
**Default value:** See _compliment configuration_ below. -| `remoteFile` | External file from which to load the compliments

**Possible values:** Path or URL (starting with `http://` or `https://`) to a JSON file containing compliments, configured as per the value of the _compliments configuration_ (see below). An object with four arrays: `morning`, `afternoon`, `evening` and `anytime`. - `compliments.json`
**Default value:** `null` (Do not load from file) -| `classes` | Override the CSS classes of the div showing the compliments

**Default value:** `thin xlarge bright` -| `morningStartTime` | Time in hours (in 24 format), after which the mode of "morning" will begin
**Possible values:** `0` - `24`

**Default value:** `3` -| `morningEndTime` | Time in hours (in 24 format), after which the mode of "morning" will end
**Possible values:** `0` - `24`

**Default value:** `12` -| `afternoonStartTime` | Time in hours (in 24 format), after which the mode "afternoon" will begin
**Possible values:** `0` - `24`

**Default value:** `12` -| `afternoonEndTime` | Time in hours (in 24 format), after which the mode "afternoon" will end
**Possible values:** `0` - `24`

**Default value:** `17` - -All the rest of the time that does not fall into the morningStartTime-morningEndTime and afternoonStartTime-afternoonEndTime ranges is considered "evening". - -### Compliment configuration - -The `compliments` property contains an object with four arrays: morning, afternoon, evening and anytime. Based on the time of the day, the compliments will be picked out of one of these arrays. The arrays contain one or multiple compliments. - - -If use the currentweather is possible use a actual weather for set compliments. The availables properties are: -- `day_sunny` -- `day_cloudy` -- `cloudy` -- `cloudy_windy` -- `showers` -- `rain` -- `thunderstorm` -- `snow` -- `fog` -- `night_clear` -- `night_cloudy` -- `night_showers` -- `night_rain` -- `night_thunderstorm` -- `night_snow` -- `night_alt_cloudy_windy` - -#### Example use with currentweather module -````javascript -config: { - compliments: { - day_sunny: [ - "Today is a sunny day", - "It's a beautiful day" - ], - snow: [ - "Snowball battle!" - ], - rain: [ - "Don't forget your umbrella" - ] - } -} -```` - - -#### Default value: -````javascript -config: { - compliments: { - anytime: [ - "Hey there sexy!" - ], - morning: [ - "Good morning, handsome!", - "Enjoy your day!", - "How was your sleep?" - ], - afternoon: [ - "Hello, beauty!", - "You look sexy!", - "Looking good today!" - ], - evening: [ - "Wow, you look hot!", - "You look nice!", - "Hi, sexy!" - ] - } -} -```` - -#### Multi-line compliments: -Use `\n` to split compliment text into multiple lines, e.g. `First line.\nSecond line.` will be shown as: -``` -First line. -Second line. -``` - -### External Compliment File -You may specify an external file that contains the three compliment arrays. This is particularly useful if you have a -large number of compliments and do not wish to crowd your `config.js` file with a large array of compliments. -Adding the `remoteFile` variable will override an array you specify in the configuration file. - -This file must be straight JSON. Note that the array names need quotes -around them ("morning", "afternoon", "evening", "snow", "rain", etc.). -#### Example compliments.json file: -````json -{ - "anytime" : [ - "Hey there sexy!" - ], - "morning" : [ - "Good morning, sunshine!", - "Who needs coffee when you have your smile?", - "Go get 'em, Tiger!" - ], - "afternoon" : [ - "Hitting your stride!", - "You are making a difference!", - "You're more fun than bubble wrap!" - ], - "evening" : [ - "You made someone smile today, I know it.", - "You are making a difference.", - "The day was better for your efforts." - ] -} -```` - +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/compliments.html). \ No newline at end of file diff --git a/modules/default/compliments/compliments_screenshot.png b/modules/default/compliments/compliments_screenshot.png deleted file mode 100644 index 12def320906445430b066a3a8186aa72013e6d74..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 26157 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 TT!qb982Hmx*H^1laftp8dqkjJ diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md index 0ce7d59a..3cbdcbea 100644 --- a/modules/default/currentweather/README.md +++ b/modules/default/currentweather/README.md @@ -2,88 +2,4 @@ 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 -![Current Weather Screenshot](weather_screenshot.png) - -## Using the module - -To use this module, add it to the modules array in the `config/config.js` file: -````javascript -modules: [ - { - module: "currentweather", - position: "top_right", // This can be any of the regions. - // Best results in left or right regions. - config: { - // See 'Configuration options' for more information. - location: "Amsterdam,Netherlands", - locationID: "", //Location ID from http://bulk.openweathermap.org/sample/city.list.json.gz - appid: "abcde12345abcde12345abcde12345ab" //openweathermap.org API key. - } - } -] -```` - -## Configuration options - -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](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` -| `degreeLabel` | Show the degree label for your chosen units (Metric = C, Imperial = F, Kelvins = 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` -| `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` -| `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. - -#### Default Icon Table -````javascript -iconTable: { - '01d': 'wi-day-sunny', - '02d': 'wi-day-cloudy', - '03d': 'wi-cloudy', - '04d': 'wi-cloudy-windy', - '09d': 'wi-showers', - '10d': 'wi-rain', - '11d': 'wi-thunderstorm', - '13d': 'wi-snow', - '50d': 'wi-fog', - '01n': 'wi-night-clear', - '02n': 'wi-night-cloudy', - '03n': 'wi-night-cloudy', - '04n': 'wi-night-cloudy', - '09n': 'wi-night-showers', - '10n': 'wi-night-rain', - '11n': 'wi-night-thunderstorm', - '13n': 'wi-night-snow', - '50n': 'wi-night-alt-cloudy-windy' -} -```` +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/currentweather.html). \ No newline at end of file diff --git a/modules/default/currentweather/weather_screenshot.png b/modules/default/currentweather/weather_screenshot.png deleted file mode 100644 index 2f6e5257928e5750cd88e0396095ab779051725f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 38566 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
Wj}2#TxQ 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 diff --git a/modules/default/helloworld/README.md b/modules/default/helloworld/README.md index d86fce3d..aa9f87f3 100644 --- a/modules/default/helloworld/README.md +++ b/modules/default/helloworld/README.md @@ -1,25 +1,4 @@ # Module: Hello World The `helloworld` module is one of the default modules of the MagicMirror. It is a simple way to display a static text on the mirror. -## Using the module -To use this module, add it to the modules array in the `config/config.js` file: -````javascript -modules: [ - { - module: "helloworld", - position: "bottom_bar", // This can be any of the regions. - config: { - // See 'Configuration options' for more information. - text: "Hello world!" - } - } -] -```` - -## Configuration options - -The following properties can be configured: - -| Option | Description -| ------ | ----------- -| `text` | The text to display.

**Example:** `'Hello world!'`
**Default value:** `'Hello world!'` +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). \ No newline at end of file diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md index c6c630e1..4dc4877b 100644 --- a/modules/default/newsfeed/README.md +++ b/modules/default/newsfeed/README.md @@ -2,106 +2,4 @@ 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 -![NYT News Feed Screenshot](newsfeed_screenshot.png) - -## Using the module - -### Configuration -To use this module, add it to the modules array in the `config/config.js` file: -````javascript -modules: [ - { - module: "newsfeed", - position: "bottom_bar", // This can be any of the regions. Best results in center regions. - config: { - // The config property is optional. - // If no config is set, an example calendar is shown. - // See 'Configuration options' for more information. - - feeds: [ - { - title: "New York Times", - url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml", - }, - { - title: "BBC", - url: "http://feeds.bbci.co.uk/news/video_and_audio/news_front_page/rss.xml?edition=uk", - }, - ] - } - } -] -```` - -### Notifications -#### Interacting with the module -MagicMirror's [notification mechanism](https://github.com/MichMich/MagicMirror/tree/master/modules#thissendnotificationnotification-payload) allows to send notifications to the `newsfeed` module. The following notifications are supported: - -| Notification Identifier | Description -| ----------------------- | ----------- -| `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`.

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. - -#### Example -The following example shows how the next news article title can be displayed on the MagicMirror. -````javascript -this.sendNotification('ARTICLE_NEXT'); -```` - -#### `newsfeed` specific notification emitting modules -The third party [MMM-Gestures](https://github.com/thobach/MMM-Gestures) module supports above notifications when moving your hand up, down, left or right in front of a gesture sensor attached to the MagicMirror. See module's readme for more details. - -## Configuration options - -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" }]`
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: - -| Option | Description -| ---------- | ----------- -| `title` | The name of the feed source to be displayed above the news items.

This property is optional. -| `url` | The url of the feed used for the headlines.

**Example:** `'http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml'` -| `encoding` | The encoding of the news feed.

This property is optional.
**Possible values:**`'UTF-8'`, `'ISO-8859-1'`, etc ...
**Default value:** `'UTF-8'` +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). \ No newline at end of file diff --git a/modules/default/newsfeed/newsfeed_screenshot.png b/modules/default/newsfeed/newsfeed_screenshot.png deleted file mode 100644 index f4391e7d2f70e810946a38a518c05467820dc157..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 45375 zcmeFYWmr|+_CAb)w9+NgTS8j8yQD)>TDp7F(jC&0(%s!1f^>IDcW#<@apKW)e&<~0 z>-*vFwSnc@D`t#2#y#$F&mcJ&v6qOi5uu=%%L}(#Kff_; zC3891!a-dahpQ%snLo{zi+(;bUpWk9Emj66WA^n0^FBSXo(i@?BrH49ad zPs#OOPwpt14%tx1zgleF*Lk0PLp6rt8#dE6QA&F}Z1*chv5W*sOGVOwU%#MAeh6P9CyAG14ZHnO=D6um%SZ#vK^3^pKaaoZ6KkTs$*gMsX_qDB zteg6rgv&OP>=ec(y}x`0lTHjRiSCzF3p14-r3@h-gZMWbn{<=7sMfuF1p>!lNkxR`6$Q0Q0 z=W4i};3c>2K$>G1+gI>#v&Xekj31b}HJ*c!Svt}Tw>nfSb)zBoS^5PiJAndS{Cbp( z3C2Eq>%4V1gwIMn$~aaJ>w4urE$<`9!V~xg_?r33bQI@z2>w9%%G3@XLC{Ag{7H9k zyKgPIJ^2EqtvTIu8{cT_A#eRY9O?$*7iVl}jN(sl%A)+;nhEb_i@icj>r zVd3WceG#qvBeV2SYKuDcqSaKQGaYvoKEkGeN8=#co=bhBvh^8`q8DZ`Qu~xszM5UH z2Ashb+{#5^>9cy6C!YoQI?^`Rk%y>C6DQKA(&tytbcp)ahx?*iX^KqNzM<>-6G!Zz zIGOQA)2@XRcH7%p`!?pe9jRE-THyxs5a=d9<_z$_ei1`ZGISfaSs}FFMu0kZTDCVV zU9Hf5)wb$bA{A9Sv3iOmaFUks^85?hLSvDxs7xCc_!%E6Ob0(^AoLF%#G*>55=DfB zSB5?>zT?JtZ|Jb7qOkf{=upf+UwVm-JP-F7UwLi}H{C{1r`*tnG=j9`<|31-cGvkFZS_7tLh;n-4DC{}A%d=*G#|-)r zUSypDTxh2DeMYBHKM`FjRZjBuO})3OFO>Zzbq9|nwA(q$3HQllx^~zxY6JFIFe7^F z!F0Sh^qte|Tqm%1AdeTGUm$DR2+ZEk+QU~QbTFde@qBlD^#ot&!mSdoV!Amsz#jz) zllmBo*!vu5y=RPO4^b6e5HF%2By&V1Lc0|QMG^i8|0NwvY9sEPr8mYoW;rH5W}twx z;}cvETpk?#q3lC&uz0pywxB_LKU(a-JK2vnKVE-Es-WNq{z*0rq9?PWV2h^z+SqrG zDIJW}orEs-Ba7yHQTBwqjQpX(QeHtpVu4GZj2u?MkcwtugUUtGF7#xC5^Vu(tVoJ* ztbDveVSaC3ZJw1ebK={hMY{RzV=Kl#C-WxQvuuPiWur@W^6;|1Wvb=WOP(cfGSNoG zWh+Nw%NB~8B~2j|i`j=-iW-g9pZlF3oGYHwS!C42vTATCHY&MBI3_ukhQ|%5rog1& zamI26IB??Oc1E=uerAeeyksn4;tgYXv&!eqr}rbU0WDsvX__E^FLz*?cC>i9Ip48P51Pu%ZjU- zKL^a!&mkPJ&N+mVhMwZSef^PT*Pmx{X_t6W*#-HUQ<+CT%(Zv|k`C~f;OoJRV&Z&0MXNBdC`q%nwVa+>&PIyNZ zec6*6A%#hWUDZR?^MebtlNLVnFP$tP#*p`rNY+Q6z^cn0dEKH&*-ffRE6Khdx3u~)D$-bgU{dC`v;}NWM zwi$nOx<>y+{7r0Div7>*EZnSa?pK}g^Y9YFXJC7`nXB0KBT;qXU{d@{eoQV?gNbJ2 z!tI4^K5|qFVcERoV^9yHq2teQsxJEzGn(Z`YtPr>x)+0L!{fVa$@3_rKIBP&({K}1 zQ)j+0lbgtl`F+0stZS=?NcEP)K{PZcKXkn1$_livsG^d^_xP+Gqc-62m8TE#qx9z^1CQ>_170GNFcaNSRZ9Km z&2jG)?`6Z)%DPH*qoki&47crX9yv6&NbSZqYlfJTRG3T6Jo@fZkSLKVu>_Odt-{2nB=cOcT({kTD*g1MRr(w`PNs`TTj&#A+ z&a7|B|J^`Autk@}^?a(i?2N}I8)Vtkar=mJ@g!SaX|bNkaO=nG+QdXn*v7cYjOvQH z!^LRF+9QO8aU~<|+Uit!?FO9v*aPl<4JkyI$kePwTwlx z9qCTjWHg3MO$s8P!=?T44u;X)@Ee{z_nM95t$LxY#bGur>*f*b(T%lsKFtU2na#N= z>mLUSij88fcD;4sWby9wM6KxHjq{I}lStE~r4FAWT0PEsvhY*boY~SA`&%w{9Ul%J zxXzBy591cb>r`x(S3D+L%^yB4@60)039R^ppy(4VId{3Aua%#lY?WkCR8e5bhNVq$ z+qq1Q5iBe|xUHR);H=@?^K^TfJXEh{UkpHd-rl>Hv*p+B#r~RX+pA!6u_{;&cb}ib zS#)~T9BO=kyd^s4-M`y@IQf~|B`bTI>q+jeb=$ouc{Y7q>I7#C3)}SuLF|O;OS^wg zF7$E3Ybf>icaFwzU*5|*vns-8aLc}fzoSr2UB+BP$8|k8^Up!ug5^{fM6}IW(Ng@{r2hSnS=reIQcBqL`l_NRa%Nu z-^zkc_p_Cr0Ug-F8n_w?iW|%c99kII>k@-4%q{IW!91jYyMhxqemYH0O8mD=?9F&c zRi)*Kg{*81h*{{E=@>|P5s8V3xotliaw-Um{^NGwe>|kd_V(7C^z=?nPIOL8bXK-T z^o$%F9P|wD>EFMn1+JjAbGEeC1=CvEk^TK4|9pK{)a4YxISxz|DZcjV((nEAD3Rd+=D|yefD2IUPI(%!WX9?kb@)M-mWk| z%>Vch<2*xzc@t$qB=jc(Kt)UKnq{Pqv$0su6i*MGa8T+Vz^yBZn`H#Qt zd4U$BX!kS-{_iIAiSP?5(3x{e{I72D!*HenEf}KL*G&K4P54DhOhSdjngaS?-6DRT zA`7%&E55u$?teGI7A-O|1}RAf{f|NX&lBf0L_tiFe>R}1LixX&P!BII-tQ+(5%f0; z`Hy4zkCXgc7?F_^*9Jw@nE$&8pI|_sjgFk?|6wqIMSVX*5EtLQdq0I0{J)z(2N;d5 z?zqJNFc`q1My`PtIC$XgA&UGzv;BW&`~O3;m3!qy@4h2xxgN&mD9e4~+jx7}I3S^v zAIJ~;9N(hq>%2wn;sU-^(<-@iV$3Qs0qMUk=8)(&f#9jk0x+WOFt#Ac->v{kd--Wh=6G(b}ss!?V9HHpbc zrZc{*|6O6-#gxWy8k^Y^4dk%#i1m$Fp)94kxVm1@+l9WbWExQi@!B4<&A>&~b#dyZ zRJEP2xUP;M3w9B=SL+dGw^gG|FmW1|9BlU6a%orlvz3cnM@`XOWWc)391r@dsZR$Z z%1=G`XhT)`*J<}Ks8mXL1mAqc+yiGovgIg~Oo*xgXl4*-@l|^?DYv zh_H(@%Y3PHPk;S*wJMlygs@+?9&Xtch{lV-wgk>}-N}x(H4+z8u(aot{}+!u7Yz9S zns;;t%Ktq5y%Y`JFRMEQ$JHhitu(xa97NlCcY4@I7GV$W;65J_I`o1g?E7SJyui5@ zNcM)1b38}dj>%}~r<>(hIBZ&wO|yPas6?}GyAPZzU1{^BdOILr?NT#<{^1RQu4`1<|%LRbNBO{eO@F+$8CBhkt0j_bbd?Lo^pQpWe zg@`eu>WqESV4{lBOA#cj86!d<%bv@wZw;`P_PKLz64`As(qtH@w@4$X)y4axAf+A` zg_gh|II=C;N4uVM<5VUqaKWBkh+IdtV%JqWage?8gw0aT(ge@Y#k2)A*KG>wDcvNvKl3UH)6R za1-Shj57Tv)B$4FxgPNH)j_Y^pKV^y1mgjV4%3?7Y!`9-Ky3+EQ4YnKw6zOk7Jwyt zNN0!8x6Bw^==CeXOA~&c_9pgcn8HZMi^xjtD;?XHS!shtu{SHOj)T0LH_1%_;)+<7 z_P<3obRdp?fXYn!9c{j|p)!!{(0g8oGy-OO=fafcag*P8cRH}x;fJ(mSYC=KL0#HZ z!F6}s*^Dz?T)VWJ>iKXjtX!1q%Z9EcF`g^y6v2CAyjIRrE+nWRD|b}H9Dt0s=D6(c z1lcVtZ7?fso|<-Y2019>?V0{dYrcyEwh)|ESocR`B%Y^7+W&YPUpJa5)|f67aN}UA zTAHKPM+Pcx*ezJH^V%t0a@nJW^x#|7IW4=hF;c-K7{sadxL>UXggXR{b$p;M{xv<& z-uRA|8Qn;M8|YKgym4mOLX-2^!bcU&So?%|08bJSz9w=z_R>}i+JWBl^SHmMXPN#q zUR*P0`s!=MPRFihbhpX0sLLJN%IWp6=aMXkfB9qev{q%O+0w@g?x=*DNHDxwe?}a? ze^?WtgcNU81hC^Hd^!R~?65APjt*v-ZP|_Kg3uK7AR6I!q8mW4 zd2LN(%}1P!O$D+!00y;Yop<%&`^z7dqSywFz*4;8o5Nm9m)0v7cJZ>SpU#6bIlwvb zg~)v3c?p?!IG%6VE7_ZenhV`Zbsd^+t#gZ2qd@J+_pFjW-g4<du>W~9LfD12%IFGyBfZV&C441dBq87%cAaC+Q*;pIHIJ*9E0eOzAq??b9_-xyDn@7nxR=&>%f^F+ zJo(Hw{vSJ#=$lq7Tdp_fs2tsRNDvs2<&jsR+lfPZ)oH(S;ye3+cBwO7tjc=cD6$E0 ziEaqJ;^>+#1a2CkZQQTWV#ntOTi3oJ0m;KjTYKY-qlM!#cHmcbV&vt5Gu{Ttu9kOI z0^x^!w>4Iv?lC_%)wU?<<1l=Lal1P|x8ZROn88ia1BLsTpAFVgN+>RdxjSk$7*1mGCi>zF$`IWD75zrh$+vo07l?mwPcrUGuP#ezPkbt zYvhZ=)#l(6#faRi9$lu?jGVt(NAO%)!>3{c0s5C8-R+Rktb^W6nQqHVibZ37xdzCR z>tZs8T}ESryDYVsFx4DKD#Go4Wdx3mRsBZX1h~F5&nL;eLZa3+^yW+Nc9qGvLO11{ zR)U?CL33@RW`f6`@V-wPNEQAyE(KGdVnvDD064)R$*QHEOU#xhsu^FXu-+aS0;0 z4%x*LRkWP5iK+>C$oC*TkcDvz06YW{euBrwr8uE%`(jQgXmb+nDNG>D9XbnkTrtrj z{1mz*#=!sP1CwnMLl@&4SvB;PF!2t`d+V1pT)fia?=v}0R`V~%BoHL`h>dIM?$HwiaLP8#zAV8jgPXfz< zULYUFJaX<8tw-c?pSX~$_zBD{5Z%E}gNCvD2?dZN7{=a8`*NRpeg82h408(Z#!`tP zCnt$~W7CDEW$Z%_VNHi83383SwE&z3WQTaornGGoCO%JmmkHy#_oT}Q9zn9-_cXi6 z*bFrbq0(^B)@i{;EaOTCB3$SP;ugx!{S|O0KQw_hS0&d(+bE-|0f%4MTQzHqTwgx) z+CoBMr2%ZIn)3G5p~x<;H zOF%E~w0Am}dhW^R8Jk{$<}zOulyQ?M1h<6r+;R2X4!1GC6rLTosI-1Fv1?BZwJjm+ zO8{DuNlnKWF=RsH1+y56jn_D;p78W<`q498s#1YC=@Nb;%l!!-VuAMzrIX%m6>0IX zRvAgcT8Mq^p(iBrmJ3-#@z$b!v*P447tNbJ~C@*4cvlc~0ddTRJ z1HIpL+Ig`?-qK2oSFmE26Ut`f^-1GP&wrRDBPE$284-cD5ZeCg%b)iruOUYW@Ddy4 z${&7XrV$1&c9I}*26#QyUa0U@T9dhA7eVw4Oi=^g@tpon>tP!(yAJZ_cNq-(waXq_ zFm1=UETr=`Qf2|=sO`{XjMw2vU{S_NRcu-By0gsI*>g!*zWXYOPT4&;eZTebVF}j- zKya=R#Pc}!%=(n1_@w+%bq4;o%szPt5?Nong}TEdFrpaNNE_toOa#TwU0&Y0AN0nV{0$JL6@J)H&)rOO+ClU-Uu9NekvP$clD6`KGX*R`&o#T*`_ zToFkOg_BUB6;f1`R6G$_Fm9~MZo_W6m0 z1BIZZ-eEMQ9*eK@c8$M#w}9p>FNki#B(l67!8c@RPFX24k~3B_wLa`IhX@NJmB!06 zWftXzf#dW1_%dTK6luY80i#Pq96d_v%ht91#iR;F@J5w>V1txN0(nO?z2Ml{(9s0n z?`4GQB?y4DcQA#dSbwcIuPIdE0St(QF5BrI{ggQh`u1+0@+d%zENFW_n@;#Ce!n* z?eOblunzb^R^|-w`nWQPhRD+B=pAPaWfgIV9iO5ECVWYTd^q;Uy$Of_FAnX6R0BRk z#c`$~jUfS%$jrUwwV7@^cbss3zVs6Qt8$!8Z_-sf$TG3aD_~p*g$ENy2g2?E`0|uM@}T1>@h2r>o2yTNMrXN`>PiEt zi+Rc&W6z^}L5*-HrX7m!XlK-2O-SA5uIDKJfGlz}fT?$%e%$}V)G@t4fT<65dgTWn zTL@%g;>aCHzd+92H1L(jM>DxPUJW8!qLmHR zF={AMhQWAlj>y%Bjhv19h(oWHoPaz|RUW4h)z0ZcswlqtQDCXw- zUQE@t2M*6ER=tF`(k*ihH4Bnq!6sC(a?K25wSB_Ld^CgjA>9MFQX;Q<|;pCIsq?7#krTA%tm?e=6rVvu0t8%5n@TPkL zuB)~rqHqn@lB=Uv>uu(hBi4LD)K>j)tC6>4w7!CR%{9cdga>~H6H0#|nCR8LQ~tdQ zj1itO-Mz)jmnKFK@n=|NCP64AM?UjKqN^jGZ1mAT#$*Tbui5h+h+Lh{GT^hfa#b3R zJCGU?m;wo<#JcT2;u@St1)gcW_o3CBOe@$U%MJ^K;QhE77CorMM)B9n8S1=BWPZ;V zioMPzI!dF3p4^+rB{lAg=GozkpsVCD@0(ubkkJvne^nN0fye{%yr~mNJc^HF;;evd zUDupu}!cMmg!iPjct z>NHdBN;4-wjl3hF3YTOajKqMvfQaGNQJ_UvfJV+ahuOX0rn1Bz`arnvD3zm&K8{!(4z3qXpryKM|l7x%wZVjdEO`9XGTRA4N z*d4>_x>U$#ieBF_@TfOeo1*q5h|-x9rx>?LA+I}ezeVlt(CHY_kKoxnY=$gZtL)bh zSP71m>2@xZOm-ilX+J^mhSbmHUsK8ab&>+Rf*QvsSQfyDZNolX2%wNvI?e;7g$+DxzgL ze>`H=ipB&DnkYK>pOjlDzUV>F6G4!GUjTbeAvNdAsA}yYNc0lA7HM0(Y$qzsb|H}# z&j?%exIMsE-y521sG|byZHV0dPF49~g5LrotJ)H*`A@QiA10Ah2lj}07$GN4FF3z$ zr)A6+bk?uK6Y8Q!IxAvcJ*liE9*pm0xo0Ij{pLMN%80R5hKxNY4RQo7ab=N)zH|SL z39KU*?+{u4<*d=RT4c9b$QeVzI+fQK|2mut?DzU6gurA~AG7L?UX$X^I*9SPCPl_{ zbI}0s)#~k3Tmgl6yLWZz@pG~+1cd!%&&T^_xgU)5O~>B1XK9c7OKxYz=JrKf;_E}9%m<{ zh4Cm(g`+E~W3KLhG7T4TT_mPhrD{xTdp5gn#H#EYJ$_RWPh>HRgIuZGbYr=5+jQv0 z`>J1MkNbi&_^41wr<4$L9je$FX2^Wk7!9BKTy>)G?PJrZ>hNLRn5_M{yFR;bP?HF{ z5G6sN7n%BD@@vT`SgOff)%B$=3vy4!q#39iAxO7j)p6G0dBgw!40~PzWKT$%u2#o^ zG5%o7NHqGee9p6C9ALt^B~KW_sFSk5Y_p#+YJnBwYDJl9fcQJi5I=7Y0Q}vOB6fe! z@6oa+14e5Nq`_pg)a2}e$QnWk05_^JhF~^MES&Ko-J(~}v zEklZb5eY@53K(DXZep{WL+gIP}w1>;=-oFC%+=9~~Y3Jn$do{nS zXmcn=6lz{R4$RyU%{U|*LBe&vJm4u)77~o&IWk@cfzbleil?n#?fY`yIq>+iK0onR8vYR z^MV1RF-q?!%JOWi`Ce7ALEx}1m#`sCOCh>vK8c{B0I1fvZA*8YzYrk6 zQVIZcnG0%56!u>yywQgurT?I6@}`9>IeTfq8i9McFBF(?*P8@ z-0ZEU?T@#qR$v7!5`-h~!jgvm5HWb0Ku6phqv6y8a@o{31yL_Dm^Egnk>A@OMmL;6Ah$3I7g@#6(`AzM!rb zq2*89W@UANRFQ5Br>Ab&g(qtA5HBDlRXMb1qQ6|QlQrtmmjA8A>)3hU_sHZQEf2Y@loFco*p@tok70-TO&(UsR1$bHlx#uVc50yR~;K^6kD z4#&Zr_|x_YiG({na(JsjPUTh6cz$ zv-a+4-LI$U1y^(}(Cb8f@Fa;`0gWh7E)jKdy0z>T^8>wFaGbZeXLb^iwV5^%9Q!Wd z^Jct}_EX)6>yd+xRvXHK)r6Dqo2IklvAz5e{Auy`^o%(Mot>1D-|xN6lDE===A@>3 z&m&CIDSSbv zG3eV}rWM%iIRC88e$RfY2Vv%t{zkA~Q|QJ@;-nYQuh`p4*?i^7fdUl>QR0p3`KTC| z=zQ&%wbOQb0B2LmF?t(AU&awoo8tK4fP`Chd$G60L(&sLbTkd6cTc@sufF=q^4V{8@3Qd?JWC(5U}%R?pD-WZRHE!;18)0Pf6{5doTd zOBWP&CQhod`J(NHD|ENFY{|T=no-N`M1)>%FoCfXe|CM1Mg9dnOiqRiFqDhuJLBuG zEPhxy`(}AT!*NdOdA$tPiN!>9MBO?r`tW+vYI*^YB*;x}3H%n5qgxX|9M)Xh-vN7p z?kQgGekf|6+NpnhxFt}u&3?f&G5=c6q!+uslnqfL&;}j@946L2V41*jR<{F`&)?xB3AQ+d4S?>zVc@? zNKBY+_4FhnI(YS*OVE}1iQ%wJahUpHAE7oM3Wo=cqJBaXyeYQ)=W;s*6bmtFDMP=9 z&#MFB7g|&w=J-70V2U4zgo=4-ipf%cWf4f{-U`9z1XQi(3 z^r~}8Jc}r$t(oa?JroJs+w{5|;yMCDgU4<-a8FMf)_H>qx1^rcFFMX&)955b|}XRl-bQb;Bq3-5ScX5*%$e8|HV*T1oMg-n<s19S4yR84iEP>O0bTB zr^h-c_JjIa;OL3e;AdFD@R#EhCkr2(bu|&1MkjgQwUNJMl|l)!8Px9$cK`_d5;hrqcF(($-saJHFfko6A@|Hd)7j9g zb&gbeaGS5!vhFYsWX`PgTL1V89{M7{R*Xh3m_ElU6j8*`eya&!94Jmw5!MGA7d8Aq zs_!>efI`X9H10a@nnxvowUYXpdz!_a7lCzM(>R}tFu5OyxPgtcM*o~*AOw*swf-Qp*8VVp# z))tri z*~?OtntBw}Ncf^@J0PLxaXI(fZ~{^=Cyd11Sb4Hr*TTpymNq2a_9i1#XI0nW3U8(i zs%KVsIT%uBa;vFXpN`2vZE24Fb#+$PzX*HGqAr}_i&3KjbFmz}!4)vV9y!@$#9fM> zCLuZ!_(QCO0{i-llmO9y@n%n61p0ztbwb#taQLX@wj?5g{RFBJaFF*gY1GA43I&nE z&gHB#{`i*L(WLY-6p+_zan-qCYG6HDw1j3juW>o+-6#sq+2=n%-T#hA&(MrH06a}A zRsjFo(|mV;Nkognr3(Mv2{`l5^#;E<6{mIESk^gi89;PEL=7Pel^aH9c%v8iv%)e| z8amct@H@>81;Kb|q;Rs7tpD+s(PiYhyKs3-Xcn@=%q7Zw6d`~NHIefm6AM2l#E#c; z$$vy1A8K687mPYt;T4kV7AJ%aU5cU5!n4zx`hpN462l)#z^Er2e;c5G+|!2ddyA?I zqFcf93&4bRoyw(pe{KkPmdzzW_+I>58F z3Pp~wxD^6JuV*k_K1PIsoM!5i7*YG5);jQm*E_!$QS8O6O2m>Q+Ilh=P(#oO>EZI_R5&86pdwcbKtjRu8-^$5mLms`6HjfX z+(elm2Ej4n(u4Z5iy~`fm=pO*zPgCbht&3AdzY6)AaJOF}`>V`-ch0Ecj>0+VAY;85(6OfDzX4s9*d}`Tkx^6bCW5oEtxhbJ+foS9Gmc z3BkA^J!{%J&UjMOEC7qgMY1La<&Rsvyq}13_@a#8#QERRhZhY@PdLHe^hdqmG8Z!{ zgCN=7Kz^;~K5!_GPwFDY94U!U5y32Le*9>& z@^-}sWuYqwXL910~ky5xFva059yk_9vwD9s67 zTki^s)|53JKDNf;q}l=1ZiivMM>lQ9*A#}%?o+OC z#n+W-oWSK&qCJ3A`u5Lx@oEtO7@lQHBhBpJq{UzDW){`~DjTKFBu~Kn1Trc{#DW>{ z>d!YBdjhd}t`*tg#lPF&pN9JPV>x(W2>f(DX8rF=M;@NgxF_B&;-6FXpO3$z0!=_{ zFA)E8J^zErtetiQVWUk~_6fF@vhfBgDyQlI~D1OM%lIQ79GkNVG|`F}qC z4`rZ#TEV~H;C1;#^4<@~sr=uu{6A;>Pyt~Uyt2rkkUj`mgztXY<(HlC0@Azhmv3AE?=xXo zNIx&{umWiK@+Xh9?{`%Q94vT7wJ4=|a+Tne;5e&a-Q6!gx*s^70F~Ws=k$ljUH+_B z+bQW{bB}})O0j$j*BaL=(UDo4i~ToQbvIh>yTT+pfcmGzp+lDIpeiR#AnkTx>m4BH zQZ}d@WGyrYDm1YqLjFq1Y6h`6>y!7&3->kcu=q-Gs(J{qqmM_PZF+!U04L)4t$st= z+48Up)z9IQ+Ns88(6CBz+8)l;9FweKfQ)w zncmY=xINx3J58ePZGe<@-hCwbaewI4dPemm+p+9?$wtG#B68n+WNw(w`~BK z8N|i|5P4Z1ue8_a)Zzmk6razdi3_OuE&^Wm2oQPZTVA^XrQ}6Gkh)pYc*yBA`BA0* zsn|Tvc$5C=IY2WfHv)FE2z<9|IF!6Ia2!ODO38-NOv94n-1MY)8%Y;(cLzk8?u&3l zZX*M>vs$x1=5UP93yj6cWs+yMO)Na!F0w~z(?9jy9(m627k9jXLPUwfvd&j$$R785+Kq}b9NDsGl(%cnY!9=;9#e1CcDL^# z%gY>ou0()T+z6hXy!(=0o11tE3~!M#lF7-T{p;t z0y4e4r|d_O%qkv|`lOmm0hD~zW~*w(M|;&o)g;gH;D0$AjWDr5&u|8u&yB)p-_A{& zlJyPD0sHJ0Rla*(?!v17V6fkZu%x8A%(k}=7m#CE0rDQ zh^!I(9e}C-xe%wWsRMHXNTOpYv#G;3i|zYC2l2cOR}L2N%_9w=Bo0t;nvYrvO^ zy0Z*O&LPg^gG*_H=Px=c0xci!w)l>s4Wgawbt^aW&NP-~O3Qm*#}<4oSFQ#GeC@ny zxt$GIE};8g6nr~p+=8qI=2pOJslGABH%f6(Ufn1ISXx!v>fy(`;m4w+lEd`Y8cC@G zgLF>zqKcc{!s!ha(Ujd7=3_mCW#}-6xvk1!UXA=$Rf-(UI;Cb=EzG-LC+LoNnzRE1 z9JWgjK9OAr^>SKSl{dr~aGLWdYA8&rqf3yWyh4z;?iUqQ;I(wdUscA9C?I2|&P{bG z$ho7;gN~~;zuk3SMG|f-{raRSRW4ZiGF6+WBsRrz-t?N)T-C37GwL~g`Q+%SMC1Jt zE&}rl;ratx@R9$pFygO_5IWPmSH3n5{f@?6zCQqde_`tzvqnwvHj*6nDByAxew-@I zm|ySQt<4#yHtGVg+cM3{s-O~mB2uZj<(505;;5CKWM`0VxkyQ@4@Vt)auiZ+TN_3r z81*z7vH;VZn0}UaK0Z*wmy)10DOqxwNpzog3aF|bSMfb0=6h|LnCR+%MZJr_o@aWE z6*affEG9UnJzp(juGrs{BMO(c^KH&;ac@#_{z;}_9j?-EwKJd*sIoLU9s}A^ zNfr0&BKOkTlK{TEcE%0W#(>>UA;tMv)xeMIUkk$-&ZveG7&BS1B$<)wj+D1BFFor( zrGSKHROl`S@%ErLE$yLXUgn;)TcHOQzlSc!0ssJEQFHb8m1YBrgN@owz-DnVrXs%QAGp-8f9tsb2Cc+k4dBl00nMH2fooh?0ghK;3Dq`Av5Q~Bkq4wv zO=fRKKVi3llXOaZS*7I^%c=bZj{Sc1We*bIEy~Adbe(ie*GQj_+qFF0>^-UBchTJ) z3=w1Px<)p9-9NO;YGES2=LD&@QuOI_&uX#N2(ivg_V?_{Qk37#}1a|d%MbEsaS zFsDsS=a)vN)Hh3bCmXy)`l2rxSR`=)a5))XUt_vs*b--r`J8MApF^eBaLc@?L%t7K z+G+3449ok0aqW#23BmT8tT_cL$shfZ@uD~g2LgEU>A4s~jHV!F$@n5Xh)g%UMc4APH?u_5{L&k&LzjQ;X&1Mn^~6Q;eqmST1XD z{CJBI+EY;SQDJAfwKaixr1wLCkMr$wiIa{kw#G%qk$@G5`_(UKkKOkT!2I52MY574)M zl1#%X{-~^$y$V(e7_b=c)@VAL@G`u8?mV{t%kH!Z)A4;oYEum>_?t!H)@}l$zUjTU z^Vz1s`>D&%*G_tK0I}wC%V3FZGx$+9Ouaq;U(GLz^fZfoayfq}axFKano}aFYKU`> z*&YQ|Y*KPEBkze9jRjQF1?lWcIMI80ge3U{;1A*-=*}D|TbE*bW!#L6eOjFUrGwO= zVxd>p2UeaMdtb_JZgz4Dp~*?|#di5A5F}Kz-5m~EZrV{iB7?Sou&mA%5Qcz3{+W}$ zM98mwdt8>UxElgs2YRPZHYaQusiz~EdP#k41KR!UJ z8~S>HJrD_n51uC>+WV(1iYbDeD%?CjGHP>ZNhBQVY{bG?d%j4iAiUCFZ*~d`%TOAZ@OZ4RZZyp zo%~iyKvApiM)Q7X!l{^szI(C-lGtBj*IyFr{%jISWv45?!;yCSX~L3>c30YcsEIu9 zY>H*&G}#I)PM1n9*yxtiBhLYoxXBMGmMf`S3yzCN8241mD`8U1FTpU>rUo`E<`SW* zOuL*}A%89|LD4D<30xTb6;Jih*@oFa*p+L?*T@C}<%f+lM{2=wo}{F|yjj}u8TK3&I3M$O2>UHElW6%;N>BS0;M8Yv`l7UQiN=HI{SMR(Eso#MpW8JQRa`Fv z0bkt{Dq^Q%>?5aUntpmDGl04+J6H&Xi$7!Y5kUILY@Y}fN%M4>hR{W8BIZH#jJ!Db*uhZ z$TQds=4?@Eb^5Lu+}80#?AAI4y#!80#~nQ(N}ra-Jjh;YRXNR>P-t((f3p4Izb+oa z*I)%mFpAxFB(+c178N9EKN_p+&Miz^e`qZ2Tt74K4BwjvI7n)M&yai)13h$e(3L17 zN@Q^Xtj(~)$ajHk#_GK}V6z1^ApK5x9H;>APvk2eOcgFzcfO<@u-e9(+z-LBph{Kz zgtNyXZ>6l|yb-rCIrG*%3R~-=hE=nJ0kB%AX&1BZ&VL;ll=#M;QJe#5c}Yd$e>1gPknHg@FCf2{hZuI9iNxB7iPw} z9_N`v*G9G7Dwh<_xC}b{1|hUH#}H~Qgu$iKuuq*819TecR-(7k9IUpMh2by#KskwI zOH9Mul~a#qHEGzJXTT1(lI~j|CSF%P96dgiUTVk!wWQ0z0V(QVOWTfW7h_95c3SOF zN?LAqd2CVIwhFcHO^XTNgRumvhnqo-Borx47H~Ax$+3%hEnCuWCGx-)0*n zABzZRuYnKPsqFo6&HND*-mnlsizA@V>pD8gic`UBZiE ze|sN3h|WcNv{zh4cG=V7^lPqiIpHftQb|#9cxkNQ7_dn~P4_GR!vlcLd8Vrg9cOf_ z*`Jb_=`f!QE}FrS>IBg>jpZ9D!toPY5lNoF0%gNRt7Fy-fKZ}Vwiz=bM%?vE*kQs$qDEn zi9uH|3`2DIm|d84&d(1C$N$HTSqrco!M$-D@dOLHo#^2>pdZ*g)R5JQv$-S2JO{|v z8h#b4ks!4DJN`Q9B|2IQ5=sQ57X^2~PN5QO&)SZ8iqCWVtUa-1gl>?=<%5pwZ&#h8 zxw1SLN+n|`teh_h(2yU%8u>S!J4???+X<}SJ|F0?Ht^XyNW`%7YIx;aDi;e45V-=b?6a60~f{dF&v z=mp?^R^wl2_JEKi)iw^8pj_%3egIBQ>R{*b4SgNUXFd-0LVtAux$khX)UoACPeM%E z#X;_m(BWb)F7#!4qaR2Bdi>Nu^Pr#~60iUeZF~>Zwl{sbLM{id6N3f^`i{C(6vxHA$Egvvg$G^E3&ZB zkHr1BnjaZK0w?jZ{s>#JG#P`odnKHjda7{&V>2ogcuIsKs7~=@8l6$?-_=j%$^FM4 z-#s;`oIB9T?5milusic$a^=vh^X|PBhz1*$Ex93_uq))54e)$>guOLSKXZASOnG3D zymkftRRVmUb!Z{M8qd|&%(=aWpMAwwwtSA8yKr6x-T#(gVB^R~8gs9VJ;F9vGV;CW zNIg+i-TaEtHlUH4%!p)Kaq%mHcuh=0P@dCk7nR$JQhm(_-#O^|b{E^lqQydjHY&t{ z(&hNe;=f1F84n^BngQ+2J$@x$DE3X3yml&{S*@@~bC$Q|Tg^)fBS|7y;L+WRvs1m^HR>1=%ni86B8^LMe(o)KbmxlB!SJ>^_iqXo3 zqBohS!^IbFT7)-1F2ICemZl^7BL@s~` zxQ2BmL)Th_Uvf;Fe}63(7?~KlB_b+)61)o`1Iwg#-FtyItv?no-Qe_|gR>QuAte|*k)~rWI_NJYbH#e4kktB6^v7@pF*3j&k zpp@&G9kKJ<1yS+IFj?fa4eSF}Thta9(|-dEZvJ}1 zJKQ5rEbYmgoiO5cn)S`=!Fbcb1a9^R{n8bL)%^9VV{AD8*K$)_VQLzCGq-HXlB+W4zxWv;@yVJ-y2V zR=B>$$F=M&I2M4(~X~V;ZtitaR zjn*Oj%mS=zWVO;`-9b3M0x2GZjKZT}?_UCcFLK?xQ`)en8mQrF`uyeX#sq#!!P^}4 z;TUjZ(d^9b(Dg`r>$=GAe*Q?Yw45Gr z7rR3E*{F8L6!$a>gLMzT_fPXZYwyMvv;^mm9<0!BUHkHS)FJlX`_dBWEhUkC6C;sR zU)LVVPH9S(gA#4`WM7JD>wDOf3hAtKloUm+$D}RRMtGbQAzo~gdlNbw74oz$&!f}J zKH=X72DzC{@I{8Xyp-;?`5=~5W0&S~yDo~H2cbSg+8pcFkMEeLH`>4W)2pM5lMqO3 zzrNQ~@%4y%i+MrpG?iMjvG1E&0{-ulCwufEUJ1X?nla>}c)_I~F}Yi;Sqz5~g_FE#LF z6Z+_uFH}37y!{MeNX-}`{RvhMfwWE)(#6x-z6niG5@w`*-L&6X5hU}*Pz>uFw2J@y z?Uye0AS0?I?p)C>zRVFjj43cWY*uaYDxs|s_BmwD zHz@S>czBZlsY+f(l8EMMaq?tIZXm=I$A8s0J?boJ?mVYi;p@o<*uN-qkCt#h{YSy~ zxaPZM`Q$Q4ZMD5WGuiBQRqD;1^m?8rif5=jWh>`Q%M-X6V5lw8@HvnKo^wT|OL=k| zZTXQ4GZ_B6q7-Ou);XHLjR<9S?A@FIQ`g&>%hS?JHX4^A*(0I(BQCMcB_XQ$-xnVhcIauTys zTZ!BG8TQA$i!0Z#oNB-Amh}EwzgybBkI86bhX#YUTDUpsd%?B3tu)-9O?T~DRv+Lr z!YAh|rGZARKP0^4PnUwUL|2MCnb%)JlVW7UGi&bAgp|9+w5ZR)<$JAP{eOMr=l|y) zzb|b9+{#MzpV=&)MO4w2uZU4<*5=Y#y7XNqlckk3yw+OVpTGQ!GQ5{fJx92RgX{~R zTi9)L59tg%YgQ``zh+kAHzP{jhxQa$ z)U2}0P`)?TadRe(uxW>xsa~hdckyE3|HN4K`|1LJiVrEU4S2*Dh~sqjGmJx3-z#e= ze_^jCF^V9MXx}F%XTJ*9nPduW4SlidHR<<)ij1Z5x@Ee|SW<7xV2_USvp5+jEycp_ zo8Y@-uYDez4!tC&BT)*UsxmZ3$tXOvm01kID0O`mtduR`CG+|)C38l0=IGkcjL~HS zTl5z6B%wuKCPF?lN^5%K4`^HFIyK>hSQc6Ouib*qyms|*41sxi zQSZ-EQB}}+Glw;8ZcA}w!rzcNdO7W#f9FDYSy+E3C5Wd!vV8uc`w22|JMHT$DPMtP z!`B7&vlhh`9cL_GJV-RZd=z{;oK&P$4J6`1t-a)PO>3GWjtzDW#-uw{A9ns!yh4A| zeKXfkR0*UrT}5#Rt(ikAdz(v4VWJ~Sxo#|i&jS!)!5Uu|4{BQaoy;ohXb5CeH#f!S zeXS10Sur#ODbjsLjBoUMnZ41Y;h)E- z->!OZ-|FLYOxn1kz@{^`8ybe$Zw|v)+ZVO>HowmAua--cvh%9x@+r2I@s(G}OmoIv z^R^tN$6gne&(TnLal2Hqp+o~$_+>19HRaJJ-y2+<;J02Uw&-g|Qci{go-P=j?My57 zp~#?GU4)h;cs3}-)nQSsR&E0LRjahDmDtH zJHPVUeMs1_j0?!?p`=jOx5B0K0SsA*Gecf~(2W%D2tch-25Btg&v&CxkMb4UwD0e1 z{z@(V^pxou_j1RfYpGHC%dB>#CLuGMak)2%QX7=Y5mnnfh~W0j>q^!G&~k$GZm?_X zRi%v74u$wPl|vz87M%S-?USO86rVTR`?Y$p`4m7d7IZK0R-e@V%Yt1ROD>0-1*>xO z$XVJ|o=YQHsL;W1v)hyPX(>Kk+w$*z`>d~>xu$=}ka&+@pfxA^`=_=KhBQlkHHcTP z(oU+P<=+qf^ObzAFYSl?0b6=D)ZsRs>W=#MtLoB`|7$?COt;juE4W%~q zFj64dy=ro^_1ZA+C?&^!zLp``M`!>3i+c82%fE?Du+?$Q4k60Z;Plhqp+kqGkF2q3 z8*FZO;S?b?U%@9ezh=m>bY?s`u5UW4e|pxuh;<(7t9m{su^AEw56%3H7Cc+A%^3*= z7pT#uYl45Lr-E z%PGUYi+|LAOEJh>SAK@9I;&@>sGW7ap7A-nUk~Dn%&$_sW#30$rCd&v?BU|X>{sPo$af0WAa`3#)DXd2oHWD6DeXJV~# zt;|d9bH>17m^}4Ya~P|#Fs^7WgaV}^Y07equhi#+D@%%peBkaq+Yf+>8u`t(s?W#07%0n~gI)U>vVADj+6v36_ft*vm!f$mKnedC1#Fk>F>xh424-H{)$pmxjlrI?v$XqorRNcxx&mou)(!2 znOS|k;ZgTX$wX=;E{Qg33WxG(hF>im3$JWC9bS;$VbHgL1<7yc+RNZ1y@lq3r8v|Z z9om%@FDhXgxa6G&0%KQGu$2;HMc;IVN$a1E-mQE-rRDOuDW!e&7Dw{y+*9A$SvM)o zpn8tUivDlSDknYxdZD)tcZ(`|3k1r-fU+|WpRt>G@m1jK*{=X@zq^8*Y+JQ!E|wE5 z_XB7H3^LnW;dVPgjenUu`=fr})9KhGRf1l_`evLDpO>XiM$lg*$afZl9v!Wd!I^2h zwiaw-v&gs!C5v&WSdkd*;F=I5M)6qkr18%u(xSQ(nK#l`0{64zQ86%T*VKKZG+{F6 zP|s&?UWX*a8+-eff4VC8)qK3REsH9@jf_)c+~_11Iwr~Q+#ny+5P5(3=10j+Jh%}N z^BAy^6O-omZyxiOqm5+p1xerKj_K%5Ik4a$X8)f5vVTDw*#+qh_eXba8!w5B*wfTu zeNE(jlvi$B_ydw0_a32QAH((vr#OPt#;r$O64v*Jj&0#-3ihOSs~MpX$TPkj6S(a| z$5A^ncht|S`7`&?kN0Dl)1<*#)+y{7N7U92OuxbJ{oa22CgFy-GHDxJ)Lseoqzc8? zsIDjHja2Y$evH1$r7SRQyu1{1yXEEGkQRQD3$0ZYy(0I#_31D zzU`8;S})vzl|?0T)!D_@0wW`2LlXh#QW{oMddg3I zxyy2?wWQABU`G@pIPTl`VULOQj9cm$i-TriQMu{|MrB6V7x&tUVuU-Xr^C6UGG~Kv zn9ABqFf1?^0j8x2e|C;N2edJK_k67B;xNzdk~m{}DRBT!>EAy_eLnib6{`D-ESFxp z=LSuuBWba|Nw%B4hmEcXum|h3V2VAjs&~d{eaB#4x*It@}h=^hRNEwejM< zB?}slUFP%mUUZ8s6>FHkqnIdR^d`a9A&syi)?_q&=?Q+fD!ehhht&M%2S_`<#)H90 zyF=%_d4O3Wa0JyX7i!0nA1lurcp1T(UYNHqwZuj5_Id9gfWua`-vHR-rS{pm#l^A( zHC|?~gAII^1l+$bbw7EP(tEfQKt{ANn%$*KK}57fgAowzCfbbD20dlmM(JG6F`Yp) zKqC@kOH>M3Oc%&_0$RJEVJvrJ!yNYk=ruxodKbJ_gwmcx!+3Xr=V#XL$*}0DZxh}( z01z_6DB4Y+q6vc;UVJdEwAb1#(g4$3&;t%FG8zGCE zCxRQh&$u^$Oxr%<4iR*N~s7tRPkkv`GvT>X~K*7`O^9 z;(&M1ccX=cFu)=bTUCG)Hk$(^%Z@|2fo4^SEZFbdl72=TqBR%jzM%)Ss}ynwYce zo*?xesOM``Js))xvQ#)-t;)!CrIo z0){p)c~?uB%{DoZh)oOL@y+>NR@lkr?nIqP35Aaa(FP*XKxQQy>}<3eFA-Tp{+&GW zLs6k@sn_7I=QEAAO+?j-;`{s6-CMUx1DR^rCtG~67qQlu9AyJm^K7@3}h2Q$PcYtp%q&$rMjc(P=!1&-@n1ij>(x*(iOcqo`bNO zbo@i5T|1sl&Hyq}AbZ#0jS{`;IX5SC`CI=-B4)SkCritfV?SL;euKsN0!=aY2EeVY z*VDbgu2DjkJyh%TtnRWySw?%RTFT!aF$v41@{azgF!ZlUE9^TZta`eZpS?LiZZq(_DdR!4MOhSwAXUW%lZB`5^?W& zsFD9Z-y(gd*ApX@KLZVq<#}zHp^%$vKZdh`h*FsSHDVb|f9KVeMKe8jQ{7_`LTPsI;D8TUIB8g`qo zDEIteAq#a=)JC%A_nlHaC{=M7DuaH%t&nu8HA!6!$g)X~d5*`z8B{to7tHFLr{A#! zg`#cql5e?8gnw)=I!Rc#G#>h)!nmax4G|65Hc_n5lw@{$9w)$>LT$-7PHd^{ zPS(!Ed68&xzdzT$xTT9yYP|dPKJxMR>m!laf~|>H-mG%7hcAahg}K?U>pk;$zK3ET^^7$E>5 zC)*E3^HiP+)7ah6z^5RabgjU1vPFdoSo1eLxX7=>d3$%PnX`6wnD9W8XqqIe*3QyW=WIOh3iNEW;c^rI zjBN3^*qg1I}AfN&=Qxdx%6= z!@tpV39C4DodJTZ~i(gxX<6_(&;lg}-ARGw1R??hlgD zMYDUxV=FejT}}#<5~CZAl9}K$O$$_|oC{TR*5O#s#*H8BHO%?Wx=5YF-9(B}0d~!K zX$)To-IDkJMkH(5Q=>UoGZi1RbTQ$Y z(ycw(%(=*N$YuUx(nfr(Jx%Z~OmL5ryOgEg9mHHRntW#7ad5Wu)l0K`g)ZL%1+S6F zJ{k#Rg*p-NMUE2n8_Hr9&On#gqE9fM@YVNJ-)>xTYC^Te zDX$tIB6fb>AlEmv3>@`NeBnP@!@BNX>TC8-E zSki4)61WYZiLl-AMhOl1$YCXB0TNO<{ljvDqHYgayL*f8Pt3M`3HGSr|~ix@rR)Hj#g z1!|(zDpzks)R8uHDHf_;?vbe_kQd&0l0&=Foj5jH9B}`7-QVshk=}j@Suc+dccmA!Dg^CsAMjcsF<2GJC}Yzfu4C z(Hob3QP^6-_tdVXQLw5oSuSXA{Cj2pQR~O+#b0@KoX%X{8z9j#w)-+ed+)7Z`j2|n z4> z>{k^!2De`%nVw8ZlZ{%>;)`*uUuAm9;EzF?5<}J_A`Iqnow(kNrlXP>))gzh(d{6xZWV zqhogcOM{JweFjWqRh$w^qzW85?^v0tsNSr2_}C_@D)p#;?!t#qY1k$dKE8D!df;b1ef*eXV2ENh1G2}g-j|JtY1_&`5HZcK;m$jb#7uC zqlenZ;$yVou*X3x$M){ZNiG$oXIhj{BJLjIF!Hw=(}t*Xp@_BdZf-~x~Jy`DM3hdc_#u_?D!~K$~>R-Svn8-h4iLs z(et;$S^)wQO{= z+#yLop@0?Y%j9#-<;T9uUde0s{uS}N6ZPtK0AIbZVwZY#hEf+~<~`YeWSWzTsyWG1 z*}K@aT_+l~l+5}q*J_LQG+SBc%VO6?RG-7s8=d5ESrX7*wp*RTSZmWe2aa3^7 z^T^y_oy|0PH_0hmbOHXe^tn8*m%l#4`fiwMttaJl8j`AaB^3z!%|v9Xs2Xt%%j z%O3e)(b21)So0B5380T5l_1S3$=jW~9|p&g4XlK)Lf`uEgw_=py;bBD{?VCatEin& z^mszxwfeUbF2=NfV!m=Nx>K(*`0rwm;nCPL1^0%uDDjQM6x*AhL zW#){jcERNDy*625|L@idU-R6$j|aQCskuiJaBkFjL7Uc5tz6_mt>65e?skEu)tIa5 zZ}&`v(!M%MQbG>}-+&`ak{My3GE5Q&LZm2ZzgEAESCHigMgr+=uH;B`yOFQltUkos z;EKaRd8|YCw25)2ycz>vHDOik=S5P}Nz$a0x7c6mC70(*u&LlELzyUjhP!?&Prb)fRvFp{KT zKS$3#rC;b+{``IU_8jgU3}zLZckVpGE)2P(b_;W&>NvByo`wH(>iUNOyomU)mcvvc ziN^;SZ&7YCoG4v`*`2q;dcTcZVRD6EHfC?hUc5B=xwv=`B@8c7F$QihYTZXb05px1 z6$faH>h|u5|3HYj?lhm{@{FYHr9y5x9_Pe8D0;2cbAd#lc0lWJIzI*1@(c#_lmGKo_3l>K*Xw z9Y}PFqmfa4v4qF&+Zs9{bVoLZXFfT7@^dt5@B6Sv^73NMJ}B$d2FmRhl+sL8>GmC* zs4h@>Nw8u$I@WRTW|v4S3oz$4Sqt!5uUSinuUo9-LRHS^ zlV{!Bb*6;+#6f8Dr0qqtX)yr7BR>c))M0G*9aCg9e?D^IYK9)5Tm=iTX6aGgSvhA( z2-(xMtdQfxqoAERRP~l#qoPBoqvY~j{pvZu$+S#Xz_M@+r{*R}+fa$hp1Tb4&_Ty! zrwP>evt;2h#5-zc_`$%W=zO=H2d1AAYL$M)gEo<*({^(+@xOe{k>>Y4k{9RxW;c#$ zs&aroH3rP==`IPUEL<=h`OqZBK3i=hx}=*kXOXrihitr2UK1Jk-CXA)*2;X2g4Esj zdhZQI6eX)n$B6mu(jD_sTCD~>{ zvk^}o=KqQ`>!pWgJ;=!zN>#*iMc31o7(vg-qn9IP8~=0c-E^&-SN}WnM7xUg-8XuY z$i|Bweem8)$LVX|YXxNGBBM)Gu%|O`h2E${s``@%Q4+l$&e6g#)S5BM>q!XBk}cK33<(uom*%9#>>2b8 z%Us@SqRrDn(t7H<;TH#*mz4*IZFUttx0&?z1?J`P7*=RuCyzayw;nTx7E1+)eXz|) zLSy>wXY%jqF!xQ@NlNJZ%e59@s--pYreG3fhIcLqyB;&EXXF~owTe!Ulx!>i9mGq3 zGDUy|j;r&;#|9GTI8X4SweGj~$A!`373uiutskxjav*LHb8J-!z~a41IBjyH_tWQ^ z@fgVpw8|-v`xzP^)%iH?n=pK=?}NIPnx2o8B1G;-1?H(t0xdF5kB(U+K>*3;ZGq1M z{mkD<`r%_$GosGJ3nm^Dwl@UHc9ay|{&{gOfJ34&zCQ;9P(tUK)r|uU^k(BX68ZNtdd7yxJa+HxDfnVM# zl-)3i`~Vb{R4U<8dmW?BSHS7-k03(13_3A)s-BH8mImff<$9!rbD|c&tkgK=+(yRr z9%ghlC{sy%U}D`+!MsLz1y(Uv{QsW)rk@t%BqG(Ey0kMc(7Z^o#%_rtA-mImC}~zW z);|$)upXV#Z9Mad2iLu|%g~~l$5n5aJXZG#vfeUp5D9A;E0EI6lzC$m2?@+*XNUJc z)Jpot@p|B7h3U0UhmlL*=#C?>>8wt^1*qJp{_>Mo+vzUdBw7!m9LCDJ{tBt+&Y~HP z(YzB{_p+2{3!KdT8{5>o#HoeL^G8}aMg1hyHA}@OGZ_qdM_r#w3@p-Be5_Jp;Cuxo zgb@ouOyiT5EXu_!!}gQ9G*GLR7@URe1P%Tgz5%-mJ;QZ$IM&Q~Bn>s0SZs5^bBrQ~ z?dV3@+63a&>Aq)yMemC&6{K~|$x2e+iIVEB)}i#_mgmNFwy%OxacW7F3#jnrdjOL4 zjHE`QYenB4&Wvdl4xCGcnSZCj>;%SuXBrFpF31!IKU6W%-9P=l-+OrbHYF5??d#q# zi3}x4B5f@fjwTR*k!e>I$_@b|QA6m;0#|K_YI%Aj#4AiM<>{ zOl<2T8g^=7qgNh%;-&5xDkySK7VJ@d!V7p0=)d$QXK{(=3CzHSM(csoe7oPI0i^Zj zw%+zf7aeDPNZ>A@7wWD#r{V}lCTF8c`9w@+bsH9+Ti%pyb6|P@WDg16VBqSu>k={g z*T{a7(^s1trOS+qw3`P4cy8VrmcQNtC_ft?T?RUf7tcz={+(HU{)-#6geodBw=U(a zq=IVy<4g1H$UKGEyFWXvOM9b;B5?quM-Y`aFn{%J8Nr1tPHAD=W>VEG0`@W8oH7~b zLrNGGy6?WA{*N8G53fu!kdHX$NwXM0!k)C-yVsMuTPw+4B=d2jhG)_C)j*bXp8no_ z^~Y+eV~xmGt}s*))u;e)o5h!ov6N6E3cj&D##0PDu^(Tvl^vBNu6=aRdHS!k-*YzG zFVx@_#y#5#)3Nzwm8=~x+rJAGOK+^DoZF=Hz3JNtAUz0|@;fkBTJ?Wg3BWE?oPDrS z)NX9nWIRLEOock?EDhFGTQ+sR)|{p2qEy`z)Zy?qX1oC1?o|8O&yxonv=S=lqgF-( zpZ_ZBduNU-z2b%U&fWnSiK=Nr+P$49S@ZIX4i2spEx41%t}=;4mFj58AQgJHL1sZz|? z%o~ef0F&LIai#sh^C%z0w~W(%3_sY4blo^NKF?xqq{#H+HE-~8@*ey$ht1lwi1Cdl zVsENGwCDrIs+Y#^o#%lgSaFyOc&}qQ&H^*uF29x6Jo5T9c1ngun`{jpYCH7i`3Ogd z^wD@rf&D|z%CcqpWtq8A7Vo9VJYi63$qoJqUx;A>Yk*VUK4>=?d`>RlsNE@88 z8@=|+uErE{`k>Btqg#&u|M8fw1Sc$~yV7U0CC!tk)&3I6z+q%zSi6K$%d{ZzMGR+A z{zWYhUZ3=B{WQH5mZ;yeZ^nrlPB8lRK3(IHD42D?*TfqY-^u|?;E;UyXO{hV&o)iW zp=I&rP?Vrx4k31CCaBwjj(A^91#)hnue#KtdevzOCLQ1shlU4-n)(G^1EM z_eOJ_WK@kYPoIK!kCaB?HEK;_upZ`#Hd!eTfX4`w93_o5jqBB0GIw7b%~~I5eEwp2 z)B`!Kz)(RErX!U;owdQS99aG9Ih$0hwmZ16+4aE006P+_nNqjBbqp2DLbM$^A&Yz{3P6Y?d=|EF~ncQTz=6kM9y4V!ruW+)d zBkGbwY_`sQA9|kI9)kR<% zW++NXS(xl)I7@XOHOgk}8oXJmp2P~>t2e}23}N@a^IUA-5gkv@BTuo{6uI>Ex+pMc zEU2~Me%>+%CIZt%Y4mWhzJ7yD$FifUu}5jcVO+6AVy1+3w`SKIUBQRYEtQlk-hALQ}PY$^vYEa7r&rsnYqLfngZfXxL zg$G4wg5s{sZm?$M8`_+80}?n;cNc{j%;}N752R^}*{k_XMXElkk6?x9F8#`RhGbm_ z8i`n2_v1U2!poyQpI=wqQ-SCw9;XTnN(^VY`~fS4TikL7j$|x z#J=H+D(D-suBz9zSC^KbozDiTb33#NxC-4tqKOY_nd5%~=0fVeY}0lGdr%kcl!)v{ znK?@6lPu34ocKchx5e=>YUbDB0RVyfy&zW4A*E6HztIy#j2_|6w{m9{Rqns1z_?yW z1vm6wj$xQ`9uM!nh~-&O81eE3l#keJr+Rr#fG#Lv0s&ZCCo%`qfp`b@0&MT-?^Yk9 zdd~Wln#Th*IwkhqTNRFo5K>olCURpbi4x#*p)b;6J#^jz#va4zIrQIq>&N?nnJS6D z>Qf}%ylN!Q@61!lXRh(|+H2m~JiTCcx7`ijrAML#;}OAivC<&>e{i0pf_634?2W$g z4Xx)hiaq8>b|bx+Kqs&!u&Dq*(zblWb8qyssZ&Zb>cM1iQku1K=(zLoa4{<3l<sSPQ(`_WAsr(#Bi{Aaz zWB!Y0jX}G82(e!tj_ocPV>(Md*n1z>HJa^|nn;X_=53WJ*B1c2{Vh7xlZe~lY#FXQ zq5;D94ZVADbVnKmvQcq&NCkI7c%z#56eE{n+yyuHchSk3NvvE>NzPNXdE zuM1#&brNlp3PbWeSoW|&9*{H4ruCXm1iYgJpPYwR8a;A8*%9;`+t-TnsnKa8Ys>DF z(Nn@9r0BCcn1eQ*ZE^oI)2Dfj+F14MRq!+Ob+i{b(6>WU_x@Zzc{1h^YXF;T)MjsM zO))$s&xqwW@q;rhr%g5kM`f9pbDEis0Tq}%K@CMz(Rad|V(_|)@8VxR_YVaeLEVp> ztlYKJtG^|?G6djSRh6ogf^uOqO)W_0oh8=Q?8pyVdzLop<)QfzPNMZ7&IQR2sHY{{zH6i6|1|jmAOmb$5_%5hY`fqsEU5wit4G zUd1Sl91>rLdUfZg-6&d_;VMF% z@c%}N!GDo*`>aPRdV^^36p}NrRN%?@Ky2tcE3Aod#NAayKuy+-4Y|z@1%&c!%(8$% zBmxXP?8Beh99Hfvg1M-od%(BiM5c*UQ9G^NI}Mgk0HqDONPjuISv~c(YFm9ok}6!; zhCHdBEvod|>xtGO2IN{y+4DMwa zlKPO8trC~NGnl3Up|4O)Wc6K(aqM1Y>t|RF8A?k`eb+`l_`0xik^1=G{F>d(XmU>~%ro97o9J zgTvzO&M+{F(Y8aS|D-oI6qb*a%sC6ynk4kPqUsPoz!;0i_cV!(_Ql22ZzYn{BjoL5 zo}dn-clX|m{CN>z=pr6n?l3Y2A5zUMI3>d6#lhrD7@a6*Jv`P&mEjJDNHuslWU{t< zFvd|`z0O1&h}q~DcTDTH7CH2k$_5eqGL;F!pjH(+ucg$a>j~JpkA6^pDgf_CK;8R# zXcPy*(|wY5&8j5y?#m^o>RTMV_N^9C8~;Tc65=Z8{lZijLH)o)s|b2xC$pcRRa6gV z5Tbr87WO9R#Yuk!dv?nL$+CEKV3)Awub$VQgYD?ZOxfsa- z=%F1pm)CyNh=U_8M$h;7xPM7P_kElN?~I3g--Mb?46&=wcB%S;szwQYQu165E`Ym zF1~cHdrbbD9x-)22Dpe)vEZw6aqVyfi%C<#k0->a({qhjmjLDL8`iLrCLoY@85yw( zpt~w*38}W1WMS3|s@^-F{6blweWqUXfrhv$n4`(L>v?L1nR~)MVkFf!yAUoy>DVMi@%f3RFW-xj z-&eiPfGt%07i&C~ZN+XQ25kys8dAG26a=NJtH?@_a~3RdJbxBLpZSl~&+0{MJxH{D zYs14lr*vQryXJjXytTGr{)NOHA4|yji193@5h{zFR9dEPZ3cVrY01h>o}U&5ZkLpo zA3LV1ftEU3GFZ^q+g8_7PO!!-LK*Ly~AqFK6!rZ1_rKK;KwuN$p39{mf-?j3%ol1mrry64@LlMnugta{$P)FgKv4; zCSX;BVIQ`g8lD)m$89kTD5*EQyI)oXZ|}?l(YR`t9j%2p%cB!WL;FSQ3;*g?YLnxI zyXL2Zar!HLd+QO1>tU=8+K_dlZH?03;zryGgbS&mOqIcUyLk{xD*E!wpz}RC-pQ-m zEh_A-T9__H52;2L_!gG5M-Oj$N`jiqoc*lRE;=jf_*qiTz3hm7kJwh@5IU>4+V(9Hzs*N@s(G`TX zP`jGw;V@tu6W9y9r;MaZqu3Qup84qDOIKZ-pvtyBNvJGOT4On zM+uo8eJ61_^OwI%5ASO#Yd#9cR*ez(MO{Qw1k^1Xcf&kUSHM7C#zJq^cxL5H&o#vb zpn~%I+$F+4^;;Fjssf%kycf{ZymjC) z1Mr(PWFT1th=P1-eKr0D1?^@F-5hucl;>pIbowA&o7*9FGwIqZW1 z;}RgIp=K5XxkgWldYq)smfy=RVCjMrI^=v@M-BwcZ-&Jb1gm~<_yBllwF3#H%*wiq zU5=m|`%eyWzuxE-V^lcy_EaeggOMaoK9aIpG5c{TpC!WTLO-FgS)n{w|5RUE zGWg=9^(k=qoBMWGo9s{+bEvd}geXNq7Ox6@9THN1`di+7_PJ)CW(X_S2ZQ8=Ep;U{ zB3pmxBJk0Jre?D*7^14&R+2PL&%y&hR=1YoW9hFENA z*%o6JklAU`H-VX(<8Cd9&1B`sLaD@4AV9z7T!K?@!T`n2lGyXZy}~rLd7|)xBDdUFrSXdQ`8T>R81)HSD&zg<6yK`sqMU z^n_8_R+z?&*6*}pRRR`xtNiT&4N2Vaaq>b;z4j&Vhfo>_7XMg}If-Ol|IKzu zv&lv0-uPC&gwInrQDUORT|Xx&@Wwqt+O8c$p)^~LjEd4%@5?Hm0Zr{zdYv8)MHH=% zfz(1C0b)hjo_MhLAg%0yGbsS3N@m^Tsx-M`v`u;3i~p~bHSM}0YHyvReni72nPUH< zlaOHW$%J7;H4^=d_D53H!)uJi)B|4f%U@4861r<(t?tdYIEG~;^Dj2R3m@Mz?>=j% zt+rPz!hg2D_lpztYkMf|qEh-kuPn5heCiu(0uVZMEr(It{@n<8sIk!>sgZHCr5yv) z$Y@~!T+h}38e@Qkl~{x6&M{PhZp=L#ivM89vg^^8{7-ta6n%P7=X>R&*qVlH!^FbX1Nd&?(OrNxPI@Xh=WmBk zO_t7?yuhhaTLC>he0`}LV`kj?0od%Xjb@O_mVUL@hH$AHdH8f2;Qmj0*A>>}wrxcq zDoBxP0HsO`f4Z?FcXl|4N)u5~l-@f^=mgjS#87p!X#oU*fOG{yi3kW% z5{h?4-S@tn^L`(E%a`PDYt1$PxyG1t%rU{S8*C3R8XcAD_#)uJkJGObI5g|xt1AK! z>Gz2*Cf+7=ZVrjvX`HPBWOQim zx62+?&7MOS%>4B>#tK^Xp@R9Jv23+E&d}o@aIbfYZk8w0;};?uz0C11sMQp$WvBP0 zDrSodIcT^<8u0Ef*P!;hucGr>wPkC{W$}Z%@7Djkz0y&+Xl`dRS?V0Nu4Sghki{y4 zw5@(ssIYn>F>7HfSqMe8>C$Ke`Hao%Aj9_ZhIGpack$ZxM}(Kqz#K-2bhsNlRLbPR z=0jC-%}pTuUE(ZP{n|_^w*G*x>+k-$*RR+uTe4@0(0e`E>IAz;N?6{##mq*`$)sSX zu3-S&h>#Udn+Fe@*ZW;tsXDb?zJIVi5>#qLO=xrlzjhey9rd&X5+u(-4|V=!Cexs@Bm|2CA!(uJajxH({CV|G>}qN&7F$u?03;s zh0^2o9&&UrB#9j|L|ADi*({R_;Po$yJc~-63-$>|c8&o#PS3A!lhC`If-q-9)Y;A1Q6CxDT*m5BOF zfKjj|ImU=xo994hd_^&&!Oi5VIn0e;`}?_uW|DZstr+f99SFp8z=b%}l6A5=%iBk? z9U!$Y#TV(AJ~$JqPw|H$>&xFa$TuNYbe|5TL>;PLj1eJ<)&2D>*ZoiI-n09k%+Sr%-(=?cdi{G3AdvygT!*Ow1{czF%z+zSpt?SkJG ze}a;GWaxBZY>ND4lHv#`g|RK1J)w7P=ZZAq4c<+gNuyoa{nqN_)7E;47?OWSOJ#gJ z{9v|qjc}*g%W)e*nUOuX3>4RC}t3w-|0lsUf48TuMNU@?k=n7j5nZO0NQbs zVY;}p(z8YZn~?#K(UyfBy1at#gB}4V;r*IRaWYUj&xN@COPYT zOf@q18Lk3gle2rhcTNlMjZ=qrT1dy0;tY3WucCWn3 z02FRS`tg@bwU*=OsvDrU43ZvO6x{5|X8U%&D8y;vC(`C@|A3HL5&JMUr%j zbfzdl%>_Unf8Uy6HE}r$WgEpr)i-|a0$8+3W=j)PLO$EV{;uKGb-hG%9VMlI|0b1c zpR2x?iha5|#9|p{tV@q!OPiWk2OCeKd8hu2Qmj$iicJjd_GFA0aTZOHgOVOs)Rf~( zQ$u8< zVw-`vB#ACwsP2IDM0*BEY?c~XZdNN6d+J)^=~{YY)FHlHivV{ce%YetLAk@y@f-Gd ze2ReOa})1kJj2|TnAITi2kdb1NJfxbWHR3J3?AxVpRUs_a)6}eM4%p7Sa-gO!}{-23k>u(AALn1VEQRi zrM?r^hb3s}3~vR1)XSb;!muUCs%IPZ(rcZaeSNfsRdqE_boM5Uch}pR529Ntt8Q3& z%{O~Lu`BwO=)usHsosMG6DH=GgDBVQ+7;z++zpj!A0>(RCfu@L%54*P>O0f00?jeGo||3hsQ+N<_cjmvpjX#(kBpt>IQQ?S4G4 zy#9*z4uATLeSJw|L6ADTUfHZhksRRkC9^4Jm@1jA)1U5z?N830H?$iCv`ygL0C$p* z4g))*#J)XGwJN8MZY>BlKGy+yOXLU;dZRT1Uqh?v`IYd)4|YudRFFNTnN-v=?wZX+ z#7G)3rn&W$SjP&&4ve2KiW2gBwi5EE8c^fL^Q;naqgGC_FYOj$`hj`&e9*1h*jGT> z+(|LfsA#O)tyh`1h5n!yN0c9S3LEH}_8k8+*xQ<%9hdFfxZ=-@T{}#AoAO-BX~)D< z*Ql*m*eEx#Wa_}{kBC{6`ql$3u7^T8Ih6Y#iv+5bs&`>`a+KAg`jheO&5N%$W)m`Y zIA?|}c9`d(OS5{1-@7+y1*6oe{xz^!)QLEHi${U(lD_mgME)2ldxcD5u8%&))=^#v zR;*X4St|e00BRPC@HI~+(l$x)`@4Z!HMcaFAhtP~k1=|Rcq7edm3bb2A|0_-cu(r< zyONuf%6P$XKCe~|#omkJSex-I zqHf}+AQ<;i?UecTG*~E4zEO){{)ax)wU3CkEu~(?!akJO?k7drhM4|uGV6D1L)et% zC(2&iyO{7NG)+N|hIgeJZk`KU+C22chNL>CF|y?@$nPHJP_t6HudjYAXE?r=fBJB!koL5{2H-#$7@d}{~Pa-N}H~YeU?o`KCwb9di}x7^_Fn5 z^T9?F>P!8YD=x{wkPas#(VHsM?nOSYgQ&WcyQLHkXHPgNepQmdGK!r##OFk#ip~?A_=C&*;4xyrRAy?pu^kgj`l93pE_{k1Te|clztRt1u;GJD=@g z#r@?Y-sY~H&D-cgcHU{0ggwsGEBFx~FQ%dHf5%S?xdJq5+CK!nE0h1^JYEKe66j5R z79g7kOOmy1DA*@(??M-15*UD5<0YzEBiv$i_r_t#V#_z9d8huR<$UMCDVOmNSU5m5 zGP#kV?B*8zNDp5lr-iB7u9|QtlEzjeOU(3I@gKO>cHEiUX}maB-2SxV#M)@))l~f& zpr_^vwEn}=cthN>lv1A;d|e47hmQF?sfFc7ge>gTrc07-$xN{xsFQ1HkNC}s4Ebj zG380L%X-3v7<9tP@Bxm9sYdDE(0!JzoORwrVp_LcYPc*T%}KRm$5|h!DbnSALyNiK zlp^#Qtmq{Q(Ebq_bl!P_=+W$GW4^D&d^C&8#$2?C-l@N?Q7K4V{O)>pE z!P&=eKrMMD(U%Zq?5?S~cHS>#`7Rf@EpXjS3dhBhI-`=FP(%fSxU8$nU5c{Ahp=A9 zf7}xF@~kv|?_ufe*yRp_#{EgP#FTf>#i+Lne)BoS2eOe7t%$>oKX6vbz0$vqacGO`rj#Gq}4 z1o}iHfZvjsbT5pJ$_($(vrFFuIY{g6sC9BOu1ctNg{o z=-FK3kS>ggD#Xc+qRJR%R6e<}wvU;L7FubLa_6r3IW=_=#R@e5s9|wQpo-Z?Qbioz z%XWA2`YBssopl7;a{fJ}V~jE~4cp6A(ED}&PTsU{_=NSZQZDQB5eQwNLyN*|5SB51 zBE3Dq|2)sC{8{?!9y4|3!J~j_ZJc-m#E`Gu1?sBLRKGU?#YP7pQUFyZN*I-;GyrYj zrMDoAxTRc}3`+R1n_;A894H)>mwS2c?UP?dRLR5#0QG={1nQdKc*xycV8V3|)CVhH z0r^T0Abe5%YzaP)*wj!F(m6DDv#Ich;nhW`P96&uA=aH5)^h;xO3|bKb;=v~t#NVg&N*%&9YyHSq?(knrwQt@=&fy?KD&|Leo;XBQLfI|bVGO_2gJ zA=zN^BJPbqO8f4aWo{XMyaMNP)P{PQBV$8Q5Qy7t0m;bRksg|^8#B1eQRuq+O z(c6OA;VWf8Jx;H-;Hd;HYA^tw;dhkap7ixggt1H0JyZmvx!l0W0 zwM*_e=&_wK4H|zAXM3O^|9E3JI%-!UZ=h=Wjv6FM0Tea)bG={aXJmUgiZ^-v@*rY@ z@$wv?qucy1iU&O;Ykg!qL+kQu-kxg+*gNL>w2~Lq$u2-crf&^o@4i??f$~5%kkV?O z=9QuqlOHYk(?{B}t0j)eJI+P_ob(^Bga7nVPWPDR&~ppE@n2W@uYde~!v8unzsK-r zxbdIt>$lnbHk)68CK!m{E9Lh}`DgC{%;C3l`0X5iJBR=0(bvcCG}u}rh|~%BbRejB OOh?mDqw0pk!~X$Q>|log diff --git a/modules/default/updatenotification/README.md b/modules/default/updatenotification/README.md index 54ba213a..652f451f 100644 --- a/modules/default/updatenotification/README.md +++ b/modules/default/updatenotification/README.md @@ -2,26 +2,4 @@ The `updatenotification` module is one of the default modules of the MagicMirror. This will display a message whenever a new version of the MagicMirror application is available. -## Using the module - -To use this module, add it to the modules array in the `config/config.js` file: -````javascript -modules: [ - { - module: "updatenotification", - position: "top_center", // This can be any of the regions. - config: { - // The config property is optional. - // See 'Configuration options' for more information. - } - } -] -```` - -## Configuration options - -The following properties can be configured: - -| Option | Description -| ---------------- | ----------- -| `updateInterval` | How often do you want to check for a new version? This value represents the interval in milliseconds.

**Possible values:** Any value above `60000` (1 minute)
**Default value:** `600000` (10 minutes); +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/updatenotification.html). \ No newline at end of file diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md index 3e6905a7..5b03b141 100755 --- a/modules/default/weather/README.md +++ b/modules/default/weather/README.md @@ -2,119 +2,4 @@ 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 - -![Current Weather Screenshot](current.png) ![Weather Forecast Screenshot](forecast.png) - -## 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). +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weather.html). \ No newline at end of file diff --git a/modules/default/weather/current.png b/modules/default/weather/current.png deleted file mode 100644 index de6c5a39ea341592fcd25d19d6a382457bad9e35..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 8141 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 BxD@~Z diff --git a/modules/default/weather/forecast.png b/modules/default/weather/forecast.png deleted file mode 100644 index 1afd31913ffba849a334aeedb0aad2c799a3de20..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16385 zcmeIZXH=8xzV?d+n1FzS^sW>QO=*!X5;}w$nl!1AE+rsULBN0%K|s0&q<2DZ(wmgf zd+!h+bO_~*bFTI7HP3#}KKp#w>&rQek-q`xrNHcW&FrsL9~rl|+(Uyu!!bCvsLa zaK*zTYx#Y<(czSBiH9d0rv#GG@iakCOG5=FuB7*}sX`7t*m+UC5RsM_tUC@5uCg4 zY5HUOlTnru2MPVjqDwR-ck%G*9*g{ehqqdc8`_f)(wlhiMD1~p{(2RNhi68{a2pTL zb(|Fs?`sRe4ZNR>e|u?ic-j>fc!?H0OpowAVYoaynLFIul1>-7wsl+IZM^>GA9j7c z9|Gkc&AOCnTu1-d6TZ4Y*FHJEC49A55p#uTCpTRWX*XTGP8dT?U1C)B4#-K*!`_BB z(o26lY8+rm@T@#|9)5iy4Ic}`-#r1o?TdW5rQGO2S(J2Ai@%#SwLQt-bj;-9r|Ot? zHkILjp*SLag>bC$tvv8wzQ{Ovb$z0t@k!!?O+Tv2e5xTjt>Itv%EX$0*atvT7U z5Mb;Bu&I7nLC5-{>f7m2*8?x0w>p-d3X9l{*hJF;q{Mc*Vq`tYahfV*X23uWarqpGPt>x!*Icr zbaNRQ8QnMMKjy&0vAZ4*< za#K)5UaN5wJ>T>5A524ps*=U{@N-{C%Sm7ittrsAE-?x~O*QMQ3f1OmYXC~>zkD+{uw8-@(j2?HGG1P2IOP9wU{#U=y)*Za<@(C&!UWC0 zZurh;Gx#f`I;7%ELo_v;61*KH%VT3_6j;Ta5^7Ve09u@@&B85HGe_Whib%ibjCPO6UA zG1Jnyi9QC1-UbEM7^vVD`I+QC1};+W1oM+BY9_eR*L`w*k1$N}Bg7!(1F&8v`u_Db zCoq=Sxh%o%;DvZt>>~x=AZ8E$X>;rM<%8GI(=0ZOVH=Q}c zbv=)*_4oWriLVbTcSq)^?XQF3x{ogT)J^;cSh^a~Gwsl{Gf5ZBZsb$LcfLUuWde`o z36&mD_lHPsKaa3xWzV9lw?WLHq>lUq3?x5(7+T5F!f)Y9m>|l1@X0BI32EBwFalS+ zb`ZB_y4@IZ2I{$DuC6-i$iMaO)(7n>t@w$iJGVut9=+X2^Jfh?crNH_6Zp0U&hGvR zgx$5QeSUr!;IM>Q-nNTf_Yh^@*Z9G5#pV~W8r2S*Bon{U^_}i*SIX%W;w_RacDUi3 z(D!6l8ni#6bVy23P<-UQtUH=;(jj5^t|f=TJmHqmS8ay5KVpX8^N|0#|EAbMl9Za5 zya7ra`yQ0!dp$qDM)6rO3bD9(#Z2xC-8dlu?4CY;x?0|Vg(qK=#6)LHh?9puVIy!k z3DfVma=4~6dCJb+RlwB}tzN+t1#Ll_9(sQ$I!W85boerV8B-L-gCx2`C2S(3)? zqU-H#aeBT{a~Av_ui13K*iKnlVfN_e&~rxqbkw`^NUECU$)+5OK*FIe*Q^GWHqca= z8uG=)4xBl6e~ztJ?@jY~K8+A&({jq)#Tdh1hVCls(eYkKISZt>xu_+DXLnb_M3JNz&W+d+G;j3FEDT5=e&1nib!MWk8?e!DU(fm~CIm=p$obpPnC)8$c zwj^b=5Z|Fu*w=m9h=!-8n0t6TGTS?exgxsjG;`wn73-|ufWwgQ8Mi?f%vsfb&n%4> zrCcG-@i`b2;EAwRY6S(jgpg2)uPN)!jH~csxhBohoO^<;)x~5kR9k-3dC)rP5#L1h zyZCr_H%1xiQUV>l*=x`15_*~GpfO29TTV$6Wh8og57LaZpScJqK02NCK`$P0UGkHt) z&kI7SoYM7mC`b07%i0HGbRiF4;YMYHII4Tn)qb&BiH2oGK`VWxLq%X_h;j$NZKMQs zjvgNzRI3ec2H)FtAHICa+7WYEtWx=dzWn0bHCYXBuCZ0j>;WGW|N0i8@#dDrciHmk z+>r+)ROrWMxDPi)K;p&QNbc2sa}rwxZio%-2vHVP*?TAEV8$aw4gMNh!yPY@Y`49hvEfdr$rE|Ik?fca zp{!)6iU+wHSM*j$viseqQG2b7`^jP?2;s+{iktMjWDwzE;Z^rZ_=(g-P`ZIC3kS&xJu|)J?J<>84I&F0 zAtGcmLu=rj>ipy_ZkdYA}eaB@wA z9}jS~#0g2{aJ9^GqjbAsw24|vQ)>uykJqB0uJ?Cy_@_97f5HGYGT3@bSBihU_cLX| zMPcCMquh;WShTUtwJ{;Tnx{zhE0H;#3mOT`k2w#erRkXA5~tu5Gu*o$e*iXJtP0oq z0eyM4bA#UqZi8@NNFWJ1l(IJtk2`tVSifZjuK>V;>EnDWHv1{ncMVThe$`MW%*N`$ zO@M(3LJKXTIS#a5d^@8vW3#&!t!gjyddP7ZIO^#R|qYt6aA)EHA0%)^ty9s4YWdkICjH5dCyvZ zL5$v!R>E5SZk-w5P7jOMM;86P&VupHlPGc?qZ#Dh&*s;-d9!?k+I-CqVBQ4gLM<`!Z-{iN0S)m!nsiwR{a_E2luA6tGb|aBkR-#v__k-+Q^_W&dHg``EKQt=sB`k z1_mDvS-5Voa^*0FF!%D?wIUEvDvSk@EsG1Gc9bK$M9pYlNHvHXB=5v``&553U;12E z?BCtG>K&OtNIm-urM$1a+n_cB(hT5_75#6Q{r`hH^WW<`{*41*%yt82w0X&TP5h-L zf(|$4hh7C{<&9>dprG^y6*J0fL44IP=gsl?q}+0=tga!h%1)=OKBa@#FP|&h=V3zoZXg=7EMY zGRWSayHPJ2RLjps4(!7KR@D;?Gu|&*?aQtQhK;w$b>0jiLbJlGASw zq(2+3t7wMN46lF6HV&(-g}On93+1H!OO%&GmuoM@-tSx<5V6eSGx%tWp*Y0{L?20h zlKa6)?y6ZWu;q}zGyEWgBG}EQW6LN(I2yie84ID%@o#hC0pxo=%h2VunzU}4DzuSw zQGQ@O))h0-U=$|{2ysZugQj!=#;waTN?wuy^fBU9EplHw*M?QL=PVut!H@U+j5LUJ z9H*RgI~(pk-QtdAX=$B#t-)rGHIlQN^9XbxU@B=Ok-@j4${vQs6fN@R>dU-*2EfhQ zu@bVz5IV+}gAg;*-(a>||CunL98pacxNx&Vt+UV@@WviwJ_45`efX=spn@xl@47FZ zQ$Uj_&mmq&)iKFaO}#_Q0=d}wg+9GLEO!FUO(?FqTKWRqK4&@*Y3hQnn_jWql1?@f ztu)Z^qYxY+7Dtzk&TNNUyu5L_|d-A4e>UO+w4ev6_xMAl6yg-zG4DBNE8|>lUKT?#*+eVd)izWLfK3( z_XUh(O!09?plcJ}G(F@n6mCC9gvJ?obh{y_Uc;WcdEBEJ%bxja?McL%_neFRclLc z(k_y4v_prs$khBG`^yvZJT9Fp#jj#q6_KK$CrwCR>6CW|##+^Mru9rByHtNFKG3}o zeysfwF!?5vUYh-EqDdo6-xA_~N@;ptA14Hsz>9`$C%qEQr*}UF`{@eF*$))f&%^ms zppq^w9UuM@Szr*zyBWb2z(E?LwDXE{)2+nb`tXZ={~xKzls#U`J7LkUB zEl)w!j?@GaMrk_EToho=ngw%#bYHtmtkI`h&zZ+|(p+=Uy^a0pHJce>^ znSXQQVbrP~47WXub}EZJeUBeG9a`W=e)h9@M2&=;Cz%>|lA@sMFLx}E`?ZXS(q;q-iTE^d<{CQU;eB1@c)Lf{TsFJ{|x#5rw8EtZEz-vdW&?!s?21d zH7}+YiT_SLgtQqfGE)DTckGq!57Gh}O0V3>Ca+pmu#>#qJyTpsSMhD!L&yju9yNNv z45@~trMSzL>!uN;-wT(&wJEK;9&JaM6+xQlYLJPA0k&k=LUhI#$)W3{w2g zop{6ufTy8LWv`6b!+QfRT&8zkXL3&q^9Fm^=*&#I0gW__zV%RcMeQgXP0i#kS)J0G z&#^C(yUgWh9qLr%EFVHSVRN>N85OZzRlt{=evy>5TG{1+QoVm_D`R{FjpJ0N;e)G! zjiKz_LH8yEN$rc?tB*C63q;10|L76@u4O9KPF9L6Ii{MPmdFV5*$snzP9GxT*(ROHH&@Q?5v(PNJKDjkZ^QmC`U;JK?{VlfGv8^>YiI!&VjCD3DFewwf4tCW zGQARj!xef%iIceE279%@7?-Uvt>O%BvyVpxQb8=*LC^$U8O+&Ghg#j zIgD1_(}7U>qu_VQgR^3X7qA&^xWz*XJJC-$uRc^)jvNnzxWZPRozMJm0ZYVBnhL~& z2)*}9nYnYoBEX+jX9w??2@XM^SdLXL25PZ()rdf+X z04g728!MUgVTT8CkydDPJyH z&M2Qq!yVFC9f6feE>PE)Bpj4SF%SkYw4NdI_C>fWk`~FMrEC!+z+!^s83I|O(XrFj z-2-4tGj~I_|3j3Yv;9CmNm3yLUwPf$>em5>IPHTQ{Gp__?nk8WKTs+mO>-^Yu+`p! zOwNS0L)8gAfTlXLj>T8y@QPdljTk|mK4H{msPJP^W;<;(>Y=Gg5JyFs8w+}NN8+*R zs2HM%D`X@JD*a64)H=Ut1v)BYsxJ9>mT-i7O^2euEHA53hrrXC$Z=;l(nl}(1cyr1 z*9;>lffcwR_kPEgrh$Jx_7aO#2lkrc+gjH)A*kat-SsZZ(+KZ?jQ2suWQ81)CTzEKPfW-&yU8N z0nde7x@Ky6Yo&_!;LEz1F5|4qj$Zjd=DC%6=eplQyWiurJp9zU*26+hJ=j6%5WOr^ zJhN2G&*(IB_D5m9+Y0VUaZe}v0ou0*D!w_Yhdd|mYS7*Qe>E_sCZjYj>-~n)qroAY z8aD=}X@u)sJ6bHf2tJ1AdVHpp00bkWjk%nnFC<%?T(nH3-^#SLKYZ)w9K?yu*p;+q z*7sZjaT}QC_{?QGx_w$uu>#-yFKw^?X+`{h^xgg~1Nd-D@|OrGjQJmwmvEnkouZ(> z@YXx^NYWRDfTK)T`dS!Zr#B&V6!uyoZ6GG)bR;e0CmV#gji5?{v zhCVZg>pPh1~U*tW~8iyKwe-7@6odO-nM7|}9=Wf)AJ4bZYLTdJLCatlo zwY?MOf&AvNMw?vXs?FbwvCdtiuq-6ClBMw5-)MMSpjtpC#ht@0CTR={ER$?cI*L+) z8K5!>r~WT&Sp1sxi_%2+6myUqM`i!<(dW4gyRa$F?_d4%Tj9q6^eOks?JzK!aI)~$ zlKb@$kOz9~rpN9dc6^^YVyU~ON?1-zI^KQ2in8$Hk}ALpm2huE+^a^AKOP+1>e3 ze;)fie8*-Lw#eicUdBxr9h>!9jw9En`M1v<_wDoef1EE<2Yz)ND>QI}*acC&tCFx2 zcRLDB30e6EjSiT%PtNatkUMBRG)zTg!RWvtVlkOYFRZS{)AMTcw$>QjY3IjO)^H$0 zP^kgG>)WJQ`t%vgcIYm`7KU}VhmiI-SgUuPiszL><`~^=b9!8{B8onNx*Ri7+|yFN zcb*7XAZLbY9X{_s%vm(@9*`up!VsM~In5netL_4h(G8oOe$?dmm*;Gx9=a!gT$z9U z`4tBbrCT`-)eQutraGxQB!>nch`g^S{l;{(u`K&*8)V3mF7;6>kuSoU0?u92rDadW zL$J$K+(eVDp#mv1uJO+td?ti~CHBs5C(i>LIVvQBBMnfKB5ABWn@-XGqlKV6etbDD zKFN<@Mi1D;t1a(c@=Gxl`c+4Zu({ZHPSrCh$LvG2|+$1-p!#MPzn2JbsK~`=1{1LVrrmjQH zH9aV+&(vd8pMgoK@~YTc7>U$J++<_M&hZ27+M8&-DQ^O2UiOSL0__(% zU6K)61oB(>{zy{rO?cS1c}XUmVpqyPh$d4*=D>7$85zWN*NDIDFt3As6j@wHWeg#V zcXL@n$=051S-@{ScQXglmkm(`XKS3$XG!;iybbIKeH*>8+iQhk(eFJ}#@s+LbS_iyt>C-nvF3%eHSSDo-Gv^~$g2^r#PD@`3t3EcoO+(B=^ z)V=ZzbjDCNdgPgJ=r=>`_aON%;DAcC&BK-m!Tp@2)_72nGE%daZ-#kmutZEZ@HEYw z*#Y8aJ3$CUlu3%$tFYirs9aTre)aD1Ox0FI%B?#3O#>^9Lj4|x^btJRKtHYTDU^&} zI~iKaLVSFd@08|&;FVTu{c#-}x3o+;>U&On-LUPw`DT7Sm>~^%q?+W$;ecc*m9gLp z#pK`eRkGwn?W`XD=RnT6~6jWr3?)zVqu41nauE!M;iFGWb9_-b@} zLQGE&1^RfaHNsnvhoaYlDhPze!2+P9HmjtENSYLNh0S>@_|#gTOlpI}cNOH#)OW|M zJ!_w$V6F~~6psh>XtV5xoE;aQe!n$=IcBkm;KvRgIGiN!P~zMJ-V1w(>w}@%FFjBr z2-tYqzv5kCT$$|cvEf7VjVa7wA&l4i7Wy#DW25ye^Mj8ah6gc+Heh62>Z~wpf58Xf z&*fVrq_%l|57V@W_@$kiML)VoY~@uAmp0%K4*Q6!8j@uV3#C*K=ItQtXZutUOHQ9H z-bkowrj9ce^ie`S&Mz9`mihy4t*sBOQK$#M?R&2-8OlCR7D068tnMtB|9tHHh#*qO zx^jwIx_JIGgVZxN)2+?Sqdsz;UjYn;gg&#Hrl={u$Dal7IMoe?wxeP`7^I1!i1!Qa zU=4N|yIM;A^O{=VLMJV4wQ$jX5cbt{5R>Z|0^rfmvMMd+Js;kb5;>pxQ>}f`_v#@s zu_j<>#IB}sRl3k`{%$J{u&CX!k+7Ika9-k}?KlkAwVv?hIO?J-aMQFONT*T9(3AS? zGcz<9h@<)dGg=+wSyhKD8}d38O$N;H<7~H%>GEx5q}F54O>VK^)oflpE9ca~)c8nd9xzmB@6i3|MmHjvalOP9Z`9a&gY{YZT( zuz&sl#~2xyiD6py^K`?-9)6?Jn0*qz+st90NII_JZs-*S%t)eSAy?uVX8uHjT09(3< zUS079!9^1OFkLB?cQA+zC9bfA=nL&xp_HK-I-kvI^e1uCU zXlBUgF+@nhRhSwdl5HOTh$y6;6b>u2EqL;pyweF+am}W5(B-``D9@h2M{LGitLa$X zgNzis-VFWlG@^nc>8XRdnk22ipXP&}spHqwcVuv!Il}^H>Z@6QI_Ar@UaS9QwNE21 zanBxl{N+<)qhZp<7{B#@4ggp<|3?78`D%o-PEe$ZFa?TTe(SDSmqiqcR^h)9zkx1$|Y(tzZZ}B5kkb9Zd66Bw3|?( zSznO-p(n?^NlB^h(OHfs^Nb&k)A&MTe1|U?j-4iURfKKNWEvUWUh33#bJnjJi=|FB z_z(PO$bL718TfAKxbW(8Q0Vdf;wH&f_^5jTXk9eO)Azd!(*(w_@=fg%6!r46m~GZT z5#jAWvjkpsJx+s_d%}pPPc+eDZQqPFO#$et8z(0AnmN8zPYqLe#!5N+`AS27>3${B zL@-%X?5j|s8_=<=if52DINZiE^sD?gI?BUW=f=c z(Chp$_R{vJsmUPwRF``VMJM|z|6IVB#?L} z$AjDE>skgn;jlA!rq^u{JIbv*(K*ZMgH`TZ??<-U)jk;@22KT(Y5mlL-?hFlqebuW zgv~lz#m;3!3@yo@_5|)H1bq^&;xoTMS3OAo;TC2BlyoVYS@D^Pk8#_E(qXu|RF-Nt zTTBPG*v1{X%c5Zs=s=c1zcyH&r33&2@1tgkBm_`OZ_qr4fIy(*J8h{3#dPU!Q4z zla%iVL4opDx4?;;Q|MCZ4zfIGWGr;WgGn`qrk9Accy87`V$S_81j%3j-D)U>F>7=J zCP{f=> zw{t@7m7@3Cq3*Rd?a;_n=v#oa?+2&d(BMA=Voz@g%GsF`Ix+k$`VcG^oQyS8ZFgO- zu6n8Njpq0bjW{AXh=yvxcNnH`X(#9!3f*Nne?EKnqvI!s$|=z;vprgf*4h`Sbl(Z8 zUEQ*akb0R^+8yW8P>?h2*#pLMb%_1rfFwt56TRDPLn5XZKbu1{CAmB$e`g}roT}=9 zn$-lC&d-^+>gaT<$gnk4rQW|%Sv{MKrsJg#@BXevUY3mPva#q_)x5?hV!_!p#JEe8 z6D99qt}y(1U65yNr}!-rmmZOhzGO}xArkd`@^G?&ar)7;;i&6A8C~A&*&jQPr!A2P zTeq-BthVtrOk>v;MQX@emL@e8b!Q!WXL2LL(&jg#%U?CY3R7MJztUGpuPtdQ&{z_H zrsM!%e|eOqWtrXZtaZ#MR&m(Qus0-EAfj?6<~J>(-KFYL^3C~_JT`;#b;x&kJO3p& zF{%fctIT1b7Txr0j_*#U|NnM5@t=a>f7Ua{ug1EPc%b#)oehRuHZ^CgCvX0=X(w0^ ztx$=H?JUltJ4zOqc%WOuFlf%ZkG56ji$*&hGm(z;5yu_XDL@KmY;24*3r4bA}`W{leE}22uUx zJ@=BG5dx;$pZE?z>EwXXlWE`W0rl=O^|Bzn5Lo2!&dhLQk8n7a-L zU(GQOe49eZV**~+_SWQT=H*o~l}!2BoeOQ&x)~R*Hy3J@Nh5X&Qfwc_VARTFFJ*i_ z{T%^?`cd$19?b3vmTobtwGsi(KLS~fbE8Nb#@7^)>g)%tE=Ja)zHBz7#L-X6b{J2? ziiZ?>uHZN(^yS$y#eakXJt5Mwh4*hG(pIPfCE{0j^SVmZEvaLtrREwHd|gzi%hX
@)5$>O#0fZ3!VDM_*}cfYQ_z{@s_2c^V@!a08s6{*nBDCV>P5z?DLh< z)T7SF@UM&=sUhAL|A-ChrsOY|8Vrt;23uSHK$FodG^A+neuYH(su)jH5;9>tr~|q& z2t_bgzJ{E@uOdzo!251kAT02=#uewF$SRMLvl}J!P?IM!W=YGtul^-IF;)4WxR3n7 zs!UmSkxxm^PH%I+M+e3|b^IIKTX+R+YEaum?bnZElQLQNnDV|t{Wa~``EVH9X=Htq zR9v0;<>8&rejtu5t+z#ibs#YR`m?+@tEHzrA46r`&wVKi92+xUxm*u(-OuQ4eINfH zjAypTh%+qksp4OW3%wHkWy;rGq<|4s7I2B}u%_?C!>p)}H1t!LU$hQDVfmLC-tLT~ z*^n;X0qPMQfs>rKDW8%uio{CO+5&49r!MKLmrLO~{tX-4smS6q`0|dfcSipb4)hcO z#`JKYrws!r^jmzPaNUPc@4@o)?19+8>y&!O!b#KroAb!X-eI4tQ{j0t>OYrs(_QP~ zP1oJ|O{7?yYs*@&Uq_1>{N{fw&?iS{!!7?#S( z>lu{ws&e$vqu{#o`ht|pB&`hZxB`ZKr!OtuYVpkXEXz!w-{eLGGWJJ@Db5}h%q^JV zMx@6%86cZ_G2t}mj>H8pNt|A6Z~tn?2mUm1ft9rxXxS^ph&5ih(J6YONXaoL;=jB` z-*QZDlg`^@nX#cVt(?Be$757q26@j3Y#hAZqzxws$a2dv7ei%|q;W}(Ci4&=*!Uk_ zMv>C*cZ2f8Eh8GRsc>B#Ys86tD37HJ=H9G0s=L)-tc+}!aEy{gra~*sVl$8?{z2FRQ><2zE1$^_ zDt9?3-XtW=vX2`j&u5=2)biLAo^b0WE|U4Nxs^%V*{Y_Ci@mOdzdn(H&s*B% zE9;bI)p)g7U3%N^;D=7{YoCPE_d!%@-ry&P=J8#awS_H~w>8t1)_c$2DOwgVB=K2p zH)kfrrERn%gBo|9=}cpOHoM}yE(sUz1>7pL{tp_`na8sK^Tma8kF_unGb~D$a6yu^ zn&+a9!CVnZcLpELMOL(%VtcJMnmEOBeynjgZVX+T#Ov(_Hqya%VD3VNE$zQ!B{o?& z$7<(0aBQ}jW5msT`aw)l;S<;3TgP6vJ;=pbnqp&jI2uzPW2FKZY?>a$T~}4;gZ4=& z9umSu9!jISyOC~FY^J{Vf-iIt44M>7AN>91UqZS6;!2xT~M3SbYU?*Key>ML}=inKAtTUe>?Pz$+G5N?ljL zCZUeHh7>q(?!Ae+yvBIG>vCgO)<;Vb^ZUF#Qcj#jx_u%Dl(b ziWRjJ9zr_e-1>iyo#ghDXJ6}oS1Dvl785zG+u}UiZ`rNYQEew7dn+IX)#RY7#3@8d z+i!(n*%qQG5T{Zy7fjExe^GFbynE&$={|%hGas6HVvyqmt*0F{hTGK^96lifKU*j@ z0e9t1<%p0AmdC8;*lTxfpj45jYRNhb37@>ntQJr1HgyR&>(zEu5y|PxQZo3Me0e6WQ$~Sdm^s6_CX|?H6<<1Po)1p#S7-eA50G>ZcW|AlEMHz1M%_}b zlI8fw0k@56(brkR{$7V#7x9#_M!FyZ#yh)%Kz-M&rM|pq1AOL=-aX#BU31dU<>N_% zE9K>C^jL~zL`%$27%AR0qS%sAQDt#J|4HtvonUql3ea46Jy>(gbx&O*TM!J+8kQpTmcY1wF zdX~GDUlx4T-tBA={P6_ENx9%hjH_522+;%+G!I~}w9}b%D^n?t;{PHf_JZqC+JM_s z`H*i~=}bm%y19ES*=~0<6P#$h#%Fp6&K8-01(Id3N9Tfnc7a`f*CZ)_)+B(T$HOZS zY5S$hu6xof+^ES}ql`4%77b&-u6tB`=SHuNxqi4{d>dDHTlRH#rQavC1+K1a9VW;H^&GLC4D#GU6-&5H6u&boG~&3- ziW?QqA<*uUF#e+nRoqm+4sajHz5R6NeT{=HcF`0E<8lkYKjGw(yMs!}z3CB_knC7m z4=o?*XWEV4h=M#@HC?L^-K>$4Uw1l+eja}hA+2ct>K@A%LLQA__y1lo18$eXx1(Op zT72t<BDoEbP z@Ot`Ubxo<^8Rrl;6I?ns$;)WFp3=d2kE?^~Br|$A;(IWqIVXxtkSjf&bJBN;MK<|9 zc607F%G3!qv-i6Y5&T3z_$tu51}?SEfN^zpeQwg;I^vkcNs&=#f<2Mx7!;&LgaW@g z@g0ufH5AegTGZnb#!aNf1>#HI#on%;g>;2-4z|?0@+idY`S6VwvlAP?p>-PSsYIYW?nqvn}~v8?BD2bTrV#JxtUrPWPu* zN7gdmZ0;?lY$7;`PmmmFfRD)m%f6T~>JTVF8}G`Y$66%?;*ddaS%P z%k)6s|II=sLSBF^z2d=f6Knx>T%0jv3A5$e67_k;DzhC?e}-q8Zn0;XS&4m2jb;5I z#xD5krQ4@wNYFG)Fwv}l)2_z>s|H~49lfDIMrmn7>0BZh?P>N(lq^`{*xyX1G{-1U zUX}xOBK^@y(7O}aOCw!ejCjrO>HI>fc>eUjnRc;rXa!Vy2Yh;K^VvdgakIP7^b^nJ zH2OR2=l&hv7b6I%Qz`!rMHb!%4K)*x-|Z*+XiWuLWM?FQd^_Kg0=zL)-(X*J-{$HO zJOmW7uVW+C_C0XBxA-6o9|IZiFggwd+(p(7jLx;HJk?Q>gCwS4=fjDNkszZ39hH6Kg6~E))emi*^mfdEn~&*TQqxB(Jq98iKVhII|A_ znTb_DQU5&dv-|Ym=ZmYVEh$q#8O_@t9=NOx;!zWho&0@E`M=u<`9GtJzimT#*f4NS ZC??9%ZOK#@g4?!_rz8gk6}~VF_+LS8+!_D? diff --git a/modules/default/weatherforecast/README.md b/modules/default/weatherforecast/README.md index a75cb984..95762daa 100644 --- a/modules/default/weatherforecast/README.md +++ b/modules/default/weatherforecast/README.md @@ -2,81 +2,4 @@ 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 -![Screenshot of 5 day forecast](forecast_screenshot.png) - -## Using the module - -To use this module, add it to the modules array in the `config/config.js` file: -````javascript -modules: [ - { - module: "weatherforecast", - position: "top_right", // This can be any of the regions. - // Best results in left or right regions. - config: { - // See 'Configuration options' for more information. - location: "Amsterdam,Netherlands", - locationID: "", //Location ID from http://bulk.openweathermap.org/sample/city.list.json.gz - appid: "abcde12345abcde12345abcde12345ab" //openweathermap.org API key. - } - } -] -```` - -## Configuration options - -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](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) -| `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.) -| `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/'` -| `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 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 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 -iconTable: { - '01d': 'wi-day-sunny', - '02d': 'wi-day-cloudy', - '03d': 'wi-cloudy', - '04d': 'wi-cloudy-windy', - '09d': 'wi-showers', - '10d': 'wi-rain', - '11d': 'wi-thunderstorm', - '13d': 'wi-snow', - '50d': 'wi-fog', - '01n': 'wi-night-clear', - '02n': 'wi-night-cloudy', - '03n': 'wi-night-cloudy', - '04n': 'wi-night-cloudy', - '09n': 'wi-night-showers', - '10n': 'wi-night-rain', - '11n': 'wi-night-thunderstorm', - '13n': 'wi-night-snow', - '50n': 'wi-night-alt-cloudy-windy' -} -```` +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weatherforecast.html). \ No newline at end of file diff --git a/modules/default/weatherforecast/forecast_screenshot.png b/modules/default/weatherforecast/forecast_screenshot.png deleted file mode 100644 index b9022adfba0e5d2a59eed7962b154bb82503b5d6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 86206 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

eXu_6BCJg&AV=|)Qca-RYEgi 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 AP5=M^ From 786641662cc52901cd6bb3d683f6b2a4577ddbb7 Mon Sep 17 00:00:00 2001 From: Sam Detweiler Date: Sun, 12 Jan 2020 10:16:59 -0600 Subject: [PATCH 008/104] cleanup installers folder --- installers/dumpactivemodules.js | 15 - installers/fixuppm2.sh | 183 ---------- installers/mm.sh | 2 - installers/raspberry.sh | 569 -------------------------------- installers/screensaveroff.sh | 101 ------ installers/upgrade-script.sh | 361 -------------------- 6 files changed, 1231 deletions(-) delete mode 100644 installers/dumpactivemodules.js delete mode 100755 installers/fixuppm2.sh delete mode 100755 installers/mm.sh delete mode 100755 installers/raspberry.sh delete mode 100755 installers/screensaveroff.sh delete mode 100755 installers/upgrade-script.sh diff --git a/installers/dumpactivemodules.js b/installers/dumpactivemodules.js deleted file mode 100644 index e32f8415..00000000 --- a/installers/dumpactivemodules.js +++ /dev/null @@ -1,15 +0,0 @@ -const config = require('../config/config.js');const fs=require('fs'); -for(let m of config.modules){ - if(!(m.disabled || false)){ - try { - let f=fs.statSync(m.module); - if(f.isDirectory()){ - f1=fs.statSync(m.module+'/package.json'); - if (f1.isFile()){ - console.log(m.module); - } - } - } - catch (ex) {} - } -} \ No newline at end of file diff --git a/installers/fixuppm2.sh b/installers/fixuppm2.sh deleted file mode 100755 index 6631ac83..00000000 --- a/installers/fixuppm2.sh +++ /dev/null @@ -1,183 +0,0 @@ -#!/bin/bash -# Define the tested version of Node.js. -NODE_TESTED="v10.1.0" -NPM_TESTED="V6.0.0" -USER=`whoami` -PM2_FILE=pm2_MagicMirror.json -mac=$(uname -s) -if [ $mac == 'Darwin' ]; then - cmd=greadlink -else - cmd=readlink -fi - -if [ -d ~/MagicMirror ]; then - # put the log where the script is located - logdir=$(dirname $($cmd -f "$0")) - # if the script was execute from the web - if [[ $logdir != *"MagicMirror/installers"* ]]; then - # use the MagicMirror/installers folder - cd ~/MagicMirror/installers >/dev/null - logdir=$(pwd) - cd - >/dev/null - fi - logfile=$logdir/pm2_setup.log - echo the log will be saved in $logfile - date +"pm2 setup starting - %a %b %e %H:%M:%S %Z %Y" >>$logfile - echo system is $(uname -a) >> $logfile - if [ "$mac" == "Darwin" ]; then - echo the os is macOS $(sw_vers -productVersion) >> $logfile - else - echo the os is $(lsb_release -a 2>/dev/null) >> $logfile - fi - node_installed=$(which node) - if [ "$node_installed." == "." ]; then - # node not installed - echo Installing node >>$logfile - if [ $mac == 'Darwin' ]; then - brew install node - else - NODE_STABLE_BRANCH="10.x" - curl -sL https://deb.nodesource.com/setup_$NODE_STABLE_BRANCH | sudo -E bash - - sudo apt-get install -y nodejs - fi - fi - node_version=$(node -v) - echo node version $node_version >>$logfile - npm_installed=$(which npm) - if [ "$npm_installed." == "." ]; then - # npm not installed - echo Installing npm >>$logfile - if [ $mac != 'Darwin' ]; then - sudo apt-get install -y npm - fi - fi - # get latest - echo force installing latest npm version via npm >>$logfile - #sudo npm i -g npm - npm_version=$(npm -v) - echo npm version $npm_version >>$logfile - # assume pm2 will be found on the path - pm2cmd=pm2 - up="" - if [ $mac == 'Darwin' ]; then - up="--unsafe-perm" - launchctl=launchctl - launchctl_path=$(which $launchctl) - `export PATH=$PATH:${launchctl_path%/$launchctl}` - fi - # check to see if already installed - pm2_installed=$(which $pm2cmd) - if [ "$pm2_installed." != "." ]; then - # does it work? - echo pm2 installed >> $logfile - pm2_fails=$(pm2 list | grep -i -m 1 "App Name" | wc -l ) - if [ $pm2_fails != 1 ]; then - # uninstall it - echo pm2 installed, but does not work, uninstalling >> $logfile - sudo npm uninstall $up -g pm2 - # force reinstall - pm2_installed= - fi - fi - # in not installed - if [ "$pm2_installed." == "." ]; then - # install it. - echo pm2 not installed, installing >>$logfile - result=$(sudo npm install $up -g pm2) - # if this is a mac - if [ $mac == 'Darwin' ]; then - echo this is a mac, fixup for path >>$logfile - # get the location of pm2 install - # parse the npm install output to get the command - pm2cmd=`echo $result | awk -F - '{print $1}' | tr -d '[:space:]'` - c='/pm2' - # get the path only - echo ${pm2cmd%$c} >installers/pm2path - fi - fi - # remove MagicMirror if defined - $pm2cmd delete MagicMirror >/dev/null 2>&1 - cd ~/MagicMirror - echo get the pm2 platform specific startup command >>$logfile - # get the platform specific pm2 startup command - v=$($pm2cmd startup | tail -n 1) - if [ $mac != 'Darwin' ]; then - # check to see if we can get the OS package name (Ubuntu) - if [ $(which lsb_release| wc -l) >0 ]; then - # fix command - # if ubuntu 18.04, pm2 startup gets something wrong - if [ $(lsb_release -r | grep -m1 18.04 | wc -l) > 0 ]; then - v=$(echo $v | sed 's/\/bin/\/bin:\/bin/') - fi - fi - fi - echo startup command = $v >>$logfile - # execute the command returned - $v 2>&1 >>$logfile - echo pm2 startup command done >>$logfile - # is this is mac - # need to fix pm2 startup, only on catalina - if [ $mac == 'Darwin' ]; then - if [ $(sw_vers -productVersion | head -c 6) == '10.15.' ]; then - # only do if the faulty tag is present (pm2 may fix this, before the script is fixed) - if [ $(grep -m 1 UserName /Users/$USER/Library/LaunchAgents/pm2.$USER.plist | wc -l) -eq 1 ]; then - # copy the pm2 startup file config - cp /Users/$USER/Library/LaunchAgents/pm2.$USER.plist . - # edit out the UserName key/value strings - sed -e '/UserName/{N;d;}' pm2.$USER.plist > pm2.$USER.plist.new - # copy the file back - sudo cp pm2.$USER.plist.new /Users/$USER/Library/LaunchAgents/pm2.$USER.plist - fi - fi - fi - - # if the user is no pi, we have to fixup the pm2 json file - echo configure the pm2 config file for MagicMirror >>$logfile - if [ "$USER" != "pi" ]; then - echo the user is not pi >>$logfile - # go to the installers folder` - cd installers - # edit the startup script for the right user - echo change mm.sh >>$logfile - if [ ! -e mm_temp.sh ]; then - echo save copy of mm.sh >> $logfile - cp mm.sh mm_temp.sh - fi - if [ $(grep pi mm_temp.sh | wc -l) -gt 0 ]; then - echo change hard coded pi username >> $logfile - sed 's/pi/'$USER'/g' mm_temp.sh >mm.sh - else - echo change relative home path to hard coded path >> $logfile - hf=$(echo $HOME |sed 's/\//\\\//g') - sed 's/\~/'$hf'/g' mm_temp.sh >mm.sh - fi - # edit the pms config file for the right user - echo change $PM2_FILE >>$logfile - sed 's/pi/'$USER'/g' $PM2_FILE > pm2_MagicMirror_new.json - # make sure to use the updated file - PM2_FILE=pm2_MagicMirror_new.json - # if this is a mac - if [ $mac == 'Darwin' ]; then - # copy the path file to the system paths list - sudo cp ./pm2path /etc/paths.d - # change the name of the home path for mac - sed 's/home/Users/g' $PM2_FILE > pm2_MagicMirror_new1.json - # make sure to use the updated file - PM2_FILE=pm2_MagicMirror_new1.json - fi - echo now using this config file $PM2_FILE >>$logfile - # go back one cd level - cd - >/dev/null - fi - echo start MagicMirror via pm2 now >>$logfile - # tell pm2 to start the app defined in the config file - $pm2cmd start $HOME/MagicMirror/installers/$PM2_FILE - # tell pm2 to save that configuration, for start at boot - echo save MagicMirror pm2 config now >>$logfile - $pm2cmd save - date +"pm2 setup completed - %a %b %e %H:%M:%S %Z %Y" >>$logfile -else - echo It appears MagicMirror has not been installed on this system - echo please run the installer, "raspberry.sh" first -fi \ No newline at end of file diff --git a/installers/mm.sh b/installers/mm.sh deleted file mode 100755 index cc6c4bb3..00000000 --- a/installers/mm.sh +++ /dev/null @@ -1,2 +0,0 @@ -cd ~/MagicMirror -DISPLAY=:0 npm start diff --git a/installers/raspberry.sh b/installers/raspberry.sh deleted file mode 100755 index 4fceaee8..00000000 --- a/installers/raspberry.sh +++ /dev/null @@ -1,569 +0,0 @@ -#!/bin/bash -# This is an installer script for MagicMirror2. It works well enough -# that it can detect if you have Node installed, run a binary script -# and then download and run MagicMirror2. - -if [ $USER == 'root' ]; then - echo Please logon as a user to execute the MagicMirror installation, not root - exit 1 -fi - -echo -e "\e[0m" -echo '$$\ $$\ $$\ $$\ $$\ $$\ $$$$$$\' -echo '$$$\ $$$ | \__| $$$\ $$$ |\__| $$ __$$\' -echo '$$$$\ $$$$ | $$$$$$\ $$$$$$\ $$\ $$$$$$$\ $$$$\ $$$$ |$$\ $$$$$$\ $$$$$$\ $$$$$$\ $$$$$$\ \__/ $$ |' -echo '$$\$$\$$ $$ | \____$$\ $$ __$$\ $$ |$$ _____|$$\$$\$$ $$ |$$ |$$ __$$\ $$ __$$\ $$ __$$\ $$ __$$\ $$$$$$ |' -echo '$$ \$$$ $$ | $$$$$$$ |$$ / $$ |$$ |$$ / $$ \$$$ $$ |$$ |$$ | \__|$$ | \__|$$ / $$ |$$ | \__|$$ ____/' -echo '$$ |\$ /$$ |$$ __$$ |$$ | $$ |$$ |$$ | $$ |\$ /$$ |$$ |$$ | $$ | $$ | $$ |$$ | $$ |' -echo '$$ | \_/ $$ |\$$$$$$$ |\$$$$$$$ |$$ |\$$$$$$$\ $$ | \_/ $$ |$$ |$$ | $$ | \$$$$$$ |$$ | $$$$$$$$\' -echo '\__| \__| \_______| \____$$ |\__| \_______|\__| \__|\__|\__| \__| \______/ \__| \________|' -echo ' $$\ $$ |' -echo ' \$$$$$$ |' -echo ' \______/' -echo -e "\e[0m" - -doInstall=1 -true=1 -false=0 -# Define the tested version of Node.js. -NODE_TESTED="v10.1.0" -NPM_TESTED="V6.0.0" -USER=`whoami` -PM2_FILE=pm2_MagicMirror.json -force_arch= -pm2setup=$false - -trim() { - local var="$*" - # remove leading whitespace characters - var="${var#"${var%%[![:space:]]*}"}" - # remove trailing whitespace characters - var="${var%"${var##*[![:space:]]}"}" - echo -n "$var" -} - - - -mac=$(uname -s) -if [ $mac == 'Darwin' ]; then - echo this is a mac | tee -a $logfile - cmd=greadlink -else - cmd=readlink -fi - - -# put the log where the script is located -logdir=$(dirname $($cmd -f "$0")) -# if the script was execute from the web -if [[ $logdir != *"MagicMirror/installers"* ]]; then - # use the MagicMirror/installers folder, if setup - if [ -d MagicMirror ]; then - cd ~/MagicMirror/installers >/dev/null - logdir=$(pwd) - cd - >/dev/null - else - # use the users home folder if initial install - logdir=$HOME - fi -fi -logfile=$logdir/install.log -echo install log being saved to $logfile - -# Determine which Pi is running. -date +"install starting - %a %b %e %H:%M:%S %Z %Y" >>$logfile -ARM=$(uname -m) -echo installing on $ARM processor system >>$logfile -echo the os is $(lsb_release -a 2>/dev/null) >> $logfile -# Check the Raspberry Pi version. -if [ "$ARM" != "armv7l" ]; then - read -p "this appears not to be a Raspberry Pi 2 or 3, do you want to continue installation (y/N)?" choice - if [[ $choice =~ ^[Nn]$ ]]; then - echo user stopped install on $ARM hardware >>$logfile - echo -e "\e[91mSorry, your Raspberry Pi is not supported." - echo -e "\e[91mPlease run MagicMirror on a Raspberry Pi 2 or 3." - echo -e "\e[91mIf this is a Pi Zero, the setup will configure to run in server only mode wih a local browser." - exit; - fi - #if [ "$ARM" == "armv6l" ]; then - # echo forcing armv71 architecture for pi 0 >>$logfile - # force_arch=-'--arch=armv7l' - # fi -fi - -# Define helper methods. -function command_exists () { type "$1" &> /dev/null ;} -function verlte() { [ "$1" = "`echo -e "$1\n$2" | sort -V | head -n1`" ];} -function verlt() { [ "$1" = "$2" ] && return 1 || verlte $1 $2 ;} - -# Update before first apt-get -if [ $mac != 'Darwin' ]; then - echo -e "\e[96mUpdating packages ...\e[90m" | tee -a $logfile - upgrade=$false - update=$(sudo apt-get update 2>&1) - echo $update >> $logfile - update_rc=$? - if [ $update_rc -ne 0 ]; then - echo -e "\e[91mUpdate failed, retrying installation ...\e[90m" | tee -a $logfile - if [ $(echo $update | grep "apt-secure" | wc -l) -eq 1 ]; then - update=$(sudo apt-get update --allow-releaseinfo-change 2>&1) - update_rc=$? - echo $update >> $logfile - if [ $update_rc -ne 0 ]; then - echo "second apt-get update failed" $update | tee -a $logfile - exit 1 - else - echo "second apt-get update completed ok" >> $logfile - upgrade=$true - fi - fi - else - echo "apt-get update completed ok" >> $logfile - upgrade=$true - fi - if [ $upgrade -eq $true ]; then - upgrade_result=$(sudo apt-get upgrade 2>&1) - upgrade_rc=$? - echo apt upgrade result ="rc=$upgrade_rc $upgrade_result" >> $logfile - fi - - # Installing helper tools - echo -e "\e[96mInstalling helper tools ...\e[90m" | tee -a $logfile - sudo apt-get --assume-yes install curl wget git build-essential unzip || exit -fi - -# Check if we need to install or upgrade Node.js. -echo -e "\e[96mCheck current Node installation ...\e[0m" | tee -a $logfile -NODE_INSTALL=false -if command_exists node; then - echo -e "\e[0mNode currently installed. Checking version number." | tee -a $logfile - NODE_CURRENT=$(node -v) - if [ "$NODE_CURRENT." == "." ]; then - NODE_CURRENT="V1.0.0" - echo forcing low Node version >> $logfile - fi - echo -e "\e[0mMinimum Node version: \e[1m$NODE_TESTED\e[0m" | tee -a $logfile - echo -e "\e[0mInstalled Node version: \e[1m$NODE_CURRENT\e[0m" | tee -a $logfile - if verlte $NODE_CURRENT $NODE_TESTED; then - echo -e "\e[96mNode should be upgraded.\e[0m" | tee -a $logfile - NODE_INSTALL=true - - # Check if a node process is currenlty running. - # If so abort installation. - if pgrep "node" > /dev/null; then - echo -e "\e[91mA Node process is currently running. Can't upgrade." | tee -a $logfile - echo "Please quit all Node processes and restart the installer." | tee -a $logfile - echo $(ps -ef | grep node | grep -v \-\-color) | tee -a $logfile - exit; - fi - - else - echo -e "\e[92mNo Node.js upgrade necessary.\e[0m" | tee -a $logfile - fi - -else - echo -e "\e[93mNode.js is not installed.\e[0m" | tee -a $logfile - NODE_INSTALL=true -fi -# Install or upgrade node if necessary. -if $NODE_INSTALL; then - - echo -e "\e[96mInstalling Node.js ...\e[90m" | tee -a $logfile - - # Fetch the latest version of Node.js from the selected branch - # The NODE_STABLE_BRANCH variable will need to be manually adjusted when a new branch is released. (e.g. 7.x) - # Only tested (stable) versions are recommended as newer versions could break MagicMirror. - if [ $mac == 'Darwin' ]; then - brew install node - else - NODE_STABLE_BRANCH="10.x" - # sudo apt-get install --only-upgrade libstdc++6 - node_info=$(curl -sL https://deb.nodesource.com/setup_$NODE_STABLE_BRANCH | sudo -E bash - ) - echo Node release info = $node_info >> $logfile - if [ "$(echo $node_info | grep "not currently supported")." == "." ]; then - sudo apt-get install -y nodejs - else - echo node $NODE_STABLE_BRANCH version installer not available, doing manually >>$logfile - # no longer supported install - sudo apt-get install -y --only-upgrade libstdc++6 >> $logfile - # have to do it manually - node_vnum=$(echo $NODE_STABLE_BRANCH | awk -F. '{print $1}') - # get the highest release number in the stable branch line for this processor architecture - node_ver=$(curl -sL https://unofficial-builds.nodejs.org/download/release/index.tab | grep $ARM | grep -m 1 v$node_vnum | awk '{print $1}') - echo latest release in the $NODE_STABLE_BRANCH family for $ARM is $node_ver >> $logfile - curl -sL https://unofficial-builds.nodejs.org/download/release/$node_ver/node-$node_ver-linux-$ARM.tar.gz >node_release-$node_ver.tar.gz - cd /usr/local - echo using release tar file = node_release-$node_ver.tar.gz >> $logfile - sudo tar --strip-components 1 -xzf $HOME/node_release-$node_ver.tar.gz - cd - >/dev/null - rm ./node_release-$node_ver.tar.gz - fi - # get the new node version number - new_ver=$(node -v 2>&1) - # if there is a failure to get it due to a missing library - if [ $(echo $new_ver | grep "not found" | wc -l) -ne 0 ]; then - # - sudo apt-get install -y --only-upgrade libstdc++6 >> $logfile - fi - echo node version is $(node -v 2>&1 >>$logfile) - fi - echo -e "\e[92mNode.js installation Done! version=$(node -v)\e[0m" | tee -a $logfile -fi -# Check if we need to install or upgrade npm. -echo -e "\e[96mCheck current NPM installation ...\e[0m" | tee -a $logfile -NPM_INSTALL=false -if command_exists npm; then - echo -e "\e[0mNPM currently installed. Checking version number." | tee -a $logfile - NPM_CURRENT='V'$(npm -v) - echo -e "\e[0mMinimum npm version: \e[1m$NPM_TESTED\e[0m" | tee -a $logfile - echo -e "\e[0mInstalled npm version: \e[1m$NPM_CURRENT\e[0m" | tee -a $logfile - if verlte $NPM_CURRENT $NPM_TESTED; then - echo -e "\e[96mnpm should be upgraded.\e[0m" | tee -a $logfile - NPM_INSTALL=true - - # Check if a node process is currently running. - # If so abort installation. - if pgrep "npm" > /dev/null; then - echo -e "\e[91mA npm process is currently running. Can't upgrade." | tee -a $logfile - echo "Please quit all npm processes and restart the installer." | tee -a $logfile - exit; - fi - - else - echo -e "\e[92mNo npm upgrade necessary.\e[0m" | tee -a $logfile - fi - -else - echo -e "\e[93mnpm is not installed.\e[0m" | tee -a $logfile - NPM_INSTALL=true -fi - -# Install or upgrade node if necessary. -if $NPM_INSTALL; then - - echo -e "\e[96mInstalling npm ...\e[90m" | tee -a $logfile - - # Fetch the latest version of npm from the selected branch - # The NODE_STABLE_BRANCH variable will need to be manually adjusted when a new branch is released. (e.g. 7.x) - # Only tested (stable) versions are recommended as newer versions could break MagicMirror. - - #NODE_STABLE_BRANCH="9.x" - #curl -sL https://deb.nodesource.com/setup_$NODE_STABLE_BRANCH | sudo -E bash - - # - # if this is a mac, npm was installed with node - if [ $mac != 'Darwin' ]; then - sudo apt-get install -y npm >>$logfile - fi - # update to the latest. - echo upgrading npm to latest >> $logfile - sudo npm i -g npm >>$logfile - echo -e "\e[92mnpm installation Done! version=V$(npm -v)\e[0m" | tee -a $logfile -fi - -# Install MagicMirror -cd ~ -if [ $doInstall == 1 ]; then - if [ -d "$HOME/MagicMirror" ] ; then - echo -e "\e[93mIt seems like MagicMirror is already installed." | tee -a $logfile - echo -e "To prevent overwriting, the installer will be aborted." | tee -a $logfile - echo -e "Please rename the \e[1m~/MagicMirror\e[0m\e[93m folder and try again.\e[0m" | tee -a $logfile - echo "" - echo -e "If you want to upgrade your installation run \e[1m\e[97mupgrade-script\e[0m from the ~/MagicMirror/installers directory." | tee -a $logfile - echo "" - exit; - fi - - echo -e "\e[96mCloning MagicMirror ...\e[90m" | tee -a $logfile - if git clone --depth=1 https://github.com/MichMich/MagicMirror.git; then - echo -e "\e[92mCloning MagicMirror Done!\e[0m" | tee -a $logfile - else - echo -e "\e[91mUnable to clone MagicMirror." | tee -a $logfile - exit; - fi - - cd ~/MagicMirror || exit - if [ $(grep version package.json | awk -F: '{print $2}') == '"2.9.0",' -a $ARM == 'armv6l' ]; then - git fetch https://github.com/MichMich/MagicMirror.git develop >/dev/null 2>&1 - git branch develop FETCH_HEAD > /dev/null 2>&1 - git checkout develop > /dev/null 2>&1 - fi - echo -e "\e[96mInstalling dependencies ...\e[90m" | tee -a $logfile - if npm install $force_arch; then - echo -e "\e[92mDependencies installation Done!\e[0m" | tee -a $logfile - else - echo -e "\e[91mUnable to install dependencies!" | tee -a $logfile - exit; - fi - - # Use sample config for start MagicMirror - echo setting up initial config.js | tee -a $logfile - cp config/config.js.sample config/config.js -fi -# Check if plymouth is installed (default with PIXEL desktop environment), then install custom splashscreen. -echo -e "\e[96mCheck plymouth installation ...\e[0m" | tee -a $logfile -if command_exists plymouth; then - THEME_DIR="/usr/share/plymouth/themes" - echo -e "\e[90mSplashscreen: Checking themes directory.\e[0m" | tee -a $logfile - if [ -d $THEME_DIR ]; then - echo -e "\e[90mSplashscreen: Create theme directory if not exists.\e[0m" | tee -a $logfile - if [ ! -d $THEME_DIR/MagicMirror ]; then - sudo mkdir $THEME_DIR/MagicMirror - fi - - if sudo cp ~/MagicMirror/splashscreen/splash.png $THEME_DIR/MagicMirror/splash.png && sudo cp ~/MagicMirror/splashscreen/MagicMirror.plymouth $THEME_DIR/MagicMirror/MagicMirror.plymouth && sudo cp ~/MagicMirror/splashscreen/MagicMirror.script $THEME_DIR/MagicMirror/MagicMirror.script; then - echo - if [ "$(which plymouth-set-default-theme)." != "." ]; then - if sudo plymouth-set-default-theme -R MagicMirror; then - echo -e "\e[92mSplashscreen: Changed theme to MagicMirror successfully.\e[0m" | tee -a $logfile - else - echo -e "\e[91mSplashscreen: Couldn't change theme to MagicMirror!\e[0m" | tee -a $logfile - fi - fi - else - echo -e "\e[91mSplashscreen: Copying theme failed!\e[0m" | tee -a $logfile - fi - else - echo -e "\e[91mSplashscreen: Themes folder doesn't exist!\e[0m" | tee -a $logfile - fi -else - echo -e "\e[93mplymouth is not installed.\e[0m" | tee -a $logfile -fi - -# Use pm2 control like a service MagicMirror -read -p "Do you want use pm2 for auto starting of your MagicMirror (y/N)?" choice -if [[ $choice =~ ^[Yy]$ ]]; then - echo install and setup pm2 | tee -a $logfile - # assume pm2 will be found on the path - pm2cmd=pm2 - # check to see if already installed - pm2_installed=$(which $pm2cmd) - up="" - if [ $mac == 'Darwin' ]; then - up="--unsafe-perm" - launchctl=launchctl - launchctl_path=$(which $launchctl) - `export PATH=$PATH:${launchctl_path%/$launchctl}` - fi - # check to see if already installed - pm2_installed=$(which $pm2cmd) - if [ "$pm2_installed." != "." ]; then - # does it work? - pm2_fails=$(pm2 list | grep -i -m 1 "App Name" | wc -l ) - if [ $pm2_fails != 1 ]; then - # uninstall it - echo pm2 installed, but does not work, uninstalling >> $logfile - sudo npm uninstall $up -g pm2 >> $logfile - # force reinstall - pm2_installed= - fi - fi - # if not installed - if [ "$pm2_installed." == "." ]; then - # install it. - echo pm2 not installed, installing >>$logfile - result=$(sudo npm install $up -g pm2 2>&1) - echo pm2 install result $result >>$logfile - # if this is a mac - if [ $mac == 'Darwin' ]; then - echo this is a mac, fixup for path >>$logfile - # get the location of pm2 install - # parse the npm install output to get the command - pm2cmd=`echo $result | awk -F - '{print $1}' | tr -d '[:space:]'` - c='/pm2' - # get the path only - echo ${pm2cmd%$c} >installers/pm2path - fi - fi - echo get the pm2 platform specific startup command >>$logfile - # get the platform specific pm2 startup command - v=$($pm2cmd startup | tail -n 1) - if [ $mac != 'Darwin' ]; then - # check to see if we can get the OS package name (Ubuntu) - if [ $(which lsb_release| wc -l) >0 ]; then - # fix command - # if ubuntu 18.04, pm2 startup gets something wrong - if [ $(lsb_release -r | grep -m1 18.04 | wc -l) > 0 ]; then - v=$(echo $v | sed 's/\/bin/\/bin:\/bin/') - fi - fi - fi - echo startup command = $v >>$logfile - # execute the command returned - $v 2>&1 >>$logfile - echo pm2 startup command done >>$logfile - # is this is mac - # need to fix pm2 startup, only on catalina - if [ $mac == 'Darwin' ];then - if [ $(sw_vers -productVersion | head -c 6) == '10.15.' ]; then - # only do if the faulty tag is present (pm2 may fix this, before the script is fixed) - if [ $(grep -m 1 UserName /Users/$USER/Library/LaunchAgents/pm2.$USER.plist | wc -l) -eq 1 ]; then - # copy the pm2 startup file config - cp /Users/$USER/Library/LaunchAgents/pm2.$USER.plist . - # edit out the UserName key/value strings - sed -e '/UserName/{N;d;}' pm2.$USER.plist > pm2.$USER.plist.new - # copy the file back - sudo cp pm2.$USER.plist.new /Users/$USER/Library/LaunchAgents/pm2.$USER.plist - fi - fi - fi - # if the user is no pi, we have to fixup the pm2 json file - echo configure the pm2 config file for MagicMirror >>$logfile - if [ "$USER" != "pi" ]; then - echo the user is not pi >>$logfile - # go to the installers folder` - cd installers - # edit the startup script for the right user - echo change mm.sh >>$logfile - if [ ! -e mm_temp.sh ]; then - echo save copy of mm.sh >> $logfile - cp mm.sh mm_temp.sh - fi - if [ $(grep pi mm_temp.sh | wc -l) -gt 0 ]; then - echo change hard coded pi username >> $logfile - sed 's/pi/'$USER'/g' mm_temp.sh >mm.sh - else - echo change relative home path to hard coded path >> $logfile - hf=$(echo $HOME |sed 's/\//\\\//g') - sed 's/\~/'$hf'/g' mm_temp.sh >mm.sh - fi - # edit the pms config file for the right user - echo change $PM2_FILE >>$logfile - sed 's/pi/'$USER'/g' $PM2_FILE > pm2_MagicMirror_new.json - # make sure to use the updated file - PM2_FILE=pm2_MagicMirror_new.json - # if this is a mac - if [ $mac == 'Darwin' ]; then - # copy the path file to the system paths list - sudo cp ./pm2path /etc/paths.d - # change the name of the home path for mac - sed 's/home/Users/g' $PM2_FILE > pm2_MagicMirror_new1.json - # make sure to use the updated file - PM2_FILE=pm2_MagicMirror_new1.json - fi - echo now using this config file $PM2_FILE >>$logfile - # go back one cd level - cd - >/dev/null - fi - echo start MagicMirror via pm2 now >>$logfile - # tell pm2 to start the app defined in the config file - $pm2cmd start $HOME/MagicMirror/installers/$PM2_FILE - # tell pm2 to save that configuration, for start at boot - echo save MagicMirror pm2 config now >>$logfile - $pm2cmd save - pm2setup=$true -fi -# Disable Screensaver -choice=n -read -p "Do you want to disable the screen saver? (y/N)?" choice -if [[ $choice =~ ^[Yy]$ ]]; then - # if this is a mac - if [ $mac == 'Darwin' ]; then - # get the current setting - setting=$(defaults -currentHost read com.apple.screensaver idleTime) - # if its on - if [ $setting != 0 ] ; then - # turn it off - echo disable screensaver via mac profile >> $logfile - defaults -currentHost write com.apple.screensaver idleTime 0 - else - echo mac profile screen saver already disabled >> $logfile - fi - else - # find out if some screen saver running - - # get just the running processes and args - # just want the program name (1st token) - # find the 1st with 'saver' in it (should only be one) - # parse with path char, get the last field ( the actual pgm name) - - screen_saver_running=$(ps -A -o args | awk '{print $1}' | grep -m1 [s]aver | awk -F\/ '{print $NF}'); - - # if we found something - if [ "$screen_saver_running." != "." ]; then - # some screensaver running - case "$screen_saver_running" in - mate-screensaver) echo 'mate screen saver' >>$logfile - #killall mate-screensaver >/dev/null 2>&1 - #$ms -d >/dev/null 2>&1 - gsettings set org.mate.screensaver lock-enabled false 2>/dev/null - gsettings set org.mate.screensaver idle-activation-enabled false 2>/dev/null - gsettings set org.mate.screensaver lock_delay 0 2>/dev/null - echo " $screen_saver_running disabled" >> $logfile - DISPLAY=:0 mate-screensaver >/dev/null 2>&1 & - ;; - gnome-screensaver) echo 'gnome screen saver' >>$logfile - gnome_screensaver-command -d >/dev/null 2>&1 - echo " $screen_saver_running disabled" >> $logfile - ;; - xscreensaver) echo 'xscreensaver running' | tee -a $logfile - if [ $(grep -m1 'mode:' ~/.xscreensaver | awk '{print $2}') != 'off' ]; then - sed -i 's/$xsetting/mode: off/' ~/.xscreensaver - echo " xscreensaver set to off" >> $logfile - else - echo " xscreensaver already disabled" >> $logfile - fi - ;; - gsd-screensaver | gsd-screensaver-proxy) - setting=$(gsettings get org.gnome.desktop.screensaver lock-enabled) - setting1=$(gsettings get org.gnome.desktop.session idle-delay) - if [ "$setting $setting1" != 'false uint32 0' ]; then - echo disable screensaver via gsettings was $setting and $setting1>> $logfile - gsettings set org.gnome.desktop.screensaver lock-enabled false - gsettings set org.gnome.desktop.screensaver idle-activation-enabled false - gsettings set org.gnome.desktop.session idle-delay 0 - else - echo gsettings screen saver already disabled >> $logfile - fi - ;; - *) echo "some other screensaver $screen_saver_running" found | tee -a $logfile - echo "please configure it manually" | tee -a $logfile - ;; - esac - elif [ -e "/etc/lightdm/lightdm.conf" ]; then - # if screen saver NOT already disabled? - if [ $(grep 'xserver-command=X -s 0 -dpms' /etc/lightdm/lightdm.conf | wc -l) == 0 ]; then - echo install screensaver via lightdm.conf >> $logfile - sudo sed -i '/^\[Seat:\*\]/a xserver-command=X -s 0 -dpms' /etc/lightdm/lightdm.conf - else - echo screensaver via lightdm already disabled >> $logfile - fi - elif [ $(which gsettings | wc -l) == 1 ]; then - setting=$(gsettings get org.gnome.desktop.screensaver lock-enabled) - setting1=$(gsettings get org.gnome.desktop.session idle-delay) - if [ "$setting $setting1" != 'false uint32 0' ]; then - echo disable screensaver via gsettings was $setting and $setting1>> $logfile - gsettings set org.gnome.desktop.screensaver lock-enabled false - gsettings set org.gnome.desktop.screensaver idle-activation-enabled false - gsettings set org.gnome.desktop.session idle-delay 0 - else - echo gsettings screen saver already disabled >> $logfile - fi - elif [ -d "/etc/xdg/lxsession" ]; then - currently_set=$(grep -m1 '\-dpms' /etc/xdg/lxsession/LXDE-pi/autostart) - if [ "$currently_set." == "." ]; then - echo disable screensaver via lxsession >> $logfile - # turn it off for the future - sudo su -c "echo -e '@xset s noblank\n@xset s off\n@xset -dpms' >> /etc/xdg/lxsession/LXDE-pi/autostart" - # turn it off now - export DISPLAY=:0; xset s noblank;xset s off;xset -dpms - else - echo lxsession screen saver already disabled >> $logfile - fi - else - echo " " - echo -e "unable to disable screen saver, /etc/xdg/lxsession does not exist" | tee -a $logfile - fi - fi -fi -echo " " -if [ $pm2setup -eq $true ]; then - rmessage="pm2 start MagicMirror" -else - rmessage="DISPLAY=:0 npm start" -fi -echo -e "\e[92mWe're ready! Run \e[1m\e[97m$rmessage\e[0m\e[92m from the ~/MagicMirror directory to start your MagicMirror.\e[0m" | tee -a $logfile - -echo " " -echo " " - -date +"install completed - %a %b %e %H:%M:%S %Z %Y" >>$logfile diff --git a/installers/screensaveroff.sh b/installers/screensaveroff.sh deleted file mode 100755 index 24e145ba..00000000 --- a/installers/screensaveroff.sh +++ /dev/null @@ -1,101 +0,0 @@ -#/bin/bash -logfile=~/screensaver.log -mac=$(uname -s) - - if [ $mac == 'Darwin' ]; then - setting=$(defaults -currentHost read com.apple.screensaver idleTime) - if [ $setting != 0 ] ; then - echo disable screensaver via mac profile >> $logfile - defaults -currentHost write com.apple.screensaver idleTime 0 - else - echo mac profile screen saver already disabled >> $logfile - fi - else - # find out if some screen saver running - - # get just the running processes and args - # just want the program name - # find the 1st with 'saver' in it (should only be one) - # if the process name is a path, parse it and get the last field ( the actual pgm name) - - screen_saver_running=$(ps -A -o args | awk '{print $1}' | grep -m1 [s]aver | awk -F\/ '{print $NF}'); - - # if we found something - if [ "$screen_saver_running." != "." ]; then - # some screensaver running - case "$screen_saver_running" in - mate-screensaver) echo 'mate screen saver' >>$logfile - #killall mate-screensaver >/dev/null 2>&1 - #ms=$(which mate-screensaver-command) - #$ms -d >/dev/null 2>&1 - gsettings set org.mate.screensaver lock-enabled false 2>/dev/null - gsettings set org.mate.screensaver idle-activation-enabled false 2>/dev/null - gsettings set org.mate.screensaver lock_delay 0 2>/dev/null - echo " $screen_saver_running disabled" >> $logfile - DISPLAY=:0 mate-screensaver >/dev/null 2>&1 & - ;; - gnome-screensaver) echo 'gnome screen saver' >>$logfile - gnome_screensaver-command -d >/dev/null 2>&1 - echo " $screen_saver_running disabled" >> $logfile - ;; - xscreensaver) echo 'xscreensaver running' | tee -a $logfile - if [ $(grep -m1 'mode:' ~/.xscreensaver | awk '{print $2}') != 'off' ]; then - sed -i 's/$xsetting/mode: off/' ~/.xscreensaver - echo " xscreensaver set to off" >> $logfile - else - echo " xscreensaver already disabled" >> $logfile - fi - ;; - gsd-screensaver | gsd-screensaver-proxy) - setting=$(gsettings get org.gnome.desktop.screensaver lock-enabled) - setting1=$(gsettings get org.gnome.desktop.session idle-delay) - if [ "$setting $setting1" != 'false uint32 0' ]; then - echo disable screensaver via gsettings was $setting and $setting1>> $logfile - gsettings set org.gnome.desktop.screensaver lock-enabled false - gsettings set org.gnome.desktop.screensaver idle-activation-enabled false - gsettings set org.gnome.desktop.session idle-delay 0 - else - echo gsettings screen saver already disabled >> $logfile - fi - ;; - *) echo "some other screensaver $screen_saver_running" found | tee -a $logfile - echo "please configure it manually" | tee -a $logfile - ;; - esac - elif [ -e "/etc/lightdm/lightdm.conf" ]; then - # if screen saver NOT already disabled? - if [ $(grep 'xserver-command=X -s 0 -dpms' /etc/lightdm/lightdm.conf | wc -l) == 0 ]; then - echo install screensaver via lightdm.conf >> $logfile - sudo sed -i '/^\[Seat:\*\]/a xserver-command=X -s 0 -dpms' /etc/lightdm/lightdm.conf - #sudo cp _myconf /etc/lightdm/lightdm.conf - #rm _myconf >/dev/null - else - echo screensaver via lightdm already disabled >> $logfile - fi - elif [ $(which gsettings | wc -l) == 1 ]; then - setting=$(gsettings get org.gnome.desktop.screensaver lock-enabled) - setting1=$(gsettings get org.gnome.desktop.session idle-delay) - if [ "$setting $setting1" != 'false uint32 0' ]; then - echo disable screensaver via gsettings was $setting and $setting1>> $logfile - gsettings set org.gnome.desktop.screensaver lock-enabled false - gsettings set org.gnome.desktop.screensaver idle-activation-enabled false - gsettings set org.gnome.desktop.session idle-delay 0 - else - echo gsettings screen saver already disabled >> $logfile - fi - elif [ -d "/etc/xdg/lxsession" ]; then - currently_set=$(grep -m1 '\-dpms' /etc/xdg/lxsession/LXDE-pi/autostart) - if [ "$currently_set." == "." ]; then - echo disable screensaver via lxsession >> $logfile - # turn it off for the future - sudo su -c "echo -e '@xset s noblank\n@xset s off\n@xset -dpms' >> /etc/xdg/lxsession/LXDE-pi/autostart" - # turn it off now - export DISPLAY=:0; xset s noblank;xset s off;xset -dpms - else - echo lxsession screen saver already disabled >> $logfile - fi - else - echo " " - echo -e "unable to disable screen saver, /etc/xdg/lxsession does not exist" | tee >>$logfile - fi - fi diff --git a/installers/upgrade-script.sh b/installers/upgrade-script.sh deleted file mode 100755 index 88dd2bb7..00000000 --- a/installers/upgrade-script.sh +++ /dev/null @@ -1,361 +0,0 @@ -#!/bin/bash -# only DO npm installs when flag is set to 1 -# test when set to 0 -true=1 -false=0 -doinstalls=$false -force=$false -justActive=$true -test_run=$true -stashed=$false -keyFile=package.json -forced_arch= -git_active_lock='./.git/index.lock' -lf=$'\n' -git_user_name= -git_user_email= - -trim() { - local var="$*" - # remove leading whitespace characters - var="${var#"${var%%[![:space:]]*}"}" - # remove trailing whitespace characters - var="${var%"${var##*[![:space:]]}"}" - echo -n "$var" -} -# is this a mac -mac=$(uname -s) -# get the processor architecture -arch=$(uname -m) -if [ $mac == 'Darwin' ]; then - cmd=greadlink -else - cmd=readlink -fi -if [ -d ~/MagicMirror ]; then - - # put the log where the script is located - logdir=$(dirname $($cmd -f "$0")) - # if the script was execute from the web - if [[ $logdir != *"MagicMirror/installers"* ]]; then - # use the MagicMirror/installers folder - cd ~/MagicMirror/installers >/dev/null - logdir=$(pwd) - cd - >/dev/null - fi - logfile=$logdir/upgrade.log - echo the log will be $logfile - echo >>$logfile - date +"Upgrade started - %a %b %e %H:%M:%S %Z %Y" >>$logfile - echo system is $(uname -a) >> $logfile - echo the os is $(lsb_release -a) >> $logfile - - # because of how its executed from the web, p0 gets overlayed with parm - # check to see if a parm was passed .. easy apply without editing - p0=$0 - # if not 'bash', and some parm specified - if [ $0 != 'bash' -a "$1." != "." ]; then - # then executed locally - # get the parm - p0=$1 - fi - # lowercase it.. watch out, mac stuff doesn't work with tr, etc - p0=$(echo $p0 | cut -c 1-5 | awk '{print tolower($0)}' ) - if [ $p0 == 'apply' ]; then - echo user requested to apply changes >>$logfile - doinstalls=$true - test_run=$false - elif [ $p0 == 'force' ]; then - echo user requested to force apply changes >>$logfile - doinstalls=$true - force=$true - test_run=$false - fi - - if [ $test_run == $true ]; then - echo doing test run = true | tee -a $logfile - else - echo doing test run = false | tee -a $logfile - fi - - # if we want just the modules listed in config.js now - if [ $justActive == $true ]; then - if [ ! -f ~/MagicMirror/installers/dumpactivemodules.js ]; then - echo downloading dumpactivemodules script >> $logfile - curl -sL https://www.dropbox.com/s/wwe6bfg2lcjmj43/dumpactivemodules.js?dl=0 > ~/MagicMirror/installers/dumpactivemodules.js - fi - fi - echo update log will be in $logfile - # used for parsing the array of module names - SAVEIFS=$IFS # Save current IFS - IFS=$'\n' - - echo | tee -a $logfile - # if the git lock file exists and git is not running - if [ -f git_active_lock ]; then - # check to see if git is actually running - git_running=`ps -ef | grep git | grep -v color | grep -v 'grep git' | wc -l` - # if not running - if [ git_running == $false ]; then - # clean up the dangling lock file - echo erasing abandonded git lock file >> $logfile - rm git_active_lock >/dev/null 2>&1 - else - # git IS running, we can't proceed - echo it appears another instance of git is running | tee -a $logfile - # if this is an actual run - if [ $doinstalls == $true ]; then - # force it back to test run - doinstalls = $false - test_run=$true - echo forcing test run mode | tee -a $logfile - echo please resolve git running already and start the update again | tee -a $logfile - fi - fi - fi - - # change to MagicMirror folder - cd ~/MagicMirror - - # save custom.css - cd css - echo "saving custom.css" | tee -a $logfile - cp -p custom.css save_custom.css - cd - >/dev/null - save_alias=$(alias git 2>/dev/null) - lang=$(locale | grep LANGUAGE | awk -F= '{print $2}') - # make sure git respones are in english, so code works - if [ "$lang." != "en_US.UTF-8." ]; then - echo not english or locale not set, set git alias >>$logfile - if [ "$LC_ALL." == "." ]; then - alias git='LANGUAGE=en_US.UTF-8 git' >>$logfile - else - alias git='LC_ALL=en_US.UTF-8 git' >>$logfile - fi - #alias >>$logfile - fi - # get the git remote name - remote=$(git remote 2>/dev/null | awk '{print $1}') - - # if remote name set - if [ "$remote." != "." ]; then - - echo remote name = $remote >>$logfile - - # get the local and remote package.json versions - local_version=$(grep -m1 version package.json | awk -F\" '{print $4}') - remote_version=$(curl -s https://raw.githubusercontent.com/MichMich/MagicMirror/master/package.json | grep -m1 version | awk -F\" '{print $4}') - - # only change if they are different - if [ "$local_version." != "$remote_version." -o $force == $true -o $test_run == $true ]; then - echo upgrading from version $local_version to $remote_version | tee -a $logfile - - # get the latest upgrade - echo fetching latest revisions | tee -a $logfile - git fetch $remote >/dev/null - rc=$? - echo git fetch rc=$rc >>$logfile - if [ $rc -eq 0 ]; then - - # need to get the current branch - current_branch=$(git branch | grep "*" | awk '{print $2}') - echo current branch = $current_branch >>$logfile - - git status 2>&1 >>$logfile - - # get the names of the files that are different locally - diffs=$(git status 2>&1 | grep modified | awk -F: '{print $2}') - - # split names into an array - diffs=($diffs) # split to array $diffs - - # if there are different files (array size greater than zero) - if [ ${#diffs[@]} -gt 0 ]; then - package_lock=0 - echo there are "${#diffs[@]}" local files that are different than the master repo | tee -a $logfile - echo | tee -a $logfile - for file in "${diffs[@]}" - do - echo "$file" | tee -a $logfile - if [ $(echo $file | grep '\-lock.json$' | wc -l) -eq 1 ]; then - package_lock=$true - fi - done - echo | tee -a $logfile - if [ $package_lock -eq 1 ]; then - echo "any *-lock.json files do not need to be saved" - fi - read -p "do you want to save these files for later (Y/n)?" choice - echo save/restore files selection = $choice >> $logfile - if [[ $choice =~ ^[Yy]$ ]]; then - git_user=$(git config --global --get user.email) - if [ "git_user." == "." ]; then - git_user_name="-c user.name=upgrade_script" - git_user_email="-c user.email=script@upgrade.com" - fi - git git_user_name git_user_email stash >>$logfile - stashed=$true - else - for file in "${diffs[@]}" - do - f="$(trim "$file")" - echo restoring $f from repo >> $logfile - if [ $test_run == $false ]; then - git checkout HEAD -- $f | tee -a $logfile - else - echo skipping restore for $f, doing test run | tee -a $logfile - fi - done - fi - else - echo no files different from github version >> $logfile - fi - - # lets test merge, in memory, no changes to working directory or local repo - test_merge_output=$(git merge-tree `git merge-base $current_branch HEAD` HEAD $current_branch | grep "^<<<<<<<\|changed in both") - echo "test merge result rc='$test_merge_output' , if empty, no conflicts" >> $logfile - - # if there were no conflicts reported - if [ "$test_merge_output." == "." ]; then - - if [ $test_run == $false ]; then - # go ahead and merge now - echo "executing merge, apply specified" >> $logfile - # get the text output of merge - merge_output=$(git merge $remote/$current_branch 2>&1) - # and its return code - merge_result=$? - # make any long line readable - merge_output=$(echo $merge_output | tr '|' '\n'| sed "s/create/\\${lf}create/g" | sed "s/mode\ change/\\${lf}mode\ change/g") - echo -e "merge result rc= $merge_result\n $merge_output">> $logfile - else - echo "skipping merge, only test run" >> $logfile - merge_output='' - merge_result=0 - fi - - # if no merge errors - if [ $merge_result == 0 ]; then - # some updates applied - if [ "$merge_output." != 'Already up to date.' -o $test_run == $true ]; then - # update any dependencies for base - if [ $doinstalls == $true ]; then - # if this is a pi zero - echo processor architecture is $arch >> $logfile - if [ "$arch" == "armv6l" ]; then - # force to look like pi 2 - echo forcing architecture armv7l >>$logfile - forced_arch='--arch=armv7l' - fi - echo "updating MagicMirror runtime, please wait" | tee -a $logfile - npm install $forced_arch 2>&1 | tee -a $logfile - done_update=`date +"completed - %a %b %e %H:%M:%S %Z %Y"` - echo npm install $done_update on base >> $ logfile - fi - # process updates for modules after base changed - cd modules - if [ $justActive == $true ]; then - # get the list of ACTIVE modules with package.json files - mtype=active - modules=$(node ../installers/dumpactivemodules.js) - else - # get the list of INSTALLED modules with package.json files - mtype=installed - modules=$(find -maxdepth 2 -name 'package.json' -printf "%h\n" | cut -d'/' -f2 ) - fi - modules=($modules) # split to array $modules - - # if the array has entries in it - if [ ${#modules[@]} -gt 0 ]; then - echo >> $logfile - echo "processing dependency changes for $mtype modules with package.json files" | tee -a $logfile - echo - for module in "${modules[@]}" - do - echo "processing for module" $module please wait | tee -a $logfile - echo '----------------------------------' | tee -a $logfile - # change to that directory - cd $module - # process its dependencies - if [ $doinstalls == $true ]; then - npm install $forced_arch 2>&1| tee -a $logfile - else - echo skipped processing for $module, doing test run | tee -a $logfile - fi - # return to modules folder - cd .. >/dev/null - echo "processing complete for module" $module | tee -a $logfile - echo - done - else - echo "no modules found needing npm refresh" | tee -a $logfile - fi - # return to Magic Mirror folder - cd .. >/dev/null - else - echo "no changes detected for modules, skipping " | tee -a $logfile - fi - else - echo there were merge errors | tee -a $logfile - echo $merge_output | tee -a %logfile - echo you should examine and resolve them | tee -a $logfile - echo using the command git log --oneline --decorate | tee -a $logfile - git log --oneline --decorate | tee -a $logfile - fi - else - echo "there are merge conflicts to be resolved, no changes have been applied" | tee -a $logfile - echo $test_merge_output | tee -a $logfile - fi - else - echo "MagicMirror git fetch failed" | tee -a $logfile - fi - else - echo "local version $local_version already same as master $remote_version" | tee -a $logfile - fi - else - echo "Unable to determine upstream git repository" | tee -a $logfile - fi - # should be in MagicMirror base - cd css - # restore custom.css - echo "restoring custom.css" | tee -a $logfile - cp -p save_custom.css custom.css - rm save_custom.css - cd - >/dev/null - if [ "$lang." != "en_US.UTF-8." ]; then - if [ "$save_alias." != "." ]; then - echo restoring git alias >>$logfile - $save_alias >/dev/null - else - echo removing git alias >>$logfile - unalias git >/dev/null - fi - fi - IFS=$SAVEIFS # Restore IFS - - if [ $stashed == $true ]; then - if [ $test_run == $true ]; then - echo test run, restoring files stashed | tee -a $logfile - git git_user_name git_user_email stash pop >> $logfile - else - echo we stashed a set of files that appear changed from the latest repo versions. you should review them | tee -a $logfile - git stash show --name-only > installers/stashed_files - echo see installers/stashed_files for the list - echo - echo you can use git checkout "stash@{0}" -- filename to extract one file from the stash - echo - echo or git stash pop to restore them all - echo - echo WARNING.. - echo WARNING.. either will overlay the file just installed by the update - echo WARNING.. - fi - fi - # return to original folder - cd - >/dev/null - date +"Upgrade ended - %a %b %e %H:%M:%S %Z %Y" >>$logfile -else - echo It appears MagicMirror has not been installed on this system - echo please run the installer, "raspberry.sh" first -fi - From a2c743167d8330a60ed0f768cc030cafffdc879d Mon Sep 17 00:00:00 2001 From: Sam Detweiler Date: Sun, 12 Jan 2020 10:19:37 -0600 Subject: [PATCH 009/104] cleanup installers foldr --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f7ad78cf..d7e63e7e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). *This release is scheduled to be released on 2020-04-01.* +### Deleted +- cleanup installers folder, remove externalized scripts + ### Added - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". From 818ed5d1894d84e512e81c6b2d9c0a2bc7e58fc2 Mon Sep 17 00:00:00 2001 From: Sebastian Limbach Date: Sun, 12 Jan 2020 20:15:04 +0100 Subject: [PATCH 010/104] Add different GitHub repos This commit adds the official docker image repo as well as the installation scripts repo to the issue template to avoid the creation of issue which don't belong to the MagicMirror core. --- .github/ISSUE_TEMPLATE.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 736795d7..897cfb41 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,8 +1,21 @@ -Please only submit reproducible issues. - +## I'm not sure if this is a bug If you're not sure if it's a real bug or if it's just you, please open a topic on the forum: [https://forum.magicmirror.builders/category/15/bug-hunt](https://forum.magicmirror.builders/category/15/bug-hunt) + +## I'm having troubles installing or configuring MagicMirror Problems installing or configuring your MagicMirror? Check out: [https://forum.magicmirror.builders/category/10/troubleshooting](https://forum.magicmirror.builders/category/10/troubleshooting) +## I found a bug in the official MagicMirror Docker image +If you are facing an issue or found a bug while running MagicMirror inside a Docker container please create an issue in the GitHub repository of the official MagicMirror Docker image: +[https://github.com/bastilimbach/docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror) + +## I found a bug in the official MagicMirror installer +If you are facing an issue or found a bug while trying to install MagicMirror via the official installer please report it in the respective GitHub repository: +[https://github.com/sdetweil/MagicMirror_scripts](https://github.com/sdetweil/MagicMirror_scripts) + +--- + +## I found a bug in MagicMirror +Please make sure to only submit reproducible issues. You can safely remove everything above dividing line. When submitting a new issue, please supply the following information: **Platform**: Place your platform here... give us your web browser/Electron version *and* your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX). From 61256f98ca0dcf3801dc4b10e7bd5c3285c2027b Mon Sep 17 00:00:00 2001 From: Sebastian Limbach Date: Mon, 13 Jan 2020 09:40:38 +0100 Subject: [PATCH 011/104] Fix typo --- .github/ISSUE_TEMPLATE.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 897cfb41..9cd28f10 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -15,7 +15,7 @@ If you are facing an issue or found a bug while trying to install MagicMirror vi --- ## I found a bug in MagicMirror -Please make sure to only submit reproducible issues. You can safely remove everything above dividing line. +Please make sure to only submit reproducible issues. You can safely remove everything above the dividing line. When submitting a new issue, please supply the following information: **Platform**: Place your platform here... give us your web browser/Electron version *and* your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX). From 1fd5fd4832296d750fefffc18a78fa68b121e604 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Tue, 14 Jan 2020 09:20:50 +0100 Subject: [PATCH 012/104] Update ISSUE_TEMPLATE.md --- .github/ISSUE_TEMPLATE.md | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 9cd28f10..43d92597 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -4,14 +4,14 @@ If you're not sure if it's a real bug or if it's just you, please open a topic o ## I'm having troubles installing or configuring MagicMirror Problems installing or configuring your MagicMirror? Check out: [https://forum.magicmirror.builders/category/10/troubleshooting](https://forum.magicmirror.builders/category/10/troubleshooting) -## I found a bug in the official MagicMirror Docker image -If you are facing an issue or found a bug while running MagicMirror inside a Docker container please create an issue in the GitHub repository of the official MagicMirror Docker image: -[https://github.com/bastilimbach/docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror) - -## I found a bug in the official MagicMirror installer -If you are facing an issue or found a bug while trying to install MagicMirror via the official installer please report it in the respective GitHub repository: +## I found a bug in the MagicMirror installer +If you are facing an issue or found a bug while trying to install MagicMirror via the installer please report it in the respective GitHub repository: [https://github.com/sdetweil/MagicMirror_scripts](https://github.com/sdetweil/MagicMirror_scripts) +## I found a bug in the MagicMirror Docker image +If you are facing an issue or found a bug while running MagicMirror inside a Docker container please create an issue in the GitHub repository of the MagicMirror Docker image: +[https://github.com/bastilimbach/docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror) + --- ## I found a bug in MagicMirror @@ -20,9 +20,9 @@ When submitting a new issue, please supply the following information: **Platform**: Place your platform here... give us your web browser/Electron version *and* your hardware (Raspberry Pi 2/3, Windows, Mac, Linux, System V UNIX). -**Node Version**: Make sure it's version 0.12.13 or later. +**Node Version**: Make sure it's version 8 or later. -**MagicMirror Version**: Now that the versions have split, tell us if you are using the PHP version (v1) or the newer JavaScript version (v2). +**MagicMirror Version**: Please let us now which version of MagicMirror you are running. It can be found in the `package.log` file. **Description**: Provide a detailed description about the issue and include specific details to help us understand the problem. Adding screenshots will help describing the problem. From 81aab7e86f7ea5dfbc0de2ea2b09857723527f39 Mon Sep 17 00:00:00 2001 From: Adi Miller Date: Thu, 16 Jan 2020 16:26:20 +0200 Subject: [PATCH 013/104] Added the ability to hide the temp label and weather icon in the `currentweather` module to allow showing only information such as wind and sunset/rise. --- CHANGELOG.md | 3 +- .../default/currentweather/currentweather.js | 55 ++++++++++--------- 2 files changed, 31 insertions(+), 27 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e63e7e..476264b8 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). - cleanup installers folder, remove externalized scripts ### Added -- Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". +- Finish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". +- Added the ability to hide the temp label and weather icon in the `currentweather` module to allow showing only information such as wind and sunset/rise. ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js index 7d917132..dcf771af 100644 --- a/modules/default/currentweather/currentweather.js +++ b/modules/default/currentweather/currentweather.js @@ -44,6 +44,7 @@ Module.register("currentweather",{ calendarClass: "calendar", onlyTemp: false, + hideTemp: false, roundTemp: false, iconTable: { @@ -194,36 +195,38 @@ Module.register("currentweather",{ var large = document.createElement("div"); large.className = "large light"; - var weatherIcon = document.createElement("span"); - weatherIcon.className = "wi weathericon " + this.weatherType; - large.appendChild(weatherIcon); + if (this.config.hideTemp === true) { + var weatherIcon = document.createElement("span"); + weatherIcon.className = "wi weathericon " + this.weatherType; + large.appendChild(weatherIcon); - var degreeLabel = ""; - if (this.config.units === "metric" || this.config.units === "imperial") { - degreeLabel += "°"; - } - if(this.config.degreeLabel) { - switch(this.config.units) { - case "metric": - degreeLabel += "C"; - break; - case "imperial": - degreeLabel += "F"; - break; - case "default": - degreeLabel += "K"; - break; + var degreeLabel = ""; + if (this.config.units === "metric" || this.config.units === "imperial") { + degreeLabel += "°"; + } + if(this.config.degreeLabel) { + 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 = "."; - } + if (this.config.decimalSymbol === "") { + this.config.decimalSymbol = "."; + } - var temperature = document.createElement("span"); - temperature.className = "bright"; - temperature.innerHTML = " " + this.temperature.replace(".", this.config.decimalSymbol) + degreeLabel; - large.appendChild(temperature); + var temperature = document.createElement("span"); + temperature.className = "bright"; + temperature.innerHTML = " " + this.temperature.replace(".", this.config.decimalSymbol) + degreeLabel; + large.appendChild(temperature); + } if (this.config.showIndoorTemperature && this.indoorTemperature) { var indoorIcon = document.createElement("span"); From 63950f572a2ebc30fcad25fc2e52ca64679754a7 Mon Sep 17 00:00:00 2001 From: Adi Miller Date: Thu, 16 Jan 2020 16:47:49 +0200 Subject: [PATCH 014/104] Adding trailing enter to avoid build warning. --- modules/default/alert/README.md | 2 +- modules/default/calendar/README.md | 2 +- modules/default/clock/README.md | 2 +- modules/default/compliments/README.md | 2 +- modules/default/currentweather/README.md | 2 +- modules/default/helloworld/README.md | 2 +- modules/default/newsfeed/README.md | 2 +- modules/default/updatenotification/README.md | 2 +- modules/default/weather/README.md | 2 +- modules/default/weatherforecast/README.md | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/default/alert/README.md b/modules/default/alert/README.md index 3bd5d00d..4d3c6a65 100644 --- a/modules/default/alert/README.md +++ b/modules/default/alert/README.md @@ -1,4 +1,4 @@ # Module: Alert The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index fbb8bfd9..5c8f187b 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -2,4 +2,4 @@ The `calendar` module is one of the default modules of the MagicMirror. This module displays events from a public .ical calendar. It can combine multiple calendars. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html). diff --git a/modules/default/clock/README.md b/modules/default/clock/README.md index 1c0bdf8c..34a1448d 100644 --- a/modules/default/clock/README.md +++ b/modules/default/clock/README.md @@ -2,4 +2,4 @@ The `clock` module is one of the default modules of the MagicMirror. This module displays the current date and time. The information will be updated realtime. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/clock.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/clock.html). diff --git a/modules/default/compliments/README.md b/modules/default/compliments/README.md index 7825bb02..c746f318 100644 --- a/modules/default/compliments/README.md +++ b/modules/default/compliments/README.md @@ -2,4 +2,4 @@ The `compliments` module is one of the default modules of the MagicMirror. This module displays a random compliment. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/compliments.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/compliments.html). diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md index 3cbdcbea..27b047da 100644 --- a/modules/default/currentweather/README.md +++ b/modules/default/currentweather/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/currentweather.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/currentweather.html). diff --git a/modules/default/helloworld/README.md b/modules/default/helloworld/README.md index aa9f87f3..8ad06f77 100644 --- a/modules/default/helloworld/README.md +++ b/modules/default/helloworld/README.md @@ -1,4 +1,4 @@ # Module: Hello World The `helloworld` module is one of the default modules of the MagicMirror. It is a simple way to display a static text on the mirror. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md index 4dc4877b..33690aa6 100644 --- a/modules/default/newsfeed/README.md +++ b/modules/default/newsfeed/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). diff --git a/modules/default/updatenotification/README.md b/modules/default/updatenotification/README.md index 652f451f..af6305e6 100644 --- a/modules/default/updatenotification/README.md +++ b/modules/default/updatenotification/README.md @@ -2,4 +2,4 @@ The `updatenotification` module is one of the default modules of the MagicMirror. This will display a message whenever a new version of the MagicMirror application is available. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/updatenotification.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/updatenotification.html). diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md index 5b03b141..ebc301f4 100755 --- a/modules/default/weather/README.md +++ b/modules/default/weather/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weather.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weather.html). diff --git a/modules/default/weatherforecast/README.md b/modules/default/weatherforecast/README.md index 95762daa..7dfbd16f 100644 --- a/modules/default/weatherforecast/README.md +++ b/modules/default/weatherforecast/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weatherforecast.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weatherforecast.html). From 8aa745471b4b8d77909a780bfef43f23cdce9375 Mon Sep 17 00:00:00 2001 From: Kurtis Blankenship Date: Fri, 17 Jan 2020 22:53:14 -0600 Subject: [PATCH 015/104] fix: Issue #1798 - fixing recurrent calendar events crosstime DST --- config/config.js.sample | 4 +- modules/default/calendar/calendarfetcher.js | 9 +- .../calendar/vendor/ical.js/node-ical.js | 15 +- modules/default/compliments/compliments.js | 22 +-- .../weather/forecastweather_default.js | 46 ++--- .../weather/forecastweather_options.js | 52 ++--- tests/e2e/modules/mocks/weather_current.js | 98 +++++----- tests/e2e/modules/mocks/weather_forecast.js | 184 +++++++++--------- tests/e2e/vendor_spec.js | 8 +- vendor/package-lock.json | 25 +-- 10 files changed, 235 insertions(+), 228 deletions(-) diff --git a/config/config.js.sample b/config/config.js.sample index 115e2dd2..1d780e23 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -25,11 +25,11 @@ var config = { timeFormat: 24, units: "metric", // serverOnly: true/false/"local" , - // local for armv6l processors, default + // local for armv6l processors, default // starts serveronly and then starts chrome browser // false, default for all NON-armv6l devices // true, force serveronly mode, because you want to.. no UI on this device - + modules: [ { module: "alert", diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index d705905c..57c1586d 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -184,7 +184,14 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri // For recurring events, get the set of start dates that fall within the range // of dates we"re looking for. - var dates = rule.between(past, future, true, limitFunction); + // kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time + var pastLocal = moment(past).subtract(past.getTimezoneOffset(), "minutes").toDate(); + var futureLocal = moment(past).subtract(future.getTimezoneOffset(), "minutes").toDate(); + var datesLocal = rule.between(pastLocal, futureLocal, true, limitFunction); + var dates = datesLocal.map(function(dateLocal) { + var date = moment(dateLocal).add(dateLocal.getTimezoneOffset(), "minutes").toDate(); + return date; + }); // The "dates" array contains the set of dates within our desired date range range that are valid // for the recurrence rule. *However*, it"s possible for us to have a specific recurrence that diff --git a/modules/default/calendar/vendor/ical.js/node-ical.js b/modules/default/calendar/vendor/ical.js/node-ical.js index 14855d63..1da04375 100644 --- a/modules/default/calendar/vendor/ical.js/node-ical.js +++ b/modules/default/calendar/vendor/ical.js/node-ical.js @@ -26,6 +26,17 @@ exports.parseFile = function(filename){ var rrule = require('rrule').RRule +function getLocaleISOString(date) { + var year = date.getFullYear().toString(10).padStart(4,'0'); + var month = date.getMonth().toString(10).padStart(2,'0'); + var day = date.getDate().toString(10).padStart(2,'0'); + var hour = date.getHours().toString(10).padStart(2,'0'); + var minute = date.getMinutes().toString(10).padStart(2,'0'); + var second = date.getSeconds().toString(10).padStart(2,'0'); + + return `${year}${month}${day}T${hour}${minute}${second}Z`; +} + ical.objectHandlers['RRULE'] = function(val, params, curr, stack, line){ curr.rrule = line; return curr @@ -50,8 +61,8 @@ ical.objectHandlers['END'] = function (val, params, curr, stack) { if (typeof curr.start.toISOString === 'function') { try { - rule += ';DTSTART=' + curr.start.toISOString().replace(/[-:]/g, ''); - rule = rule.replace(/\.[0-9]{3}/, ''); + // kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time + rule += ';DTSTART=' + getLocaleISOString(curr.start); } catch (error) { console.error("ERROR when trying to convert to ISOString", error); } diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 198664b7..606da1df 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -39,7 +39,7 @@ Module.register("compliments", { afternoonEndTime: 17, random: true }, - lastIndexUsed:-1, + lastIndexUsed:-1, // Set currentweather from module currentWeatherType: "", @@ -151,7 +151,7 @@ Module.register("compliments", { // get the current time of day compliments list var compliments = this.complimentArray(); // variable for index to next message to display - let index=0 + let index=0; // are we randomizing if(this.config.random){ // yes @@ -160,28 +160,28 @@ Module.register("compliments", { else{ // no, sequetial // if doing sequential, don't fall off the end - index = (this.lastIndexUsed >= (compliments.length-1))?0: ++this.lastIndexUsed + index = (this.lastIndexUsed >= (compliments.length-1))?0: ++this.lastIndexUsed; } return compliments[index]; }, -// Override dom generator. + // Override dom generator. getDom: function() { var wrapper = document.createElement("div"); wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright pre-line"; - // get the compliment text + // get the compliment text var complimentText = this.randomCompliment(); - // split it into parts on newline text - var parts= complimentText.split('\n') + // split it into parts on newline text + var parts= complimentText.split("\n"); // create a span to hold it all - var compliment=document.createElement('span') - // process all the parts of the compliment text + var compliment=document.createElement("span"); + // process all the parts of the compliment text for (part of parts){ // create a text element for each part - compliment.appendChild(document.createTextNode(part)) + compliment.appendChild(document.createTextNode(part)); // add a break ` - compliment.appendChild(document.createElement('BR')) + compliment.appendChild(document.createElement("BR")); } // remove the last break compliment.lastElementChild.remove(); diff --git a/tests/configs/modules/weather/forecastweather_default.js b/tests/configs/modules/weather/forecastweather_default.js index 697cbeb4..c87ca260 100644 --- a/tests/configs/modules/weather/forecastweather_default.js +++ b/tests/configs/modules/weather/forecastweather_default.js @@ -6,31 +6,31 @@ */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - language: "en", - timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - }, - }, + language: "en", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, - modules: [ - { - module: "weather", - position: "bottom_bar", - config: { - type: "forecast", - location: "Munich", - apiKey: "fake key", - weatherEndpoint: "/forecast/daily", - initialLoadDelay: 3000 - } - } - ] + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "forecast", + location: "Munich", + apiKey: "fake key", + weatherEndpoint: "/forecast/daily", + initialLoadDelay: 3000 + } + } + ] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ diff --git a/tests/configs/modules/weather/forecastweather_options.js b/tests/configs/modules/weather/forecastweather_options.js index cc1b8773..82e3da08 100644 --- a/tests/configs/modules/weather/forecastweather_options.js +++ b/tests/configs/modules/weather/forecastweather_options.js @@ -6,34 +6,34 @@ */ let config = { - port: 8080, - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - language: "en", - timeFormat: 12, - units: "metric", - electronOptions: { - webPreferences: { - nodeIntegration: true, - }, - }, + language: "en", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, - modules: [ - { - module: "weather", - position: "bottom_bar", - config: { - type: "forecast", - location: "Munich", - apiKey: "fake key", - weatherEndpoint: "/forecast/daily", - initialLoadDelay: 3000, - showPrecipitationAmount: true, - colored: true, - tableClass: "myTableClass" - } - } - ] + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "forecast", + location: "Munich", + apiKey: "fake key", + weatherEndpoint: "/forecast/daily", + initialLoadDelay: 3000, + showPrecipitationAmount: true, + colored: true, + tableClass: "myTableClass" + } + } + ] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ diff --git a/tests/e2e/modules/mocks/weather_current.js b/tests/e2e/modules/mocks/weather_current.js index cd87aa11..807ee559 100644 --- a/tests/e2e/modules/mocks/weather_current.js +++ b/tests/e2e/modules/mocks/weather_current.js @@ -1,54 +1,54 @@ -const _ = require('lodash'); +const _ = require("lodash"); function generateWeather(extendedData = {}) { - return JSON.stringify(_.merge({}, { - coord:{ - lon: 11.58, - lat: 48.14 - }, - weather:[ - { - id: 615, - main: "Snow", - description: "light rain and snow", - icon: "13d" - }, - { - id: 500, - main: "Rain", - description: "light rain", - icon: "10d" - } - ], - base: "stations", - main:{ - temp: 1.49, - pressure: 1005, - humidity: 93.7, - temp_min: 1, - temp_max: 2 - }, - visibility: 7000, - wind:{ - speed: 11.8, - deg: 250 - }, - clouds:{ - all: 75 - }, - dt: 1547387400, - sys:{ - type: 1, - id: 1267, - message: 0.0031, - country: "DE", - sunrise: 1547362817, - sunset: 1547394301 - }, - id: 2867714, - name: "Munich", - cod: 200 - }, extendedData)); + return JSON.stringify(_.merge({}, { + coord:{ + lon: 11.58, + lat: 48.14 + }, + weather:[ + { + id: 615, + main: "Snow", + description: "light rain and snow", + icon: "13d" + }, + { + id: 500, + main: "Rain", + description: "light rain", + icon: "10d" + } + ], + base: "stations", + main:{ + temp: 1.49, + pressure: 1005, + humidity: 93.7, + temp_min: 1, + temp_max: 2 + }, + visibility: 7000, + wind:{ + speed: 11.8, + deg: 250 + }, + clouds:{ + all: 75 + }, + dt: 1547387400, + sys:{ + type: 1, + id: 1267, + message: 0.0031, + country: "DE", + sunrise: 1547362817, + sunset: 1547394301 + }, + id: 2867714, + name: "Munich", + cod: 200 + }, extendedData)); } module.exports = generateWeather; diff --git a/tests/e2e/modules/mocks/weather_forecast.js b/tests/e2e/modules/mocks/weather_forecast.js index 420367a0..9e74262f 100644 --- a/tests/e2e/modules/mocks/weather_forecast.js +++ b/tests/e2e/modules/mocks/weather_forecast.js @@ -1,97 +1,97 @@ -const _ = require('lodash'); +const _ = require("lodash"); function generateWeatherForecast(extendedData = {}) { - return JSON.stringify(_.merge({}, { - "city": { - "id": 2867714, - "name": "Munich", - "coord": {"lon": 11.5754, "lat": 48.1371}, - "country": "DE", - "population": 1260391, - "timezone": 7200 - }, - "cod": "200", - "message": 0.9653487, - "cnt": 7, - "list": [{ - "dt": 1568372400, - "sunrise": 1568350044, - "sunset": 1568395948, - "temp": {"day": 24.44, "min": 15.35, "max": 24.44, "night": 15.35, "eve": 18, "morn": 23.03}, - "pressure": 1031.65, - "humidity": 70, - "weather": [{"id": 801, "main": "Clouds", "description": "few clouds", "icon": "02d"}], - "speed": 3.35, - "deg": 314, - "clouds": 21 - }, { - "dt": 1568458800, - "sunrise": 1568436525, - "sunset": 1568482223, - "temp": {"day": 20.81, "min": 13.56, "max": 21.02, "night": 13.56, "eve": 16.6, "morn": 15.88}, - "pressure": 1028.81, - "humidity": 72, - "weather": [{"id": 500, "main": "Rain", "description": "light rain", "icon": "10d"}], - "speed": 2.21, - "deg": 81, - "clouds": 100 - }, { - "dt": 1568545200, - "sunrise": 1568523007, - "sunset": 1568568497, - "temp": {"day": 22.65, "min": 13.76, "max": 22.88, "night": 15.27, "eve": 17.45, "morn": 13.76}, - "pressure": 1023.75, - "humidity": 64, - "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], - "speed": 1.15, - "deg": 7, - "clouds": 0 - }, { - "dt": 1568631600, - "sunrise": 1568609489, - "sunset": 1568654771, - "temp": {"day": 23.45, "min": 13.95, "max": 23.45, "night": 13.95, "eve": 17.75, "morn": 15.21}, - "pressure": 1020.41, - "humidity": 64, - "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], - "speed": 3.07, - "deg": 298, - "clouds": 7 - }, { - "dt": 1568718000, - "sunrise": 1568695970, - "sunset": 1568741045, - "temp": {"day": 20.55, "min": 10.95, "max": 20.55, "night": 10.95, "eve": 14.82, "morn": 13.24}, - "pressure": 1019.4, - "humidity": 66, - "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], - "speed": 2.8, - "deg": 333, - "clouds": 2 - }, { - "dt": 1568804400, - "sunrise": 1568782452, - "sunset": 1568827319, - "temp": {"day": 18.15, "min": 7.75, "max": 18.15, "night": 7.75, "eve": 12.45, "morn": 9.41}, - "pressure": 1017.56, - "humidity": 52, - "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], - "speed": 2.92, - "deg": 34, - "clouds": 0 - }, { - "dt": 1568890800, - "sunrise": 1568868934, - "sunset": 1568913593, - "temp": {"day": 14.85, "min": 5.56, "max": 15.05, "night": 5.56, "eve": 9.56, "morn": 6.25}, - "pressure": 1022.7, - "humidity": 59, - "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], - "speed": 2.89, - "deg": 51, - "clouds": 1 - }] - }, extendedData)); + return JSON.stringify(_.merge({}, { + "city": { + "id": 2867714, + "name": "Munich", + "coord": {"lon": 11.5754, "lat": 48.1371}, + "country": "DE", + "population": 1260391, + "timezone": 7200 + }, + "cod": "200", + "message": 0.9653487, + "cnt": 7, + "list": [{ + "dt": 1568372400, + "sunrise": 1568350044, + "sunset": 1568395948, + "temp": {"day": 24.44, "min": 15.35, "max": 24.44, "night": 15.35, "eve": 18, "morn": 23.03}, + "pressure": 1031.65, + "humidity": 70, + "weather": [{"id": 801, "main": "Clouds", "description": "few clouds", "icon": "02d"}], + "speed": 3.35, + "deg": 314, + "clouds": 21 + }, { + "dt": 1568458800, + "sunrise": 1568436525, + "sunset": 1568482223, + "temp": {"day": 20.81, "min": 13.56, "max": 21.02, "night": 13.56, "eve": 16.6, "morn": 15.88}, + "pressure": 1028.81, + "humidity": 72, + "weather": [{"id": 500, "main": "Rain", "description": "light rain", "icon": "10d"}], + "speed": 2.21, + "deg": 81, + "clouds": 100 + }, { + "dt": 1568545200, + "sunrise": 1568523007, + "sunset": 1568568497, + "temp": {"day": 22.65, "min": 13.76, "max": 22.88, "night": 15.27, "eve": 17.45, "morn": 13.76}, + "pressure": 1023.75, + "humidity": 64, + "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], + "speed": 1.15, + "deg": 7, + "clouds": 0 + }, { + "dt": 1568631600, + "sunrise": 1568609489, + "sunset": 1568654771, + "temp": {"day": 23.45, "min": 13.95, "max": 23.45, "night": 13.95, "eve": 17.75, "morn": 15.21}, + "pressure": 1020.41, + "humidity": 64, + "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], + "speed": 3.07, + "deg": 298, + "clouds": 7 + }, { + "dt": 1568718000, + "sunrise": 1568695970, + "sunset": 1568741045, + "temp": {"day": 20.55, "min": 10.95, "max": 20.55, "night": 10.95, "eve": 14.82, "morn": 13.24}, + "pressure": 1019.4, + "humidity": 66, + "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], + "speed": 2.8, + "deg": 333, + "clouds": 2 + }, { + "dt": 1568804400, + "sunrise": 1568782452, + "sunset": 1568827319, + "temp": {"day": 18.15, "min": 7.75, "max": 18.15, "night": 7.75, "eve": 12.45, "morn": 9.41}, + "pressure": 1017.56, + "humidity": 52, + "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], + "speed": 2.92, + "deg": 34, + "clouds": 0 + }, { + "dt": 1568890800, + "sunrise": 1568868934, + "sunset": 1568913593, + "temp": {"day": 14.85, "min": 5.56, "max": 15.05, "night": 5.56, "eve": 9.56, "morn": 6.25}, + "pressure": 1022.7, + "humidity": 59, + "weather": [{"id": 800, "main": "Clear", "description": "sky is clear", "icon": "01d"}], + "speed": 2.89, + "deg": 51, + "clouds": 1 + }] + }, extendedData)); } module.exports = generateWeatherForecast; diff --git a/tests/e2e/vendor_spec.js b/tests/e2e/vendor_spec.js index 7e53ec5b..834c90d6 100644 --- a/tests/e2e/vendor_spec.js +++ b/tests/e2e/vendor_spec.js @@ -36,9 +36,9 @@ describe("Vendors", function () { urlVendor = "http://localhost:8080/vendor/" + vendors[vendor]; request.get(urlVendor, function (err, res, body) { if (!err) - expect(res.statusCode).to.equal(200); + {expect(res.statusCode).to.equal(200);} else - mlog.pending(`There error vendor 200 test ${err}`); + {mlog.pending(`There error vendor 200 test ${err}`);} }); }); }); @@ -48,9 +48,9 @@ describe("Vendors", function () { urlVendor = "http://localhost:8080/" + vendors[vendor]; request.get(urlVendor, function (err, res, body) { if (!err) - expect(res.statusCode).to.equal(404); + {expect(res.statusCode).to.equal(404);} else - mlog.pending(`There error vendor 404 test ${err}`); + {mlog.pending(`There error vendor 404 test ${err}`);} }); }); }); diff --git a/vendor/package-lock.json b/vendor/package-lock.json index 3253cc4e..61c1d19e 100644 --- a/vendor/package-lock.json +++ b/vendor/package-lock.json @@ -703,7 +703,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", - "optional": true, "requires": { "is-glob": "^2.0.0" } @@ -717,8 +716,7 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "optional": true + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" }, "invert-kv": { "version": "1.0.0", @@ -737,8 +735,7 @@ "is-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", - "optional": true + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" }, "is-dotfile": { "version": "1.0.3", @@ -764,8 +761,7 @@ "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", - "optional": true + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -779,7 +775,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", - "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -808,8 +803,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "optional": true + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "isobject": { "version": "2.1.0", @@ -824,7 +818,6 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -890,7 +883,6 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "optional": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -1039,14 +1031,12 @@ "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=", - "optional": true + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=" }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", - "optional": true + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" }, "repeat-string": { "version": "1.6.1", @@ -1057,8 +1047,7 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", - "optional": true + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" }, "set-immediate-shim": { "version": "1.0.1", From 762bae907c3b629234d3d18d042ea9150b402d80 Mon Sep 17 00:00:00 2001 From: Kurtis Blankenship Date: Fri, 17 Jan 2020 23:04:51 -0600 Subject: [PATCH 016/104] perf: updating changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e63e7e..da66c6c3 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) +- Fix calendar time offset for recurring evenst crossing DST (ISSUE #1798) ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). From 84f74c53b5311df731fe81ba813f6dea11485726 Mon Sep 17 00:00:00 2001 From: Kurtis Blankenship Date: Fri, 17 Jan 2020 23:08:34 -0600 Subject: [PATCH 017/104] perf: fix wording on changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index da66c6c3..dc55134e 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) -- Fix calendar time offset for recurring evenst crossing DST (ISSUE #1798) +- Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). From 08b9e7b5b5dcd969da116e383647c403fb1f7bbc Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Fri, 17 Jan 2020 21:52:04 -0800 Subject: [PATCH 018/104] add sun/moon rise/set times Icons become bold when the object is above the horizon. Also shows percent of moon illumination. --- CHANGELOG.md | 1 + modules/default/clock/clock.js | 38 +++++++++++++++++++++++++- modules/default/clock/clock_styles.css | 7 +++++ 3 files changed, 45 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7e63e7e..2549defb 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". +- Sun and Moon data to the `clock` module. ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index d566c52f..4eb7a6d3 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -26,10 +26,15 @@ Module.register("clock",{ analogShowDate: "top", // options: false, 'top', or 'bottom' secondsColor: "#888888", timezone: null, + + showSunTimes: false, + showMoonTimes: false, + lat: 47.630539, + lon: -122.344147, }, // Define required scripts. getScripts: function() { - return ["moment.js", "moment-timezone.js"]; + return ["moment.js", "moment-timezone.js", "suncalc.js"]; }, // Define styles. getStyles: function() { @@ -93,11 +98,15 @@ Module.register("clock",{ var timeWrapper = document.createElement("div"); var secondsWrapper = document.createElement("sup"); var periodWrapper = document.createElement("span"); + var sunWrapper = document.createElement("div"); + var moonWrapper = document.createElement("div"); var weekWrapper = document.createElement("div"); // Style Wrappers dateWrapper.className = "date normal medium"; timeWrapper.className = "time bright large light"; secondsWrapper.className = "dimmed"; + sunWrapper.className = "sun dimmed small"; + moonWrapper.className = "moon dimmed small"; weekWrapper.className = "week dimmed medium"; // Set content of wrappers. @@ -142,6 +151,29 @@ Module.register("clock",{ timeWrapper.appendChild(periodWrapper); } + function formatTime(config, time) { + var formatString = hourSymbol + ':mm'; + if (config.showPeriod && config.timeFormat !== 24) { + formatString += config.showPeriodUpper ? 'A' : 'a'; + } + return moment(time).format(formatString); + } + if (this.config.showSunTimes) { + const sunTimes = SunCalc.getTimes(now, this.config.lat, this.config.lon); + const isVisible = now.isBetween(sunTimes.sunrise, sunTimes.sunset); + sunWrapper.innerHTML = '' + + '' + formatTime(this.config, sunTimes.sunrise) + '' + + '' + formatTime(this.config, sunTimes.sunset) + ''; + } + if (this.config.showMoonTimes) { + const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); + const moonTimes = SunCalc.getMoonTimes(now, this.config.lat, this.config.lon); + const isVisible = now.isBetween(moonTimes.rise, moonTimes.set); + moonWrapper.innerHTML = ' ' + moonIllumination.fraction.toLocaleString(undefined, {style: 'percent'}) + '' + + ' ' + formatTime(this.config, moonTimes.rise) + ''+ + ' ' + formatTime(this.config, moonTimes.set) + ''; + } + /**************************************************************** * Create wrappers for ANALOG clock, only if specified in config */ @@ -210,6 +242,8 @@ Module.register("clock",{ // Display only a digital clock wrapper.appendChild(dateWrapper); wrapper.appendChild(timeWrapper); + wrapper.appendChild(sunWrapper); + wrapper.appendChild(moonWrapper); wrapper.appendChild(weekWrapper); } else if (this.config.displayType === "analog") { // Display only an analog clock @@ -244,6 +278,8 @@ Module.register("clock",{ digitalWrapper.style.cssFloat = "none"; digitalWrapper.appendChild(dateWrapper); digitalWrapper.appendChild(timeWrapper); + digitalWrapper.appendChild(sunWrapper); + digitalWrapper.appendChild(moonWrapper); digitalWrapper.appendChild(weekWrapper); var appendClocks = function(condition, pos1, pos2) { diff --git a/modules/default/clock/clock_styles.css b/modules/default/clock/clock_styles.css index 1df9bf83..7bd4554a 100644 --- a/modules/default/clock/clock_styles.css +++ b/modules/default/clock/clock_styles.css @@ -66,3 +66,10 @@ -ms-transform-origin: 50% 100%; transform-origin: 50% 100%; } + +.module.clock .sun, .module.clock .moon { + display: flex; +} +.module.clock .sun > *, .module.clock .moon > * { + flex: 1; +} From af9f555e8f8929537f43dee39dda6233bf4e7645 Mon Sep 17 00:00:00 2001 From: kblankenship1989 Date: Sat, 18 Jan 2020 06:28:21 -0600 Subject: [PATCH 019/104] fix: fixing copy / paste error on futureLocal --- modules/default/calendar/calendarfetcher.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index 57c1586d..a9bf37ee 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -186,7 +186,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri // of dates we"re looking for. // kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time var pastLocal = moment(past).subtract(past.getTimezoneOffset(), "minutes").toDate(); - var futureLocal = moment(past).subtract(future.getTimezoneOffset(), "minutes").toDate(); + var futureLocal = moment(future).subtract(future.getTimezoneOffset(), "minutes").toDate(); var datesLocal = rule.between(pastLocal, futureLocal, true, limitFunction); var dates = datesLocal.map(function(dateLocal) { var date = moment(dateLocal).add(dateLocal.getTimezoneOffset(), "minutes").toDate(); From 70ca9ce2e0e7be3f6974a1b8f8269db712026738 Mon Sep 17 00:00:00 2001 From: Kurtis Blankenship Date: Sat, 18 Jan 2020 06:38:01 -0600 Subject: [PATCH 020/104] fix: fixing lint error --- modules/default/alert/README.md | 2 +- modules/default/calendar/README.md | 2 +- modules/default/clock/README.md | 2 +- modules/default/compliments/README.md | 2 +- modules/default/currentweather/README.md | 2 +- modules/default/helloworld/README.md | 2 +- modules/default/newsfeed/README.md | 2 +- modules/default/updatenotification/README.md | 2 +- modules/default/weather/README.md | 2 +- modules/default/weatherforecast/README.md | 2 +- 10 files changed, 10 insertions(+), 10 deletions(-) diff --git a/modules/default/alert/README.md b/modules/default/alert/README.md index 3bd5d00d..4d3c6a65 100644 --- a/modules/default/alert/README.md +++ b/modules/default/alert/README.md @@ -1,4 +1,4 @@ # Module: Alert The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index fbb8bfd9..5c8f187b 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -2,4 +2,4 @@ The `calendar` module is one of the default modules of the MagicMirror. This module displays events from a public .ical calendar. It can combine multiple calendars. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html). diff --git a/modules/default/clock/README.md b/modules/default/clock/README.md index 1c0bdf8c..34a1448d 100644 --- a/modules/default/clock/README.md +++ b/modules/default/clock/README.md @@ -2,4 +2,4 @@ The `clock` module is one of the default modules of the MagicMirror. This module displays the current date and time. The information will be updated realtime. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/clock.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/clock.html). diff --git a/modules/default/compliments/README.md b/modules/default/compliments/README.md index 7825bb02..c746f318 100644 --- a/modules/default/compliments/README.md +++ b/modules/default/compliments/README.md @@ -2,4 +2,4 @@ The `compliments` module is one of the default modules of the MagicMirror. This module displays a random compliment. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/compliments.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/compliments.html). diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md index 3cbdcbea..27b047da 100644 --- a/modules/default/currentweather/README.md +++ b/modules/default/currentweather/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/currentweather.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/currentweather.html). diff --git a/modules/default/helloworld/README.md b/modules/default/helloworld/README.md index aa9f87f3..8ad06f77 100644 --- a/modules/default/helloworld/README.md +++ b/modules/default/helloworld/README.md @@ -1,4 +1,4 @@ # Module: Hello World The `helloworld` module is one of the default modules of the MagicMirror. It is a simple way to display a static text on the mirror. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md index 4dc4877b..33690aa6 100644 --- a/modules/default/newsfeed/README.md +++ b/modules/default/newsfeed/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). diff --git a/modules/default/updatenotification/README.md b/modules/default/updatenotification/README.md index 652f451f..af6305e6 100644 --- a/modules/default/updatenotification/README.md +++ b/modules/default/updatenotification/README.md @@ -2,4 +2,4 @@ The `updatenotification` module is one of the default modules of the MagicMirror. This will display a message whenever a new version of the MagicMirror application is available. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/updatenotification.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/updatenotification.html). diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md index 5b03b141..ebc301f4 100755 --- a/modules/default/weather/README.md +++ b/modules/default/weather/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weather.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weather.html). diff --git a/modules/default/weatherforecast/README.md b/modules/default/weatherforecast/README.md index 95762daa..7dfbd16f 100644 --- a/modules/default/weatherforecast/README.md +++ b/modules/default/weatherforecast/README.md @@ -2,4 +2,4 @@ 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. -For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weatherforecast.html). \ No newline at end of file +For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weatherforecast.html). From 85a52523cf02eb3ec81530fc94874b056748aa43 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Sat, 18 Jan 2020 08:39:54 -0800 Subject: [PATCH 021/104] show sun/moon as bright rather than bold if obj is visible --- modules/default/clock/clock.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 4eb7a6d3..6022998e 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -161,7 +161,7 @@ Module.register("clock",{ if (this.config.showSunTimes) { const sunTimes = SunCalc.getTimes(now, this.config.lat, this.config.lon); const isVisible = now.isBetween(sunTimes.sunrise, sunTimes.sunset); - sunWrapper.innerHTML = '' + + sunWrapper.innerHTML = '' + '' + formatTime(this.config, sunTimes.sunrise) + '' + '' + formatTime(this.config, sunTimes.sunset) + ''; } @@ -169,7 +169,7 @@ Module.register("clock",{ const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); const moonTimes = SunCalc.getMoonTimes(now, this.config.lat, this.config.lon); const isVisible = now.isBetween(moonTimes.rise, moonTimes.set); - moonWrapper.innerHTML = ' ' + moonIllumination.fraction.toLocaleString(undefined, {style: 'percent'}) + '' + + moonWrapper.innerHTML = ' ' + moonIllumination.fraction.toLocaleString(undefined, {style: 'percent'}) + '' + ' ' + formatTime(this.config, moonTimes.rise) + ''+ ' ' + formatTime(this.config, moonTimes.set) + ''; } From 40a9f9dd85c861d3e0e2cab28792b51951b07dca Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Sat, 18 Jan 2020 08:45:52 -0800 Subject: [PATCH 022/104] fix stylelint:simple --- modules/default/clock/clock_styles.css | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/modules/default/clock/clock_styles.css b/modules/default/clock/clock_styles.css index 7bd4554a..fa6c2d5d 100644 --- a/modules/default/clock/clock_styles.css +++ b/modules/default/clock/clock_styles.css @@ -67,9 +67,12 @@ transform-origin: 50% 100%; } -.module.clock .sun, .module.clock .moon { +.module.clock .sun, +.module.clock .moon { display: flex; } -.module.clock .sun > *, .module.clock .moon > * { + +.module.clock .sun > *, +.module.clock .moon > * { flex: 1; } From 36762a6e46402e7ff5f410775ef2cc9e1750710a Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Sat, 18 Jan 2020 09:50:43 -0800 Subject: [PATCH 023/104] add duration until next sunset/sunrise --- modules/default/clock/clock.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 6022998e..e6ac880b 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -161,7 +161,18 @@ Module.register("clock",{ if (this.config.showSunTimes) { const sunTimes = SunCalc.getTimes(now, this.config.lat, this.config.lon); const isVisible = now.isBetween(sunTimes.sunrise, sunTimes.sunset); - sunWrapper.innerHTML = '' + + var nextEvent; + if (now.isBefore(sunTimes.sunrise)) { + nextEvent = sunTimes.sunrise; + } else if (now.isBefore(sunTimes.sunset)) { + nextEvent = sunTimes.sunset; + } else { + const tomorrowSunTimes = SunCalc.getTimes(now.add(1, 'day'), this.config.lat, this.config.lon); + nextEvent = tomorrowSunTimes.sunrise; + } + const untilNextEvent = moment.duration(moment(nextEvent).diff(now)); + const untilNextEventString = untilNextEvent.hours() + 'h ' + untilNextEvent.minutes() + 'm'; + sunWrapper.innerHTML = ' ' + untilNextEventString + '' + '' + formatTime(this.config, sunTimes.sunrise) + '' + '' + formatTime(this.config, sunTimes.sunset) + ''; } @@ -169,7 +180,8 @@ Module.register("clock",{ const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); const moonTimes = SunCalc.getMoonTimes(now, this.config.lat, this.config.lon); const isVisible = now.isBetween(moonTimes.rise, moonTimes.set); - moonWrapper.innerHTML = ' ' + moonIllumination.fraction.toLocaleString(undefined, {style: 'percent'}) + '' + + const illuminatedFractionString = moonIllumination.fraction.toLocaleString(undefined, {style: 'percent'}); + moonWrapper.innerHTML = ' ' + illuminatedFractionString + '' + ' ' + formatTime(this.config, moonTimes.rise) + ''+ ' ' + formatTime(this.config, moonTimes.set) + ''; } From e24d1a1261a3e7490b8e9fef95c7eb331938c851 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 18 Jan 2020 21:02:49 +0100 Subject: [PATCH 024/104] Fix newlines? --- modules/default/alert/README.md | 1 + modules/default/calendar/README.md | 1 + modules/default/clock/README.md | 1 + modules/default/compliments/README.md | 1 + modules/default/currentweather/README.md | 1 + modules/default/helloworld/README.md | 1 + modules/default/newsfeed/README.md | 1 + modules/default/updatenotification/README.md | 1 + modules/default/weather/README.md | 1 + modules/default/weatherforecast/README.md | 1 + 10 files changed, 10 insertions(+) diff --git a/modules/default/alert/README.md b/modules/default/alert/README.md index 4d3c6a65..8700aea7 100644 --- a/modules/default/alert/README.md +++ b/modules/default/alert/README.md @@ -2,3 +2,4 @@ The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). + diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index 5c8f187b..e7192eeb 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -3,3 +3,4 @@ The `calendar` module is one of the default modules of the MagicMirror. This module displays events from a public .ical calendar. It can combine multiple calendars. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html). + diff --git a/modules/default/clock/README.md b/modules/default/clock/README.md index 34a1448d..973415cb 100644 --- a/modules/default/clock/README.md +++ b/modules/default/clock/README.md @@ -3,3 +3,4 @@ The `clock` module is one of the default modules of the MagicMirror. This module displays the current date and time. The information will be updated realtime. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/clock.html). + diff --git a/modules/default/compliments/README.md b/modules/default/compliments/README.md index c746f318..b9d2f448 100644 --- a/modules/default/compliments/README.md +++ b/modules/default/compliments/README.md @@ -3,3 +3,4 @@ The `compliments` module is one of the default modules of the MagicMirror. This module displays a random compliment. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/compliments.html). + diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md index 27b047da..d43df316 100644 --- a/modules/default/currentweather/README.md +++ b/modules/default/currentweather/README.md @@ -3,3 +3,4 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/currentweather.html). + diff --git a/modules/default/helloworld/README.md b/modules/default/helloworld/README.md index 8ad06f77..80e66ebd 100644 --- a/modules/default/helloworld/README.md +++ b/modules/default/helloworld/README.md @@ -2,3 +2,4 @@ The `helloworld` module is one of the default modules of the MagicMirror. It is a simple way to display a static text on the mirror. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). + diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md index 33690aa6..b90232fb 100644 --- a/modules/default/newsfeed/README.md +++ b/modules/default/newsfeed/README.md @@ -3,3 +3,4 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). + diff --git a/modules/default/updatenotification/README.md b/modules/default/updatenotification/README.md index af6305e6..3f7b9533 100644 --- a/modules/default/updatenotification/README.md +++ b/modules/default/updatenotification/README.md @@ -3,3 +3,4 @@ The `updatenotification` module is one of the default modules of the MagicMirror This will display a message whenever a new version of the MagicMirror application is available. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/updatenotification.html). + diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md index ebc301f4..b834bc7d 100755 --- a/modules/default/weather/README.md +++ b/modules/default/weather/README.md @@ -3,3 +3,4 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weather.html). + diff --git a/modules/default/weatherforecast/README.md b/modules/default/weatherforecast/README.md index 7dfbd16f..b320afe1 100644 --- a/modules/default/weatherforecast/README.md +++ b/modules/default/weatherforecast/README.md @@ -3,3 +3,4 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weatherforecast.html). + From a85ed709afe1b1cc5f7a3ee087d4c2afca073dae Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 18 Jan 2020 21:09:18 +0100 Subject: [PATCH 025/104] Remove newlines. --- modules/default/alert/README.md | 1 - modules/default/calendar/README.md | 1 - modules/default/clock/README.md | 1 - modules/default/compliments/README.md | 1 - modules/default/currentweather/README.md | 1 - modules/default/helloworld/README.md | 1 - modules/default/newsfeed/README.md | 1 - modules/default/updatenotification/README.md | 1 - modules/default/weather/README.md | 1 - modules/default/weatherforecast/README.md | 1 - 10 files changed, 10 deletions(-) diff --git a/modules/default/alert/README.md b/modules/default/alert/README.md index 8700aea7..4d3c6a65 100644 --- a/modules/default/alert/README.md +++ b/modules/default/alert/README.md @@ -2,4 +2,3 @@ The alert module is one of the default modules of the MagicMirror. This module displays notifications from other modules. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/alert.html). - diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index e7192eeb..5c8f187b 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -3,4 +3,3 @@ The `calendar` module is one of the default modules of the MagicMirror. This module displays events from a public .ical calendar. It can combine multiple calendars. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/calendar.html). - diff --git a/modules/default/clock/README.md b/modules/default/clock/README.md index 973415cb..34a1448d 100644 --- a/modules/default/clock/README.md +++ b/modules/default/clock/README.md @@ -3,4 +3,3 @@ The `clock` module is one of the default modules of the MagicMirror. This module displays the current date and time. The information will be updated realtime. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/clock.html). - diff --git a/modules/default/compliments/README.md b/modules/default/compliments/README.md index b9d2f448..c746f318 100644 --- a/modules/default/compliments/README.md +++ b/modules/default/compliments/README.md @@ -3,4 +3,3 @@ The `compliments` module is one of the default modules of the MagicMirror. This module displays a random compliment. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/compliments.html). - diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md index d43df316..27b047da 100644 --- a/modules/default/currentweather/README.md +++ b/modules/default/currentweather/README.md @@ -3,4 +3,3 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/currentweather.html). - diff --git a/modules/default/helloworld/README.md b/modules/default/helloworld/README.md index 80e66ebd..8ad06f77 100644 --- a/modules/default/helloworld/README.md +++ b/modules/default/helloworld/README.md @@ -2,4 +2,3 @@ The `helloworld` module is one of the default modules of the MagicMirror. It is a simple way to display a static text on the mirror. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/helloworld.html). - diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md index b90232fb..33690aa6 100644 --- a/modules/default/newsfeed/README.md +++ b/modules/default/newsfeed/README.md @@ -3,4 +3,3 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/newsfeed.html). - diff --git a/modules/default/updatenotification/README.md b/modules/default/updatenotification/README.md index 3f7b9533..af6305e6 100644 --- a/modules/default/updatenotification/README.md +++ b/modules/default/updatenotification/README.md @@ -3,4 +3,3 @@ The `updatenotification` module is one of the default modules of the MagicMirror This will display a message whenever a new version of the MagicMirror application is available. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/updatenotification.html). - diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md index b834bc7d..ebc301f4 100755 --- a/modules/default/weather/README.md +++ b/modules/default/weather/README.md @@ -3,4 +3,3 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weather.html). - diff --git a/modules/default/weatherforecast/README.md b/modules/default/weatherforecast/README.md index b320afe1..7dfbd16f 100644 --- a/modules/default/weatherforecast/README.md +++ b/modules/default/weatherforecast/README.md @@ -3,4 +3,3 @@ 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. For configuration options, please check the [MagicMirror² documentation](https://docs.magicmirror.builders/modules/weatherforecast.html). - From db72e22e612c13ece03b498a3974de43582f4854 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 18 Jan 2020 21:17:54 +0100 Subject: [PATCH 026/104] Fuck it. --- Gruntfile.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index ee4ab7b8..a825a766 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -77,7 +77,8 @@ module.exports = function(grunt) { "MD018": false, "MD012": false, "MD026": false, - "MD038": false + "MD038": false, + "MD047": false } }, src: [ From 9cffa3dd676ec2e978bdf1d1ba2e51dd96055df4 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Sat, 18 Jan 2020 17:01:26 -0800 Subject: [PATCH 027/104] fix calculation of duration until next sunrise --- modules/default/clock/clock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index e6ac880b..96c31143 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -167,7 +167,7 @@ Module.register("clock",{ } else if (now.isBefore(sunTimes.sunset)) { nextEvent = sunTimes.sunset; } else { - const tomorrowSunTimes = SunCalc.getTimes(now.add(1, 'day'), this.config.lat, this.config.lon); + const tomorrowSunTimes = SunCalc.getTimes(now.clone().add(1, 'day'), this.config.lat, this.config.lon); nextEvent = tomorrowSunTimes.sunrise; } const untilNextEvent = moment.duration(moment(nextEvent).diff(now)); From cce57c72298d53a632b2352d678d71f364492704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Ram=C3=ADrez=20Norambuena?= Date: Sun, 19 Jan 2020 04:06:21 -0300 Subject: [PATCH 028/104] Fix the vendor_spec test: This change set after startApplication the configuration to run this test. The previous statement when e2e are running using --recursive the MM_CONFIG_FILE was setting by the test running before this one. --- tests/e2e/vendor_spec.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/e2e/vendor_spec.js b/tests/e2e/vendor_spec.js index 834c90d6..addbe335 100644 --- a/tests/e2e/vendor_spec.js +++ b/tests/e2e/vendor_spec.js @@ -15,6 +15,7 @@ describe("Vendors", function () { var app = null; before(function () { + process.env.MM_CONFIG_FILE = "tests/configs/env.js"; return helpers.startApplication({ args: ["js/electron.js"] }).then(function (startedApp) { app = startedApp; }); @@ -26,10 +27,6 @@ describe("Vendors", function () { describe("Get list vendors", function () { - before(function () { - process.env.MM_CONFIG_FILE = "tests/configs/env.js"; - }); - var vendors = require(__dirname + "/../../vendor/vendor.js"); Object.keys(vendors).forEach(vendor => { it(`should return 200 HTTP code for vendor "${vendor}"`, function () { From 81b310086f012c99dcf66fc8dbdab991c00794f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Ram=C3=ADrez=20Norambuena?= Date: Sun, 19 Jan 2020 04:40:05 -0300 Subject: [PATCH 029/104] Revert permission mode for CHANGELOG This change revert change of permission mode for file CHANGELOG.md introduced in commit a619fc4fefe17a2205537d48131b40e9f8076990 --- CHANGELOG.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100755 => 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md old mode 100755 new mode 100644 From 6e7edd9824ecb8fb5a6f5b9ae9662b405b224954 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Ram=C3=ADrez=20Norambuena?= Date: Sun, 19 Jan 2020 08:19:09 -0300 Subject: [PATCH 030/104] Revert error logging introduced in 1e97b5c --- tests/e2e/vendor_spec.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/tests/e2e/vendor_spec.js b/tests/e2e/vendor_spec.js index addbe335..5824f737 100644 --- a/tests/e2e/vendor_spec.js +++ b/tests/e2e/vendor_spec.js @@ -32,10 +32,7 @@ describe("Vendors", function () { it(`should return 200 HTTP code for vendor "${vendor}"`, function () { urlVendor = "http://localhost:8080/vendor/" + vendors[vendor]; request.get(urlVendor, function (err, res, body) { - if (!err) - {expect(res.statusCode).to.equal(200);} - else - {mlog.pending(`There error vendor 200 test ${err}`);} + expect(res.statusCode).to.equal(200); }); }); }); @@ -44,10 +41,7 @@ describe("Vendors", function () { it(`should return 404 HTTP code for vendor https://localhost/"${vendor}"`, function() { urlVendor = "http://localhost:8080/" + vendors[vendor]; request.get(urlVendor, function (err, res, body) { - if (!err) - {expect(res.statusCode).to.equal(404);} - else - {mlog.pending(`There error vendor 404 test ${err}`);} + expect(res.statusCode).to.equal(404); }); }); }); From a7ee2ef3a6c0889bcf999f4b5951162fbb394bfa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rodrigo=20Ram=C3=ADrez=20Norambuena?= Date: Mon, 20 Jan 2020 21:57:57 +0000 Subject: [PATCH 031/104] Upgrade to Electron 6: New version of Electron has enable by default sandbox http://www.atom.pe/docs/api/sandbox-option/ There was some issues to migrate a new version of Electron for MagicMirror. Using the new version in Travis CI was failing at this time. The problem is because the testing runner is a Docker enviroment The issue experimented is the same topic mentioned here: - https://github.com/electron/electron/issues/17972 - https://github.com/electron-userland/spectron/issues/443 The fix for to all of this is to set the `--no-sandbox` mode in CI testing https://electronjs.org/docs/all#--no-sandbox This change use the feature to set and disable Sandbox using by enviroment variable `ELECTRON_DISABLE_SANDBOX=1` https://github.com/electron/electron/pull/16576 This change has reference #1800 --- .travis.yml | 1 + package-lock.json | 3521 +++++++++++++++++++-------------------------- package.json | 6 +- 3 files changed, 1453 insertions(+), 2075 deletions(-) diff --git a/.travis.yml b/.travis.yml index 58f85360..5f8f6024 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ before_script: - yarn danger ci - npm install grunt-cli -g - "export DISPLAY=:99.0" + - "export ELECTRON_DISABLE_SANDBOX=1" - "sh -e /etc/init.d/xvfb start" - sleep 5 script: diff --git a/package-lock.json b/package-lock.json index 145947fb..dff1462c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,29 +5,30 @@ "requires": true, "dependencies": { "@babel/code-frame": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.5.5.tgz", - "integrity": "sha512-27d4lZoomVyo51VegxI20xZPuSHusqbQag/ztrBC7wegWoQ1nLREPVSKSW8byhTlzTKyNE4ifaTA6lCp7JjpFw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.8.3.tgz", + "integrity": "sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g==", "dev": true, "requires": { - "@babel/highlight": "^7.0.0" + "@babel/highlight": "^7.8.3" } }, "@babel/core": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.7.7.tgz", - "integrity": "sha512-jlSjuj/7z138NLZALxVgrx13AOtqip42ATZP7+kYl53GvDV6+4dCek1mVUo8z8c8Xnw/mx2q3d9HWh3griuesQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", + "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", "dev": true, "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.7", - "@babel/helpers": "^7.7.4", - "@babel/parser": "^7.7.7", - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4", + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helpers": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3", "convert-source-map": "^1.7.0", "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", "json5": "^2.1.0", "lodash": "^4.17.13", "resolve": "^1.3.2", @@ -62,12 +63,12 @@ } }, "@babel/generator": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.7.7.tgz", - "integrity": "sha512-/AOIBpHh/JU1l0ZFS4kiRCBnLi6OTHzh0RPk3h9isBxkkqELtQNFi1Vr/tiG9p1yfoUdKVwISuXWQR+hwwM4VQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", + "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", "dev": true, "requires": { - "@babel/types": "^7.7.4", + "@babel/types": "^7.8.3", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -82,49 +83,49 @@ } }, "@babel/helper-function-name": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.7.4.tgz", - "integrity": "sha512-AnkGIdiBhEuiwdoMnKm7jfPfqItZhgRaZfMg1XX3bS25INOnLPjPG1Ppnajh8eqgt5kPJnfqrRHqFqmjKDZLzQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz", + "integrity": "sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.7.4", - "@babel/template": "^7.7.4", - "@babel/types": "^7.7.4" + "@babel/helper-get-function-arity": "^7.8.3", + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" } }, "@babel/helper-get-function-arity": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.4.tgz", - "integrity": "sha512-QTGKEdCkjgzgfJ3bAyRwF4yyT3pg+vDgan8DSivq1eS0gwi+KGKE5x8kRcbeFTb/673mkO5SN1IZfmCfA5o+EA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz", + "integrity": "sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA==", "dev": true, "requires": { - "@babel/types": "^7.7.4" + "@babel/types": "^7.8.3" } }, "@babel/helper-split-export-declaration": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.4.tgz", - "integrity": "sha512-guAg1SXFcVr04Guk9eq0S4/rWS++sbmyqosJzVs8+1fH5NI+ZcmkaSkc7dmtAFbHFva6yRJnjW3yAcGxjueDug==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", + "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", "dev": true, "requires": { - "@babel/types": "^7.7.4" + "@babel/types": "^7.8.3" } }, "@babel/helpers": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.7.4.tgz", - "integrity": "sha512-ak5NGZGJ6LV85Q1Zc9gn2n+ayXOizryhjSUBTdu5ih1tlVCJeuQENzc4ItyCVhINVXvIT/ZQ4mheGIsfBkpskg==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.3.tgz", + "integrity": "sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==", "dev": true, "requires": { - "@babel/template": "^7.7.4", - "@babel/traverse": "^7.7.4", - "@babel/types": "^7.7.4" + "@babel/template": "^7.8.3", + "@babel/traverse": "^7.8.3", + "@babel/types": "^7.8.3" } }, "@babel/highlight": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.5.0.tgz", - "integrity": "sha512-7dV4eu9gBxoM0dAnj/BCFDW9LFU0zvTrkq0ugM7pnHEgguOEeOz1so2ZghEdzviYzQEED0r4EAgpsBChKy1TRQ==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.8.3.tgz", + "integrity": "sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg==", "dev": true, "requires": { "chalk": "^2.0.0", @@ -164,15 +165,15 @@ } }, "@babel/parser": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.7.7.tgz", - "integrity": "sha512-WtTZMZAZLbeymhkd/sEaPD8IQyGAhmuTuvTzLiCFM7iXiVdY0gc0IaI+cW0fh1BnSMbJSzXX6/fHllgHKwHhXw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", + "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", "dev": true }, "@babel/runtime": { - "version": "7.7.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.7.7.tgz", - "integrity": "sha512-uCnC2JEVAu8AKB5do1WRIsvrdJ0flYx/A/9f/6chdacnEZ7LmavjdsDXr5ksYBegxtuTPR5Va9/+13QF/kFkCA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", + "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", "dev": true, "requires": { "regenerator-runtime": "^0.13.2" @@ -187,28 +188,28 @@ } }, "@babel/template": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.7.4.tgz", - "integrity": "sha512-qUzihgVPguAzXCK7WXw8pqs6cEwi54s3E+HrejlkuWO6ivMKx9hZl3Y2fSXp9i5HgyWmj7RKP+ulaYnKM4yYxw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", + "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4" + "@babel/code-frame": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3" } }, "@babel/traverse": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.7.4.tgz", - "integrity": "sha512-P1L58hQyupn8+ezVA2z5KBm4/Zr4lCC8dwKCMYzsa5jFMDMQAzaBNy9W5VjB+KAmBjb40U7a/H6ao+Xo+9saIw==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", + "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", "dev": true, "requires": { - "@babel/code-frame": "^7.5.5", - "@babel/generator": "^7.7.4", - "@babel/helper-function-name": "^7.7.4", - "@babel/helper-split-export-declaration": "^7.7.4", - "@babel/parser": "^7.7.4", - "@babel/types": "^7.7.4", + "@babel/code-frame": "^7.8.3", + "@babel/generator": "^7.8.3", + "@babel/helper-function-name": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/parser": "^7.8.3", + "@babel/types": "^7.8.3", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -232,9 +233,9 @@ } }, "@babel/types": { - "version": "7.7.4", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.7.4.tgz", - "integrity": "sha512-cz5Ji23KCi4T+YIE/BolWosrJuSmoZeN1EFnRtBwF+KKLi8GG/Z2c2hOJJeCXPk4mwk4QFvTmwIodJowXgttRA==", + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", + "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -242,22 +243,32 @@ "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==", + "@nodelib/fs.scandir": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.3.tgz", + "integrity": "sha512-eGmwYQn3gxo4r7jdQnkrrN6bY478C3P+a/y72IJukF8LjB6ZHeB3c+Ehacj3sYeSmUXGlnA67/PmbM9CVwL7Dw==", "dev": true, "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" + "@nodelib/fs.stat": "2.0.3", + "run-parallel": "^1.1.9" } }, "@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==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.3.tgz", + "integrity": "sha512-bQBFruR2TAwoevBEd/NWMoAAtNGzTRgdrqnYCc7dhzfoNvqPzLyqlEQnzZ3kVnNrSp25iyxE00/3h2fqGAGArA==", "dev": true }, + "@nodelib/fs.walk": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.4.tgz", + "integrity": "sha512-1V9XOY4rDW0rehzbrcqAmHnz8e7SKvX27gh8Gt2WgB0+pdzdiLV83p72kZPU+jvMbS1qU5mauP2iOvO8rhmurQ==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.3", + "fastq": "^1.6.0" + } + }, "@octokit/rest": { "version": "15.18.3", "resolved": "https://registry.npmjs.org/@octokit/rest/-/rest-15.18.3.tgz", @@ -276,31 +287,19 @@ } }, "@prantlf/jsonlint": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/@prantlf/jsonlint/-/jsonlint-6.2.1.tgz", - "integrity": "sha512-/qPFlMyAYpebu+xS7W9XUlpBrpWyHq9ElslIxfOpfKOxWy+p++gicvxtn7f4GJQ3ikyM738/IIDf6Ngl9ta18w==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@prantlf/jsonlint/-/jsonlint-10.2.0.tgz", + "integrity": "sha512-KMFfds0peWLLfCu3bhClTiEN0tdj/Z86QJvn1awKHws6r+Sx6T3a44Eadz6OvqN6ZpsRkqaRpZxqddvvDAdDZQ==", "dev": true, "requires": { - "ajv": "6.10.0", - "commander": "2.20.0" + "ajv": "6.10.2", + "commander": "4.0.1" }, "dependencies": { - "ajv": { - "version": "6.10.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", - "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.0.1.tgz", + "integrity": "sha512-IPF4ouhCP+qdlcmCedhxX4xiGBPyigb8v5NeUp+0LyhwLgxMqyp3S0vl7TAPfS/hiP7FC3caI/PB9lTmP8r1NA==", "dev": true } } @@ -311,33 +310,23 @@ "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", "dev": true }, - "@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==", + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", "dev": true }, "@types/node": { - "version": "10.17.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", - "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==" + "version": "13.1.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.8.tgz", + "integrity": "sha512-6XzyyNM9EKQW4HKuzbo/CkOIjn/evtCmsU+MUM1xDfJ+3/rNjBttM1NgN7AOQvN6tP1Sl1D1PIKMreTArnxM9A==", + "dev": true + }, + "@types/normalize-package-data": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", + "integrity": "sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA==", + "dev": true }, "@types/parse-json": { "version": "4.0.0", @@ -453,6 +442,12 @@ "uri-js": "^4.2.2" } }, + "ansi-colors": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", + "dev": true + }, "ansi-escapes": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.0.tgz", @@ -472,6 +467,24 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" }, + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } + } + }, "apache-crypt": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/apache-crypt/-/apache-crypt-1.2.1.tgz", @@ -487,121 +500,6 @@ "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.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "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" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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", @@ -619,24 +517,6 @@ } } }, - "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", @@ -654,24 +534,9 @@ "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=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true }, "arraybuffer.slice": { @@ -704,12 +569,6 @@ "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", @@ -739,17 +598,17 @@ "dev": true }, "autoprefixer": { - "version": "9.7.3", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.3.tgz", - "integrity": "sha512-8T5Y1C5Iyj6PgkPSFd0ODvK9DIleuPKUPYniNxybS47g2k2wFgLZ46lGQHlBuGKIAEV8fbCDfKCCRS1tvOgc3Q==", + "version": "9.7.4", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", + "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", "dev": true, "requires": { - "browserslist": "^4.8.0", - "caniuse-lite": "^1.0.30001012", + "browserslist": "^4.8.3", + "caniuse-lite": "^1.0.30001020", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.23", + "postcss": "^7.0.26", "postcss-value-parser": "^4.0.2" }, "dependencies": { @@ -840,61 +699,6 @@ "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", @@ -939,63 +743,11 @@ "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" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - }, - "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" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } - } - } + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true }, "blob": { "version": "0.0.5", @@ -1063,21 +815,12 @@ } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", "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" + "fill-range": "^7.0.1" } }, "browser-process-hrtime": { @@ -1087,20 +830,20 @@ "dev": true }, "browser-stdout": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.0.tgz", - "integrity": "sha1-81HTKWnTL6XXpVZxVCY9korjvR8=", + "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 }, "browserslist": { - "version": "4.8.2", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.2.tgz", - "integrity": "sha512-+M4oeaTplPm/f1pXDw84YohEv7B1i/2Aisei8s4s6k3QsoSHa7i5sz8u/cGQkkatCPxMASKxPualR4wwYgVboA==", + "version": "4.8.3", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.3.tgz", + "integrity": "sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001015", + "caniuse-lite": "^1.0.30001017", "electron-to-chromium": "^1.3.322", - "node-releases": "^1.1.42" + "node-releases": "^1.1.44" } }, "btoa-lite": { @@ -1163,29 +906,6 @@ "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 - }, "callsite": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz", @@ -1217,9 +937,9 @@ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, "caniuse-lite": { - "version": "1.0.30001017", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001017.tgz", - "integrity": "sha512-EDnZyOJ6eYh6lHmCvCdHAFbfV4KJ9lSdfv4h/ppEhrU/Yudkl7jujwMZ1we6RX7DXqBfT04pVMQ4J+1wcTlsKA==", + "version": "1.0.30001021", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001021.tgz", + "integrity": "sha512-wuMhT7/hwkgd8gldgp2jcrUjOU9RXJ4XxGumQeOsUr91l3WwmM68Cpa/ymCnWEDqakwFXhuDQbaKNHXBPgeE9g==", "dev": true }, "caseless": { @@ -1304,34 +1024,35 @@ "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", "dev": true }, + "chokidar": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.3.0.tgz", + "integrity": "sha512-dGmKLDdT3Gdl7fBUe8XK+gAtGmzy5Fn0XkkWQuYxGIgWVPPse2CxFA5mtrlD0TOHaHjEUqkWNyP1XdHoJES/4A==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.2.0" + }, + "dependencies": { + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + } + } + }, "clarinet": { "version": "0.12.4", "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.4.tgz", "integrity": "sha512-Rx9Zw8KQkoPO3/O2yPRchCZm3cGubCQiRLmmFAlbkDKobUIPP3JYul+bKILR9DIv1gSVwPQSgF8JGGkXzX8Q0w==" }, - "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", @@ -1443,16 +1164,6 @@ "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", @@ -1502,56 +1213,6 @@ "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" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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", @@ -1674,12 +1335,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.11", "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.11.tgz", @@ -1733,54 +1388,6 @@ "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" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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", @@ -2035,50 +1642,20 @@ "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==", + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", "dev": true, "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" + "object-keys": "^1.0.12" }, "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" - } + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true } } }, @@ -2104,33 +1681,24 @@ "dev": true }, "diff": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.3.1.tgz", - "integrity": "sha512-MKPHZDMB0o6yHyDryUOScqZibp914ksXwAMYMTHj6KO8UeKsRYNJD3oNCKjTqZon+V488P7N/HzXF8t7ZR95ww==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", "dev": true }, "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", + "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, "requires": { - "path-type": "^3.0.0" + "path-type": "^4.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=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true } } @@ -2245,24 +1813,32 @@ "dev": true }, "electron": { - "version": "3.1.13", - "resolved": "https://registry.npmjs.org/electron/-/electron-3.1.13.tgz", - "integrity": "sha512-aRNywoUSO1Va/lpU4nz3K6GDyFqYtlOnHGLcERAAHfhB+IJrJ34cUJW4FVBpm43AwvUdAeuCkVKRLtOmrgx5CA==", + "version": "6.1.7", + "resolved": "https://registry.npmjs.org/electron/-/electron-6.1.7.tgz", + "integrity": "sha512-QhBA/fcYJit2XJGkD2xEfxlWTtTaWYu7qkKVohtVWXpELFqkpel2DCDxet5BTo0qs8ukuZHxlQPnIonODnl2bw==", "optional": true, "requires": { - "@types/node": "^10.1.4", + "@types/node": "^10.12.18", "electron-download": "^4.1.0", "extract-zip": "^1.0.3" + }, + "dependencies": { + "@types/node": { + "version": "10.17.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.13.tgz", + "integrity": "sha512-pMCcqU2zT4TjqYFrWtYHKal7Sl30Ims6ulZ4UFXxI4xbtQqK/qqKwkDoBFCfooRqqmRu9vY3xaJRwxSh673aYg==", + "optional": true + } } }, "electron-chromedriver": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-1.8.0.tgz", - "integrity": "sha512-m1f3nle5MaGp94bcDTtMZZMMOgPO54+TXoPBlTbBSUjfINR5SJ46yQXLfuE79/qsFfJKslZB1UzWURDDFIRmpQ==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/electron-chromedriver/-/electron-chromedriver-6.0.0.tgz", + "integrity": "sha512-UIhRl0sN5flfUjqActXsFrZQU1NmBObvlxzPnyeud8vhR67TllXCoqfvhQJmIrJAJJK+5M1DFhJ5iTGT++dvkg==", "dev": true, "requires": { - "electron-download": "^4.1.0", - "extract-zip": "^1.6.5" + "electron-download": "^4.1.1", + "extract-zip": "^1.6.7" } }, "electron-download": { @@ -2289,9 +1865,9 @@ } }, "electron-to-chromium": { - "version": "1.3.322", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.322.tgz", - "integrity": "sha512-Tc8JQEfGQ1MzfSzI/bTlSr7btJv/FFO7Yh6tanqVmIWOuNCu6/D1MilIEgLtmWqIrsv+o4IjpLAhgMBr/ncNAA==", + "version": "1.3.338", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.338.tgz", + "integrity": "sha512-wlmfixuHEc9CkfOKgcqdtzBmRW4NStM9ptl5oPILY2UDyHuSXb3Yit+yLVyLObTgGuMMU36hhnfs2GDJId7ctA==", "dev": true }, "emoji-regex": { @@ -2409,6 +1985,44 @@ "is-arrayish": "^0.2.1" } }, + "es-abstract": { + "version": "1.17.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.3.tgz", + "integrity": "sha512-AwiVPKf3sKGMoWtFw0J7Y4MTZ4Iek67k4COWOwHqS8B9TOZ71DCfcoBmdamy8Y6mj4MDz0+VNUpC2HKHFHA3pg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.1.5", + "is-regex": "^1.0.5", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimleft": "^2.1.1", + "string.prototype.trimright": "^2.1.1" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -2685,47 +2299,6 @@ "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", @@ -2849,62 +2422,6 @@ } } }, - "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", @@ -2942,80 +2459,16 @@ "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==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", + "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", "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" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "is-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" - } - } + "@nodelib/fs.stat": "^2.0.2", + "@nodelib/fs.walk": "^1.2.3", + "glob-parent": "^5.1.0", + "merge2": "^1.3.0", + "micromatch": "^4.0.2" } }, "fast-json-stable-stringify": { @@ -3029,6 +2482,15 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fastq": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", + "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "dev": true, + "requires": { + "reusify": "^1.0.0" + } + }, "fd-slicer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", @@ -3071,15 +2533,12 @@ } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "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": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" + "to-regex-range": "^5.0.1" } }, "finalhandler": { @@ -3144,6 +2603,15 @@ } } }, + "flat": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", + "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", + "dev": true, + "requires": { + "is-buffer": "~2.0.3" + } + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", @@ -3161,12 +2629,6 @@ "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", "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", @@ -3187,15 +2649,6 @@ "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", @@ -3234,6 +2687,19 @@ "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", "dev": true }, + "fsevents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", + "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "dev": true, + "optional": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "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", @@ -3249,6 +2715,12 @@ "globule": "^1.0.0" } }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, "get-caller-file": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", @@ -3275,12 +2747,6 @@ "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", @@ -3329,12 +2795,6 @@ "is-glob": "^4.0.1" } }, - "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", @@ -3365,45 +2825,23 @@ } }, "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", + "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", "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" + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.1.1", + "ignore": "^5.1.4", + "merge2": "^1.3.0", + "slash": "^3.0.0" }, "dependencies": { - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "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==", + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true } } @@ -3470,9 +2908,9 @@ "dev": true }, "growl": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.3.tgz", - "integrity": "sha512-hKlsbA5Vu3xsh1Cg3J7jSmX/WaW6A5oBeqzM88oNbCRQFz+zUaXm6yxS4RVytp1scBoJzSYl4YAEOQIt6O8V1Q==", + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, "grunt": { @@ -3571,12 +3009,12 @@ } }, "grunt-jsonlint": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-jsonlint/-/grunt-jsonlint-2.0.0.tgz", - "integrity": "sha512-bCodmPAoHxujSST/Pn5FdR6K1QytaZhlYW3dyU5Ut27h1usDBPnoBLWb7EoPE2EmW1UgQTrSNu/qP9tUMBSrZg==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/grunt-jsonlint/-/grunt-jsonlint-2.1.1.tgz", + "integrity": "sha512-A3i+rKoYXvLaOSu75kkqQY8UXFXVIcPiuBKQJ7VVCx/8iA7c3IZnFEqkc6ZpU56zDyNLGYhZX2WT691PNSc70Q==", "dev": true, "requires": { - "@prantlf/jsonlint": "6.2.1" + "@prantlf/jsonlint": "10.2.0" } }, "grunt-known-options": { @@ -3746,6 +3184,21 @@ "har-schema": "^2.0.0" } }, + "hard-rejection": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", + "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, "has-ansi": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", @@ -3780,37 +3233,11 @@ "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" - } - } - } + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true }, "he": { "version": "1.1.1", @@ -4029,9 +3456,9 @@ "dev": true }, "iconv-lite": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.0.tgz", - "integrity": "sha512-NnEhI9hIEKHOzJ4f697DMz9IQEXr/MMJ5w64vN2/4Ai+wRnvV7SBrL0KLoRlwaKVghOc7LQ5YkPLuX146b6Ydw==", + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.1.tgz", + "integrity": "sha512-ONHr16SQvKZNSqjQT9gy5z24Jw+uqfO02/ngBSBoqChZ+W8qXX7GPRa1RoUnzGADw8K63R1BXUMzarCVQBpY8Q==", "requires": { "safer-buffer": ">= 2.1.2 < 3" } @@ -4115,9 +3542,9 @@ "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, "inquirer": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.1.tgz", - "integrity": "sha512-V1FFQ3TIO15det8PijPLFR9M9baSlnRs9nL7zWu1MNVA2T9YVl9ZbrHJhYs7e9X8jeMZ3lr2JH/rdHFgNCBdYw==", + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-7.0.3.tgz", + "integrity": "sha512-+OiOVeVydu4hnCGLCSX+wedovR/Yzskv9BFqUNNKq9uU2qg7LCcCo3R86S2E7WLo0y/x2pnEZfZe1CoYnORUAw==", "dev": true, "requires": { "ansi-escapes": "^4.2.1", @@ -4238,26 +3665,6 @@ "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", @@ -4285,57 +3692,39 @@ "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=", + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", "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" - } - } + "binary-extensions": "^2.0.0" } }, + "is-buffer": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", + "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", + "dev": true + }, + "is-callable": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.5.tgz", + "integrity": "sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==", + "dev": true + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, "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-extendable": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", @@ -4380,24 +3769,10 @@ "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" - } - } - } + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true }, "is-obj": { "version": "1.0.1", @@ -4411,21 +3786,21 @@ "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-regex": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.5.tgz", + "integrity": "sha512-vlKW17SNq44owv5AQR3Cq0bQPEb8+kF3UKZ2fiZNOWtztYE5i0CzCZxFDwO58qAOWtxdBRVO/V5Qin1wjCqFYQ==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, "is-regexp": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", @@ -4438,6 +3813,15 @@ "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", "dev": true }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, "is-typedarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", @@ -4454,12 +3838,6 @@ "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", @@ -4477,12 +3855,6 @@ "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", @@ -4733,9 +4105,9 @@ } }, "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true }, "known-css-properties": { @@ -4760,9 +4132,9 @@ "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==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "dev": true, "requires": { "core-util-is": "~1.0.0", @@ -5014,26 +4386,11 @@ "p-defer": "^1.0.0" } }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, "map-obj": { "version": "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", @@ -5151,41 +4508,6 @@ "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": { @@ -5212,6 +4534,12 @@ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", "dev": true }, + "min-indent": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.0.tgz", + "integrity": "sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY=", + "dev": true + }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", @@ -5227,36 +4555,15 @@ "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==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.0.2.tgz", + "integrity": "sha512-seq4hpWkYSUh1y7NXxzucwAN9yVlBc3Upgdjz8vLCP97jG8kaOmzYrVH/m7tQ1NYD1wdtZbSLfdy4zFmRWuc/w==", "dev": true, "requires": { "arrify": "^1.0.1", "is-plain-obj": "^1.1.0" } }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "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", @@ -5273,42 +4580,116 @@ } }, "mocha": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-4.1.0.tgz", - "integrity": "sha512-0RVnjg1HJsXY2YFDoTNzcc1NKhYuXKRrBAG2gDygmJJA136Cs2QlRliZG1mA0ap7cuaT30mw16luAeln+4RiNA==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.0.0.tgz", + "integrity": "sha512-CirsOPbO3jU86YKjjMzFLcXIb5YiGLUrjrXFHoJ3e2z9vWiaZVCZQ2+gtRGMPWF+nFhN6AWwLM/juzAQ6KRkbA==", "dev": true, "requires": { - "browser-stdout": "1.3.0", - "commander": "2.11.0", - "debug": "3.1.0", - "diff": "3.3.1", + "ansi-colors": "3.2.3", + "browser-stdout": "1.3.1", + "chokidar": "3.3.0", + "debug": "3.2.6", + "diff": "3.5.0", "escape-string-regexp": "1.0.5", - "glob": "7.1.2", - "growl": "1.10.3", - "he": "1.1.1", + "find-up": "3.0.0", + "glob": "7.1.3", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "3.13.1", + "log-symbols": "2.2.0", + "minimatch": "3.0.4", "mkdirp": "0.5.1", - "supports-color": "4.4.0" + "ms": "2.1.1", + "node-environment-flags": "1.0.6", + "object.assign": "4.1.0", + "strip-json-comments": "2.0.1", + "supports-color": "6.0.0", + "which": "1.3.1", + "wide-align": "1.1.3", + "yargs": "13.3.0", + "yargs-parser": "13.1.1", + "yargs-unparser": "1.6.0" }, "dependencies": { - "commander": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.11.0.tgz", - "integrity": "sha512-b0553uYA5YAEGgyYIGYROzKQ7X5RAqedkfjiZxwi0kL1g3bOaBNNZfYkzt/CL0umgD5wc9Jec2FbB98CjkMRvQ==", + "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 }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "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": { - "ms": "2.0.0" + "color-convert": "^1.9.0" } }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "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 + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, "glob": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", - "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "dev": true, "requires": { "fs.realpath": "^1.0.0", @@ -5319,25 +4700,151 @@ "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=", + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", "dev": true }, - "ms": { + "is-fullwidth-code-point": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", "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==", + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", "dev": true, "requires": { - "has-flag": "^2.0.0" + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "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" + } + }, + "supports-color": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", + "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -5464,46 +4971,6 @@ "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", "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", @@ -5532,6 +4999,16 @@ "integrity": "sha1-esGavSl+Caf3KnFUXZUbUX5N3iw=", "dev": true }, + "node-environment-flags": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.6.tgz", + "integrity": "sha512-5Evy2epuL+6TM0lCQGpFIj6KwiEsGh1SrHUhTbNX+sLbBtjidPZFAnVK9y5yU1+h//RitLbRHTIMyxQPtxMdHw==", + "dev": true, + "requires": { + "object.getownpropertydescriptors": "^2.0.3", + "semver": "^5.7.0" + } + }, "node-fetch": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.0.tgz", @@ -5539,9 +5016,9 @@ "dev": true }, "node-releases": { - "version": "1.1.44", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.44.tgz", - "integrity": "sha512-NwbdvJyR7nrcGrXvKAvzc5raj/NkoJudkarh2yIpJ4t0NH4aqjUDz/486P+ynIW5eokKOfzGNRdYoLfBlomruw==", + "version": "1.1.46", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.46.tgz", + "integrity": "sha512-YOjdx+Uoh9FbRO7yVYbnbt1puRWPQMemR3SutLeyv2XfxKs1ihpe0OLAUwBPEP2ImNH/PZC7SEiC6j32dwRZ7g==", "dev": true, "requires": { "semver": "^6.3.0" @@ -5575,15 +5052,6 @@ "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", @@ -5672,58 +5140,45 @@ "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-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true }, "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=", + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", "dev": true, "requires": { - "isobject": "^3.0.0" + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + }, + "dependencies": { + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + } } }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", "dev": true, "requires": { - "isobject": "^3.0.1" + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" } }, "on-finished": { @@ -5963,18 +5418,6 @@ "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": "2.1.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-2.1.0.tgz", @@ -6032,9 +5475,9 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.1.1.tgz", - "integrity": "sha512-OYMyqkKzK7blWO/+XZYP6w8hH0LDvkBvdvKukti+7kqYFCiEAk+gI3DWnryapc0Dau05ugGTy0foQ6mqn4AHYA==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", + "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", "dev": true }, "pify": { @@ -6073,12 +5516,6 @@ "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.26", "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", @@ -6162,9 +5599,9 @@ } }, "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==", + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz", + "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -6184,9 +5621,9 @@ } }, "postcss-jsx": { - "version": "0.36.3", - "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.3.tgz", - "integrity": "sha512-yV8Ndo6KzU8eho5mCn7LoLUGPkXrRXRjhMpX4AaYJ9wLJPv099xbtpbRQ8FrPnzVxb/cuMebbPR7LweSt+hTfA==", + "version": "0.36.4", + "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.4.tgz", + "integrity": "sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA==", "dev": true, "requires": { "@babel/core": ">=7.2.2" @@ -6419,9 +5856,9 @@ "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=", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", "dev": true }, "range-parser": { @@ -6507,6 +5944,15 @@ "string_decoder": "~0.10.x" } }, + "readdirp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.2.0.tgz", + "integrity": "sha512-crk4Qu3pmXwgxdSgGhgA/eXiJAPQiX4GMOZZMXnqKxHX7TaoL+3gQVo/WeuAiogr07DpnfjIMpXXa+PAIvwPGQ==", + "dev": true, + "requires": { + "picomatch": "^2.0.4" + } + }, "readline-sync": { "version": "1.4.10", "resolved": "https://registry.npmjs.org/readline-sync/-/readline-sync-1.4.10.tgz", @@ -6533,37 +5979,6 @@ "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", @@ -6648,12 +6063,6 @@ "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", @@ -6769,10 +6178,10 @@ "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==", + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", "dev": true }, "rfc6902": { @@ -6835,6 +6244,12 @@ "is-promise": "^2.1.0" } }, + "run-parallel": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.1.9.tgz", + "integrity": "sha512-DEqnSRTDw/Tc3FXf49zedI638Z9onwUotBMiUFKmrO2sdFKIbXamXGQ3Axd4qgphxKB4kw/qP1w5kTxnfU1B9Q==", + "dev": true + }, "rx-lite": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/rx-lite/-/rx-lite-4.0.8.tgz", @@ -6864,15 +6279,6 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", "integrity": "sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==" }, - "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", @@ -6947,18 +6353,6 @@ "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", "dev": true }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "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", @@ -7050,125 +6444,6 @@ } } }, - "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.3.0", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.3.0.tgz", @@ -7343,16 +6618,399 @@ "dev": true }, "spectron": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/spectron/-/spectron-3.8.0.tgz", - "integrity": "sha512-fQ7gFp6UuEaONjXFLifLeIUI022pOsm3b+NFAm696r2umUkSZ9IbnEgHwrvBX+pJ3QUDyCEs5bPHUieYU7FvaQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/spectron/-/spectron-8.0.0.tgz", + "integrity": "sha512-MI9+lAamDnw7S0vKaxXjU3g5qaW5KANaFLc+Hgq+QmMCkQbZLt6ukFFGfalmwIuYrmq+yWQPCD4CXgt3VSHrLA==", "dev": true, "requires": { "dev-null": "^0.1.1", - "electron-chromedriver": "~1.8.0", - "request": "^2.81.0", + "electron-chromedriver": "^6.0.0", + "request": "^2.87.0", "split": "^1.0.0", - "webdriverio": "^4.8.0" + "webdriverio": "^4.13.0" + }, + "dependencies": { + "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": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "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" + } + }, + "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" + } + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "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" + } + }, + "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" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "chardet": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", + "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "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" + } + }, + "deepmerge": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.0.1.tgz", + "integrity": "sha512-VIPwiMJqJ13ZQfaCsIFnp5Me9tnjURiaIFxfz7EH0Ci0dTSQpZtSLrqOicXqEd/z2r+z+Klk9GzmnRsgpgbOsQ==", + "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" + } + }, + "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" + } + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "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" + } + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "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 + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "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 + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "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" + } + }, + "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" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "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" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "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" + }, + "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 + } + } + }, + "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" + } + }, + "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" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "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" + } + } } }, "speedometer": { @@ -7369,36 +7027,6 @@ "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", @@ -7427,27 +7055,6 @@ "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", @@ -7469,6 +7076,26 @@ "strip-ansi": "^3.0.0" } }, + "string.prototype.trimleft": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz", + "integrity": "sha512-iu2AGd3PuP5Rp7x2kEZCrB2Nf41ehzh+goo8TV7z8/XDBbsvc6HQIlUl9RjkZ4oyrW1XM5UwlGl1oVEaDjg6Ag==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, + "string.prototype.trimright": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.1.tgz", + "integrity": "sha512-qFvWL3/+QIgZXVmJBfpHmxLB7xsUXz6HsUmP8+5dRaC3Q7oKUv9Vo6aMCRZC1smrtyECFsIT30PqBJ1gTjAs+g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "function-bind": "^1.1.1" + } + }, "string_decoder": { "version": "0.10.31", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", @@ -7528,12 +7155,12 @@ "dev": true }, "stylelint": { - "version": "12.0.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-12.0.1.tgz", - "integrity": "sha512-1mn39pqZiC/e8KUPoRMc1WMM83Upb2ILaSGxkCvKxALHutEOs2txcPQocJiXdO4Zx4FY4prGqjlkwrbthAxqig==", + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.0.0.tgz", + "integrity": "sha512-6sjgOJbM3iLhnUtmRO0J1vvxie9VnhIZX/2fCehjylv9Gl9u0ytehGCTm9Lhw2p1F8yaNZn5UprvhCB8C3g/Tg==", "dev": true, "requires": { - "autoprefixer": "^9.7.1", + "autoprefixer": "^9.7.3", "balanced-match": "^1.0.0", "chalk": "^3.0.0", "cosmiconfig": "^6.0.0", @@ -7542,7 +7169,7 @@ "file-entry-cache": "^5.0.1", "get-stdin": "^7.0.0", "global-modules": "^2.0.0", - "globby": "^9.2.0", + "globby": "^11.0.0", "globjoin": "^0.1.4", "html-tags": "^3.1.0", "ignore": "^5.1.4", @@ -7553,10 +7180,10 @@ "lodash": "^4.17.15", "log-symbols": "^3.0.0", "mathml-tag-names": "^2.1.1", - "meow": "^5.0.0", + "meow": "^6.0.0", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", - "postcss": "^7.0.21", + "postcss": "^7.0.26", "postcss-html": "^0.36.0", "postcss-jsx": "^0.36.3", "postcss-less": "^3.1.4", @@ -7600,20 +7227,20 @@ } }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true }, "camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha1-oqpfsa9oh1glnDLBQUJteJI7m3c=", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.1.1.tgz", + "integrity": "sha512-kEPCddRFChEzO0d6w61yh0WbBiSv9gBnfZWGfXRYPlGqIdIGef6HMR6pgqVSEWCYkrp8B0AtEpEXNY+Jx0xk1A==", "dev": true, "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" + "camelcase": "^5.3.1", + "map-obj": "^4.0.0", + "quick-lru": "^4.0.1" } }, "chalk": { @@ -7651,12 +7278,13 @@ } }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, "requires": { - "locate-path": "^2.0.0" + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" } }, "get-stdin": { @@ -7678,9 +7306,9 @@ "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=", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true }, "is-fullwidth-code-point": { @@ -7689,95 +7317,121 @@ "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=", + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" + "p-locate": "^4.1.0" } }, "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha1-plzSkIepJZi4eRJXpSPgISIqwfk=", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", + "integrity": "sha512-glc9y00wgtwcDmp7GaE/0b0OnxpNJsVf3ael/An6Fe2Q51LLwN1er6sdomLRzz5h0+yMpiYLhWYF5R7HeqVd4g==", "dev": true }, "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.0.0.tgz", + "integrity": "sha512-x4rYsjigPBDAxY+BGuK83YLhUIqui5wYyZoqb6QJCUOs+0fiYq+i/NV4Jt8OgIfObZFxG9iTyvLDu4UTohGTFw==", "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" + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.1.1", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.0.0", + "minimist-options": "^4.0.1", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.0", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.8.1", + "yargs-parser": "^16.1.0" } }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.0.0.tgz", + "integrity": "sha512-OOY5b7PAEFV0E2Fir1KOkxchnZNCdowAJgQ5NuxjpBKTRP3pQhwkrkxqQjeoKJ+fO7bCpmIZaogI4eZGDMEGOw==", "dev": true, "requires": { + "@babel/code-frame": "^7.0.0", "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" + "json-parse-better-errors": "^1.0.1", + "lines-and-columns": "^1.1.6" } }, - "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=", + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", "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=", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "dependencies": { + "type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "dev": true + } } }, "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=", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" } }, "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", "dev": true, "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" } }, "resolve-from": { @@ -7806,17 +7460,14 @@ "ansi-regex": "^5.0.0" } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - }, "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } }, "supports-color": { "version": "7.1.0", @@ -7828,18 +7479,19 @@ } }, "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha1-tAPQuRvlDDMd/EuC7s6yLD3hbSA=", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.0.tgz", + "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", "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==", + "version": "16.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", + "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", "dev": true, "requires": { - "camelcase": "^4.1.0" + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" } } } @@ -7995,65 +7647,6 @@ } } }, - "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" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - } - } - }, "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -8139,67 +7732,13 @@ "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=", + "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": "^3.0.0", - "repeat-string": "^1.6.1" + "is-number": "^7.0.0" } }, "toidentifier": { @@ -8367,18 +7906,6 @@ "x-is-string": "^0.1.0" } }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, "uniq": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", @@ -8461,52 +7988,6 @@ "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", @@ -8545,12 +8026,6 @@ "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", @@ -8613,12 +8088,6 @@ "vfile-message": "^1.0.0" }, "dependencies": { - "is-buffer": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.4.tgz", - "integrity": "sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A==", - "dev": true - }, "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", @@ -8679,240 +8148,6 @@ "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-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": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.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" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "chardet": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.4.2.tgz", - "integrity": "sha1-tUc7M9yXxCTl2Y3IfVXU2KKci/I=", - "dev": true - }, - "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" - } - }, - "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" - } - }, - "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" - } - }, - "glob": { - "version": "7.1.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "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" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "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 - }, - "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 - }, - "mute-stream": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", - "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", - "dev": true - }, - "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" - } - }, - "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" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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" - }, - "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 - } - } - } - } - }, "webidl-conversions": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-4.0.2.tgz", @@ -8977,6 +8212,15 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, "windows-release": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/windows-release/-/windows-release-3.2.0.tgz", @@ -9164,6 +8408,189 @@ } } }, + "yargs-unparser": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.6.0.tgz", + "integrity": "sha512-W9tKgmSn0DpSatfri0nx52Joq5hVXgeLiqR/5G0sZNDoLZFOr/xjBUDcShCOGNsBnEMNo1KAMBkTej1Hm62HTw==", + "dev": true, + "requires": { + "flat": "^4.1.0", + "lodash": "^4.17.15", + "yargs": "^13.3.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 + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + } + }, + "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 + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "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 + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "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" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + } + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yargs": { + "version": "13.3.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz", + "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.1" + } + }, + "yargs-parser": { + "version": "13.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", + "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "yauzl": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", @@ -9176,56 +8603,6 @@ "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" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - }, - "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 b59dee38..308a3a9b 100644 --- a/package.json +++ b/package.json @@ -47,16 +47,16 @@ "http-auth": "^3.2.3", "jsdom": "^11.6.2", "jshint": "^2.10.2", - "mocha": "^4.1.0", + "mocha": "^7.0.0", "mocha-each": "^1.1.0", "mocha-logger": "^1.0.6", - "spectron": "^3.8.0", + "spectron": "^8.0.0", "stylelint": "latest", "stylelint-config-standard": "latest", "time-grunt": "latest" }, "optionalDependencies": { - "electron": "^3.0.13" + "electron": "^6.1.7" }, "dependencies": { "colors": "^1.1.2", From 7ad0cfd5f69515b6ffcdfd36ccde7e54969550c1 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Tue, 21 Jan 2020 19:16:42 -0800 Subject: [PATCH 032/104] update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d6584d0e..6356300d 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Added - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". - Added the ability to hide the temp label and weather icon in the `currentweather` module to allow showing only information such as wind and sunset/rise. -- Sun and Moon data to the `clock` module. +- The `clock` module now optionally displays sun and moon data, including rise/set times, remaining daylight, and percent of moon illumination. ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) From 2ca81f965a4e0b06483d889262e3cc4e59b9df0a Mon Sep 17 00:00:00 2001 From: adimi Date: Wed, 22 Jan 2020 22:03:34 +0200 Subject: [PATCH 033/104] Add hebrew translation --- CHANGELOG.md | 1 + translations/he.json | 36 ++++++++++++++++++++++++++++++++++++ translations/translations.js | 9 +++++---- 3 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 translations/he.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 6356300d..08e08d56 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". - Added the ability to hide the temp label and weather icon in the `currentweather` module to allow showing only information such as wind and sunset/rise. - The `clock` module now optionally displays sun and moon data, including rise/set times, remaining daylight, and percent of moon illumination. +- Added Hebrew translation. ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) diff --git a/translations/he.json b/translations/he.json new file mode 100644 index 00000000..5e1f5f8b --- /dev/null +++ b/translations/he.json @@ -0,0 +1,36 @@ +{ + "LOADING": "טוען...", + + "TODAY": "היום", + "TOMORROW": "מחר", + "DAYAFTERTOMORROW": "בעוד יומיים", + "RUNNING": "מסתיים ב", + "EMPTY": "אין ארועים", + + "WEEK": "{weekNumber} שבוע", + + "N": "צ", + "NNE": "צ-צ-מז", + "NE": "צ-מז", + "ENE": "מז-צ-מז", + "E": "מז", + "ESE": "מז-ד-מז", + "SE": "ד-מז", + "SSE": "ד-ד-מז", + "S": "ד", + "SSW": "ד-ד-מע", + "SW": "ד-מע", + "WSW": "מע-ד-מע", + "W": "מע", + "WNW": "מע-ז-מע", + "NW": "ז-מע", + "NNW": "צ-צ-מע", + + "UPDATE_NOTIFICATION": "עדכון זמין ל-MagicMirror", + "UPDATE_NOTIFICATION_MODULE": "עדכון זמין ב-{MODULE_NAME} מודול", + "UPDATE_INFO_SINGLE": "ההתקנה הנוכחית נמצאת מאחור הענף {BRANCH_NAME} ב-{COMMIT_COUNT} מופע", + "UPDATE_INFO_MULTIPLE": "ההתקנה הנוכחית נמצאת מאחור הענף {BRANCH_NAME} ב-{COMMIT_COUNT} מופעים", + + "FEELS": "מרגיש כמו", + "PRECIP": "משקעים" +} diff --git a/translations/translations.js b/translations/translations.js index 767590e8..2b6f65bf 100644 --- a/translations/translations.js +++ b/translations/translations.js @@ -36,12 +36,13 @@ var translations = { "kr" : "translations/kr.json", // Korean "ro" : "translations/ro.json", // Romanian "cy" : "translations/cy.json", // Welsh (Cymraeg) - "bg" : "translations/bg.json", // Bulgarian - "cs" : "translations/cs.json", // Czech + "bg" : "translations/bg.json", // Bulgarian + "cs" : "translations/cs.json", // Czech "hr" : "translations/hr.json", // Croatian - "sk" : "translations/sk.json", // Slovak + "sk" : "translations/sk.json", // Slovak "tlh" : "translations/tlh.json", // Klingon - "ms-my" : "translations/ms-my.json" // Malay + "ms-my" : "translations/ms-my.json", // Malay + "he" : "translations/he.json" // Hebrew }; if (typeof module !== "undefined") {module.exports = translations;} From b44ab88927e5aef80190c654b04f4a808d5c0177 Mon Sep 17 00:00:00 2001 From: Karol Sejka Date: Thu, 23 Jan 2020 02:24:47 +0100 Subject: [PATCH 034/104] adds PRECIP polish translation --- translations/pl.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/translations/pl.json b/translations/pl.json index 09f44d88..b81a6dad 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -31,5 +31,6 @@ "UPDATE_INFO_SINGLE": "Zainstalowana wersja odbiega o {COMMIT_COUNT} commit od gałęzi {BRANCH_NAME}.", "UPDATE_INFO_MULTIPLE": "Zainstalowana wersja odbiega o {COMMIT_COUNT} commitów od gałęzi {BRANCH_NAME}.", - "FEELS": "Odczuwalna" + "FEELS": "Odczuwalna", + "PRECIP": "Szansa opadów" } From 95dedf0d800319470abf642cd4710aaa966431bf Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 23 Jan 2020 19:38:15 +0100 Subject: [PATCH 035/104] Skip weather tests for now --- tests/e2e/modules/weather_spec.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/e2e/modules/weather_spec.js b/tests/e2e/modules/weather_spec.js index d6596587..009f5142 100644 --- a/tests/e2e/modules/weather_spec.js +++ b/tests/e2e/modules/weather_spec.js @@ -11,6 +11,13 @@ const {generateWeather, generateWeatherForecast} = require("./mocks"); const wait = () => new Promise(res => setTimeout(res, 3000)); describe("Weather module", function() { + before(function() { + // See issue: https://github.com/MichMich/MagicMirror/issues/1840 + // Skipping the weather tests for now since these seem to give issues. + // Please send a PR if you know how to fix these. Thanks! + this.skip(); + }); + let app; helpers.setupTimeout(this); From 13ebe6d0e1ce966058f0e18b4fd644c578cbe175 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Thu, 23 Jan 2020 19:52:07 +0100 Subject: [PATCH 036/104] Check method --- tests/e2e/modules/weather_spec.js | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/tests/e2e/modules/weather_spec.js b/tests/e2e/modules/weather_spec.js index 009f5142..dad11f50 100644 --- a/tests/e2e/modules/weather_spec.js +++ b/tests/e2e/modules/weather_spec.js @@ -10,13 +10,12 @@ const {generateWeather, generateWeatherForecast} = require("./mocks"); const wait = () => new Promise(res => setTimeout(res, 3000)); -describe("Weather module", function() { - before(function() { - // See issue: https://github.com/MichMich/MagicMirror/issues/1840 - // Skipping the weather tests for now since these seem to give issues. - // Please send a PR if you know how to fix these. Thanks! - this.skip(); - }); +// See issue: https://github.com/MichMich/MagicMirror/issues/1840 +// Skipping the weather tests for now since these seem to give issues. +// Please send a PR if you know how to fix these. Thanks! + + +describe.skip("Weather module", function() { let app; From 6ba5056c960ea62408e2e12f37be7cf5e793e49e Mon Sep 17 00:00:00 2001 From: Jon Kolb Date: Fri, 24 Jan 2020 10:42:45 -0500 Subject: [PATCH 037/104] Fix regression causing 'undefined' to show up when config.hideTemp is false --- .../default/currentweather/currentweather.js | 44 +++++++++---------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js index dcf771af..2f58de5b 100644 --- a/modules/default/currentweather/currentweather.js +++ b/modules/default/currentweather/currentweather.js @@ -195,33 +195,33 @@ Module.register("currentweather",{ var large = document.createElement("div"); large.className = "large light"; + var degreeLabel = ""; + if (this.config.units === "metric" || this.config.units === "imperial") { + degreeLabel += "°"; + } + if(this.config.degreeLabel) { + 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 = "."; + } + if (this.config.hideTemp === true) { var weatherIcon = document.createElement("span"); weatherIcon.className = "wi weathericon " + this.weatherType; large.appendChild(weatherIcon); - var degreeLabel = ""; - if (this.config.units === "metric" || this.config.units === "imperial") { - degreeLabel += "°"; - } - if(this.config.degreeLabel) { - 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 = "."; - } - var temperature = document.createElement("span"); temperature.className = "bright"; temperature.innerHTML = " " + this.temperature.replace(".", this.config.decimalSymbol) + degreeLabel; From a5b09d784659e2dd277c85429f8fb39e627cff99 Mon Sep 17 00:00:00 2001 From: Jon Kolb Date: Fri, 24 Jan 2020 10:50:56 -0500 Subject: [PATCH 038/104] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08e08d56..d036074f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Force declaration of public ip adress in config file (ISSUE #1852) - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) - Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) +- Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). From 85d26f73204d28679535d5c84e8a1e1511cde948 Mon Sep 17 00:00:00 2001 From: Mpho Mphego Date: Sun, 26 Jan 2020 14:10:24 +0200 Subject: [PATCH 039/104] Grammar fixes to config. This PR does the following: - [x] Corrects grammar on `config.js.sample` --- CHANGELOG.md | 5 +++++ config/config.js.sample | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08e08d56..9707cf8e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core. +## [2.11.0] - 2020-01-24 + +### Changed +- Updated config.js.sample: Corrected some grammar on `config.js.sample` comment section. + ## [2.11.0] - Unreleased (Develop Branch) *This release is scheduled to be released on 2020-04-01.* diff --git a/config/config.js.sample b/config/config.js.sample index 1ab46833..c22960e5 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -3,7 +3,7 @@ * By Michael Teeuw http://michaelteeuw.nl * MIT Licensed. * - * For more information how you can configurate this file + * For more information on how you can configure this file * See https://github.com/MichMich/MagicMirror#configuration * */ From 602119fa41010fa8c61e44c5c5cc36b2f6780aec Mon Sep 17 00:00:00 2001 From: sergge1 <49363121+sergge1@users.noreply.github.com> Date: Fri, 31 Jan 2020 11:17:11 +0200 Subject: [PATCH 040/104] Ukrainian translation added --- translations/uk.json | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 translations/uk.json diff --git a/translations/uk.json b/translations/uk.json new file mode 100644 index 00000000..b9e154ab --- /dev/null +++ b/translations/uk.json @@ -0,0 +1,36 @@ +{ + "LOADING": "Завантаження …", + + "TODAY": "Сьогодні", + "TOMORROW": "Завтра", + "DAYAFTERTOMORROW": "Післязавтра", + "RUNNING": "Закінчується через", + "EMPTY": "Немає найближчих подій", + + "WEEK": "Тиждень {weekNumber}", + + "N": "Пн", + "NNE": "ПнПнСх", + "NE": "ПнСх", + "ENE": "СхПнСх", + "E": "Сх", + "ESE": "СхПдСх", + "SE": "СхПд", + "SSE": "СхСхПд", + "S": "Пд", + "SSW": "ПдПдЗх", + "SW": "ПдЗх", + "WSW": "ЗхПдЗх", + "W": "Зх", + "WNW": "ЗхПнЗх", + "NW": "ПнЗх", + "NNW": "ПнПнЗх", + + "UPDATE_NOTIFICATION": "Є оновлення для MagicMirror².", + "UPDATE_NOTIFICATION_MODULE": "Є оновлення для модуля {MODULE_NAME}.", + "UPDATE_INFO_SINGLE": "Поточна версія на {COMMIT_COUNT} комміт позаду від гілки {BRANCH_NAME}.", + "UPDATE_INFO_MULTIPLE": "Поточна інсталяція на {COMMIT_COUNT} комітів позаду від гілки {BRANCH_NAME}.", + + "FEELS": "Відчувається як", + "PRECIP": "Опади" +} From c41d6965abfc45a8b56b443b1cb7115324e31c87 Mon Sep 17 00:00:00 2001 From: sergge1 <49363121+sergge1@users.noreply.github.com> Date: Fri, 31 Jan 2020 11:18:43 +0200 Subject: [PATCH 041/104] added Ukrainian translation --- translations/translations.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/translations/translations.js b/translations/translations.js index 2b6f65bf..4cc6420d 100644 --- a/translations/translations.js +++ b/translations/translations.js @@ -42,7 +42,8 @@ var translations = { "sk" : "translations/sk.json", // Slovak "tlh" : "translations/tlh.json", // Klingon "ms-my" : "translations/ms-my.json", // Malay - "he" : "translations/he.json" // Hebrew + "he" : "translations/he.json", // Hebrew + "uk" : "translations/uk.json" // Ukrainian }; if (typeof module !== "undefined") {module.exports = translations;} From d7f6f46805e4f0618c6caf07a8b3e19dcac479a0 Mon Sep 17 00:00:00 2001 From: sergge1 <49363121+sergge1@users.noreply.github.com> Date: Fri, 31 Jan 2020 11:28:00 +0200 Subject: [PATCH 042/104] 2.11.0 - added Ukrainian translation --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 060abab6..53441236 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - cleanup installers folder, remove externalized scripts ### Added +- Ukrainian translation. - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". - Added the ability to hide the temp label and weather icon in the `currentweather` module to allow showing only information such as wind and sunset/rise. - The `clock` module now optionally displays sun and moon data, including rise/set times, remaining daylight, and percent of moon illumination. From 88b15797a0a55807034f249f6a9643ba3d8fba60 Mon Sep 17 00:00:00 2001 From: Kurtis Blankenship Date: Fri, 31 Jan 2020 20:35:46 -0600 Subject: [PATCH 043/104] fix: add missing +1 for month --- modules/default/calendar/vendor/ical.js/node-ical.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/calendar/vendor/ical.js/node-ical.js b/modules/default/calendar/vendor/ical.js/node-ical.js index 1da04375..593dc1e0 100644 --- a/modules/default/calendar/vendor/ical.js/node-ical.js +++ b/modules/default/calendar/vendor/ical.js/node-ical.js @@ -28,7 +28,7 @@ var rrule = require('rrule').RRule function getLocaleISOString(date) { var year = date.getFullYear().toString(10).padStart(4,'0'); - var month = date.getMonth().toString(10).padStart(2,'0'); + var month = (date.getMonth().toString(10) + 1).padStart(2,'0'); var day = date.getDate().toString(10).padStart(2,'0'); var hour = date.getHours().toString(10).padStart(2,'0'); var minute = date.getMinutes().toString(10).padStart(2,'0'); From ca49d8adb323543380cfa72c31851678ee36f644 Mon Sep 17 00:00:00 2001 From: Kurtis Blankenship Date: Fri, 31 Jan 2020 20:46:43 -0600 Subject: [PATCH 044/104] fix: correcting syntax --- modules/default/calendar/vendor/ical.js/node-ical.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/calendar/vendor/ical.js/node-ical.js b/modules/default/calendar/vendor/ical.js/node-ical.js index 593dc1e0..424fd2e6 100644 --- a/modules/default/calendar/vendor/ical.js/node-ical.js +++ b/modules/default/calendar/vendor/ical.js/node-ical.js @@ -28,7 +28,7 @@ var rrule = require('rrule').RRule function getLocaleISOString(date) { var year = date.getFullYear().toString(10).padStart(4,'0'); - var month = (date.getMonth().toString(10) + 1).padStart(2,'0'); + var month = (date.getMonth() + 1).toString(10).padStart(2,'0'); var day = date.getDate().toString(10).padStart(2,'0'); var hour = date.getHours().toString(10).padStart(2,'0'); var minute = date.getMinutes().toString(10).padStart(2,'0'); From c8c327b6abcfcd41edd3ea8cf81ad449ae99b98f Mon Sep 17 00:00:00 2001 From: karenorman Date: Sat, 1 Feb 2020 20:46:26 +0800 Subject: [PATCH 045/104] Add HTTPS support --- CHANGELOG.md | 5 +++++ config/config.js.sample | 4 ++++ js/server.js | 14 ++++++++++++-- serveronly/index.js | 3 ++- 4 files changed, 23 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 060abab6..35d38f15 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core. +## [2.12.0] - 2020-01-31 + +### Changed +- Add HTTPS support and update config.js.sample + ## [2.11.0] - 2020-01-24 ### Changed diff --git a/config/config.js.sample b/config/config.js.sample index c22960e5..90610106 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -21,6 +21,10 @@ var config = { // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], + useHttps: false, // Support HTTPS or not + httpsPrivateKey: "", // HTTPS Private Key path + httpsCertificate: "", // HTTPS Certificate path + language: "en", timeFormat: 24, units: "metric", diff --git a/js/server.js b/js/server.js index b9c9b0d8..19bdfb91 100644 --- a/js/server.js +++ b/js/server.js @@ -7,8 +7,6 @@ var express = require("express"); var app = require("express")(); -var server = require("http").Server(app); -var io = require("socket.io")(server); var path = require("path"); var ipfilter = require("express-ipfilter").IpFilter; var fs = require("fs"); @@ -22,6 +20,18 @@ var Server = function(config, callback) { port = process.env.MM_PORT; } + var server = null; + if(config.useHttps){ + var options = { + key: fs.readFileSync(config.httpsPrivateKey), + cert: fs.readFileSync(config.httpsCertificate) + } + server = require("https").Server(options, app); + }else{ + server = require("http").Server(app); + } + var io = require("socket.io")(server); + console.log("Starting server on port " + port + " ... "); server.listen(port, config.address ? config.address : "localhost"); diff --git a/serveronly/index.js b/serveronly/index.js index 3b8013ef..f7da58f5 100644 --- a/serveronly/index.js +++ b/serveronly/index.js @@ -1,5 +1,6 @@ var app = require("../js/app.js"); app.start(function(config) { var bindAddress = config.address ? config.address : "localhost"; - console.log("\nReady to go! Please point your browser to: http://" + bindAddress + ":" + config.port); + var httpType = config.useHttps ? "https" : "http"; + console.log("\nReady to go! Please point your browser to: " + httpType + "://" + bindAddress + ":" + config.port); }); From 09c1ea992c669cad3fe24eeb7fd328fc0d526906 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 13:56:15 +0100 Subject: [PATCH 046/104] Update start methods. --- CHANGELOG.md | 3 ++ js/app.js | 6 +++- package.json | 3 +- run-start.sh | 75 -------------------------------------------------- untrack-css.sh | 11 -------- 5 files changed, 10 insertions(+), 88 deletions(-) delete mode 100755 run-start.sh delete mode 100755 untrack-css.sh diff --git a/CHANGELOG.md b/CHANGELOG.md index 53441236..a97536ba 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,9 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Changed - Updated config.js.sample: Corrected some grammar on `config.js.sample` comment section. +- Remove `run-start.sh` script and update start commands: + - To start using electron, use `npm run start`. + - To start in server only mode, use `npm run server`. ## [2.11.0] - Unreleased (Develop Branch) diff --git a/js/app.js b/js/app.js index 3c7a51f8..920d0c49 100644 --- a/js/app.js +++ b/js/app.js @@ -4,7 +4,6 @@ * By Michael Teeuw http://michaelteeuw.nl * MIT Licensed. */ - var fs = require("fs"); var Server = require(__dirname + "/server.js"); var Utils = require(__dirname + "/utils.js"); @@ -24,6 +23,11 @@ console.log("Starting MagicMirror: v" + global.version); // global absolute root path global.root_path = path.resolve(__dirname + "/../"); +if (!process.env.DISPLAY) { + console.log("DISPLAY environment variable not set. Using DISPLAY=:0"); + process.env.DISPLAY = ":0"; +} + if (process.env.MM_CONFIG_FILE) { global.configuration_file = process.env.MM_CONFIG_FILE; } diff --git a/package.json b/package.json index 42baf1da..31490b5f 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,8 @@ "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { - "start": "./run-start.sh", + "start": "./node_modules/.bin/electron js/electron.js", + "server": "node ./serveronly", "install": "cd vendor && npm install", "install-fonts": "cd fonts && npm install", "postinstall": "sh untrack-css.sh && sh installers/postinstall/postinstall.sh && npm run install-fonts", diff --git a/run-start.sh b/run-start.sh deleted file mode 100755 index f4c2d4e3..00000000 --- a/run-start.sh +++ /dev/null @@ -1,75 +0,0 @@ -#!/bin/bash - # use bash instead of sh -./untrack-css.sh - -if grep docker /proc/1/cgroup -qa; then - # if running in docker, only start electron - - electron js/electron.js $1; -else - # not running in docker - - if [ -z "$DISPLAY" ]; then #If not set DISPLAY is SSH remote or tty - export DISPLAY=:0 # Set by default display - fi - # get the processor architecture - arch=$(uname -m) - false='false' - - # get the config option, if any - # only check non comment lines - serveronly=$(grep -v '^\s//' config/config.js | grep -i serveronly: | awk '{print tolower($2)}' | tr -d ,\"\') - # set default if not defined in config - serveronly=${serveronly:-false} - # check for xwindows running - xorg=$(pgrep Xorg) - #check for macOS - mac=$(uname) - # - # if the user requested serveronly OR - # electron support for armv6l has been dropped OR - # system is in text mode - # - if [ "$serveronly." != "false." -o "$arch" == "armv6l" ] || [ "$xorg." == "." -a $mac != 'Darwin' ]; then - - # if user explicitly configured to run server only (no ui local) - # OR there is no xwindows running, so no support for browser graphics - if [ "$serveronly." == "true." -o "$xorg." == "." ]; then - # start server mode, - node serveronly - else - # start the server in the background - # wait for server to be ready - # need bash for this - exec 3< <(node serveronly) - - # Read the output of server line by line until one line 'point your browser' - while read line; do - case "$line" in - *point\ your\ browser*) - echo $line - break - ;; - *) - echo $line - #sleep .25 - ;; - esac - done <&3 - - # Close the file descriptor - exec 3<&- - - # lets use chrome to display here now - # get the server port address from the ready message - port=$(echo $line | awk -F\: '{print $4}') - # start chromium - echo "Starting chromium browser now, have patience, it takes a minute" - chromium-browser -noerrdialogs -kiosk -start_maximized --disable-infobars --app=http://localhost:$port --ignore-certificate-errors-spki-list --ignore-ssl-errors --ignore-certificate-errors 2>/dev/null - exit - fi - else - # we can use electron directly - electron js/electron.js $1; - fi -fi \ No newline at end of file diff --git a/untrack-css.sh b/untrack-css.sh deleted file mode 100755 index d5969b84..00000000 --- a/untrack-css.sh +++ /dev/null @@ -1,11 +0,0 @@ -# Long history here -# https://github.com/MichMich/MagicMirror/pull/1540 -STATUS_CUSTOM_CSS=$(git ls-files -v css/custom.css| awk '{print $1}') - -if [ "$STATUS_CUSTOM_CSS" = "H" ]; then - echo "We'll remove from the repository the css/custom.css" - echo "This script apply git update-index --skip-worktree css/custom.css" - git update-index --skip-worktree css/custom.css - git rm --cached css/custom.css -fi - From 21dbaa1a0335597d558ef733019a7b26f5bcb225 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 13:59:13 +0100 Subject: [PATCH 047/104] Move DISPLAY default to electron script. --- js/app.js | 5 ----- js/electron.js | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/js/app.js b/js/app.js index 920d0c49..08612dd8 100644 --- a/js/app.js +++ b/js/app.js @@ -23,11 +23,6 @@ console.log("Starting MagicMirror: v" + global.version); // global absolute root path global.root_path = path.resolve(__dirname + "/../"); -if (!process.env.DISPLAY) { - console.log("DISPLAY environment variable not set. Using DISPLAY=:0"); - process.env.DISPLAY = ":0"; -} - if (process.env.MM_CONFIG_FILE) { global.configuration_file = process.env.MM_CONFIG_FILE; } diff --git a/js/electron.js b/js/electron.js index c5e9c4cb..77820db2 100644 --- a/js/electron.js +++ b/js/electron.js @@ -1,5 +1,10 @@ /* jshint esversion: 6 */ +if (!process.env.DISPLAY) { + console.log("DISPLAY environment variable not set. Using DISPLAY=:0"); + process.env.DISPLAY = ":0"; +} + "use strict"; const electron = require("electron"); From 7f2ecbd04f2f9f549a581f70ebe0c0d594b5871b Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 14:32:38 +0100 Subject: [PATCH 048/104] Cleanup. --- installers/postinstall/postinstall.sh | 2 -- package.json | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) delete mode 100644 installers/postinstall/postinstall.sh diff --git a/installers/postinstall/postinstall.sh b/installers/postinstall/postinstall.sh deleted file mode 100644 index dc19df98..00000000 --- a/installers/postinstall/postinstall.sh +++ /dev/null @@ -1,2 +0,0 @@ -echo "\033[32mMagicMirror installation successful!" -exit 0 diff --git a/package.json b/package.json index 31490b5f..21618fe1 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "server": "node ./serveronly", "install": "cd vendor && npm install", "install-fonts": "cd fonts && npm install", - "postinstall": "sh untrack-css.sh && sh installers/postinstall/postinstall.sh && npm run install-fonts", + "postinstall": "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", From e2afee32755a075968760c2e19bf4fd311c40853 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 14:39:50 +0100 Subject: [PATCH 049/104] Add feedback. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 21618fe1..6209067e 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,9 @@ "scripts": { "start": "./node_modules/.bin/electron js/electron.js", "server": "node ./serveronly", - "install": "cd vendor && npm install", - "install-fonts": "cd fonts && npm install", - "postinstall": "npm run install-fonts", + "install": "echo \"Installing vendor files ...\n\n\" && cd vendor && npm install --loglevel=error", + "install-fonts": "echo \"Installing fonts ...\n\n\" && cd fonts && npm install --loglevel=error", + "postinstall": "npm run install-fonts && echo \"Installing done! Use `npm start` to start MagicMirror. \n\n\"", "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", From 1b38e73eb201d33ae2badad70d1b93b1027d1aaf Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 14:41:46 +0100 Subject: [PATCH 050/104] Fix install scripts. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index 6209067e..091aec66 100644 --- a/package.json +++ b/package.json @@ -6,9 +6,9 @@ "scripts": { "start": "./node_modules/.bin/electron js/electron.js", "server": "node ./serveronly", - "install": "echo \"Installing vendor files ...\n\n\" && cd vendor && npm install --loglevel=error", - "install-fonts": "echo \"Installing fonts ...\n\n\" && cd fonts && npm install --loglevel=error", - "postinstall": "npm run install-fonts && echo \"Installing done! Use `npm start` to start MagicMirror. \n\n\"", + "install": "echo \"Installing vendor files ...\n\" && cd vendor && npm install --loglevel=error", + "install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error", + "postinstall": "npm run install-fonts && echo \"\nInstallation done! \"", "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", From 65b1d61295d4b3cc552f4c4c84544495f2a2d008 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 14:43:43 +0100 Subject: [PATCH 051/104] Improve feedback. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 091aec66..3786b79d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "server": "node ./serveronly", "install": "echo \"Installing vendor files ...\n\" && cd vendor && npm install --loglevel=error", "install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error", - "postinstall": "npm run install-fonts && echo \"\nInstallation done! \"", + "postinstall": "npm run install-fonts && echo \"Installation finished successfully! \n\"", "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", From e2d4a0fde8f2dfac7a6acb7a041538281f46092f Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 14:52:52 +0100 Subject: [PATCH 052/104] Improve Feedback. --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3786b79d..9c753db7 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "server": "node ./serveronly", "install": "echo \"Installing vendor files ...\n\" && cd vendor && npm install --loglevel=error", "install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error", - "postinstall": "npm run install-fonts && echo \"Installation finished successfully! \n\"", + "postinstall": "npm run install-fonts && echo \"MagicMirror installation finished successfully! \n\"", "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", From 8ef8388c3289ce041ecb8aeb09d96b8844bd090e Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 15:02:47 +0100 Subject: [PATCH 053/104] Set default DISPLAY in package.json. --- js/electron.js | 5 ----- package.json | 2 +- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/js/electron.js b/js/electron.js index 77820db2..c5e9c4cb 100644 --- a/js/electron.js +++ b/js/electron.js @@ -1,10 +1,5 @@ /* jshint esversion: 6 */ -if (!process.env.DISPLAY) { - console.log("DISPLAY environment variable not set. Using DISPLAY=:0"); - process.env.DISPLAY = ":0"; -} - "use strict"; const electron = require("electron"); diff --git a/package.json b/package.json index 9c753db7..1b150ed4 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,7 @@ "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { - "start": "./node_modules/.bin/electron js/electron.js", + "start": "DISPLAY=\"${DISPLAY:=:0}\" ./node_modules/.bin/electron js/electron.js", "server": "node ./serveronly", "install": "echo \"Installing vendor files ...\n\" && cd vendor && npm install --loglevel=error", "install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error", From a41bae3132d046a3d30a79dd1ffbff3b70286b76 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 15:05:26 +0100 Subject: [PATCH 054/104] Cleanup --- CHANGELOG.md | 3 ++- installers/pm2_MagicMirror.json | 7 ------- 2 files changed, 2 insertions(+), 8 deletions(-) delete mode 100644 installers/pm2_MagicMirror.json diff --git a/CHANGELOG.md b/CHANGELOG.md index a97536ba..bfcfe878 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,7 +18,8 @@ This project adheres to [Semantic Versioning](http://semver.org/). *This release is scheduled to be released on 2020-04-01.* ### Deleted -- cleanup installers folder, remove externalized scripts +- Remove installers. +- Remove externalized scripts. ### Added - Ukrainian translation. diff --git a/installers/pm2_MagicMirror.json b/installers/pm2_MagicMirror.json deleted file mode 100644 index 3f905020..00000000 --- a/installers/pm2_MagicMirror.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "apps" : [{ - "name" : "MagicMirror", - "script" : "/home/pi/MagicMirror/installers/mm.sh", - "watch" : ["/home/pi/MagicMirror/config/config.js"] - }] -} From cbcc893f649bfc370f3b5f59308b2e0f94ed3ce6 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 15:16:23 +0100 Subject: [PATCH 055/104] Restore MM.sh to keep PM2 working. --- installers/mm.sh | 3 +++ 1 file changed, 3 insertions(+) create mode 100755 installers/mm.sh diff --git a/installers/mm.sh b/installers/mm.sh new file mode 100755 index 00000000..f5a65fbe --- /dev/null +++ b/installers/mm.sh @@ -0,0 +1,3 @@ +# This file is still here to keep PM2 working on older installations. +cd ~/MagicMirror +DISPLAY=:0 npm start. \ No newline at end of file From 19afd89df51147d49888afdd505b8b8b8a0e1e34 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 16:48:35 +0100 Subject: [PATCH 056/104] Fix Typo --- installers/mm.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/installers/mm.sh b/installers/mm.sh index f5a65fbe..cbbadd24 100755 --- a/installers/mm.sh +++ b/installers/mm.sh @@ -1,3 +1,3 @@ # This file is still here to keep PM2 working on older installations. cd ~/MagicMirror -DISPLAY=:0 npm start. \ No newline at end of file +DISPLAY=:0 npm start From 1315aceb44913988bda73e2fbd4c2996df40d178 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 17:41:49 +0100 Subject: [PATCH 057/104] Remove duplicate 2.11 entry. --- CHANGELOG.md | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index bfcfe878..7d22bbc2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,15 +3,7 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). -❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core. - -## [2.11.0] - 2020-01-24 - -### Changed -- Updated config.js.sample: Corrected some grammar on `config.js.sample` comment section. -- Remove `run-start.sh` script and update start commands: - - To start using electron, use `npm run start`. - - To start in server only mode, use `npm run server`. +❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² ## [2.11.0] - Unreleased (Develop Branch) @@ -36,6 +28,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). +- Updated config.js.sample: Corrected some grammar on `config.js.sample` comment section. +- Removed `run-start.sh` script and update start commands: + - To start using electron, use `npm run start`. + - To start in server only mode, use `npm run server`. ## [2.10.1] - 2020-01-10 From 561827e8967aff98231a1439622074594c0c5a30 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sat, 1 Feb 2020 19:12:05 +0100 Subject: [PATCH 058/104] Remove logging. --- CHANGELOG.md | 3 ++- js/module.js | 4 ++-- modules/default/calendar/calendar.js | 2 -- modules/default/newsfeed/newsfeed.js | 3 --- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d22bbc2..603ac1b8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,12 +26,13 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) - Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false -### Updated +### Changed - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). - Updated config.js.sample: Corrected some grammar on `config.js.sample` comment section. - Removed `run-start.sh` script and update start commands: - To start using electron, use `npm run start`. - To start in server only mode, use `npm run server`. +- Remove redundant logging from modules. ## [2.10.1] - 2020-01-10 diff --git a/js/module.js b/js/module.js index 62bf80ce..a245db52 100644 --- a/js/module.js +++ b/js/module.js @@ -151,9 +151,9 @@ var Module = Class.extend({ */ notificationReceived: function (notification, payload, sender) { if (sender) { - Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name); + // Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name); } else { - Log.log(this.name + " received a system notification: " + notification); + // Log.log(this.name + " received a system notification: " + notification); } }, diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 9c91afe5..2678edae 100755 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -138,8 +138,6 @@ Module.register("calendar", { this.loaded = true; } else if (notification === "INCORRECT_URL") { Log.error("Calendar Error. Incorrect url: " + payload.url); - } else { - Log.log("Calendar received an unknown socket notification: " + notification); } this.updateDom(this.config.animationSpeed); diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index d358110c..9738ccc4 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -367,7 +367,6 @@ Module.register("newsfeed",{ }, notificationReceived: function(notification, payload, sender) { - Log.info(this.name + " - received notification: " + notification); if(notification === "ARTICLE_NEXT"){ var before = this.activeItem; this.activeItem++; @@ -425,8 +424,6 @@ Module.register("newsfeed",{ desc: this.newsItems[this.activeItem].description, url: this.getActiveItemURL() }); - } else { - Log.info(this.name + " - unknown notification, ignoring: " + notification); } }, From 65ea341ed062662a6db48984ebfcf48e519c3cdc Mon Sep 17 00:00:00 2001 From: Rico Date: Mon, 3 Feb 2020 21:39:46 +0100 Subject: [PATCH 059/104] feat: use date in log timestamp I find it quite hard to look something up in the logs, when there is no date in the log file. The time itself is not sufficient for debugging, hence I suggest also logging the date. --- js/app.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/app.js b/js/app.js index 08612dd8..ef66a44c 100644 --- a/js/app.js +++ b/js/app.js @@ -14,7 +14,7 @@ var path = require("path"); require("module-alias/register"); // add timestamps in front of log messages -require("console-stamp")(console, "HH:MM:ss.l"); +require("console-stamp")(console, "yyyy-mm-dd HH:MM:ss.l"); // Get version number. global.version = JSON.parse(fs.readFileSync("package.json", "utf8")).version; From e160f9a0f6f470515f70a581524c962b74e657dc Mon Sep 17 00:00:00 2001 From: Rico Date: Mon, 3 Feb 2020 21:43:45 +0100 Subject: [PATCH 060/104] docs: add info about changed timestamp in changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7d22bbc2..be681cbb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -32,6 +32,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Removed `run-start.sh` script and update start commands: - To start using electron, use `npm run start`. - To start in server only mode, use `npm run server`. +- Timestamp in log output now also contains the date ## [2.10.1] - 2020-01-10 From 5511c15921d15522db6a66e21cbdb30f187201db Mon Sep 17 00:00:00 2001 From: karenorman Date: Wed, 5 Feb 2020 10:23:49 +0800 Subject: [PATCH 061/104] Update description in config.js.sample --- config/config.js.sample | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/config/config.js.sample b/config/config.js.sample index 90610106..01a41caa 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -21,9 +21,9 @@ var config = { // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], - useHttps: false, // Support HTTPS or not - httpsPrivateKey: "", // HTTPS Private Key path - httpsCertificate: "", // HTTPS Certificate path + useHttps: false, // Support HTTPS or not, default "false" will use HTTP + httpsPrivateKey: "", // HTTPS private key path, only require when useHttps is true + httpsCertificate: "", // HTTPS Certificate path, only require when useHttps is true language: "en", timeFormat: 24, From 271f1cd71b5d106ebd39e66c5d3bcbdc444dfb2a Mon Sep 17 00:00:00 2001 From: sergge1 <49363121+sergge1@users.noreply.github.com> Date: Thu, 6 Feb 2020 00:04:48 +0200 Subject: [PATCH 062/104] to make logic of name to actual behaviour hideTemp = false -> temp shold appear at the MM hideTemp === true -> should not appear. This is the logic. Worked vise versa, just corrected in the code --- modules/default/currentweather/currentweather.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js index 2f58de5b..ac9e251d 100644 --- a/modules/default/currentweather/currentweather.js +++ b/modules/default/currentweather/currentweather.js @@ -217,7 +217,7 @@ Module.register("currentweather",{ this.config.decimalSymbol = "."; } - if (this.config.hideTemp === true) { + if (this.config.hideTemp === false) { var weatherIcon = document.createElement("span"); weatherIcon.className = "wi weathericon " + this.weatherType; large.appendChild(weatherIcon); From d5c02d10318966c5ea225376904659c0f20726a9 Mon Sep 17 00:00:00 2001 From: Stjepan Date: Sun, 9 Feb 2020 10:22:41 +0100 Subject: [PATCH 063/104] Update hr.json Fix FEELS translation in Croatian. --- translations/hr.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/translations/hr.json b/translations/hr.json index d714cc7b..6ed6d314 100644 --- a/translations/hr.json +++ b/translations/hr.json @@ -31,5 +31,5 @@ "UPDATE_INFO_SINGLE": "Instalirana verzija {COMMIT_COUNT} commit kasni za branch-om {BRANCH_NAME}.", "UPDATE_INFO_MULTIPLE": "Instalirana verzija {COMMIT_COUNT} commit-ova kasni za branch-om {BRANCH_NAME}.", - "FEELS": "Osjeća" + "FEELS": "Osjećaj" } From 845c2571fe35f225726f81c843e5cc915f70a78f Mon Sep 17 00:00:00 2001 From: Stjepan Date: Sun, 9 Feb 2020 10:24:20 +0100 Subject: [PATCH 064/104] Update CHANGELOG.md Fix FEELS translation in Croatian --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0debd80f..c6a9a6d8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -27,6 +27,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) - Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) - Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false +- Fix FEELS translation for Croatian ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). From f4c3e412a2103d50555cfbde62453eae1fffde10 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Sun, 9 Feb 2020 21:59:51 -0800 Subject: [PATCH 065/104] fix bugs in showMoonTimes in clock module 1. as reported on https://github.com/MichMich/MagicMirror/pull/1885, toLocaleString is not supported on old iPad Safari 2. SunCalc.getMoonTimes returns moonRise/moonSet times for the given date, so moonRise can be after moonSet. We want to display the most relevant times, which are today's moonRise and the next moonSet. --- modules/default/clock/clock.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 96c31143..6e70f1e2 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -179,11 +179,19 @@ Module.register("clock",{ if (this.config.showMoonTimes) { const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); const moonTimes = SunCalc.getMoonTimes(now, this.config.lat, this.config.lon); - const isVisible = now.isBetween(moonTimes.rise, moonTimes.set); - const illuminatedFractionString = moonIllumination.fraction.toLocaleString(undefined, {style: 'percent'}); + const moonRise = moonTimes.rise; + var moonSet; + if (moment(moonTimes.set).isAfter(moonTimes.rise)) { + moonSet = moonTimes.set; + } else { + const nextMoonTimes = SunCalc.getMoonTimes(now.clone().add(1, 'day'), this.config.lat, this.config.lon); + moonSet = nextMoonTimes.set; + } + const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true; + const illuminatedFractionString = moonIllumination.fraction.toFixed(2) * 100 + '%'; moonWrapper.innerHTML = ' ' + illuminatedFractionString + '' + - ' ' + formatTime(this.config, moonTimes.rise) + ''+ - ' ' + formatTime(this.config, moonTimes.set) + ''; + ' ' + (moonRise ? formatTime(this.config, moonRise) : '...') + ''+ + ' ' + (moonSet ? formatTime(this.config, moonSet) : '...') + ''; } /**************************************************************** From de6a9f5811786b0fe64d67425851740af48a4883 Mon Sep 17 00:00:00 2001 From: Felix Wiedenbach Date: Mon, 10 Feb 2020 18:56:55 +0100 Subject: [PATCH 066/104] fix timing issue in weather tests => returning response by url instead of index --- tests/e2e/modules/weather_spec.js | 45 ++++++++----------- tests/node_modules/webdriverajaxstub/index.js | 4 +- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/tests/e2e/modules/weather_spec.js b/tests/e2e/modules/weather_spec.js index dad11f50..ea916e5e 100644 --- a/tests/e2e/modules/weather_spec.js +++ b/tests/e2e/modules/weather_spec.js @@ -8,14 +8,7 @@ const helpers = require("../global-setup"); const {generateWeather, generateWeatherForecast} = require("./mocks"); -const wait = () => new Promise(res => setTimeout(res, 3000)); - -// See issue: https://github.com/MichMich/MagicMirror/issues/1840 -// Skipping the weather tests for now since these seem to give issues. -// Please send a PR if you know how to fix these. Thanks! - - -describe.skip("Weather module", function() { +describe("Weather module", function() { let app; @@ -49,7 +42,7 @@ describe.skip("Weather module", function() { it("should render wind speed and wind direction", async function() { const weather = generateWeather(); - await setup([weather, template]); + await setup({template, data: weather}); return app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(2)", "6 WSW", 10000); }); @@ -59,7 +52,7 @@ describe.skip("Weather module", function() { const sunset = moment().startOf("day").unix(); const weather = generateWeather({sys: {sunrise, sunset}}); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitForExist(".weather .normal.medium span.wi.dimmed.wi-sunrise", 10000); @@ -71,7 +64,7 @@ describe.skip("Weather module", function() { const sunset = moment().endOf("day").unix(); const weather = generateWeather({sys: {sunrise, sunset}}); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitForExist(".weather .normal.medium span.wi.dimmed.wi-sunset", 10000); @@ -80,7 +73,7 @@ describe.skip("Weather module", function() { it("should render temperature with icon", async function() { const weather = generateWeather(); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitForExist(".weather .large.light span.wi.weathericon.wi-snow", 10000); @@ -89,7 +82,7 @@ describe.skip("Weather module", function() { it("should render feels like temperature", async function() { const weather = generateWeather(); - await setup([weather, template]); + await setup({template, data: weather}); return app.client.waitUntilTextExists(".weather .normal.medium span.dimmed", "Feels like -5.6°", 10000); }); @@ -102,14 +95,14 @@ describe.skip("Weather module", function() { it("should render useBeaufort = false", async function() { const weather = generateWeather(); - await setup([weather, template]); + await setup({template, data: weather}); return app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(2)", "12", 10000); }); it("should render showWindDirectionAsArrow = true", async function() { const weather = generateWeather(); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitForExist(".weather .normal.medium sup i.fa-long-arrow-up", 10000); const element = await app.client.getHTML(".weather .normal.medium sup i.fa-long-arrow-up"); @@ -119,7 +112,7 @@ describe.skip("Weather module", function() { it("should render showHumidity = true", async function() { const weather = generateWeather(); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(3)", "93", 10000); return app.client.waitForExist(".weather .normal.medium sup i.wi-humidity", 10000); @@ -127,7 +120,7 @@ describe.skip("Weather module", function() { it("should render degreeLabel = true", async function() { const weather = generateWeather(); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitUntilTextExists(".weather .large.light span.bright", "1°C", 10000); @@ -151,7 +144,7 @@ describe.skip("Weather module", function() { speed: 11.8 * 2.23694 }, }); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(2)", "6 WSW", 10000); await app.client.waitUntilTextExists(".weather .large.light span.bright", "34,7°", 10000); @@ -169,7 +162,7 @@ describe.skip("Weather module", function() { speed: 11.8 * 2.23694 }, }); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(3)", "93,7", 10000); await app.client.waitUntilTextExists(".weather .large.light span.bright", "34,7°", 10000); @@ -192,7 +185,7 @@ describe.skip("Weather module", function() { it("should render days", async function() { const weather = generateWeatherForecast(); - await setup([weather, template]); + await setup({template, data: weather}); const days = ["Fri", "Sat", "Sun", "Mon", "Tue"]; @@ -203,7 +196,7 @@ describe.skip("Weather module", function() { it("should render icons", async function() { const weather = generateWeatherForecast(); - await setup([weather, template]); + await setup({template, data: weather}); const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"]; @@ -214,7 +207,7 @@ describe.skip("Weather module", function() { it("should render max temperatures", async function() { const weather = generateWeatherForecast(); - await setup([weather, template]); + await setup({template, data: weather}); const temperatures = ["24.4°", "21.0°", "22.9°", "23.4°", "20.6°"]; @@ -225,7 +218,7 @@ describe.skip("Weather module", function() { it("should render min temperatures", async function() { const weather = generateWeatherForecast(); - await setup([weather, template]); + await setup({template, data: weather}); const temperatures = ["15.3°", "13.6°", "13.8°", "13.9°", "10.9°"]; @@ -236,7 +229,7 @@ describe.skip("Weather module", function() { it("should render fading of rows", async function() { const weather = generateWeatherForecast(); - await setup([weather, template]); + await setup({template, data: weather}); const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667]; @@ -256,14 +249,14 @@ describe.skip("Weather module", function() { it("should render custom table class", async function() { const weather = generateWeatherForecast(); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitForExist(".weather table.myTableClass", 10000); }); it("should render colored rows", async function() { const weather = generateWeatherForecast(); - await setup([weather, template]); + await setup({template, data: weather}); await app.client.waitForExist(".weather table.myTableClass", 10000); diff --git a/tests/node_modules/webdriverajaxstub/index.js b/tests/node_modules/webdriverajaxstub/index.js index ed524ddb..031de5ac 100644 --- a/tests/node_modules/webdriverajaxstub/index.js +++ b/tests/node_modules/webdriverajaxstub/index.js @@ -3,7 +3,7 @@ function plugin (wdInstance, requests) { throw new Error("You can't use WebdriverAjaxStub with this version of WebdriverIO"); } - function stub(requests, done) { + function stub({template, data}, done) { window.XMLHttpRequest = function () { this.open = function (method, url) { this.method = method; @@ -13,7 +13,7 @@ function plugin (wdInstance, requests) { this.send = function () { this.status = 200; this.readyState = 4; - const response = requests.shift() || []; + const response = this.url.includes('.njk') ? template : data; this.response = response; this.responseText = response; this.onreadystatechange(); From cd7b6450c6d472cd2eb2f1e23141e81603caed5e Mon Sep 17 00:00:00 2001 From: fewieden Date: Mon, 10 Feb 2020 21:51:29 +0100 Subject: [PATCH 067/104] Run tests also on lts and last stable version of nodejs --- .travis.yml | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5f8f6024..b6f2e352 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,22 +1,24 @@ dist: trusty language: node_js node_js: - - "10" + - 10 + - lts/* + - node before_install: - npm i -g npm before_script: - - yarn danger ci - - npm install grunt-cli -g - - "export DISPLAY=:99.0" - - "export ELECTRON_DISABLE_SANDBOX=1" - - "sh -e /etc/init.d/xvfb start" - - sleep 5 + - yarn danger ci + - npm install grunt-cli -g + - "export DISPLAY=:99.0" + - "export ELECTRON_DISABLE_SANDBOX=1" + - "sh -e /etc/init.d/xvfb start" + - sleep 5 script: -- npm run test:e2e -- npm run test:unit -- grunt + - npm run test:e2e + - npm run test:unit + - grunt after_script: - - npm list + - npm list cache: - directories: - - node_modules + directories: + - node_modules From 56392e41d0d6803a9cf5cdf2a2f3fca5b082ef90 Mon Sep 17 00:00:00 2001 From: fewieden Date: Mon, 10 Feb 2020 22:05:43 +0100 Subject: [PATCH 068/104] Add 1840 to changelog --- CHANGELOG.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0debd80f..49128c11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,13 +20,14 @@ This project adheres to [Semantic Versioning](http://semver.org/). - The `clock` module now optionally displays sun and moon data, including rise/set times, remaining daylight, and percent of moon illumination. - Added Hebrew translation. - Add HTTPS support and update config.js.sample - +- Run tests on long term support and latest stable version of nodejs ### Fixed - Force declaration of public ip adress in config file (ISSUE #1852) - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) - Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) - Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false +- Fixed weather tests [#1840](https://github.com/MichMich/MagicMirror/issues/1840) ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). From c925e8847522e0f122778fac82b3b4fca5d49bf7 Mon Sep 17 00:00:00 2001 From: buxxi Date: Tue, 11 Feb 2020 18:13:39 +0100 Subject: [PATCH 069/104] Adding support for ignoring update check for certain modules --- CHANGELOG.md | 1 + .../default/updatenotification/node_helper.js | 27 ++++++++++++++----- .../updatenotification/updatenotification.js | 1 + 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0debd80f..c9bf13c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,6 +20,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - The `clock` module now optionally displays sun and moon data, including rise/set times, remaining daylight, and percent of moon illumination. - Added Hebrew translation. - Add HTTPS support and update config.js.sample +- Added the ability to configure a list of modules that shouldn't be update checked. ### Fixed diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index 03ecd745..818697c0 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -22,7 +22,7 @@ module.exports = NodeHelper.create({ simpleGits.push({"module": "default", "git": SimpleGit(path.normalize(__dirname + "/../../../"))}); for (moduleName in modules) { - if (defaultModules.indexOf(moduleName) < 0) { + if (!this.ignoreUpdateChecking(moduleName)) { // Default modules are included in the main MagicMirror repo var moduleFolder = path.normalize(__dirname + "/../../" + moduleName); @@ -56,15 +56,15 @@ module.exports = NodeHelper.create({ this.config = payload; } else if(notification === "MODULES") { // if this is the 1st time thru the update check process - if(this.updateProcessStarted==false ){ - this.updateProcessStarted=true; + if (!this.updateProcessStarted) { + this.updateProcessStarted = true; this.configureModules(payload); - this.preformFetch(); + this.performFetch(); } } }, - preformFetch() { + performFetch() { var self = this; simpleGits.forEach(function(sg) { sg.git.fetch().status(function(err, data) { @@ -91,8 +91,23 @@ module.exports = NodeHelper.create({ var self = this; clearTimeout(this.updateTimer); this.updateTimer = setTimeout(function() { - self.preformFetch(); + self.performFetch(); }, delay); + }, + + ignoreUpdateChecking: function(moduleName) { + // Should not check for updates for default modules + if (defaultModules.indexOf(moduleName) >= 0) { + return true; + } + + // Should not check for updates for ignored modules + if (this.config.ignoreModules.indexOf(moduleName) >= 0) { + return true; + } + + // The rest of the modules that passes should check for updates + return false; } }); diff --git a/modules/default/updatenotification/updatenotification.js b/modules/default/updatenotification/updatenotification.js index d4bdc568..35a018bf 100644 --- a/modules/default/updatenotification/updatenotification.js +++ b/modules/default/updatenotification/updatenotification.js @@ -3,6 +3,7 @@ Module.register("updatenotification", { defaults: { updateInterval: 10 * 60 * 1000, // every 10 minutes refreshInterval: 24 * 60 * 60 * 1000, // one day + ignoreModules: [] }, suspended: false, From 75c8c3f50bd4176197805cd74eaa1f1264dac94e Mon Sep 17 00:00:00 2001 From: buxxi Date: Mon, 17 Feb 2020 22:56:06 +0100 Subject: [PATCH 070/104] Using promises to resolve which modules has a git remote so the modules wont be skipped on the first check --- CHANGELOG.md | 1 + .../default/updatenotification/node_helper.js | 49 +++++++++++-------- 2 files changed, 29 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1e671f4..91142e06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false - Fix FEELS translation for Croatian - Fixed weather tests [#1840](https://github.com/MichMich/MagicMirror/issues/1840) +- Fix update checking skipping 3rd party modules the first time ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index 818697c0..4386b146 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -18,37 +18,30 @@ module.exports = NodeHelper.create({ 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 + // others will be added in front + // this method returns promises so we can't wait for every one to resolve before continuing simpleGits.push({"module": "default", "git": SimpleGit(path.normalize(__dirname + "/../../../"))}); + var promises = []; + for (moduleName in modules) { if (!this.ignoreUpdateChecking(moduleName)) { // Default modules are included in the main MagicMirror repo var moduleFolder = path.normalize(__dirname + "/../../" + moduleName); - var stat; try { //console.log("checking git for module="+moduleName) - stat = fs.statSync(path.join(moduleFolder, ".git")); + let stat = fs.statSync(path.join(moduleFolder, ".git")); + promises.push(this.resolveRemote(moduleName, moduleFolder)); } catch(err) { // Error when directory .git doesn't exist // This module is not managed with git, skip continue; } - - var res = function(mn, mf) { - var git = SimpleGit(mf); - git.getRemotes(true, function(err, remotes) { - if (remotes.length < 1 || remotes[0].name.length < 1) { - // No valid remote for folder, skip - return; - } - // Folder has .git and has at least one git remote, watch this folder - simpleGits.unshift({"module": mn, "git": git}); - }); - }(moduleName, moduleFolder); } } + + return Promise.all(promises); }, socketNotificationReceived: function (notification, payload) { @@ -58,19 +51,33 @@ module.exports = NodeHelper.create({ // if this is the 1st time thru the update check process if (!this.updateProcessStarted) { this.updateProcessStarted = true; - this.configureModules(payload); - this.performFetch(); + this.configureModules(payload).then(() => this.performFetch()); } } }, - performFetch() { + resolveRemote: function(moduleName, moduleFolder) { + return new Promise((resolve, reject) => { + var git = SimpleGit(moduleFolder); + git.getRemotes(true, (err, remotes) => { + if (remotes.length < 1 || remotes[0].name.length < 1) { + // No valid remote for folder, skip + return resolve(); + } + // Folder has .git and has at least one git remote, watch this folder + simpleGits.unshift({"module": moduleName, "git": git}); + resolve(); + }); + }); + }, + + performFetch: function() { var self = this; - simpleGits.forEach(function(sg) { - sg.git.fetch().status(function(err, data) { + simpleGits.forEach((sg) => { + sg.git.fetch().status((err, data) => { data.module = sg.module; if (!err) { - sg.git.log({"-1": null}, function(err, data2) { + sg.git.log({"-1": null}, (err, data2) => { if (!err && data2.latest && "hash" in data2.latest) { data.hash = data2.latest.hash; self.sendSocketNotification("STATUS", data); From 7b56817ae60f0e010792cd60e5000fc2edb9bbba Mon Sep 17 00:00:00 2001 From: Leon Kiefer Date: Tue, 18 Feb 2020 17:09:25 +0100 Subject: [PATCH 071/104] use relative path for socket.io fix #1934 --- CHANGELOG.md | 1 + index.html | 2 +- js/socketclient.js | 4 +++- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1e671f4..16babe83 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -30,6 +30,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false - Fix FEELS translation for Croatian - Fixed weather tests [#1840](https://github.com/MichMich/MagicMirror/issues/1840) +- Fixed Socket.io can't be used with Reverse Proxy in serveronly mode [#1934](https://github.com/MichMich/MagicMirror/issues/1934) ### Updated - Remove documentation from core repository and link to new dedicated docs site: [docs.magicmirror.builders](https://docs.magicmirror.builders). diff --git a/index.html b/index.html index d8604256..5a46bb72 100644 --- a/index.html +++ b/index.html @@ -37,7 +37,7 @@

- + diff --git a/js/socketclient.js b/js/socketclient.js index baead68e..62341f27 100644 --- a/js/socketclient.js +++ b/js/socketclient.js @@ -8,7 +8,9 @@ var MMSocket = function(moduleName) { self.moduleName = moduleName; // Private Methods - self.socket = io("/" + self.moduleName); + self.socket = io("/" + self.moduleName, { + path: window.location.pathname + "/socket.io" + }); var notificationCallback = function() {}; var onevent = self.socket.onevent; From b6fc063c754830a07ed5090611f84f31e36dce46 Mon Sep 17 00:00:00 2001 From: mustafa <971530+tosbaha@users.noreply.github.com> Date: Wed, 19 Feb 2020 15:21:25 +0300 Subject: [PATCH 072/104] Turkish translation updated --- translations/tr.json | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/translations/tr.json b/translations/tr.json index c79956b8..61726f6d 100644 --- a/translations/tr.json +++ b/translations/tr.json @@ -3,8 +3,11 @@ "TODAY": "Bugün", "TOMORROW": "Yarın", + "DAYAFTERTOMORROW": "İki gün içinde", "RUNNING": "Biten", "EMPTY": "Yakında etkinlik yok.", + + "WEEK": "Hafta {weekNumber}", "N": "K", "NNE": "KKD", @@ -21,5 +24,14 @@ "W": "B", "WNW": "BKB", "NW": "KB", - "NNW": "KKB" + "NNW": "KKB", + + "UPDATE_NOTIFICATION": "MagicMirror² güncellemesi mevcut.", + "UPDATE_NOTIFICATION_MODULE": "{MODULE_NAME} modulü için güncelleme mevcut.", + "UPDATE_INFO_SINGLE": "Sahip olduğunuz kurulum {BRANCH_NAME} branchinden {COMMIT_COUNT} commit geridedir.", + "UPDATE_INFO_MULTIPLE": "Sahip olduğunuz kurulum {BRANCH_NAME} branchinden {COMMIT_COUNT} commit geridedir.", + + "FEELS": "Hissedilen", + "PRECIP": "Yağış" + } From 3b7df1d5c23bb024f140c2fdc61e3aed0660d702 Mon Sep 17 00:00:00 2001 From: mustafa <971530+tosbaha@users.noreply.github.com> Date: Wed, 19 Feb 2020 15:25:46 +0300 Subject: [PATCH 073/104] Changelog updated --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c1e671f4..a2069abb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -38,6 +38,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - To start using electron, use `npm run start`. - To start in server only mode, use `npm run server`. - Timestamp in log output now also contains the date +- Turkish translation. ## [2.10.1] - 2020-01-10 From 3f78c664eb79b0aef93c2708c3fdeb7d0e1fc023 Mon Sep 17 00:00:00 2001 From: Denis Treskunov Date: Wed, 19 Feb 2020 09:28:40 -0800 Subject: [PATCH 074/104] fix floating point bug in moon illumination calc --- modules/default/clock/clock.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 6e70f1e2..2490a0ce 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -188,7 +188,7 @@ Module.register("clock",{ moonSet = nextMoonTimes.set; } const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true; - const illuminatedFractionString = moonIllumination.fraction.toFixed(2) * 100 + '%'; + const illuminatedFractionString = Math.round(moonIllumination.fraction * 100) + '%'; moonWrapper.innerHTML = ' ' + illuminatedFractionString + '' + ' ' + (moonRise ? formatTime(this.config, moonRise) : '...') + ''+ ' ' + (moonSet ? formatTime(this.config, moonSet) : '...') + ''; From 6aeec81072f19bbe6670efa8b4a2542a8651a279 Mon Sep 17 00:00:00 2001 From: Leon Kiefer Date: Wed, 19 Feb 2020 20:58:58 +0100 Subject: [PATCH 075/104] removed additional slash from the socket.io path --- js/socketclient.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/js/socketclient.js b/js/socketclient.js index 62341f27..5e138636 100644 --- a/js/socketclient.js +++ b/js/socketclient.js @@ -9,7 +9,7 @@ var MMSocket = function(moduleName) { // Private Methods self.socket = io("/" + self.moduleName, { - path: window.location.pathname + "/socket.io" + path: window.location.pathname + "socket.io" }); var notificationCallback = function() {}; From c877b5fc70e339253b926155aa7b4fcfe82521fe Mon Sep 17 00:00:00 2001 From: Jose Forte Date: Fri, 21 Feb 2020 10:17:05 -0300 Subject: [PATCH 076/104] Add new default config to 'current weather' module --- modules/default/currentweather/currentweather.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js index 7d917132..c718ff1e 100644 --- a/modules/default/currentweather/currentweather.js +++ b/modules/default/currentweather/currentweather.js @@ -42,6 +42,7 @@ Module.register("currentweather",{ appendLocationNameToHeader: true, calendarClass: "calendar", + tableClass: "large", onlyTemp: false, roundTemp: false, @@ -174,6 +175,7 @@ Module.register("currentweather",{ // Override dom generator. getDom: function() { var wrapper = document.createElement("div"); + wrapper.className = this.config.tableClass; if (this.config.appid === "") { wrapper.innerHTML = "Please set the correct openweather appid in the config for module: " + this.name + "."; @@ -192,7 +194,7 @@ Module.register("currentweather",{ } var large = document.createElement("div"); - large.className = "large light"; + large.className = "light"; var weatherIcon = document.createElement("span"); weatherIcon.className = "wi weathericon " + this.weatherType; From f338b68f36d47e60b6495c41db3b98b5d3b26c4b Mon Sep 17 00:00:00 2001 From: Jose Forte Date: Fri, 21 Feb 2020 10:31:40 -0300 Subject: [PATCH 077/104] Update CHANGELOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 464d8642..c4ec96b2 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,11 @@ This project adheres to [Semantic Versioning](http://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² core. +## [2.10.2] - 2020-02-21 + +### Added +- Option to configure the size of the currentweather module. + ## [2.10.1] - 2020-01-10 ### Changed From 5517a913d44c8781983f7e5577df13c1eb3fa67d Mon Sep 17 00:00:00 2001 From: rejas Date: Thu, 13 Feb 2020 08:35:09 +0100 Subject: [PATCH 078/104] Run linter manually --- config/config.js.sample | 2 +- js/server.js | 4 ++-- modules/default/clock/clock.js | 16 ++++++++-------- tests/node_modules/webdriverajaxstub/index.js | 2 +- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/config/config.js.sample b/config/config.js.sample index 01a41caa..67656392 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -24,7 +24,7 @@ var config = { useHttps: false, // Support HTTPS or not, default "false" will use HTTP httpsPrivateKey: "", // HTTPS private key path, only require when useHttps is true httpsCertificate: "", // HTTPS Certificate path, only require when useHttps is true - + language: "en", timeFormat: 24, units: "metric", diff --git a/js/server.js b/js/server.js index 19bdfb91..185790af 100644 --- a/js/server.js +++ b/js/server.js @@ -25,13 +25,13 @@ var Server = function(config, callback) { var options = { key: fs.readFileSync(config.httpsPrivateKey), cert: fs.readFileSync(config.httpsCertificate) - } + }; server = require("https").Server(options, app); }else{ server = require("http").Server(app); } var io = require("socket.io")(server); - + console.log("Starting server on port " + port + " ... "); server.listen(port, config.address ? config.address : "localhost"); diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 2490a0ce..ab17a3c7 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -152,9 +152,9 @@ Module.register("clock",{ } function formatTime(config, time) { - var formatString = hourSymbol + ':mm'; + var formatString = hourSymbol + ":mm"; if (config.showPeriod && config.timeFormat !== 24) { - formatString += config.showPeriodUpper ? 'A' : 'a'; + formatString += config.showPeriodUpper ? "A" : "a"; } return moment(time).format(formatString); } @@ -167,14 +167,14 @@ Module.register("clock",{ } else if (now.isBefore(sunTimes.sunset)) { nextEvent = sunTimes.sunset; } else { - const tomorrowSunTimes = SunCalc.getTimes(now.clone().add(1, 'day'), this.config.lat, this.config.lon); + const tomorrowSunTimes = SunCalc.getTimes(now.clone().add(1, "day"), this.config.lat, this.config.lon); nextEvent = tomorrowSunTimes.sunrise; } const untilNextEvent = moment.duration(moment(nextEvent).diff(now)); - const untilNextEventString = untilNextEvent.hours() + 'h ' + untilNextEvent.minutes() + 'm'; - sunWrapper.innerHTML = ' ' + untilNextEventString + '' + - '' + formatTime(this.config, sunTimes.sunrise) + '' + - '' + formatTime(this.config, sunTimes.sunset) + ''; + const untilNextEventString = untilNextEvent.hours() + "h " + untilNextEvent.minutes() + "m"; + sunWrapper.innerHTML = " " + untilNextEventString + "" + + "" + formatTime(this.config, sunTimes.sunrise) + "" + + "" + formatTime(this.config, sunTimes.sunset) + ""; } if (this.config.showMoonTimes) { const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); @@ -184,7 +184,7 @@ Module.register("clock",{ if (moment(moonTimes.set).isAfter(moonTimes.rise)) { moonSet = moonTimes.set; } else { - const nextMoonTimes = SunCalc.getMoonTimes(now.clone().add(1, 'day'), this.config.lat, this.config.lon); + const nextMoonTimes = SunCalc.getMoonTimes(now.clone().add(1, "day"), this.config.lat, this.config.lon); moonSet = nextMoonTimes.set; } const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true; diff --git a/tests/node_modules/webdriverajaxstub/index.js b/tests/node_modules/webdriverajaxstub/index.js index 031de5ac..186033b6 100644 --- a/tests/node_modules/webdriverajaxstub/index.js +++ b/tests/node_modules/webdriverajaxstub/index.js @@ -13,7 +13,7 @@ function plugin (wdInstance, requests) { this.send = function () { this.status = 200; this.readyState = 4; - const response = this.url.includes('.njk') ? template : data; + const response = this.url.includes(".njk") ? template : data; this.response = response; this.responseText = response; this.onreadystatechange(); From 6c926b8876bea847bee58daf2386514a50165144 Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 8 Mar 2020 16:23:27 +0100 Subject: [PATCH 079/104] Add husky for pre-commit hook --- modules/default/clock/clock.js | 8 +- package-lock.json | 198 +++++++++++++++++++++++++++++++-- package.json | 6 + vendor/package-lock.json | 25 +++-- 4 files changed, 219 insertions(+), 18 deletions(-) diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index ab17a3c7..08dcced0 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -188,10 +188,10 @@ Module.register("clock",{ moonSet = nextMoonTimes.set; } const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true; - const illuminatedFractionString = Math.round(moonIllumination.fraction * 100) + '%'; - moonWrapper.innerHTML = ' ' + illuminatedFractionString + '' + - ' ' + (moonRise ? formatTime(this.config, moonRise) : '...') + ''+ - ' ' + (moonSet ? formatTime(this.config, moonSet) : '...') + ''; + const illuminatedFractionString = Math.round(moonIllumination.fraction * 100) + "%"; + moonWrapper.innerHTML = " " + illuminatedFractionString + "" + + " " + (moonRise ? formatTime(this.config, moonRise) : "...") + ""+ + " " + (moonSet ? formatTime(this.config, moonSet) : "...") + ""; } /**************************************************************** diff --git a/package-lock.json b/package-lock.json index 2509883d..077f1ff3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1048,6 +1048,12 @@ } } }, + "ci-info": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", + "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", + "dev": true + }, "clarinet": { "version": "0.12.4", "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.4.tgz", @@ -1198,6 +1204,12 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, + "compare-versions": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", + "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", + "dev": true + }, "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", @@ -2579,6 +2591,15 @@ "pinkie-promise": "^2.0.0" } }, + "find-versions": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", + "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", + "dev": true, + "requires": { + "semver-regex": "^2.0.0" + } + }, "findup-sync": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", @@ -3100,12 +3121,12 @@ } }, "grunt-markdownlint": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/grunt-markdownlint/-/grunt-markdownlint-2.8.0.tgz", - "integrity": "sha512-3HNNKB1C+qC+iB9ecDGymQMv2CVx+XHFxP3e1n/d1lE44GvJOaJFYCS6IgAc//Fhcz4v4X9XJCHDCTfAWuq5gg==", + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/grunt-markdownlint/-/grunt-markdownlint-2.9.0.tgz", + "integrity": "sha512-jLzTzNVZN/u2iblV2j+2xfJGG+Mv8NMl5CAOWNQftV7SOHnstwR/tiZPac8ZTmJFqwAqCwafIvu9wP2naAS8Og==", "dev": true, "requires": { - "markdownlint": "^0.18.0" + "markdownlint": "^0.19.0" } }, "grunt-stylelint": { @@ -3449,6 +3470,76 @@ "debug": "^3.1.0" } }, + "husky": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.3.tgz", + "integrity": "sha512-VxTsSTRwYveKXN4SaH1/FefRJYCtx+wx04sSVcOpD7N2zjoHxa+cEJ07Qg5NmV3HAK+IRKOyNVpi2YBIVccIfQ==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.5.1", + "cosmiconfig": "^6.0.0", + "find-versions": "^3.2.0", + "opencollective-postinstall": "^2.0.2", + "pkg-dir": "^4.2.0", + "please-upgrade-node": "^3.2.0", + "slash": "^3.0.0", + "which-pm-runs": "^1.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", + "dev": true, + "requires": { + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "hyperlinker": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", @@ -4417,9 +4508,9 @@ "dev": true }, "markdownlint": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.18.0.tgz", - "integrity": "sha512-nQAfK9Pbq0ZRoMC/abNGterEnV3kL8MZmi0WHhw8WJKoIbsm3cXGufGsxzCRvjW15cxe74KWcxRSKqwplS26Bw==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.19.0.tgz", + "integrity": "sha512-+MsWOnYVUH4klcKM7iRx5cno9FQMDAb6FC6mWlZkeXPwIaK6Z5Vd9VkXkykPidRqmLHU2wI+MNyfUMnUCBw3pQ==", "dev": true, "requires": { "markdown-it": "10.0.0" @@ -5207,6 +5298,12 @@ "mimic-fn": "^2.1.0" } }, + "opencollective-postinstall": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", + "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", + "dev": true + }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -5504,6 +5601,75 @@ "integrity": "sha1-DPd1eml38b9/ajIge3CeN3OI6HQ=", "dev": true }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + }, + "dependencies": { + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", + "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + } + } + }, + "please-upgrade-node": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", + "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", + "dev": true, + "requires": { + "semver-compare": "^1.0.0" + } + }, "plur": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", @@ -6294,6 +6460,18 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", + "dev": true + }, + "semver-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", + "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", + "dev": true + }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -8212,6 +8390,12 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, + "which-pm-runs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", + "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", + "dev": true + }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", diff --git a/package.json b/package.json index 1b150ed4..bb431a74 100644 --- a/package.json +++ b/package.json @@ -46,6 +46,7 @@ "grunt-stylelint": "latest", "grunt-yamllint": "latest", "http-auth": "^3.2.3", + "husky": "^4.2.3", "jsdom": "^11.6.2", "jshint": "^2.10.2", "mocha": "^7.0.0", @@ -79,5 +80,10 @@ }, "_moduleAliases": { "node_helper": "js/node_helper.js" + }, + "husky": { + "hooks": { + "pre-commit": "npm run lint" + } } } diff --git a/vendor/package-lock.json b/vendor/package-lock.json index 61c1d19e..3253cc4e 100644 --- a/vendor/package-lock.json +++ b/vendor/package-lock.json @@ -703,6 +703,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", "integrity": "sha1-gTg9ctsFT8zPUzbaqQLxgvbtuyg=", + "optional": true, "requires": { "is-glob": "^2.0.0" } @@ -716,7 +717,8 @@ "inherits": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=" + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "optional": true }, "invert-kv": { "version": "1.0.0", @@ -735,7 +737,8 @@ "is-buffer": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.5.tgz", - "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=" + "integrity": "sha1-Hzsm72E7IUuIy8ojzGwB2Hlh7sw=", + "optional": true }, "is-dotfile": { "version": "1.0.3", @@ -761,7 +764,8 @@ "is-extglob": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-1.0.0.tgz", - "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=" + "integrity": "sha1-rEaBd8SUNAWgkvyPKXYMb/xiBsA=", + "optional": true }, "is-fullwidth-code-point": { "version": "1.0.0", @@ -775,6 +779,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-2.0.1.tgz", "integrity": "sha1-0Jb5JqPe1WAPP9/ZEZjLCIjC2GM=", + "optional": true, "requires": { "is-extglob": "^1.0.0" } @@ -803,7 +808,8 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "optional": true }, "isobject": { "version": "2.1.0", @@ -818,6 +824,7 @@ "version": "3.2.2", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "optional": true, "requires": { "is-buffer": "^1.1.5" } @@ -883,6 +890,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "optional": true, "requires": { "remove-trailing-separator": "^1.0.1" } @@ -1031,12 +1039,14 @@ "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=" + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "optional": true }, "repeat-element": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.2.tgz", - "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=" + "integrity": "sha1-7wiaF40Ug7quTZPrmLT55OEdmQo=", + "optional": true }, "repeat-string": { "version": "1.6.1", @@ -1047,7 +1057,8 @@ "safe-buffer": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz", - "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==" + "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg==", + "optional": true }, "set-immediate-shim": { "version": "1.0.1", From ca2571b4389d03090a8fd9f41e4284f44f7c2c0c Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 8 Mar 2020 16:31:34 +0100 Subject: [PATCH 080/104] Update changelog --- CHANGELOG.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0236e6de..3e8a9643 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,9 +22,10 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Add HTTPS support and update config.js.sample - Run tests on long term support and latest stable version of nodejs - Added the ability to configure a list of modules that shouldn't be update checked. +- Run linters on git commits ### Fixed -- Force declaration of public ip adress in config file (ISSUE #1852) +- Force declaration of public ip address in config file (ISSUE #1852) - Fixes `run-start.sh`: If running in docker-container, don't check the environment, just start electron (ISSUE #1859) - Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) - Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false @@ -584,7 +585,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Added option `remoteFile` to compliments module to load compliment array from filesystem. - Added option `zoom` to scale the whole mirror display with a given factor. - Added option `roundTemp` for currentweather and weatherforecast modules to display temperatures rounded to nearest integer. -- Added abilty set the classes option to compliments module for style and text size of compliments. +- Added ability set the classes option to compliments module for style and text size of compliments. - Added ability to configure electronOptions - Calendar module: option to hide private events - Add root_path for global vars From c3d57eef4f26d3c244fa5a79782295ec344c5285 Mon Sep 17 00:00:00 2001 From: rejas Date: Wed, 11 Mar 2020 08:52:25 +0100 Subject: [PATCH 081/104] Remove husky again, move lint as test to travis --- .travis.yml | 2 +- package.json | 7 +------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/.travis.yml b/.travis.yml index b6f2e352..2f9f3690 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,9 +14,9 @@ before_script: - "sh -e /etc/init.d/xvfb start" - sleep 5 script: + - npm run test:lint - npm run test:e2e - npm run test:unit - - grunt after_script: - npm list cache: diff --git a/package.json b/package.json index bb431a74..a3ffd9b8 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "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", + "test:lint": "grunt", "config:check": "node tests/configs/check_config.js", "lint": "grunt" }, @@ -46,7 +47,6 @@ "grunt-stylelint": "latest", "grunt-yamllint": "latest", "http-auth": "^3.2.3", - "husky": "^4.2.3", "jsdom": "^11.6.2", "jshint": "^2.10.2", "mocha": "^7.0.0", @@ -80,10 +80,5 @@ }, "_moduleAliases": { "node_helper": "js/node_helper.js" - }, - "husky": { - "hooks": { - "pre-commit": "npm run lint" - } } } From 0b2e836e3d39ebf8a05ab1b2ffae7654bd31385c Mon Sep 17 00:00:00 2001 From: rejas Date: Wed, 11 Mar 2020 09:01:21 +0100 Subject: [PATCH 082/104] Commit a faulty js to see if travis complains --- modules/default/defaultmodules.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/default/defaultmodules.js b/modules/default/defaultmodules.js index 656ba6b8..f36d028e 100644 --- a/modules/default/defaultmodules.js +++ b/modules/default/defaultmodules.js @@ -8,7 +8,7 @@ // Modules listed below can be loaded without the 'default/' prefix. Omitting the default folder name. var defaultModules = [ - "alert", + 'alert', "calendar", "clock", "compliments", From 7470a3b8132bb3833df2574f3d977ecc5ae36de7 Mon Sep 17 00:00:00 2001 From: rejas Date: Wed, 11 Mar 2020 10:48:43 +0100 Subject: [PATCH 083/104] Dont fix eslint errors automatically --- Gruntfile.js | 1 - 1 file changed, 1 deletion(-) diff --git a/Gruntfile.js b/Gruntfile.js index a825a766..829279e2 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -4,7 +4,6 @@ module.exports = function(grunt) { pkg: grunt.file.readJSON("package.json"), eslint: { options: { - fix: "true", configFile: ".eslintrc.json" }, target: [ From f22e39e22b83c87a723db5f7b3ee96972dafb535 Mon Sep 17 00:00:00 2001 From: rejas Date: Wed, 11 Mar 2020 11:12:30 +0100 Subject: [PATCH 084/104] Add switch to auto fix eslint and stylelint issues --- Gruntfile.js | 5 ++++- package.json | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 829279e2..2b2048d7 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -1,9 +1,10 @@ module.exports = function(grunt) { require("time-grunt")(grunt); + var fix = (grunt.option("env") || "lint") === "lint"; grunt.initConfig({ - pkg: grunt.file.readJSON("package.json"), eslint: { options: { + fix: fix, configFile: ".eslintrc.json" }, target: [ @@ -26,6 +27,7 @@ module.exports = function(grunt) { stylelint: { simple: { options: { + fix: fix, configFile: ".stylelintrc.json" }, src: [ @@ -101,5 +103,6 @@ module.exports = function(grunt) { grunt.loadNpmTasks("grunt-jsonlint"); grunt.loadNpmTasks("grunt-yamllint"); grunt.loadNpmTasks("grunt-markdownlint"); + grunt.registerTask("default", ["eslint", "stylelint", "jsonlint", "markdownlint", "yamllint"]); }; diff --git a/package.json b/package.json index a3ffd9b8..4640e627 100644 --- a/package.json +++ b/package.json @@ -12,9 +12,9 @@ "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", - "test:lint": "grunt", + "test:lint": "grunt --env=test", "config:check": "node tests/configs/check_config.js", - "lint": "grunt" + "lint": "grunt --env=lint" }, "repository": { "type": "git", From f3d45eff697da3d71dd625bd84032f7a9f24012b Mon Sep 17 00:00:00 2001 From: rejas Date: Wed, 11 Mar 2020 11:43:45 +0100 Subject: [PATCH 085/104] Fix js error but add a stylelint error --- modules/default/currentweather/currentweather.css | 2 +- modules/default/defaultmodules.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/default/currentweather/currentweather.css b/modules/default/currentweather/currentweather.css index b7669bda..594dafac 100644 --- a/modules/default/currentweather/currentweather.css +++ b/modules/default/currentweather/currentweather.css @@ -1,7 +1,7 @@ .currentweather .weathericon, .currentweather .fa-home { font-size: 75%; - line-height: 65px; + line-height:65px; display: inline-block; -ms-transform: translate(0, -3px); /* IE 9 */ -webkit-transform: translate(0, -3px); /* Safari */ diff --git a/modules/default/defaultmodules.js b/modules/default/defaultmodules.js index f36d028e..656ba6b8 100644 --- a/modules/default/defaultmodules.js +++ b/modules/default/defaultmodules.js @@ -8,7 +8,7 @@ // Modules listed below can be loaded without the 'default/' prefix. Omitting the default folder name. var defaultModules = [ - 'alert', + "alert", "calendar", "clock", "compliments", From 437d0305027ef9767c5baab4efda924ee65a28c1 Mon Sep 17 00:00:00 2001 From: rejas Date: Wed, 11 Mar 2020 12:44:44 +0100 Subject: [PATCH 086/104] Remove some dead files, fix stylelint error --- Gruntfile.js | 4 +--- modules/default/currentweather/currentweather.css | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/Gruntfile.js b/Gruntfile.js index 2b2048d7..36a90c5e 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -20,8 +20,7 @@ module.exports = function(grunt) { "!modules/default/alert/classie.js", "config/*", "translations/translations.js", - "vendor/vendor.js", - "modules/node_modules/node_helper/index.js" + "vendor/vendor.js" ] }, stylelint: { @@ -45,7 +44,6 @@ module.exports = function(grunt) { "package.json", ".eslintrc.json", ".stylelintrc.json", - "installers/pm2_MagicMirror.json", "translations/*.json", "modules/default/*/translations/*.json", "vendor/package.json" diff --git a/modules/default/currentweather/currentweather.css b/modules/default/currentweather/currentweather.css index 594dafac..b7669bda 100644 --- a/modules/default/currentweather/currentweather.css +++ b/modules/default/currentweather/currentweather.css @@ -1,7 +1,7 @@ .currentweather .weathericon, .currentweather .fa-home { font-size: 75%; - line-height:65px; + line-height: 65px; display: inline-block; -ms-transform: translate(0, -3px); /* IE 9 */ -webkit-transform: translate(0, -3px); /* Safari */ From 5a4ae9928364c7652425c91d1b027b0ba6fec156 Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 15 Mar 2020 15:49:34 +0100 Subject: [PATCH 087/104] Add no-multi-spaces rule to eslint and run it --- .eslintrc.json | 1 + config/config.js.sample | 4 ++-- js/app.js | 8 ++++---- js/loader.js | 6 +++--- js/main.js | 10 +++++----- js/node_helper.js | 4 ++-- js/socketclient.js | 4 ++-- modules/default/calendar/calendar.js | 2 +- modules/default/calendar/calendarfetcher.js | 4 ++-- modules/default/calendar/debug.js | 2 +- modules/default/newsfeed/newsfeed.js | 2 +- modules/default/updatenotification/node_helper.js | 2 +- tests/unit/functions/currentweather_spec.js | 1 + tests/unit/functions/weatherforecast_spec.js | 1 + 14 files changed, 27 insertions(+), 24 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index eee62330..e5aca766 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,6 +7,7 @@ "curly": "error", "camelcase": ["error", {"properties": "never"}], "no-multiple-empty-lines": ["error", { "max": 1, "maxEOF": 1 }], + "no-multi-spaces": "error", "no-trailing-spaces": ["error", {"ignoreComments": false }], "no-irregular-whitespace": ["error"] }, diff --git a/config/config.js.sample b/config/config.js.sample index 67656392..414054da 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -67,7 +67,7 @@ var config = { position: "top_right", config: { location: "New York", - locationID: "", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + 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" } }, @@ -77,7 +77,7 @@ var config = { header: "Weather Forecast", config: { location: "New York", - locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city + 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" } }, diff --git a/js/app.js b/js/app.js index ef66a44c..b7c55ffa 100644 --- a/js/app.js +++ b/js/app.js @@ -111,10 +111,10 @@ var App = function() { var elements = module.split("/"); var moduleName = elements[elements.length - 1]; - var moduleFolder = __dirname + "/../modules/" + module; + var moduleFolder = __dirname + "/../modules/" + module; if (defaultModules.indexOf(moduleName) !== -1) { - moduleFolder = __dirname + "/../modules/default/" + module; + moduleFolder = __dirname + "/../modules/default/" + module; } var helperPath = moduleFolder + "/node_helper.js"; @@ -262,7 +262,7 @@ var App = function() { */ process.on("SIGINT", () => { console.log("[SIGINT] Received. Shutting down server..."); - setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds + setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds this.stop(); process.exit(0); }); @@ -271,7 +271,7 @@ var App = function() { */ process.on("SIGTERM", () => { console.log("[SIGTERM] Received. Shutting down server..."); - setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds + setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds this.stop(); process.exit(0); }); diff --git a/js/loader.js b/js/loader.js index 3a4e05c3..6db46ad5 100644 --- a/js/loader.js +++ b/js/loader.js @@ -83,10 +83,10 @@ var Loader = (function() { var elements = module.split("/"); var moduleName = elements[elements.length - 1]; - var moduleFolder = config.paths.modules + "/" + module; + var moduleFolder = config.paths.modules + "/" + module; if (defaultModules.indexOf(moduleName) !== -1) { - moduleFolder = config.paths.modules + "/default/" + module; + moduleFolder = config.paths.modules + "/default/" + module; } if (moduleData.disabled === true) { @@ -172,7 +172,7 @@ var Loader = (function() { */ var loadFile = function(fileName, callback) { - var extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); + var extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); switch (extension.toLowerCase()) { case "js": diff --git a/js/main.js b/js/main.js index de44ccce..f7d1f773 100644 --- a/js/main.js +++ b/js/main.js @@ -377,7 +377,7 @@ var MM = (function() { * * return array - Filtered collection of modules. */ - var exceptWithClass = function(className) { + var exceptWithClass = function(className) { return modulesByClass(className, false); }; @@ -439,10 +439,10 @@ var MM = (function() { }); }; - if (typeof modules.withClass === "undefined") { Object.defineProperty(modules, "withClass", {value: withClass, enumerable: false}); } - if (typeof modules.exceptWithClass === "undefined") { Object.defineProperty(modules, "exceptWithClass", {value: exceptWithClass, enumerable: false}); } - if (typeof modules.exceptModule === "undefined") { Object.defineProperty(modules, "exceptModule", {value: exceptModule, enumerable: false}); } - if (typeof modules.enumerate === "undefined") { Object.defineProperty(modules, "enumerate", {value: enumerate, enumerable: false}); } + if (typeof modules.withClass === "undefined") { Object.defineProperty(modules, "withClass", {value: withClass, enumerable: false}); } + if (typeof modules.exceptWithClass === "undefined") { Object.defineProperty(modules, "exceptWithClass", {value: exceptWithClass, enumerable: false}); } + if (typeof modules.exceptModule === "undefined") { Object.defineProperty(modules, "exceptModule", {value: exceptModule, enumerable: false}); } + if (typeof modules.enumerate === "undefined") { Object.defineProperty(modules, "enumerate", {value: enumerate, enumerable: false}); } }; return { diff --git a/js/node_helper.js b/js/node_helper.js index a083d332..326a8cce 100644 --- a/js/node_helper.js +++ b/js/node_helper.js @@ -101,9 +101,9 @@ NodeHelper = Class.extend({ var onevent = socket.onevent; socket.onevent = function(packet) { var args = packet.data || []; - onevent.call(this, packet); // original call + onevent.call(this, packet); // original call packet.data = ["*"].concat(args); - onevent.call(this, packet); // additional call to catch-all + onevent.call(this, packet); // additional call to catch-all }; // register catch all. diff --git a/js/socketclient.js b/js/socketclient.js index baead68e..10c26ad3 100644 --- a/js/socketclient.js +++ b/js/socketclient.js @@ -14,9 +14,9 @@ var MMSocket = function(moduleName) { var onevent = self.socket.onevent; self.socket.onevent = function(packet) { var args = packet.data || []; - onevent.call(this, packet); // original call + onevent.call(this, packet); // original call packet.data = ["*"].concat(args); - onevent.call(this, packet); // additional call to catch-all + onevent.call(this, packet); // additional call to catch-all }; // register catch all. diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 9c91afe5..98ae5636 100755 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -320,7 +320,7 @@ Module.register("calendar", { } if(this.config.showEnd){ timeWrapper.innerHTML += "-" ; - timeWrapper.innerHTML += this.capFirst(moment(event.endDate , "x").format(this.config.fullDayEventDateFormat)); + timeWrapper.innerHTML += this.capFirst(moment(event.endDate , "x").format(this.config.fullDayEventDateFormat)); } } else { if (event.startDate >= new Date()) { diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index a9bf37ee..c393d5d6 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -28,7 +28,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); var opts = { headers: { - "User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)" + "User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)" }, gzip: true }; @@ -249,7 +249,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri showRecurrence = false; } - endDate = moment(parseInt(startDate.format("x")) + duration, "x"); + endDate = moment(parseInt(startDate.format("x")) + duration, "x"); if (startDate.format("x") == endDate.format("x")) { endDate = endDate.endOf("day"); } diff --git a/modules/default/calendar/debug.js b/modules/default/calendar/debug.js index bf65a279..84fc2f86 100644 --- a/modules/default/calendar/debug.js +++ b/modules/default/calendar/debug.js @@ -8,7 +8,7 @@ var CalendarFetcher = require("./calendarfetcher.js"); -var url = "https://calendar.google.com/calendar/ical/pkm1t2uedjbp0uvq1o7oj1jouo%40group.calendar.google.com/private-08ba559f89eec70dd74bbd887d0a3598/basic.ics"; // Standard test URL +var url = "https://calendar.google.com/calendar/ical/pkm1t2uedjbp0uvq1o7oj1jouo%40group.calendar.google.com/private-08ba559f89eec70dd74bbd887d0a3598/basic.ics"; // Standard test URL // var url = "https://www.googleapis.com/calendar/v3/calendars/primary/events/"; // URL for Bearer auth (must be configured in Google OAuth2 first) var fetchInterval = 60 * 60 * 1000; var maximumEntries = 10; diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index d358110c..53cb3065 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -213,7 +213,7 @@ Module.register("newsfeed",{ }, getActiveItemURL: function() { - return typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href; + return typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href; }, /* registerFeeds() diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index 4386b146..2d41626c 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -27,7 +27,7 @@ module.exports = NodeHelper.create({ for (moduleName in modules) { if (!this.ignoreUpdateChecking(moduleName)) { // Default modules are included in the main MagicMirror repo - var moduleFolder = path.normalize(__dirname + "/../../" + moduleName); + var moduleFolder = path.normalize(__dirname + "/../../" + moduleName); try { //console.log("checking git for module="+moduleName) diff --git a/tests/unit/functions/currentweather_spec.js b/tests/unit/functions/currentweather_spec.js index 0afbbd7b..d630cb9f 100644 --- a/tests/unit/functions/currentweather_spec.js +++ b/tests/unit/functions/currentweather_spec.js @@ -1,3 +1,4 @@ +/* eslint no-multi-spaces: 0 */ var expect = require("chai").expect; describe("Functions module currentweather", function() { diff --git a/tests/unit/functions/weatherforecast_spec.js b/tests/unit/functions/weatherforecast_spec.js index 6c40531e..ea078bc7 100644 --- a/tests/unit/functions/weatherforecast_spec.js +++ b/tests/unit/functions/weatherforecast_spec.js @@ -1,3 +1,4 @@ +/* eslint no-multi-spaces: 0 */ var expect = require("chai").expect; describe("Functions module weatherforecast", function() { From a91f2de26a1d18c48cf48bf456f7c2345ca4c756 Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 15 Mar 2020 20:38:52 +0100 Subject: [PATCH 088/104] Remove jshint dependency, use eslint for config verification --- clientonly/index.js | 2 - js/electron.js | 2 - js/main.js | 1 - package-lock.json | 486 ++++++++++++++-------------------- package.json | 1 - tests/configs/check_config.js | 14 +- 6 files changed, 201 insertions(+), 305 deletions(-) diff --git a/clientonly/index.js b/clientonly/index.js index 895dacae..6430b270 100644 --- a/clientonly/index.js +++ b/clientonly/index.js @@ -1,5 +1,3 @@ -/* jshint esversion: 6 */ - "use strict"; // Use separate scope to prevent global scope pollution diff --git a/js/electron.js b/js/electron.js index c5e9c4cb..f7615b1c 100644 --- a/js/electron.js +++ b/js/electron.js @@ -1,5 +1,3 @@ -/* jshint esversion: 6 */ - "use strict"; const electron = require("electron"); diff --git a/js/main.js b/js/main.js index de44ccce..51bfd7d4 100644 --- a/js/main.js +++ b/js/main.js @@ -1,5 +1,4 @@ /* global Log, Loader, Module, config, defaults */ -/* jshint -W020, esversion: 6 */ /* Magic Mirror * Main System diff --git a/package-lock.json b/package-lock.json index 2509883d..5c3e882f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,18 +14,18 @@ } }, "@babel/core": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.3.tgz", - "integrity": "sha512-4XFkf8AwyrEG7Ziu3L2L0Cv+WyY47Tcsp70JFmpftbAA1K7YL/sgE9jh9HyNj08Y/U50ItUchpN0w6HxAoX1rA==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", + "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", - "@babel/helpers": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/generator": "^7.8.7", + "@babel/helpers": "^7.8.4", + "@babel/parser": "^7.8.7", + "@babel/template": "^7.8.6", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -63,12 +63,12 @@ } }, "@babel/generator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.3.tgz", - "integrity": "sha512-WjoPk8hRpDRqqzRpvaR8/gDUPkrnOOeuT2m8cNICJtZH6mwaCo3v0OKMI7Y6SM1pBtyijnLtAL0HDi41pf41ug==", + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", + "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", "dev": true, "requires": { - "@babel/types": "^7.8.3", + "@babel/types": "^7.8.7", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -112,13 +112,13 @@ } }, "@babel/helpers": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.3.tgz", - "integrity": "sha512-LmU3q9Pah/XyZU89QvBgGt+BCsTPoQa+73RxAQh8fb8qkDyIfeQnmgs+hvzhTCKTzqOyk7JTkS3MS1S8Mq5yrQ==", + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", + "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", "dev": true, "requires": { "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.3", + "@babel/traverse": "^7.8.4", "@babel/types": "^7.8.3" } }, @@ -165,51 +165,51 @@ } }, "@babel/parser": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.3.tgz", - "integrity": "sha512-/V72F4Yp/qmHaTALizEm9Gf2eQHV3QyTL3K0cNfijwnMnb1L+LDlAubb/ZnSdGAVzVSWakujHYs1I26x66sMeQ==", + "version": "7.8.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", + "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", "dev": true }, "@babel/runtime": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.3.tgz", - "integrity": "sha512-fVHx1rzEmwB130VTkLnxR+HmxcTjGzH12LYQcFFoBwakMd3aOMD4OsRN7tGG/UOYE2ektgFrS8uACAoRk1CY0w==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", + "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", "dev": true, "requires": { - "regenerator-runtime": "^0.13.2" + "regenerator-runtime": "^0.13.4" }, "dependencies": { "regenerator-runtime": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz", - "integrity": "sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw==", + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", "dev": true } } }, "@babel/template": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.3.tgz", - "integrity": "sha512-04m87AcQgAFdvuoyiQ2kgELr2tV8B4fP/xJAVUL3Yb3bkNdMedD3d0rlSQr3PegP0cms3eHjl1F7PWlvWbU8FQ==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", + "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6" } }, "@babel/traverse": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.3.tgz", - "integrity": "sha512-we+a2lti+eEImHmEXp7bM9cTxGzxPmBiVJlLVD+FuuQMeeO7RaDbutbgeheDkw+Xe3mCfJHnGOWLswT74m2IPg==", + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", + "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.3", + "@babel/generator": "^7.8.6", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.3", - "@babel/types": "^7.8.3", + "@babel/parser": "^7.8.6", + "@babel/types": "^7.8.6", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -233,9 +233,9 @@ } }, "@babel/types": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.3.tgz", - "integrity": "sha512-jBD+G8+LWpMBBWvVcdr4QysjUE4mU/syrhN17o1u3gx0/WzJB1kwiVZAXRtWbsIPOwW8pF/YJV5+nmetPzepXg==", + "version": "7.8.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", + "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", "dev": true, "requires": { "esutils": "^2.0.2", @@ -317,9 +317,9 @@ "dev": true }, "@types/node": { - "version": "13.1.8", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.1.8.tgz", - "integrity": "sha512-6XzyyNM9EKQW4HKuzbo/CkOIjn/evtCmsU+MUM1xDfJ+3/rNjBttM1NgN7AOQvN6tP1Sl1D1PIKMreTArnxM9A==", + "version": "13.9.1", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz", + "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==", "dev": true }, "@types/normalize-package-data": { @@ -688,9 +688,9 @@ "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==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", "dev": true }, "balanced-match": { @@ -836,14 +836,14 @@ "dev": true }, "browserslist": { - "version": "4.8.3", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.8.3.tgz", - "integrity": "sha512-iU43cMMknxG1ClEZ2MDKeonKE1CCrFVkQK2AqO2YWFmvIrx4JWrvQ4w4hQez6EpVI8rHTtqh/ruHHDHSOKxvUg==", + "version": "4.9.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", + "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001017", - "electron-to-chromium": "^1.3.322", - "node-releases": "^1.1.44" + "caniuse-lite": "^1.0.30001030", + "electron-to-chromium": "^1.3.363", + "node-releases": "^1.1.50" } }, "btoa-lite": { @@ -937,9 +937,9 @@ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, "caniuse-lite": { - "version": "1.0.30001021", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001021.tgz", - "integrity": "sha512-wuMhT7/hwkgd8gldgp2jcrUjOU9RXJ4XxGumQeOsUr91l3WwmM68Cpa/ymCnWEDqakwFXhuDQbaKNHXBPgeE9g==", + "version": "1.0.30001035", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz", + "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==", "dev": true }, "caseless": { @@ -948,9 +948,9 @@ "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==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.0.5.tgz", + "integrity": "sha512-MOli1W+nfbPLlKEhInaxhRdp7KVLFxLN5ykwzHgLsLI3H3gs5jjFAK4Eoj3OzzcxCtumDaI8onoVDeQyWaNTkw==", "dev": true }, "chai": { @@ -989,27 +989,27 @@ } }, "character-entities": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.3.tgz", - "integrity": "sha512-yB4oYSAa9yLcGyTbB4ItFwHw43QHdH129IJ5R+WvxOkWlyFnR5FAaBNnUq4mcxsTVZGh28bHoeTHMKXH1wZf3w==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", "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==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", + "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", "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==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", "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==", + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", "dev": true }, "chardet": { @@ -1053,32 +1053,6 @@ "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.4.tgz", "integrity": "sha512-Rx9Zw8KQkoPO3/O2yPRchCZm3cGubCQiRLmmFAlbkDKobUIPP3JYul+bKILR9DIv1gSVwPQSgF8JGGkXzX8Q0w==" }, - "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.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", - "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", - "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": "3.1.0", "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", @@ -1159,9 +1133,9 @@ "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==", + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", "dev": true }, "color-convert": { @@ -1264,15 +1238,6 @@ } } }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, "console-stamp": { "version": "0.2.9", "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-0.2.9.tgz", @@ -1428,6 +1393,12 @@ "integrity": "sha1-Xv1sLupeof1rasV+wEJ7GEUkJOo=", "dev": true }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, "cssom": { "version": "0.3.8", "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", @@ -1569,12 +1540,6 @@ } } }, - "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", @@ -1774,15 +1739,6 @@ "resolved": "https://registry.npmjs.org/dont-sniff-mimetype/-/dont-sniff-mimetype-1.1.0.tgz", "integrity": "sha512-ZjI4zqTaxveH2/tTlzS1wFp+7ncxNZaIEWYg3lzZRHkKf5zPT/MnEG6WL0BhHMJUabkh8GeU5NL5j+rEUCb7Ug==" }, - "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", @@ -1865,9 +1821,9 @@ } }, "electron-to-chromium": { - "version": "1.3.338", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.338.tgz", - "integrity": "sha512-wlmfixuHEc9CkfOKgcqdtzBmRW4NStM9ptl5oPILY2UDyHuSXb3Yit+yLVyLObTgGuMMU36hhnfs2GDJId7ctA==", + "version": "1.3.376", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.376.tgz", + "integrity": "sha512-cv/PYVz5szeMz192ngilmezyPNFkUjuynuL2vNdiqIrio440nfTDdc0JJU0TS2KHLSVCs9gBbt4CFqM+HcBnjw==", "dev": true }, "emoji-regex": { @@ -2459,16 +2415,17 @@ "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, "fast-glob": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.1.1.tgz", - "integrity": "sha512-nTCREpBY8w8r+boyFYAx21iL6faSsQynliPHM4Uf56SbkyohCNxpVPEH9xrF5TXKy+IsjkPUHDKiUkzBVRXn9g==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", + "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.0", "merge2": "^1.3.0", - "micromatch": "^4.0.2" + "micromatch": "^4.0.2", + "picomatch": "^2.2.1" } }, "fast-json-stable-stringify": { @@ -2483,12 +2440,12 @@ "dev": true }, "fastq": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.0.tgz", - "integrity": "sha512-jmxqQ3Z/nXoeyDmWAzF9kH1aGZSis6e/SbfPmJpUnyZ0ogr6iscHQaml4wsEepEWSdtmpy+eVXmCRIMpxaXqOA==", + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.1.tgz", + "integrity": "sha512-mpIH5sKYueh3YyeJwqtVo8sORi0CgtmkVbK6kZStpQlZBYQuTzG2CZ7idSiJuA7bY0SFCWUc5WIs+oYumGCQNw==", "dev": true, "requires": { - "reusify": "^1.0.0" + "reusify": "^1.0.4" } }, "fd-slicer": { @@ -3109,9 +3066,9 @@ } }, "grunt-stylelint": { - "version": "0.13.0", - "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.13.0.tgz", - "integrity": "sha512-Ju9N03UBvPwcdoJYL77pDk0k0E8VD4oYtTfoRwvvPM1ON2MjOXWwPyaeIoYPnhUwcfN9D7TaXnTtuhNoWNsyrQ==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/grunt-stylelint/-/grunt-stylelint-0.14.0.tgz", + "integrity": "sha512-4gi/Yw9djHEdRlikKvFjy2wkHlD1YVzlJOePUPlYm1PIpGi3PMVJoc7Eon6RVSjdRcj3NcYHbeNA0EzplXzp7w==", "dev": true, "requires": { "chalk": "^2.4.2" @@ -3350,27 +3307,6 @@ "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "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.4", "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.2.4.tgz", @@ -3666,9 +3602,9 @@ "integrity": "sha512-M4Sjn6N/+O6/IXSJseKqHoFc+5FdGJ22sXqnjTpdZweHK64MzEPAyQZyEU3R/KRv2GLoa7nNtg/C2Ev6m7z+eA==" }, "is-alphabetical": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.3.tgz", - "integrity": "sha512-eEMa6MKpHFzw38eKm56iNNi6GJ7lf6aLLio7Kr23sJPAECscgRtZvOBYybejWDQ2bM949Y++61PY+udzj5QMLA==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", "dev": true }, "is-alphanumeric": { @@ -3678,9 +3614,9 @@ "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==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", "dev": true, "requires": { "is-alphabetical": "^1.0.0", @@ -3720,9 +3656,9 @@ "dev": true }, "is-decimal": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.3.tgz", - "integrity": "sha512-bvLSwoDg2q6Gf+E2LEPiklHZxxiSi3XAh4Mav65mKqTfCO1HM3uBs24TjEH8iJX3bbDdLXKJXBTmGzuTUuAEjQ==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", "dev": true }, "is-extendable": { @@ -3763,9 +3699,9 @@ } }, "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==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", "dev": true }, "is-number": { @@ -3774,12 +3710,6 @@ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", "dev": true }, - "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", @@ -3833,15 +3763,15 @@ "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==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", "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==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", "dev": true }, "isarray": { @@ -3938,30 +3868,6 @@ "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true }, - "jshint": { - "version": "2.10.3", - "resolved": "https://registry.npmjs.org/jshint/-/jshint-2.10.3.tgz", - "integrity": "sha512-d8AoXcNNYzmm7cdmulQ3dQApbrPYArtVBO6n4xOICe4QsXGNHCAKDcFORzqP52LhK61KX0VhY39yYzCsNq+bxQ==", - "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", @@ -4111,9 +4017,9 @@ "dev": true }, "known-css-properties": { - "version": "0.17.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.17.0.tgz", - "integrity": "sha512-Vi3nxDGMm/z+lAaCjvAR1u+7fiv+sG6gU/iYDj5QOF8h76ytK9EW/EKfF0NeTyiGBi8Jy6Hklty/vxISrLox3w==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.18.0.tgz", + "integrity": "sha512-69AgJ1rQa7VvUsd2kpvVq+VeObDuo3zrj0CzM5Slmf6yduQFAI2kXPDQJR2IE/u6MSAUOJrwSzjg5vlz8qcMiw==", "dev": true }, "lazystream": { @@ -4351,9 +4257,9 @@ } }, "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==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", "dev": true }, "loud-rejection": { @@ -4392,9 +4298,9 @@ "integrity": "sha1-2TPOuSBdgr3PSIb2dCvcK03qFG0=" }, "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==", + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", "dev": true }, "markdown-it": { @@ -4426,9 +4332,9 @@ } }, "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==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true }, "mdast-util-compact": { @@ -5016,9 +4922,9 @@ "dev": true }, "node-releases": { - "version": "1.1.46", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.46.tgz", - "integrity": "sha512-YOjdx+Uoh9FbRO7yVYbnbt1puRWPQMemR3SutLeyv2XfxKs1ihpe0OLAUwBPEP2ImNH/PZC7SEiC6j32dwRZ7g==", + "version": "1.1.52", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz", + "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==", "dev": true, "requires": { "semver": "^6.3.0" @@ -5517,9 +5423,9 @@ "dev": true }, "postcss": { - "version": "7.0.26", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.26.tgz", - "integrity": "sha512-IY4oRjpXWYshuTDFxMVkJDtWIk2LhsTlu8bZnbEJA4+bYT16Lvpo8Qv6EvDumhYRgzjZl489pmsY3qVgJQ08nA==", + "version": "7.0.27", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", + "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -5599,9 +5505,9 @@ } }, "readable-stream": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.5.0.tgz", - "integrity": "sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==", + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", "dev": true, "requires": { "inherits": "^2.0.3", @@ -5713,12 +5619,12 @@ "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==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", "dev": true, "requires": { - "postcss": "^7.0.0" + "postcss": "^7.0.26" } }, "postcss-sass": { @@ -5741,12 +5647,12 @@ } }, "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=", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", "dev": true, "requires": { - "dot-prop": "^4.1.1", + "cssesc": "^3.0.0", "indexes-of": "^1.0.1", "uniq": "^1.0.1" } @@ -5758,9 +5664,9 @@ "dev": true }, "postcss-value-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.2.tgz", - "integrity": "sha512-LmeoohTpp/K4UiyQCwuGWlONxXamGzCMtFxLq4W1nZVGIQLYvMCJx3yAF9qyyuFpflABI9yVdtJAqbihOsCsJQ==", + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", + "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==", "dev": true }, "prelude-ls": { @@ -6373,12 +6279,6 @@ "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", @@ -7050,9 +6950,9 @@ } }, "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==", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", "dev": true }, "statuses": { @@ -7155,12 +7055,12 @@ "dev": true }, "stylelint": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.0.0.tgz", - "integrity": "sha512-6sjgOJbM3iLhnUtmRO0J1vvxie9VnhIZX/2fCehjylv9Gl9u0ytehGCTm9Lhw2p1F8yaNZn5UprvhCB8C3g/Tg==", + "version": "13.2.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.2.1.tgz", + "integrity": "sha512-461ZV4KpUe7pEHHgMOsH4kkjF7qsjkCIMJYOf7QQC4cvgPUJ0z4Nj+ah5fvKl1rzqBqc5EZa6P0nna4CGoJX+A==", "dev": true, "requires": { - "autoprefixer": "^9.7.3", + "autoprefixer": "^9.7.4", "balanced-match": "^1.0.0", "chalk": "^3.0.0", "cosmiconfig": "^6.0.0", @@ -7175,17 +7075,17 @@ "ignore": "^5.1.4", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", - "known-css-properties": "^0.17.0", + "known-css-properties": "^0.18.0", "leven": "^3.1.0", "lodash": "^4.17.15", "log-symbols": "^3.0.0", - "mathml-tag-names": "^2.1.1", - "meow": "^6.0.0", + "mathml-tag-names": "^2.1.3", + "meow": "^6.0.1", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", - "postcss": "^7.0.26", + "postcss": "^7.0.27", "postcss-html": "^0.36.0", - "postcss-jsx": "^0.36.3", + "postcss-jsx": "^0.36.4", "postcss-less": "^3.1.4", "postcss-markdown": "^0.36.0", "postcss-media-query-parser": "^0.2.3", @@ -7194,9 +7094,9 @@ "postcss-safe-parser": "^4.0.1", "postcss-sass": "^0.4.2", "postcss-scss": "^2.0.0", - "postcss-selector-parser": "^3.1.0", + "postcss-selector-parser": "^6.0.2", "postcss-syntax": "^0.36.2", - "postcss-value-parser": "^4.0.2", + "postcss-value-parser": "^4.0.3", "resolve-from": "^5.0.0", "slash": "^3.0.0", "specificity": "^0.4.1", @@ -7207,7 +7107,7 @@ "svg-tags": "^1.0.0", "table": "^5.4.6", "v8-compile-cache": "^2.1.0", - "write-file-atomic": "^3.0.1" + "write-file-atomic": "^3.0.3" }, "dependencies": { "ansi-regex": { @@ -7233,9 +7133,9 @@ "dev": true }, "camelcase-keys": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.1.1.tgz", - "integrity": "sha512-kEPCddRFChEzO0d6w61yh0WbBiSv9gBnfZWGfXRYPlGqIdIGef6HMR6pgqVSEWCYkrp8B0AtEpEXNY+Jx0xk1A==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.1.tgz", + "integrity": "sha512-BPCNVH56RVIxQQIXskp5tLQXUNGQ6sXr7iCv1FHDt81xBOQ/1r6H8SPxf19InVP6DexWar4s87q9thfuk8X9HA==", "dev": true, "requires": { "camelcase": "^5.3.1", @@ -7333,9 +7233,9 @@ "dev": true }, "meow": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-6.0.0.tgz", - "integrity": "sha512-x4rYsjigPBDAxY+BGuK83YLhUIqui5wYyZoqb6QJCUOs+0fiYq+i/NV4Jt8OgIfObZFxG9iTyvLDu4UTohGTFw==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.0.1.tgz", + "integrity": "sha512-kxGTFgT/b7/oSRSQsJ0qsT5IMU+bgZ1eAdSA3kIV7onkW0QWo/hL5RbGlMfvBjHJKPE1LaPX0kdecYFiqYWjUw==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -7503,9 +7403,9 @@ "dev": true }, "stylelint-config-standard": { - "version": "19.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-19.0.0.tgz", - "integrity": "sha512-VvcODsL1PryzpYteWZo2YaA5vU/pWfjqBpOvmeA8iB2MteZ/ZhI1O4hnrWMidsS4vmEJpKtjdhLdfGJmmZm6Cg==", + "version": "20.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-20.0.0.tgz", + "integrity": "sha512-IB2iFdzOTA/zS4jSVav6z+wGtin08qfj+YyExHB3LF9lnouQht//YyB0KZq9gGz5HNPkddHOzcY8HsUey6ZUlA==", "dev": true, "requires": { "stylelint-config-recommended": "^3.0.0" @@ -7783,15 +7683,15 @@ "integrity": "sha1-WIeWa7WCpFA6QetST301ARgVphM=" }, "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==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.3.tgz", + "integrity": "sha512-4ku0mmjXifQcTVfYDfR5lpgV7zVqPg6zV9rdZmwOPqq0+Zq19xDqEgagqVbc4pOOShbncuAOIs59R3+3gcF3ZA==", "dev": true }, "trough": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.4.tgz", - "integrity": "sha512-tdzBRDGWcI1OpPVmChbdSKhvSVurznZ8X36AYURAcl+0o2ldlCY2XPzyXNNxwJwwyIU+rIglTCG4kxtNKBQH7Q==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", "dev": true }, "tslib": { @@ -7873,13 +7773,13 @@ } }, "unherit": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.2.tgz", - "integrity": "sha512-W3tMnpaMG7ZY6xe/moK04U9fBhi6wEiCYHUW5Mop/wQHf12+79EQGwxYejNdhEz2mkqkBlGwm7pxmgBKMVUj0w==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", "dev": true, "requires": { - "inherits": "^2.0.1", - "xtend": "^4.0.1" + "inherits": "^2.0.0", + "xtend": "^4.0.0" }, "dependencies": { "xtend": { @@ -7937,9 +7837,9 @@ } }, "unist-util-stringify-position": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.2.tgz", - "integrity": "sha512-nK5n8OGhZ7ZgUwoUbL8uiVRwAbZyzBsB/Ddrlbu6jwwubFza4oe15KlyEaLNMXQW1svOQq4xesUeqA85YrIUQA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", "dev": true, "requires": { "@types/unist": "^2.0.2" @@ -8112,9 +8012,9 @@ "dev": true }, "vfile-message": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.2.tgz", - "integrity": "sha512-gNV2Y2fDvDOOqq8bEe7cF3DXU6QgV4uA9zMR2P8tix11l1r7zju3zry3wZ8sx+BEfuO6WQ7z2QzfWTvqHQiwsA==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.3.tgz", + "integrity": "sha512-qQg/2z8qnnBHL0psXyF72kCjb9YioIynvyltuNKFaUhRtqTIcIMP3xnBaPzirVZNuBrUe1qwFciSx2yApa4byw==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -8268,9 +8168,9 @@ } }, "write-file-atomic": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.1.tgz", - "integrity": "sha512-JPStrIyyVJ6oCSz/691fAjFtefZ6q+fP6tm+OS4Qw6o+TGQxNp1ziY2PgS+X/m0V8OWhZiO/m4xSj+Pr4RrZvw==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", "dev": true, "requires": { "imurmurhash": "^0.1.4", @@ -8321,12 +8221,12 @@ "dev": true }, "yaml": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.7.2.tgz", - "integrity": "sha512-qXROVp90sb83XtAoqE8bP9RwAkTTZbugRUTm5YeFCBfNRPEp2YzTeqWiz7m5OORHzEvrA/qcGS8hp/E+MMROYw==", + "version": "1.8.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.2.tgz", + "integrity": "sha512-omakb0d7FjMo3R1D2EbTKVIk6dAVLRxFXdLZMEUToeAvuqgG/YuHMuQOZ5fgk+vQ8cx+cnGKwyg+8g8PNT0xQg==", "dev": true, "requires": { - "@babel/runtime": "^7.6.3" + "@babel/runtime": "^7.8.7" } }, "yargs": { diff --git a/package.json b/package.json index 1b150ed4..e9cfbd12 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,6 @@ "grunt-yamllint": "latest", "http-auth": "^3.2.3", "jsdom": "^11.6.2", - "jshint": "^2.10.2", "mocha": "^7.0.0", "mocha-each": "^1.1.0", "mocha-logger": "^1.0.6", diff --git a/tests/configs/check_config.js b/tests/configs/check_config.js index 03a275bf..917b6d32 100644 --- a/tests/configs/check_config.js +++ b/tests/configs/check_config.js @@ -9,7 +9,10 @@ * */ -var v = require("jshint"); +const Linter = require("eslint").Linter; +const linter = new Linter(); +const config = require(__dirname + "/../../.eslintrc.json"); + var path = require("path"); var fs = require("fs"); var Utils = require(__dirname + "/../../js/utils.js"); @@ -50,16 +53,15 @@ function checkConfigFile() { // 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) { + const messages = linter.verify(data, config); + if (messages.length === 0) { console.log("Your configuration file doesn't contain syntax errors :)"); return true; } else { - errors = v.JSHINT.data().errors; + errors = messages; for (var idx in errors) { error = errors[idx]; - console.log("Line", error.line, "col", error.character, error.reason); + console.log("Line", error.line, "col", error.column, error.message); } } }); From e9461586cbae70f4e1aeaadd6eba52b3bc02b4e7 Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 15 Mar 2020 21:25:11 +0100 Subject: [PATCH 089/104] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0236e6de..39a04374 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ### Deleted - Remove installers. - Remove externalized scripts. +- Remove jshint dependency, instead eslint checks your config file now ### Added - Ukrainian translation. From 8aa7a55559a408a9bc4e1b7ca84f0c99caa14230 Mon Sep 17 00:00:00 2001 From: bugsounet Date: Thu, 19 Mar 2020 19:03:25 +0100 Subject: [PATCH 090/104] issue #1956 --- js/main.js | 4 +++- js/module.js | 7 +++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/js/main.js b/js/main.js index de44ccce..29d8f71e 100644 --- a/js/main.js +++ b/js/main.js @@ -306,7 +306,9 @@ var MM = (function() { module.showHideTimer = setTimeout(function() { if (typeof callback === "function") { callback(); } }, speed); - + } else { + // invoke callback + if (typeof callback === "function") { callback(); } } }; diff --git a/js/module.js b/js/module.js index 62bf80ce..6339dd7d 100644 --- a/js/module.js +++ b/js/module.js @@ -417,8 +417,11 @@ var Module = Class.extend({ callback = callback || function () { }; options = options || {}; - this.resume(); - MM.showModule(this, speed, callback, options); + var self = this; + MM.showModule(this, speed, function () { + self.resume(); + callback; + }, options); } }); From c342f7bce6d8c96bc45ad0c9cb0e40a23e87a227 Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Mon, 23 Mar 2020 14:55:36 -0300 Subject: [PATCH 091/104] Update pt-br.json --- translations/pt-br.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/translations/pt-br.json b/translations/pt-br.json index 898e4f1f..e5726cc0 100644 --- a/translations/pt-br.json +++ b/translations/pt-br.json @@ -26,5 +26,8 @@ "UPDATE_NOTIFICATION": "Nova atualização para MagicMirror disponível.", "UPDATE_NOTIFICATION_MODULE": "Atualização para o módulo {MODULE_NAME} disponível.", "UPDATE_INFO_SINGLE": "Sua versão atual é a {COMMIT_COUNT} commit dentro do seguinte branch {BRANCH_NAME}.", - "UPDATE_INFO_MULTIPLE": "Sua versão atual é a {COMMIT_COUNT} commits dentro do seguinte branch {BRANCH_NAME}." + "UPDATE_INFO_MULTIPLE": "Sua versão atual é a {COMMIT_COUNT} commits dentro do seguinte branch {BRANCH_NAME}.", + + "FEELS": "Percebida", + "PRECIP": "PoP" } From 8f203852ca00012e3eeb13b3cd19f1ddbf175af8 Mon Sep 17 00:00:00 2001 From: Federico Leoni Date: Tue, 24 Mar 2020 10:06:12 -0300 Subject: [PATCH 092/104] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0236e6de..ae112aa9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Remove externalized scripts. ### Added +- Brazilian translation for "FEELS". - Ukrainian translation. - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". - Added the ability to hide the temp label and weather icon in the `currentweather` module to allow showing only information such as wind and sunset/rise. From 82b50d3059c0e04db246fd0ae9c49841e4fec73e Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 8 Mar 2020 23:18:09 +0100 Subject: [PATCH 093/104] Add basic compliment on a specific day of the year --- modules/default/compliments/compliments.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 606da1df..c137a379 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -28,7 +28,10 @@ Module.register("compliments", { "Wow, you look hot!", "You look nice!", "Hi, sexy!" - ] + ], + date: [ + ["12-10", "Happy birthday, Ada Lovelace!"] + ], }, updateInterval: 30000, remoteFile: null, @@ -102,6 +105,8 @@ Module.register("compliments", { */ complimentArray: function() { var hour = moment().hour(); + var year = moment().year(); + var today = moment(new Date()); var compliments; if (hour >= this.config.morningStartTime && hour < this.config.morningEndTime && this.config.compliments.hasOwnProperty("morning")) { @@ -122,6 +127,12 @@ Module.register("compliments", { compliments.push.apply(compliments, this.config.compliments.anytime); + this.config.compliments.date.forEach(d => { + if (today.isSame(year + "-" + d[0], "month")) { + compliments.push(d[1]); + } + }); + return compliments; }, From cafa4211a657b454f631e2755aacabd1c92bab70 Mon Sep 17 00:00:00 2001 From: rejas Date: Mon, 9 Mar 2020 18:24:27 +0100 Subject: [PATCH 094/104] Update changelog and add another birtday --- CHANGELOG.md | 1 + modules/default/compliments/compliments.js | 1 + 2 files changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b7f5572..6be1c1a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). - Run tests on long term support and latest stable version of nodejs - Added the ability to configure a list of modules that shouldn't be update checked. - Run linters on git commits +- Added date functionality to compliments: display birthday wishes or celebrate an anniversary ### Fixed - Force declaration of public ip address in config file (ISSUE #1852) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index c137a379..6a2fca2c 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -30,6 +30,7 @@ Module.register("compliments", { "Hi, sexy!" ], date: [ + ["03-14", "Happy birthday, Albert Einstein!"], ["12-10", "Happy birthday, Ada Lovelace!"] ], }, From 2a31ece0c691a3b6ae73fec60766e0ebccc36c85 Mon Sep 17 00:00:00 2001 From: rejas Date: Tue, 10 Mar 2020 10:45:09 +0100 Subject: [PATCH 095/104] Refactor code --- modules/default/compliments/compliments.js | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 6a2fca2c..3ccf742e 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -29,10 +29,12 @@ Module.register("compliments", { "You look nice!", "Hi, sexy!" ], - date: [ - ["03-14", "Happy birthday, Albert Einstein!"], - ["12-10", "Happy birthday, Ada Lovelace!"] + 1403 : [ + "Happy birthday, Albert Einstein!" ], + 1012: [ + "Happy birthday, Ada Lovelace!" + ] }, updateInterval: 30000, remoteFile: null, @@ -106,8 +108,7 @@ Module.register("compliments", { */ complimentArray: function() { var hour = moment().hour(); - var year = moment().year(); - var today = moment(new Date()); + var date = moment().format("DDMM"); var compliments; if (hour >= this.config.morningStartTime && hour < this.config.morningEndTime && this.config.compliments.hasOwnProperty("morning")) { @@ -128,11 +129,9 @@ Module.register("compliments", { compliments.push.apply(compliments, this.config.compliments.anytime); - this.config.compliments.date.forEach(d => { - if (today.isSame(year + "-" + d[0], "month")) { - compliments.push(d[1]); - } - }); + if (date in this.config.compliments) { + compliments.push.apply(compliments, this.config.compliments[date]); + } return compliments; }, From b08f8823247328b51e44192a2f8ac9738c2c6cbf Mon Sep 17 00:00:00 2001 From: rejas Date: Sat, 14 Mar 2020 21:14:45 +0100 Subject: [PATCH 096/104] Add (failing) test for new date field --- .../modules/compliments/compliments_date.js | 40 +++++++++++++++++++ tests/e2e/modules/compliments_spec.js | 37 +++++++++++++++++ 2 files changed, 77 insertions(+) create mode 100644 tests/configs/modules/compliments/compliments_date.js diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js new file mode 100644 index 00000000..04acdde4 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_date.js @@ -0,0 +1,40 @@ +/* Magic Mirror Test config compliments with date type + * + * By Rejas + * + * MIT Licensed. + */ + +let config = { + port: 8080, + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], + + language: "en", + timeFormat: 12, + units: "metric", + electronOptions: { + webPreferences: { + nodeIntegration: true, + }, + }, + + modules: [ + { + module: "compliments", + position: "middle_center", + config: { + compliments: { + morning: [], + afternoon: [], + evening: [], + 1012: [ + "Happy birthday, Ada Lovelace!" + ] + } + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") {module.exports = config;} diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 35529b19..68dcb7ff 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -1,5 +1,6 @@ const helpers = require("../global-setup"); const expect = require("chai").expect; +const moment = require("moment"); const describe = global.describe; const it = global.it; @@ -89,4 +90,40 @@ describe("Compliments module", function() { }); }); }); + + describe("Feature date in compliments module", function() { + describe("Set date and empty compliments for anytime, morning, evening and afternoon", function() { + let RealDate; + + before(function() { + // Set config sample for use in test + process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_date.js"; + + RealDate = Date; + let customTimeMs = moment("2015-10-12T06:00:00.000Z").valueOf(); + + function MockDate() { + return new RealDate(customTimeMs); + } + + MockDate.now = function () { + return new MockDate().valueOf(); + }; + + MockDate.prototype = RealDate.prototype; + + Date = MockDate; + }); + + 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(["Happy birthday, Ada Lovelace!"]); + }); + }); + + after(function() { + Date = RealDate; + }); + }); + }); }); From e2427fe29901cd24bcd11ffb7023439c4d468f7a Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 15 Mar 2020 09:11:55 +0100 Subject: [PATCH 097/104] Try out a mockdate class --- tests/e2e/modules/compliments_spec.js | 24 ++------ tests/e2e/modules/mocks/date.js | 86 +++++++++++++++++++++++++++ 2 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 tests/e2e/modules/mocks/date.js diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 68dcb7ff..2ebd2e82 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -1,6 +1,6 @@ const helpers = require("../global-setup"); const expect = require("chai").expect; -const moment = require("moment"); +const MockDate = require("./mocks/date.js"); const describe = global.describe; const it = global.it; @@ -93,36 +93,20 @@ describe("Compliments module", function() { describe("Feature date in compliments module", function() { describe("Set date and empty compliments for anytime, morning, evening and afternoon", function() { - let RealDate; - before(function() { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_date.js"; - - RealDate = Date; - let customTimeMs = moment("2015-10-12T06:00:00.000Z").valueOf(); - - function MockDate() { - return new RealDate(customTimeMs); - } - - MockDate.now = function () { - return new MockDate().valueOf(); - }; - - MockDate.prototype = RealDate.prototype; - - Date = MockDate; + MockDate.set("2000-12-10"); }); - it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function() { + it("Show happy birthday compliment on special date", function() { return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { expect(text).to.be.oneOf(["Happy birthday, Ada Lovelace!"]); }); }); after(function() { - Date = RealDate; + MockDate.reset(); }); }); }); diff --git a/tests/e2e/modules/mocks/date.js b/tests/e2e/modules/mocks/date.js new file mode 100644 index 00000000..ff33f2e6 --- /dev/null +++ b/tests/e2e/modules/mocks/date.js @@ -0,0 +1,86 @@ +(function(name, definition) { + if (typeof module !== 'undefined') module.exports = definition(); + else if (typeof define === 'function' && typeof define.amd === 'object') define(definition); + else this[name] = definition(); +}('MockDate', function() { + "use strict"; + + var _Date = Date + , _getTimezoneOffset = Date.prototype.getTimezoneOffset + , now = null + ; + + function MockDate(y, m, d, h, M, s, ms) { + var date; + + switch (arguments.length) { + + case 0: + if (now !== null) { + date = new _Date(now); + } else { + date = new _Date(); + } + break; + + case 1: + date = new _Date(y); + break; + + default: + d = typeof d === 'undefined' ? 1 : d; + h = h || 0; + M = M || 0; + s = s || 0; + ms = ms || 0; + date = new _Date(y, m, d, h, M, s, ms); + break; + } + + return date; + } + + MockDate.UTC = _Date.UTC; + + MockDate.now = function() { + return new MockDate().valueOf(); + }; + + MockDate.parse = function(dateString) { + return _Date.parse(dateString); + }; + + MockDate.toString = function() { + return _Date.toString(); + }; + + MockDate.prototype = _Date.prototype; + + function set(date, timezoneOffset) { + var dateObj = new Date(date) + if (isNaN(dateObj.getTime())) { + throw new TypeError('mockdate: The time set is an invalid date: ' + date) + } + + if (typeof timezoneOffset === 'number') { + MockDate.prototype.getTimezoneOffset = function() { + return timezoneOffset; + } + } + + Date = MockDate; + + now = dateObj.valueOf(); + } + + function reset() { + Date = _Date; + Date.prototype.getTimezoneOffset = _getTimezoneOffset + } + + return { + set: set, + reset: reset + }; + +})); From 65e1b60fb7bc773cb60041080e8966e8e6bd53ad Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 15 Mar 2020 09:49:32 +0100 Subject: [PATCH 098/104] Fix error when no compliments are set --- modules/default/compliments/compliments.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 3ccf742e..7b2fa74a 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -162,19 +162,19 @@ Module.register("compliments", { // get the current time of day compliments list var compliments = this.complimentArray(); // variable for index to next message to display - let index=0; + let index = 0; // are we randomizing if(this.config.random){ // yes index = this.randomIndex(compliments); } else{ - // no, sequetial - // if doing sequential, don't fall off the end + // no, sequential + // if doing sequential, don't fall off the end index = (this.lastIndexUsed >= (compliments.length-1))?0: ++this.lastIndexUsed; } - return compliments[index]; + return compliments[index] || ""; }, // Override dom generator. @@ -184,9 +184,9 @@ Module.register("compliments", { // get the compliment text var complimentText = this.randomCompliment(); // split it into parts on newline text - var parts= complimentText.split("\n"); + var parts = complimentText.split("\n"); // create a span to hold it all - var compliment=document.createElement("span"); + var compliment = document.createElement("span"); // process all the parts of the compliment text for (part of parts){ // create a text element for each part From 3659b5b5c97efbf0298f6a7ed5e8b0fcf643bff6 Mon Sep 17 00:00:00 2001 From: rejas Date: Sun, 15 Mar 2020 10:20:20 +0100 Subject: [PATCH 099/104] Update mockdate info --- tests/e2e/modules/mocks/date.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/e2e/modules/mocks/date.js b/tests/e2e/modules/mocks/date.js index ff33f2e6..b254e1da 100644 --- a/tests/e2e/modules/mocks/date.js +++ b/tests/e2e/modules/mocks/date.js @@ -1,3 +1,10 @@ +/** + * MockDate + * + * By Bob Lauer (https://github.com/boblauer/MockDate + * MIT Licensed. +*/ + (function(name, definition) { if (typeof module !== 'undefined') module.exports = definition(); else if (typeof define === 'function' && typeof define.amd === 'object') define(definition); From 4e4d3418b365b1c639a344f7512e9eaea0a92ec6 Mon Sep 17 00:00:00 2001 From: rejas Date: Wed, 25 Mar 2020 06:53:09 +0100 Subject: [PATCH 100/104] LInt mockdate helper --- tests/e2e/modules/mocks/date.js | 128 ++++++++++++++++---------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/tests/e2e/modules/mocks/date.js b/tests/e2e/modules/mocks/date.js index b254e1da..35113566 100644 --- a/tests/e2e/modules/mocks/date.js +++ b/tests/e2e/modules/mocks/date.js @@ -6,88 +6,88 @@ */ (function(name, definition) { - if (typeof module !== 'undefined') module.exports = definition(); - else if (typeof define === 'function' && typeof define.amd === 'object') define(definition); - else this[name] = definition(); -}('MockDate', function() { - "use strict"; + if (typeof module !== "undefined") {module.exports = definition();} + else if (typeof define === "function" && typeof define.amd === "object") {define(definition);} + else {this[name] = definition();} +}("MockDate", function() { + "use strict"; - var _Date = Date - , _getTimezoneOffset = Date.prototype.getTimezoneOffset - , now = null + var _Date = Date + , _getTimezoneOffset = Date.prototype.getTimezoneOffset + , now = null ; - function MockDate(y, m, d, h, M, s, ms) { - var date; + function MockDate(y, m, d, h, M, s, ms) { + var date; - switch (arguments.length) { + switch (arguments.length) { - case 0: - if (now !== null) { - date = new _Date(now); - } else { - date = new _Date(); - } - break; + case 0: + if (now !== null) { + date = new _Date(now); + } else { + date = new _Date(); + } + break; - case 1: - date = new _Date(y); - break; + case 1: + date = new _Date(y); + break; - default: - d = typeof d === 'undefined' ? 1 : d; - h = h || 0; - M = M || 0; - s = s || 0; - ms = ms || 0; - date = new _Date(y, m, d, h, M, s, ms); - break; - } + default: + d = typeof d === "undefined" ? 1 : d; + h = h || 0; + M = M || 0; + s = s || 0; + ms = ms || 0; + date = new _Date(y, m, d, h, M, s, ms); + break; + } - return date; - } + return date; + } - MockDate.UTC = _Date.UTC; + MockDate.UTC = _Date.UTC; - MockDate.now = function() { - return new MockDate().valueOf(); - }; + MockDate.now = function() { + return new MockDate().valueOf(); + }; - MockDate.parse = function(dateString) { - return _Date.parse(dateString); - }; + MockDate.parse = function(dateString) { + return _Date.parse(dateString); + }; - MockDate.toString = function() { - return _Date.toString(); - }; + MockDate.toString = function() { + return _Date.toString(); + }; - MockDate.prototype = _Date.prototype; + MockDate.prototype = _Date.prototype; - function set(date, timezoneOffset) { - var dateObj = new Date(date) - if (isNaN(dateObj.getTime())) { - throw new TypeError('mockdate: The time set is an invalid date: ' + date) - } + function set(date, timezoneOffset) { + var dateObj = new Date(date); + if (isNaN(dateObj.getTime())) { + throw new TypeError("mockdate: The time set is an invalid date: " + date); + } - if (typeof timezoneOffset === 'number') { - MockDate.prototype.getTimezoneOffset = function() { - return timezoneOffset; - } - } + if (typeof timezoneOffset === "number") { + MockDate.prototype.getTimezoneOffset = function() { + return timezoneOffset; + }; + } - Date = MockDate; + Date = MockDate; - now = dateObj.valueOf(); - } + now = dateObj.valueOf(); + } - function reset() { - Date = _Date; - Date.prototype.getTimezoneOffset = _getTimezoneOffset - } + function reset() { + Date = _Date; + Date.prototype.getTimezoneOffset = _getTimezoneOffset; + } - return { - set: set, - reset: reset - }; + return { + set: set, + reset: reset + }; })); From ff7dc95e93c46599949b3bae93e8ca0f6622c935 Mon Sep 17 00:00:00 2001 From: rejas Date: Sat, 28 Mar 2020 09:24:30 +0100 Subject: [PATCH 101/104] Implement suggestions from Michael --- modules/default/compliments/compliments.js | 19 ++++++++++++------- .../modules/compliments/compliments_date.js | 4 ++-- tests/e2e/modules/compliments_spec.js | 6 +++--- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 7b2fa74a..14ad67dc 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -29,11 +29,14 @@ Module.register("compliments", { "You look nice!", "Hi, sexy!" ], - 1403 : [ - "Happy birthday, Albert Einstein!" + "....-01-01": [ + "Happy new year!" ], - 1012: [ - "Happy birthday, Ada Lovelace!" + "....-..-14": [ + "Have a great 14th day of the month!" + ], + "2020-12-10": [ + "Happy 205th Birthday, Ada Lovelace!" ] }, updateInterval: 30000, @@ -108,7 +111,7 @@ Module.register("compliments", { */ complimentArray: function() { var hour = moment().hour(); - var date = moment().format("DDMM"); + var date = moment().format("YYYY-MM-DD"); var compliments; if (hour >= this.config.morningStartTime && hour < this.config.morningEndTime && this.config.compliments.hasOwnProperty("morning")) { @@ -129,8 +132,10 @@ Module.register("compliments", { compliments.push.apply(compliments, this.config.compliments.anytime); - if (date in this.config.compliments) { - compliments.push.apply(compliments, this.config.compliments[date]); + for (entry in this.config.compliments) { + if (new RegExp(entry).test(date)) { + compliments.push.apply(compliments, this.config.compliments[entry]); + } } return compliments; diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js index 04acdde4..649d789b 100644 --- a/tests/configs/modules/compliments/compliments_date.js +++ b/tests/configs/modules/compliments/compliments_date.js @@ -27,8 +27,8 @@ let config = { morning: [], afternoon: [], evening: [], - 1012: [ - "Happy birthday, Ada Lovelace!" + "....-01-01": [ + "Happy new year!" ] } } diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 2ebd2e82..d7828268 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -96,12 +96,12 @@ describe("Compliments module", function() { before(function() { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_date.js"; - MockDate.set("2000-12-10"); + MockDate.set("2000-01-01"); }); - it("Show happy birthday compliment on special date", function() { + it("Show happy new year compliment on new years day", function() { return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { - expect(text).to.be.oneOf(["Happy birthday, Ada Lovelace!"]); + expect(text).to.be.oneOf(["Happy new year!"]); }); }); From 2674bf22d8188ac0e1aec7d87e0470ed8bf2c777 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Wed, 1 Apr 2020 09:44:22 +0200 Subject: [PATCH 102/104] Let's use sensible defaults. :) --- modules/default/compliments/compliments.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 14ad67dc..ca275d27 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -31,12 +31,6 @@ Module.register("compliments", { ], "....-01-01": [ "Happy new year!" - ], - "....-..-14": [ - "Have a great 14th day of the month!" - ], - "2020-12-10": [ - "Happy 205th Birthday, Ada Lovelace!" ] }, updateInterval: 30000, From 2464d0189169faa4f3c645146d964b11e2b4c2fd Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Wed, 1 Apr 2020 10:57:50 +0200 Subject: [PATCH 103/104] Fix date test. --- modules/default/compliments/compliments.js | 5 +- .../modules/compliments/compliments_date.js | 1 + tests/e2e/modules/compliments_spec.js | 6 -- tests/e2e/modules/mocks/date.js | 93 ------------------- 4 files changed, 4 insertions(+), 101 deletions(-) delete mode 100644 tests/e2e/modules/mocks/date.js diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index ca275d27..bf7bca9f 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -40,7 +40,8 @@ Module.register("compliments", { morningEndTime: 12, afternoonStartTime: 12, afternoonEndTime: 17, - random: true + random: true, + mockDate: null }, lastIndexUsed:-1, // Set currentweather from module @@ -105,7 +106,7 @@ Module.register("compliments", { */ complimentArray: function() { var hour = moment().hour(); - var date = moment().format("YYYY-MM-DD"); + var date = this.config.mockDate ? this.config.mockDate : moment().format("YYYY-MM-DD"); var compliments; if (hour >= this.config.morningStartTime && hour < this.config.morningEndTime && this.config.compliments.hasOwnProperty("morning")) { diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js index 649d789b..7ea984b1 100644 --- a/tests/configs/modules/compliments/compliments_date.js +++ b/tests/configs/modules/compliments/compliments_date.js @@ -23,6 +23,7 @@ let config = { module: "compliments", position: "middle_center", config: { + mockDate: "2020-01-01", compliments: { morning: [], afternoon: [], diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index d7828268..97fd0ed9 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -1,6 +1,5 @@ const helpers = require("../global-setup"); const expect = require("chai").expect; -const MockDate = require("./mocks/date.js"); const describe = global.describe; const it = global.it; @@ -96,7 +95,6 @@ describe("Compliments module", function() { before(function() { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_date.js"; - MockDate.set("2000-01-01"); }); it("Show happy new year compliment on new years day", function() { @@ -104,10 +102,6 @@ describe("Compliments module", function() { expect(text).to.be.oneOf(["Happy new year!"]); }); }); - - after(function() { - MockDate.reset(); - }); }); }); }); diff --git a/tests/e2e/modules/mocks/date.js b/tests/e2e/modules/mocks/date.js deleted file mode 100644 index 35113566..00000000 --- a/tests/e2e/modules/mocks/date.js +++ /dev/null @@ -1,93 +0,0 @@ -/** - * MockDate - * - * By Bob Lauer (https://github.com/boblauer/MockDate - * MIT Licensed. -*/ - -(function(name, definition) { - if (typeof module !== "undefined") {module.exports = definition();} - else if (typeof define === "function" && typeof define.amd === "object") {define(definition);} - else {this[name] = definition();} -}("MockDate", function() { - "use strict"; - - var _Date = Date - , _getTimezoneOffset = Date.prototype.getTimezoneOffset - , now = null - ; - - function MockDate(y, m, d, h, M, s, ms) { - var date; - - switch (arguments.length) { - - case 0: - if (now !== null) { - date = new _Date(now); - } else { - date = new _Date(); - } - break; - - case 1: - date = new _Date(y); - break; - - default: - d = typeof d === "undefined" ? 1 : d; - h = h || 0; - M = M || 0; - s = s || 0; - ms = ms || 0; - date = new _Date(y, m, d, h, M, s, ms); - break; - } - - return date; - } - - MockDate.UTC = _Date.UTC; - - MockDate.now = function() { - return new MockDate().valueOf(); - }; - - MockDate.parse = function(dateString) { - return _Date.parse(dateString); - }; - - MockDate.toString = function() { - return _Date.toString(); - }; - - MockDate.prototype = _Date.prototype; - - function set(date, timezoneOffset) { - var dateObj = new Date(date); - if (isNaN(dateObj.getTime())) { - throw new TypeError("mockdate: The time set is an invalid date: " + date); - } - - if (typeof timezoneOffset === "number") { - MockDate.prototype.getTimezoneOffset = function() { - return timezoneOffset; - }; - } - - Date = MockDate; - - now = dateObj.valueOf(); - } - - function reset() { - Date = _Date; - Date.prototype.getTimezoneOffset = _getTimezoneOffset; - } - - return { - set: set, - reset: reset - }; - -})); From 46df59d77aa4a0f5d4cdd82f2dcdb2f9cf963c0b Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Wed, 1 Apr 2020 11:52:39 +0200 Subject: [PATCH 104/104] Prepare release 2.11.0 --- CHANGELOG.md | 8 +- package-lock.json | 543 +++++++++++++++++++--------------------------- package.json | 2 +- 3 files changed, 230 insertions(+), 323 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a80d8883..0c952791 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,9 +5,13 @@ This project adheres to [Semantic Versioning](http://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² -## [2.11.0] - Unreleased (Develop Branch) +## [2.11.0] - 2020-04-01 -*This release is scheduled to be released on 2020-04-01.* +🚨 READ THIS BEFORE UPDATING 🚨 + +In the past years the project has grown a lot. This came with a huge downside: poor maintainability. If I let the project continue the way it was, it would eventually crash and burn. More important: I would completely lose the drive and interest to continue the project. Because of this the decision was made to simplify the core by removing all side features like automatic installers and support for exotic platforms. This release (2.11.0) is the first real release that will reflect (parts) of these changes. As a result of this, some things might break. So before you continue make sure to backup your installation. Your config, your modules or better yet: your full MagicMirror folder. In other words: update at your own risk. + +For more information regarding this major change, please check issue [#1860](https://github.com/MichMich/MagicMirror/issues/1860). ### Deleted - Remove installers. diff --git a/package-lock.json b/package-lock.json index b7c363b5..319f0d90 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.11.0-develop", + "version": "2.11.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -14,22 +14,23 @@ } }, "@babel/core": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.8.7.tgz", - "integrity": "sha512-rBlqF3Yko9cynC5CCFy6+K/w2N+Sq/ff2BPy+Krp7rHlABIr5epbA7OxVeKoMHB39LZOp1UY5SuLjy6uWi35yA==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.9.0.tgz", + "integrity": "sha512-kWc7L0fw1xwvI0zi8OKVBuxRVefwGOrKSQMvrQ3dW+bIIavBY3/NpXmpjMy7bQnLgwgzWQZ8TlM57YHpHNHz4w==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.7", - "@babel/helpers": "^7.8.4", - "@babel/parser": "^7.8.7", + "@babel/generator": "^7.9.0", + "@babel/helper-module-transforms": "^7.9.0", + "@babel/helpers": "^7.9.0", + "@babel/parser": "^7.9.0", "@babel/template": "^7.8.6", - "@babel/traverse": "^7.8.6", - "@babel/types": "^7.8.7", + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", - "json5": "^2.1.0", + "json5": "^2.1.2", "lodash": "^4.17.13", "resolve": "^1.3.2", "semver": "^5.4.1", @@ -46,14 +47,20 @@ } }, "json5": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.1.tgz", - "integrity": "sha512-l+3HXD0GEI3huGq1njuqtzYK8OYJyXMkOLtQ53pjWh89tvWS2h6l+1zMkYWqlb57+SiQodKZyvMEFb2X+KrFhQ==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", + "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", "dev": true, "requires": { - "minimist": "^1.2.0" + "minimist": "^1.2.5" } }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, "source-map": { "version": "0.5.7", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", @@ -63,12 +70,12 @@ } }, "@babel/generator": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.8.8.tgz", - "integrity": "sha512-HKyUVu69cZoclptr8t8U5b6sx6zoWjh8jiUhnuj3MpZuKT2dJ8zPTuiy31luq32swhI0SpwItCIlU8XW7BZeJg==", + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", + "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", "dev": true, "requires": { - "@babel/types": "^7.8.7", + "@babel/types": "^7.9.0", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -102,6 +109,70 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-member-expression-to-functions": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.8.3.tgz", + "integrity": "sha512-fO4Egq88utkQFjbPrSHGmGLFqmrshs11d46WI+WZDESt7Wu7wN2G2Iu+NMMZJFDOVRHAMIkB5SNh30NtwCA7RA==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-imports": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.8.3.tgz", + "integrity": "sha512-R0Bx3jippsbAEtzkpZ/6FIiuzOURPcMjHp+Z6xPe6DtApDJx+w7UYyOLanZqO8+wKR9G10s/FmHXvxaMd9s6Kg==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-module-transforms": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.9.0.tgz", + "integrity": "sha512-0FvKyu0gpPfIQ8EkxlrAydOWROdHpBmiCiRwLkUiBGhCUPRRbVD2/tm3sFr/c/GWFrQ/ffutGUAnx7V0FzT2wA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.8.3", + "@babel/helper-replace-supers": "^7.8.6", + "@babel/helper-simple-access": "^7.8.3", + "@babel/helper-split-export-declaration": "^7.8.3", + "@babel/template": "^7.8.6", + "@babel/types": "^7.9.0", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.8.3.tgz", + "integrity": "sha512-Kag20n86cbO2AvHca6EJsvqAd82gc6VMGule4HwebwMlwkpXuVqrNRj6CkCV2sKxgi9MyAUnZVnZ6lJ1/vKhHQ==", + "dev": true, + "requires": { + "@babel/types": "^7.8.3" + } + }, + "@babel/helper-replace-supers": { + "version": "7.8.6", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.8.6.tgz", + "integrity": "sha512-PeMArdA4Sv/Wf4zXwBKPqVj7n9UF/xg6slNRtZW84FM7JpE1CbG8B612FyM4cxrf4fMAMGO0kR7voy1ForHHFA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.8.3", + "@babel/helper-optimise-call-expression": "^7.8.3", + "@babel/traverse": "^7.8.6", + "@babel/types": "^7.8.6" + } + }, + "@babel/helper-simple-access": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.8.3.tgz", + "integrity": "sha512-VNGUDjx5cCWg4vvCTR8qQ7YJYZ+HBjxOgXEl7ounz+4Sn7+LMD3CFrCTEU6/qXKbA2nKg21CwhhBzO0RpRbdCw==", + "dev": true, + "requires": { + "@babel/template": "^7.8.3", + "@babel/types": "^7.8.3" + } + }, "@babel/helper-split-export-declaration": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz", @@ -111,15 +182,21 @@ "@babel/types": "^7.8.3" } }, + "@babel/helper-validator-identifier": { + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.9.0.tgz", + "integrity": "sha512-6G8bQKjOh+of4PV/ThDm/rRqlU7+IGoJuofpagU5GlEl29Vv0RGqqt86ZGRV8ZuSOY3o+8yXl5y782SMcG7SHw==", + "dev": true + }, "@babel/helpers": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.8.4.tgz", - "integrity": "sha512-VPbe7wcQ4chu4TDQjimHv/5tj73qz88o12EPkO2ValS2QiQS/1F2SsjyIGNnAD0vF/nZS6Cf9i+vW6HIlnaR8w==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", + "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", "dev": true, "requires": { "@babel/template": "^7.8.3", - "@babel/traverse": "^7.8.4", - "@babel/types": "^7.8.3" + "@babel/traverse": "^7.9.0", + "@babel/types": "^7.9.0" } }, "@babel/highlight": { @@ -165,15 +242,15 @@ } }, "@babel/parser": { - "version": "7.8.8", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.8.8.tgz", - "integrity": "sha512-mO5GWzBPsPf6865iIbzNE0AvkKF3NE+2S3eRUpE+FE07BOAkXh6G+GW/Pj01hhXjve1WScbaIO4UlY1JKeqCcA==", + "version": "7.9.4", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", + "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", "dev": true }, "@babel/runtime": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.8.7.tgz", - "integrity": "sha512-+AATMUFppJDw6aiR5NVPHqIQBlV/Pj8wY/EZH+lmvRdUo9xBaz/rF3alAwFJQavvKfeOlPE7oaaDHVbcySbCsg==", + "version": "7.9.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.9.2.tgz", + "integrity": "sha512-NE2DtOdufG7R5vnfQUTehdTfNycfUANEtCa9PssN9O/xmTzP4E08UI797ixaei6hBEVL9BI/PsdJS5x7mWoB9Q==", "dev": true, "requires": { "regenerator-runtime": "^0.13.4" @@ -199,17 +276,17 @@ } }, "@babel/traverse": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.8.6.tgz", - "integrity": "sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", + "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", "dev": true, "requires": { "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.8.6", + "@babel/generator": "^7.9.0", "@babel/helper-function-name": "^7.8.3", "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6", + "@babel/parser": "^7.9.0", + "@babel/types": "^7.9.0", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" @@ -233,12 +310,12 @@ } }, "@babel/types": { - "version": "7.8.7", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.8.7.tgz", - "integrity": "sha512-k2TreEHxFA4CjGkL+GYjRyx35W0Mr7DP5+9q6WMkyKXB+904bYmG40syjMFV0oLlhhFCwWl0vA0DyzTDkwAiJw==", + "version": "7.9.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", + "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", "dev": true, "requires": { - "esutils": "^2.0.2", + "@babel/helper-validator-identifier": "^7.9.0", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -317,9 +394,9 @@ "dev": true }, "@types/node": { - "version": "13.9.1", - "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.1.tgz", - "integrity": "sha512-E6M6N0blf/jiZx8Q3nb0vNaswQeEyn0XlupO+xN6DtJ6r6IT4nXrTry7zhIfYvFCl3/8Cu6WIysmUBKiqV0bqQ==", + "version": "13.9.8", + "resolved": "https://registry.npmjs.org/@types/node/-/node-13.9.8.tgz", + "integrity": "sha512-1WgO8hsyHynlx7nhP1kr0OFzsgKz5XDQL+Lfc3b1Q3qIln/n8cKD4m09NJ0+P1Rq7Zgnc7N0+SsMnoD1rEb0kA==", "dev": true }, "@types/normalize-package-data": { @@ -598,18 +675,18 @@ "dev": true }, "autoprefixer": { - "version": "9.7.4", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.4.tgz", - "integrity": "sha512-g0Ya30YrMBAEZk60lp+qfX5YQllG+S5W3GYCFvyHTvhOki0AEQJLPEcIuGRsqVwLi8FvXPVtwTGhfr38hVpm0g==", + "version": "9.7.5", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.5.tgz", + "integrity": "sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg==", "dev": true, "requires": { - "browserslist": "^4.8.3", - "caniuse-lite": "^1.0.30001020", + "browserslist": "^4.11.0", + "caniuse-lite": "^1.0.30001036", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.26", - "postcss-value-parser": "^4.0.2" + "postcss": "^7.0.27", + "postcss-value-parser": "^4.0.3" }, "dependencies": { "ansi-styles": { @@ -836,14 +913,15 @@ "dev": true }, "browserslist": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.9.1.tgz", - "integrity": "sha512-Q0DnKq20End3raFulq6Vfp1ecB9fh8yUNV55s8sekaDDeqBaCtWlRHCUdaWyUeSSBJM7IbM6HcsyaeYqgeDhnw==", + "version": "4.11.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz", + "integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001030", - "electron-to-chromium": "^1.3.363", - "node-releases": "^1.1.50" + "caniuse-lite": "^1.0.30001038", + "electron-to-chromium": "^1.3.390", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" } }, "btoa-lite": { @@ -937,9 +1015,9 @@ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, "caniuse-lite": { - "version": "1.0.30001035", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001035.tgz", - "integrity": "sha512-C1ZxgkuA4/bUEdMbU5WrGY4+UhMFFiXrgNAfxiMIqWgFTWfv/xsZCS2xEHT2LMq7xAZfuAnu6mcqyDl0ZR6wLQ==", + "version": "1.0.30001038", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001038.tgz", + "integrity": "sha512-zii9quPo96XfOiRD4TrfYGs+QsGZpb2cGiMAzPjtf/hpFgB6zCPZgJb7I1+EATeMw/o+lG8FyRAnI+CWStHcaQ==", "dev": true }, "caseless": { @@ -1048,12 +1126,6 @@ } } }, - "ci-info": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz", - "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==", - "dev": true - }, "clarinet": { "version": "0.12.4", "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.4.tgz", @@ -1178,12 +1250,6 @@ "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", "dev": true }, - "compare-versions": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-3.6.0.tgz", - "integrity": "sha512-W6Af2Iw1z4CB7q4uU4hv646dW9GQuBM+YpC0UvUCWSD8w90SJjp+ujJuXaEMtAXBtSqGfMPuFOVn4/+FlaqfBA==", - "dev": true - }, "component-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz", @@ -1728,18 +1794,18 @@ } }, "domhandler": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.3.0.tgz", - "integrity": "sha1-LeWaCCLVAn+r/28DLCsloqir5zg=", + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", "dev": true, "requires": { "domelementtype": "1" } }, "domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", "dev": true, "requires": { "dom-serializer": "0", @@ -1833,9 +1899,9 @@ } }, "electron-to-chromium": { - "version": "1.3.376", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.376.tgz", - "integrity": "sha512-cv/PYVz5szeMz192ngilmezyPNFkUjuynuL2vNdiqIrio440nfTDdc0JJU0TS2KHLSVCs9gBbt4CFqM+HcBnjw==", + "version": "1.3.392", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.392.tgz", + "integrity": "sha512-/hsgeVdReDsyTBE0aU9FRdh1wnNPrX3xlz3t61F+CJPOT+Umfi9DXHsCX85TEgWZQqlow0Rw44/4/jbU2Sqgkg==", "dev": true }, "emoji-regex": { @@ -2548,15 +2614,6 @@ "pinkie-promise": "^2.0.0" } }, - "find-versions": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-3.2.0.tgz", - "integrity": "sha512-P8WRou2S+oe222TOCHitLy8zj+SIsVJh52VP4lvXkaFVnOFFdoWv1H1Jjvel1aI6NCFOAaeAVm8qrI0odiLcww==", - "dev": true, - "requires": { - "semver-regex": "^2.0.0" - } - }, "findup-sync": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", @@ -2858,18 +2915,18 @@ } }, "gonzales-pe": { - "version": "4.2.4", - "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.2.4.tgz", - "integrity": "sha512-v0Ts/8IsSbh9n1OJRnSfa7Nlxi4AkXIsWB6vPept8FDbL4bXn3FNuxjYtO/nmBGu7GDkL9MFeGebeSu6l55EPQ==", + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", "dev": true, "requires": { - "minimist": "1.1.x" + "minimist": "^1.2.5" }, "dependencies": { "minimist": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.1.3.tgz", - "integrity": "sha1-O+39kaktOQFvz6ocaB6Pqhoe/ag=", + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", "dev": true } } @@ -2987,9 +3044,9 @@ } }, "grunt-jsonlint": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/grunt-jsonlint/-/grunt-jsonlint-2.1.1.tgz", - "integrity": "sha512-A3i+rKoYXvLaOSu75kkqQY8UXFXVIcPiuBKQJ7VVCx/8iA7c3IZnFEqkc6ZpU56zDyNLGYhZX2WT691PNSc70Q==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/grunt-jsonlint/-/grunt-jsonlint-2.1.2.tgz", + "integrity": "sha512-I80WQf6SaBA4Qpi+GYyah+sHIm3o34ETTawDKM9LDEE97vztZeKjGexuD4OG7wasFL5pLI0xTsc8Vm16/Z60QA==", "dev": true, "requires": { "@prantlf/jsonlint": "10.2.0" @@ -3328,6 +3385,48 @@ "integrity": "sha512-1qYz89hW3lFDEazhjW0yVAV87lw8lVkrJocr72XmBkMKsoSVJCQx3W8BXsC7hO2qAt8BoVjYjtAcZ9perqGnNg==", "dev": true }, + "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" + }, + "dependencies": { + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "string_decoder": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", + "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", + "dev": true, + "requires": { + "safe-buffer": "~5.2.0" + } + } + } + }, "http-auth": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/http-auth/-/http-auth-3.2.4.tgz", @@ -3406,76 +3505,6 @@ "debug": "^3.1.0" } }, - "husky": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.3.tgz", - "integrity": "sha512-VxTsSTRwYveKXN4SaH1/FefRJYCtx+wx04sSVcOpD7N2zjoHxa+cEJ07Qg5NmV3HAK+IRKOyNVpi2YBIVccIfQ==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "ci-info": "^2.0.0", - "compare-versions": "^3.5.1", - "cosmiconfig": "^6.0.0", - "find-versions": "^3.2.0", - "opencollective-postinstall": "^2.0.2", - "pkg-dir": "^4.2.0", - "please-upgrade-node": "^3.2.0", - "slash": "^3.0.0", - "which-pm-runs": "^1.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", - "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", - "dev": true, - "requires": { - "@types/color-name": "^1.1.1", - "color-convert": "^2.0.1" - } - }, - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "supports-color": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", - "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, "hyperlinker": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/hyperlinker/-/hyperlinker-1.0.0.tgz", @@ -5013,21 +5042,10 @@ "dev": true }, "node-releases": { - "version": "1.1.52", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.52.tgz", - "integrity": "sha512-snSiT1UypkgGt2wxPqS6ImEUICbNCMb31yaxWrOLXjhlt2z2/IBpaOxzONExqSm4y5oLnAqjjRWu+wsDzK5yNQ==", - "dev": true, - "requires": { - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } + "version": "1.1.53", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", + "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==", + "dev": true }, "nopt": { "version": "3.0.6", @@ -5204,12 +5222,6 @@ "mimic-fn": "^2.1.0" } }, - "opencollective-postinstall": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/opencollective-postinstall/-/opencollective-postinstall-2.0.2.tgz", - "integrity": "sha512-pVOEP16TrAO2/fjej1IdOyupJY8KDUM1CvsaScRbw6oddvpQoOfGk4ywha0HKKVAD6RkW4x6Q+tNBwhf3Bgpuw==", - "dev": true - }, "optimist": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", @@ -5507,75 +5519,26 @@ "integrity": "sha1-DPd1eml38b9/ajIge3CeN3OI6HQ=", "dev": true }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", "dev": true, "requires": { - "find-up": "^4.0.0" + "find-up": "^2.1.0" }, "dependencies": { "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "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": "^5.0.0", - "path-exists": "^4.0.0" + "locate-path": "^2.0.0" } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", - "dev": true } } }, - "please-upgrade-node": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", - "integrity": "sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==", - "dev": true, - "requires": { - "semver-compare": "^1.0.0" - } - }, "plur": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", @@ -5648,48 +5611,6 @@ "dev": true, "requires": { "htmlparser2": "^3.10.0" - }, - "dependencies": { - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "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.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - }, - "string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dev": true, - "requires": { - "safe-buffer": "~5.2.0" - } - } } }, "postcss-jsx": { @@ -6366,18 +6287,6 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=", - "dev": true - }, - "semver-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-2.0.0.tgz", - "integrity": "sha512-mUdIBBvdn0PLOeP3TEkMH7HHeUP3GjsXCwKarjv/kGmUFOYg1VqEemKhoQpWMu6X2I8kHeuVdGibLGkVK+/5Qw==", - "dev": true - }, "send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", @@ -7411,9 +7320,9 @@ "dev": true }, "meow": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-6.0.1.tgz", - "integrity": "sha512-kxGTFgT/b7/oSRSQsJ0qsT5IMU+bgZ1eAdSA3kIV7onkW0QWo/hL5RbGlMfvBjHJKPE1LaPX0kdecYFiqYWjUw==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.0.tgz", + "integrity": "sha512-iIAoeI01v6pmSfObAAWFoITAA4GgiT45m4SmJgoxtZfvI0fyZwhV4d0lTwiUXvAKIPlma05Feb2Xngl52Mj5Cg==", "dev": true, "requires": { "@types/minimist": "^1.2.0", @@ -7426,7 +7335,7 @@ "redent": "^3.0.0", "trim-newlines": "^3.0.0", "type-fest": "^0.8.1", - "yargs-parser": "^16.1.0" + "yargs-parser": "^18.1.1" } }, "p-limit": { @@ -7563,9 +7472,9 @@ "dev": true }, "yargs-parser": { - "version": "16.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-16.1.0.tgz", - "integrity": "sha512-H/V41UNZQPkUMIT5h5hiwg4QKIY1RPvoBV4XcjUbRM8Bk2oKqqyZ0DIEbTFZB0XjbtSPG8SAa/0DxCQmiRgzKg==", + "version": "18.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.2.tgz", + "integrity": "sha512-hlIPNR3IzC1YuL1c2UwwDKpXlNFBqD1Fswwh1khz5+d8Cq/8yc/Mn0i+rQXduu8hcrFKvO7Eryk+09NecTQAAQ==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -8190,9 +8099,9 @@ "dev": true }, "vfile-message": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.3.tgz", - "integrity": "sha512-qQg/2z8qnnBHL0psXyF72kCjb9YioIynvyltuNKFaUhRtqTIcIMP3xnBaPzirVZNuBrUe1qwFciSx2yApa4byw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", + "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", "dev": true, "requires": { "@types/unist": "^2.0.0", @@ -8290,12 +8199,6 @@ "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", "dev": true }, - "which-pm-runs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/which-pm-runs/-/which-pm-runs-1.0.0.tgz", - "integrity": "sha1-Zws6+8VS4LVd9rd4DKdGFfI60cs=", - "dev": true - }, "wide-align": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", @@ -8405,9 +8308,9 @@ "dev": true }, "yaml": { - "version": "1.8.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.2.tgz", - "integrity": "sha512-omakb0d7FjMo3R1D2EbTKVIk6dAVLRxFXdLZMEUToeAvuqgG/YuHMuQOZ5fgk+vQ8cx+cnGKwyg+8g8PNT0xQg==", + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.3.tgz", + "integrity": "sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw==", "dev": true, "requires": { "@babel/runtime": "^7.8.7" diff --git a/package.json b/package.json index 823624e5..317969ee 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.11.0-develop", + "version": "2.11.0", "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": {