diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..db01ad9e90 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,15 @@ +# editorconfig.org +root = true + +[*] +charset = utf-8 +end_of_line = lf +indent_size = 2 +indent_style = space +insert_final_newline = true +max_line_length = 250 +trim_trailing_whitespace = true + +[*.{js,json}] +indent_size = 4 +indent_style = tab diff --git a/.eslintignore b/.eslintignore index 7862c971cd..fa7668825a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,5 +1 @@ -vendor/* -!/vendor/vendor.js -!/modules/default/** -!/modules/node_helper -!/modules/node_helper/** +modules/default/calendar/vendor/* diff --git a/.eslintrc.json b/.eslintrc.json index e5aca76607..6d6839d6bc 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,20 +1,18 @@ { - "rules": { - "indent": ["error", "tab"], - "quotes": ["error", "double"], - "semi": ["error"], - "max-len": ["error", 250], - "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"] - }, + "extends": ["eslint:recommended", "plugin:prettier/recommended"], + "plugins": ["prettier"], "env": { "browser": true, - "node": true, - "es6": true + "es6": true, + "mocha": true, + "node": true + }, + "globals": { + "config": true, + "Log": true, + "MM": true, + "Module": true, + "moment": true }, "parserOptions": { "sourceType": "module", @@ -22,5 +20,11 @@ "ecmaFeatures": { "globalReturn": true } - } + }, + "rules": { + "prettier/prettier": "error", + "eqeqeq": "error", + "no-prototype-builtins": "off", + "no-unused-vars": "off" + } } diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 254458863d..92423b0be2 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -1,25 +1,24 @@ -Contribution Policy for MagicMirror² -==================================== +# Contribution Policy for MagicMirror² Thanks for contributing to MagicMirror²! We hold our code to standard, and these standards are documented below. -If you wish to run both linters, use `grunt` without any arguments. +If you wish to run our linters, use `npm run lint` without any arguments. ### JavaScript: Run ESLint -We use [ESLint](http://eslint.org) on our JavaScript files. +We use [ESLint](https://eslint.org) on our JavaScript files. Our ESLint configuration is in our .eslintrc.json and .eslintignore files. -To run ESLint, use `grunt eslint`. +To run ESLint, use `npm run lint:js`. ### CSS: Run StyleLint -We use [StyleLint](http://stylelint.io) to lint our CSS. Our configuration is in our .stylelintrc file. +We use [StyleLint](https://stylelint.io) to lint our CSS. Our configuration is in our .stylelintrc file. -To run StyleLint, use `grunt stylelint`. +To run StyleLint, use `npm run lint:style`. ### Submitting Issues @@ -30,7 +29,7 @@ Problems installing or configuring your MagicMirror? Check out: [https://forum.m 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). +**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. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 43d925972b..e3ececd664 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,28 +1,33 @@ ## 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 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 -Please make sure to only submit reproducible issues. You can safely remove everything above the 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). +**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 8 or later. -**MagicMirror Version**: Please let us now which version of MagicMirror you are running. It can be found in the `package.log` file. +**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. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index 1462d11127..28b7161685 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -7,8 +7,7 @@ pull request to send us your changes. This makes everyone's lives easier (including yours) and helps us out on the development team. Thanks! - -* Does the pull request solve a **related** issue? -* If so, can you reference the issue? -* What does the pull request accomplish? Use a list if needed. -* If it includes major visual changes please add screenshots. +- Does the pull request solve a **related** issue? +- If so, can you reference the issue? +- What does the pull request accomplish? Use a list if needed. +- If it includes major visual changes please add screenshots. diff --git a/.gitignore b/.gitignore index 96c1ab5ddd..c3cf9bdb2e 100644 --- a/.gitignore +++ b/.gitignore @@ -8,7 +8,6 @@ pids *.seed lib-cov coverage -.grunt .lock-wscript build/Release /node_modules/**/* @@ -78,4 +77,4 @@ Temporary Items *.rej *.bak -!/tests/node_modules/**/* \ No newline at end of file +!/tests/node_modules/**/* diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000000..e4a776578e --- /dev/null +++ b/.prettierignore @@ -0,0 +1,5 @@ +package-lock.json +/config/**/* +/modules/default/calendar/vendor/ical.js/**/* +/vendor/**/* +!/vendor/vendor.js diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000000..1518304d4c --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,3 @@ +{ + "trailingComma": "none" +} diff --git a/.stylelintrc.json b/.stylelintrc.json index db05c7132f..d450c732dc 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,5 +1,7 @@ { - "extends": "stylelint-config-standard", - "font-family-name-quotes": "double-where-recommended", - "block-no-empty": false + "extends": ["stylelint-prettier/recommended"], + "plugins": ["stylelint-prettier"], + "rules": { + "prettier/prettier": true + } } diff --git a/.travis.yml b/.travis.yml index 2f9f3690cb..b2c4ae0f99 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,13 +8,14 @@ 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 script: - - npm run test:lint + - npm run test:prettier + - npm run test:js + - npm run test:css - npm run test:e2e - npm run test:unit after_script: diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c952791e1..3b4ee497f9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,10 +1,49 @@ # MagicMirror² Change Log All notable changes to this project will be documented in this file. -This project adheres to [Semantic Versioning](http://semver.org/). +This project adheres to [Semantic Versioning](https://semver.org/). ❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/donate) With your help we can continue to improve the MagicMirror² +## [2.12.0] - 2020-07-01 + +Special thanks to the following contributors: @AndreKoepke, @andrezibaia, @bryanzzhu, @chamakura, @DarthBrento, @Ekristoffe, @khassel, @Legion2, @ndom91, @radokristof, @rejas, @XBCreepinJesus & @ZoneMR. + +ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. + +### Added + +- Added option to config the level of logging. +- Added prettier for an even cleaner codebase. +- Hide Sunrise/Sunset in Weather module. +- Hide Sunrise/Sunset in Current Weather module. +- Added Met Office DataHub (UK) provider. + +### Updated + +- Cleaned up alert module code. +- Cleaned up check_config code. +- Replaced grunt-based linters with their non-grunt equivalents. +- Switch to most of the eslint:recommended rules and fix warnings. +- Replaced insecure links with https ones. +- Cleaned up all "no-undef" warnings from eslint. +- Added location title wrapping for calendar module. +- Updated the BG translation. + +### Deleted + +- Removed truetype (ttf) fonts. + +### Fixed + +- The broken modules due to Socket.io change from last release. [#1973](https://github.com/MichMich/MagicMirror/issues/1973) +- Add backward compatibility for old module code in socketclient.js. [#1973](https://github.com/MichMich/MagicMirror/issues/1973) +- Support multiple instances of calendar module with different config. [#1109](https://github.com/MichMich/MagicMirror/issues/1109) +- Fix the use of "maxNumberOfDays" in the module "weatherforecast". [#2018](https://github.com/MichMich/MagicMirror/issues/2018) +- Throw error when check_config fails. [#1928](https://github.com/MichMich/MagicMirror/issues/1928) +- Bug fix related to 'maxEntries' not displaying Calendar events. [#2050](https://github.com/MichMich/MagicMirror/issues/2050) +- Updated ical library to latest version. [#1926](https://github.com/MichMich/MagicMirror/issues/1926) + ## [2.11.0] - 2020-04-01 🚨 READ THIS BEFORE UPDATING 🚨 @@ -14,11 +53,13 @@ In the past years the project has grown a lot. This came with a huge downside: p For more information regarding this major change, please check issue [#1860](https://github.com/MichMich/MagicMirror/issues/1860). ### Deleted + - Remove installers. - Remove externalized scripts. - Remove jshint dependency, instead eslint checks your config file now ### Added + - Brazilian translation for "FEELS". - Ukrainian translation. - Finnish translation for "PRECIP", "UPDATE_INFO_MULTIPLE" and "UPDATE_INFO_SINGLE". @@ -30,8 +71,10 @@ For more information regarding this major change, please check issue [#1860](htt - 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 +- Add HTTPS support for clientonly-mode. ### Fixed + - 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) @@ -42,6 +85,7 @@ For more information regarding this major change, please check issue [#1860](htt - Fix update checking skipping 3rd party modules the first time ### 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: @@ -55,6 +99,7 @@ For more information regarding this major change, please check issue [#1860](htt ## [2.10.1] - 2020-01-10 ### Changed + - Updated README.md: Added links to the official documentation website and remove links to broken installer. ## [2.10.0] - 2020-01-01 @@ -64,12 +109,14 @@ 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 + - Timestamps in log output. - Padding in dateheader mode of the calendar module. - New upgrade script to help users consume regular updates installers/upgrade-script.sh. - New script to help setup pm2, without install installers/fixuppm2.sh. ### Updated + - Updated lower bound of `lodash` and `helmet` dependencies for security patches. - Updated compliments.js to handle newline in text, as textfields to not interpolate contents. - Updated raspberry.sh installer script to handle new platform issues, split node/npm, pm2, and screen saver changes. @@ -78,6 +125,7 @@ Special thanks to @sdetweil for all his great contributions! - Only check for xwindows running if not on macOS. ### Fixed + - 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. @@ -90,18 +138,21 @@ 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`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md). ### Added + - Spanish translation for "PRECIP". - Adding a Malay (Malaysian) translation for MagicMirror². - Add test check URLs of vendors 200 and 404 HTTP CODE. - Add tests for new weather module and helper to stub ajax requests. ### Updated + - Updatenotification module: Display update notification for a limited (configurable) time. - Enabled e2e/vendor_spec.js tests. -- The css/custom.css will be rename after the next release. We've add into `run-start.sh` a instruction by GIT to ignore with `--skip-worktree` and `rm --cached`. [#1540](https://github.com/MichMich/MagicMirror/issues/1540) +- The css/custom.css will be renamed after the next release. We've added into `run-start.sh` an instruction by GIT to ignore with `--skip-worktree` and `rm --cached`. [#1540](https://github.com/MichMich/MagicMirror/issues/1540) - Disable sending of notification CLOCK_SECOND when displaySeconds is false. ### Fixed + - Updatenotification module: Properly handle race conditions, prevent crash. - Send `NEWS_FEED` notification also for the first news messages which are shown. - Fixed issue where weather module would not refresh data after a network or API outage. [#1722](https://github.com/MichMich/MagicMirror/issues/1722) @@ -113,6 +164,7 @@ 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`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md). ### Added + - Option to show event location in calendar - Finnish translation for "Feels" and "Weeks" - Russian translation for “Feels” @@ -132,13 +184,15 @@ Special thanks to @sdetweil for all his great contributions! - Added to `newsfeed.js`: in order to design the news article better with css, three more class-names were introduced: newsfeed-desc, newsfeed-desc, newsfeed-desc ### Updated + - English translation for "Feels" to "Feels like" -- Fixed the example calender url in `config.js.sample` +- Fixed the example calendar url in `config.js.sample` - Update `ical.js` to solve various calendar issues. - Update weather city list url [#1676](https://github.com/MichMich/MagicMirror/issues/1676) - Only update clock once per minute when seconds aren't shown ### Fixed + - Fixed uncaught exception, race condition on module update - Fixed issue [#1696](https://github.com/MichMich/MagicMirror/issues/1696), some ical files start date to not parse to date type - Allowance HTML5 autoplay-policy (policy is changed from Chrome 66 updates) @@ -150,6 +204,7 @@ Special thanks to @sdetweil for all his great contributions! - Updated the fetchedLocationName variable in currentweather.js so that city shows up in the header ### Updated installer + - give non-pi2+ users (pi0, odroid, jetson nano, mac, windows, ...) option to continue install - use current username vs hardcoded 'pi' to support non-pi install - check for npm installed. node install doesn't do npm anymore @@ -166,6 +221,7 @@ Fixed `package.json` version number. ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues running Electron, make sure your [Raspbian is up to date](https://www.raspberrypi.org/documentation/raspbian/updating.md). ### Added + - Italian translation for "Feels" - Basic Klingon (tlhIngan Hol) translations - Disabled the screensaver on raspbian with installation script @@ -179,12 +235,14 @@ Fixed `package.json` version number. - Add `name` config option for calendars to be sent along with event broadcasts ### Updated + - Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500) - Updated modernizr code in alert module, fixed a small typo there too - More verbose error message on console if the config is malformed - Updated installer script to install Node.js version 10.x ### Fixed + - Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503), [#1511](https://github.com/MichMich/MagicMirror/issues/1511). - Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MichMich/MagicMirror/issues/1285). - Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504). @@ -193,7 +251,7 @@ Fixed `package.json` version number. - Installation script problems with raspbian - Calendar: only show repeating count if the event is actually repeating [#1534](https://github.com/MichMich/MagicMirror/pull/1534) - Calendar: Fix exdate handling when multiple values are specified (comma separated) -- Calendar: Fix relative date handling for fulldate events, calculate difference always from start of day [#1572](https://github.com/MichMich/MagicMirror/issues/1572) +- Calendar: Fix relative date handling for fulldate events, calculate difference always from start of day [#1572](https://github.com/MichMich/MagicMirror/issues/1572) - Fix null dereference in moduleNeedsUpdate when the module isn't visible - Calendar: Fixed event end times by setting default calendarEndTime to "LT" (Local time format). [#1479] - Calendar: Fixed missing calendar fetchers after server process restarts [#1589](https://github.com/MichMich/MagicMirror/issues/1589) @@ -202,6 +260,7 @@ Fixed `package.json` version number. - Fix documentation of `useKMPHwind` option in currentweather ### New weather module + - Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499). - Dimmed loading indicator for weather forecast. - Implemented config option `decimalSymbol` [#1499](https://github.com/MichMich/MagicMirror/issues/1499). @@ -219,11 +278,13 @@ Fixed `package.json` version number. ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install`. If you are having issues updating, make sure you are running the latest version of Node. ### ✨ Experimental ✨ + - New default [module weather](modules/default/weather). This module will eventually replace the current `currentweather` and `weatherforecast` modules. The new module is still pretty experimental, but it's included so you can give it a try and help us improve this module. Please give us you feedback using [this forum post](https://forum.magicmirror.builders/topic/9335/default-weather-module-refactoring). A huge, huge, huge thanks to user @fewieden for all his hard work on the new `weather` module! ### Added + - Possibility to add classes to the cell of symbol, title and time of the events of calendar. - Font-awesome 5, still has 4 for backwards compatibility. - Missing `showEnd` in calendar documentation @@ -238,22 +299,25 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Documentation for the existing `scale` option in the Weather Forecast module. ### Fixed -- Allow to parse recurring calendar events where the start date is before 1900 + +- Allow parsing recurring calendar events where the start date is before 1900 - Fixed Polish translation for Single Update Info - Ignore entries with unparseable details in the calendar module - Bug showing FullDayEvents one day too long in calendar fixed - Bug in newsfeed when `removeStartTags` is used on the description [#1478](https://github.com/MichMich/MagicMirror/issues/1478) ### Updated + - The default calendar setting `showEnd` is changed to `false`. ### Changed -- The Weather Forecast module by default displays the ° symbol after every numeric value to be consistent with the Current Weather module. +- The Weather Forecast module by default displays the ° symbol after every numeric value to be consistent with the Current Weather module. ## [2.5.0] - 2018-10-01 ### Added + - Romanian translation for "Feels" - Support multi-line compliments - Simplified Chinese translation for "Feels" @@ -268,6 +332,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Support for showing end of events through config parameters showEnd and dateEndFormat ### Fixed + - Fixed gzip encoded calendar loading issue #1400. - Mixup between german and spanish translation for newsfeed. - Fixed close dates to be absolute, if no configured in the config.js - module Calendar @@ -313,11 +378,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add update translations for Português Brasileiro ### Changed + - Upgrade to Electron 2.0.0. - Remove yarn-or-npm which breaks production builds. - Invoke module suspend even if no dom content. [#1308](https://github.com/MichMich/MagicMirror/issues/1308) ### Fixed + - Fixed issue where wind chill could not be displayed in Fahrenheit. [#1247](https://github.com/MichMich/MagicMirror/issues/1247) - Fixed issues where a module crashes when it tries to dismiss a non existing alert. [#1240](https://github.com/MichMich/MagicMirror/issues/1240) - In default module currentWeather/currentWeather.js line 296, 300, self.config.animationSpeed can not be found because the notificationReceived function does not have "self" variable. @@ -330,6 +397,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MichMich/MagicMirror/issues/1263) ### Updated + - Updated Italian translation - Updated German translation - Updated Dutch translation @@ -337,6 +405,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ## [2.3.1] - 2018-04-01 ### Fixed + - Downgrade electron to 1.4.15 to solve the black screen issue.[#1243](https://github.com/MichMich/MagicMirror/issues/1243) ## [2.3.0] - 2018-04-01 @@ -347,7 +416,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add system notification `MODULE_DOM_CREATED` for notifying each module when their Dom has been fully loaded. - Add types for module. - Implement Danger.js to notify contributors when CHANGELOG.md is missing in PR. -- Allow to scroll in full page article view of default newsfeed module with gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures) +- Allow scrolling in full page article view of default newsfeed module with gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures) - Changed 'compliments.js' - update DOM if remote compliments are loaded instead of waiting one updateInterval to show custom compliments - Automated unit tests utils, deprecated, translator, cloneObject(lockstrings) - Automated integration tests translations @@ -357,6 +426,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add dc:date to parsing in newsfeed module, which allows parsing of more rss feeds. ### Changed + - Add link to GitHub repository which contains the respective Dockerfile. - Optimized automated unit tests cloneObject, cmpVersions - Update notifications use now translation templates instead of normal strings. @@ -364,6 +434,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Changed Electron dependency to v1.7.13. ### Fixed + - News article in fullscreen (iframe) is now shown in front of modules. - Forecast respects maxNumberOfDays regardless of endpoint. - Fix exception on translation of objects. @@ -381,6 +452,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ## [2.2.1] - 2018-01-01 ### Fixed + - Fixed linting errors. ## [2.2.0] - 2018-01-01 @@ -388,10 +460,12 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` ### Changed -- Calender week is now handled with a variable translation in order to move number language specific. + +- Calendar week is now handled with a variable translation in order to move number language specific. - Reverted the Electron dependency back to 1.4.15 since newer version don't seem to work on the Raspberry Pi very well. ### Added + - Add option to use [Nunjucks](https://mozilla.github.io/nunjucks/) templates in modules. (See `helloworld` module as an example.) - Add Bulgarian translations for MagicMirror² and Alert module. - Add graceful shutdown of modules by calling `stop` function of each `node_helper` on SIGINT before exiting. @@ -405,6 +479,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add option for decimal symbols other than the decimal point for temperature values in both default weather modules: WeatherForecast and CurrentWeather. ### Fixed + - Fixed issue with calendar module showing more than `maximumEntries` allows - WeatherForecast and CurrentWeather are now using HTTPS instead of HTTP - Correcting translation for Indonesian language @@ -415,9 +490,11 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` ### Changed + - Remove Roboto fonts files inside `fonts` and these are installed by npm install command. ### Added + - Add `clientonly` script to start only the electron client for a remote server. - Add symbol and color properties of event when `CALENDAR_EVENTS` notification is broadcasted from `default/calendar` module. - Add `.vscode/` folder to `.gitignore` to keep custom Visual Studio Code config out of git. @@ -434,6 +511,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add Slack badge to Readme. ### Updated + - Changed 'default.js' - listen on all attached interfaces by default. - Add execution of `npm list` after the test are ran in Travis CI. - Change hooks for the vendors e2e tests. @@ -442,6 +520,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Set version of the `express-ipfilter` on 0.3.1. ### Fixed + - Fixed issue with incorrect alignment of analog clock when displayed in the center column of the MM. - Fixed ipWhitelist behaviour to make empty whitelist ([]) allow any and all hosts access to the MM. - Fixed issue with calendar module where 'excludedEvents' count towards 'maximumEntries'. @@ -452,11 +531,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ## [2.1.2] - 2017-07-01 ### Changed + - Revert Docker related changes in favor of [docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror). All Docker images are outsourced. ([#856](https://github.com/MichMich/MagicMirror/pull/856)) - Change Docker base image (Debian + Node) to an arm based distro (AlpineARM + Node) ([#846](https://github.com/MichMich/MagicMirror/pull/846)) - Fix the dockerfile to have it running from the first time. ### Added + - Add in option to wrap long calendar events to multiple lines using `wrapEvents` configuration option. - Add test e2e `show title newsfeed` for newsfeed module. - Add task to check configuration file. @@ -475,11 +556,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Added Romanian translation. ### Updated + - Added missing keys to Polish translation. - Added missing key to German translation. - Added better translation with flexible word order to Finnish translation. ### Fixed + - Fix instruction in README for using automatically installer script. - Bug of duplicated compliments as described in [here](https://forum.magicmirror.builders/topic/2381/compliments-module-stops-cycling-compliments). - Fix double message about port when server is starting @@ -493,6 +576,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` ### Changed + - Add `anytime` group for Compliments module. - Compliments module can use remoteFile without default daytime arrays defined. - Installer: Use init config.js from config.js.sample. @@ -508,8 +592,9 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Restructured Test Suite. ### Added + - Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)). -- Calendar-specific support for `maximumEntries`, and ` maximumNumberOfDays`. +- Calendar-specific support for `maximumEntries`, and `maximumNumberOfDays`. - Add loaded function to modules, providing an async callback. - Made default newsfeed module aware of gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures) - Add use pm2 for manager process into Installer RaspberryPi script. @@ -550,11 +635,12 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Added a configurable Week section to the clock module. ### Fixed + - Update .gitignore to not ignore default modules folder. - Remove white flash on boot up. - Added `update` in Raspberry Pi installation script. - Fix an issue where the analog clock looked scrambled. ([#611](https://github.com/MichMich/MagicMirror/issues/611)) -- If units is set to imperial, the showRainAmount option of weatherforecast will show the correct unit. +- If units are set to imperial, the showRainAmount option of weatherforecast will show the correct unit. - Module currentWeather: check if temperature received from api is defined. - Fix an issue with module hidden status changing to `true` although lock string prevented showing it. - Fix newsfeed module bug (removeStartTags) @@ -566,6 +652,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` ### Added + - Finnish translation. - Danish translation. - Turkish translation. @@ -578,7 +665,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Module API: Method to overwrite the module's header. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#getheader) for more information. - Module API: Option to define the minimum MagicMirror version to run a module. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#requiresversion) for more information. - Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/calendar) for more information. -- Possibility to use the the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/weatherforecast) for more information. +- Possibility to use the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/weatherforecast) for more information. - Added option to show rain amount in the weatherforecast default module - Add module `updatenotification` to get an update whenever a new version is available. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information. - Add the ability to set timezone on the date display in the Clock Module @@ -586,7 +673,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Possibility to use currentweather for the compliments - Added option `disabled` for modules. - Added option `address` to set bind address. -- Added option `onlyTemp` for currentweather module to show show only current temperature and weather icon. +- Added option `onlyTemp` for currentweather module to show only current temperature and weather icon. - 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. @@ -596,6 +683,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add root_path for global vars ### Updated + - Modified translations for Frysk. - Modified core English translations. - Updated package.json as a result of Snyk security update. @@ -606,6 +694,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Modules are now secure, and Helmet is now used to prevent abuse of the Mirror's API. ### Fixed + - Solve an issue where module margins would appear when the first module of a section was hidden. - Solved visual display errors on chrome, if all modules in one of the right sections are hidden. - Global and Module default config values are no longer modified when setting config values. @@ -616,6 +705,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ## [2.0.5] - 2016-09-20 ### Added + - Added ability to remove tags from the beginning or end of newsfeed items in 'newsfeed.js'. - Added ability to define "the day after tomorrow" for calendar events (Definition for German and Dutch already included). - Added CII Badge (we are compliant with the CII Best Practices) @@ -623,11 +713,13 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add the ability to turn off and on the date display in the Clock Module ### Fixed + - Fix typo in installer. - Add message to unsupported Pi error to mention that Pi Zeros must use server only mode, as ARMv6 is unsupported. Closes #374. - Fix API url for weather API. ### Updated + - Force fullscreen when kioskmode is active. - Update the .github templates and information with more modern information. - Update the Gruntfile with a more functional StyleLint implementation. @@ -635,6 +727,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ## [2.0.4] - 2016-08-07 ### Added + - Brazilian Portuguese Translation. - Option to enable Kiosk mode. - Added ability to start the app with Dev Tools. @@ -642,6 +735,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Greek Translation ### Fixed + - Prevent `getModules()` selectors from returning duplicate entries. - Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337)) - Corrected grammar in `module.js` from 'suspend' to 'suspended'. @@ -650,55 +744,72 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MichMich/MagicMirror/issues/388)) ### Updated + - Updated package.json to fix possible vulnerabilities. (Using Snyk) - Updated weathericons - Updated default weatherforecast to work with the new icons. - More detailed error message in case config file couldn't be loaded. ## [2.0.3] - 2016-07-12 + ### Added + - Add max newsitems parameter to the newsfeed module. - Translations for Simplified Chinese, Traditional Chinese and Japanese. - Polish Translation - Add an analog clock in addition to the digital one. ### Fixed + - Edit Alert Module to display title & message if they are provided in the notification (Issue [#300](https://github.com/MichMich/MagicMirror/issues/300)) - Removed 'null' reference from updateModuleContent(). This fixes recent Edge and Internet Explorer browser displays (Issue [#319](https://github.com/MichMich/MagicMirror/issues/319)) ### Changed + - Added default string to calendar titleReplace. ## [2.0.2] - 2016-06-05 + ### Added + - Norwegian Translations (nb and nn) - Portuguese Translation - Swedish Translation ### Fixed + - Added reference to Italian Translation. - Added the missing NE translation to all languages. [#344](https://github.com/MichMich/MagicMirror/issues/344) - Added proper User-Agent string to calendar call. ### Changed + - Add option to use locationID in weather modules. ## [2.0.1] - 2016-05-18 + ### Added + - Changelog - Italian Translation ### Changed + - Improve the installer by fetching the latest Node.js without any 3rd party interferences. ## [2.0.0] - 2016-05-03 + ### Initial release of MagicMirror² + It includes (but is not limited to) the following features: + - Modular system allowing 3rd party plugins. - An Node/Electron based application taking away the need for external servers or browsers. - A complete development API documentation. - Small cute fairies that kiss you while you sleep. ## [1.0.0] - 2014-02-16 + ### Initial release of MagicMirror. -This was part of the blogpost: [http://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the](http://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the) + +This was part of the blogpost: [https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the](https://michaelteeuw.nl/post/83916869600/magic-mirror-part-vi-production-of-the) diff --git a/Gruntfile.js b/Gruntfile.js deleted file mode 100644 index 36a90c5eb1..0000000000 --- a/Gruntfile.js +++ /dev/null @@ -1,106 +0,0 @@ -module.exports = function(grunt) { - require("time-grunt")(grunt); - var fix = (grunt.option("env") || "lint") === "lint"; - grunt.initConfig({ - eslint: { - options: { - fix: fix, - configFile: ".eslintrc.json" - }, - target: [ - "js/*.js", - "modules/default/*.js", - "modules/default/*/*.js", - "serveronly/*.js", - "clientonly/*.js", - "*.js", - "tests/**/*.js", - "!modules/default/alert/notificationFx.js", - "!modules/default/alert/modernizr.custom.js", - "!modules/default/alert/classie.js", - "config/*", - "translations/translations.js", - "vendor/vendor.js" - ] - }, - stylelint: { - simple: { - options: { - fix: fix, - configFile: ".stylelintrc.json" - }, - src: [ - "css/main.css", - "modules/default/calendar/calendar.css", - "modules/default/clock/clock_styles.css", - "modules/default/currentweather/currentweather.css", - "modules/default/weatherforcast/weatherforcast.css" - ] - } - }, - jsonlint: { - main: { - src: [ - "package.json", - ".eslintrc.json", - ".stylelintrc.json", - "translations/*.json", - "modules/default/*/translations/*.json", - "vendor/package.json" - ], - options: { - reporter: "jshint" - } - } - }, - markdownlint: { - all: { - options: { - config: { - "default": true, - "line-length": false, - "blanks-around-headers": false, - "no-duplicate-header": false, - "no-inline-html": false, - "MD010": false, - "MD001": false, - "MD031": false, - "MD040": false, - "MD002": false, - "MD029": false, - "MD041": false, - "MD032": false, - "MD036": false, - "MD037": false, - "MD009": false, - "MD018": false, - "MD012": false, - "MD026": false, - "MD038": false, - "MD047": false - } - }, - src: [ - "README.md", - "CHANGELOG.md", - "LICENSE.md", - "modules/README.md", - "modules/default/**/*.md", - "!modules/default/calendar/vendor/ical.js/readme.md" - ] - } - }, - yamllint: { - all: [ - ".travis.yml" - ] - } - }); - grunt.loadNpmTasks("grunt-eslint"); - grunt.loadNpmTasks("grunt-stylelint"); - grunt.loadNpmTasks("grunt-jsonlint"); - grunt.loadNpmTasks("grunt-yamllint"); - grunt.loadNpmTasks("grunt-markdownlint"); - - grunt.registerTask("default", ["eslint", "stylelint", "jsonlint", "markdownlint", "yamllint"]); -}; diff --git a/LICENSE.md b/LICENSE.md index 07c1fb070d..ec13937f7c 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,5 +1,4 @@ -The MIT License (MIT) -===================== +# The MIT License (MIT) Copyright © 2016-2019 Michael Teeuw diff --git a/README.md b/README.md index 01f788861f..e09e2e34d4 100644 --- a/README.md +++ b/README.md @@ -4,19 +4,21 @@ Dependency Status devDependency Status - License + License Travis Known Vulnerabilities

-**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](http://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MichMich/MagicMirror/graphs/contributors). +**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](https://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MichMich/MagicMirror/graphs/contributors). -MagicMirror² focuses on a modular plugin system and uses [Electron](http://electron.atom.io/) as an application wrapper. So no more web server or browser installs necessary! +MagicMirror² focuses on a modular plugin system and uses [Electron](https://www.electronjs.org/) as an application wrapper. So no more web server or browser installs necessary! ## Documentation + For the full documentation including **[installation instructions](https://docs.magicmirror.builders/getting-started/installation.html)**, please visit our dedicated documentation website: [https://docs.magicmirror.builders](https://docs.magicmirror.builders). ## Links + - Website: [https://magicmirror.builders](https://magicmirror.builders) - Documentation: [https://docs.magicmirror.builders](https://docs.magicmirror.builders) - Forum: [https://forum.magicmirror.builders](https://forum.magicmirror.builders) @@ -28,7 +30,6 @@ For the full documentation including **[installation instructions](https://docs. Contributions of all kinds are welcome, not only in the form of code but also with regards bug reports and documentation. For the full contribution guidelines, check out: [https://docs.magicmirror.builders/getting-started/contributing.html](https://docs.magicmirror.builders/getting-started/contributing.html) - ## Enjoying MagicMirror? Consider a donation! MagicMirror² is opensource and free. That doesn't mean we don't need any money. diff --git a/clientonly/index.js b/clientonly/index.js index 6430b270cc..7d1c4fe3b3 100644 --- a/clientonly/index.js +++ b/clientonly/index.js @@ -18,6 +18,9 @@ ["address", "port"].forEach((key) => { config[key] = getCommandLineParameter(key, process.env[key.toUpperCase()]); }); + + // determine if "--use-tls"-flag was provided + config["tls"] = process.argv.indexOf("--use-tls") > 0; } function getServerConfig(url) { @@ -29,16 +32,16 @@ var configData = ""; // Gather incoming data - response.on("data", function(chunk) { + response.on("data", function (chunk) { configData += chunk; }); // Resolve promise at the end of the HTTP/HTTPS stream - response.on("end", function() { + response.on("end", function () { resolve(JSON.parse(configData)); }); }); - request.on("error", function(error) { + request.on("error", function (error) { reject(new Error(`Unable to read config from server (${url} (${error.message}`)); }); }); @@ -48,7 +51,7 @@ if (message !== undefined && typeof message === "string") { console.log(message); } else { - console.log("Usage: 'node clientonly --address 192.168.1.10 --port 8080'"); + console.log("Usage: 'node clientonly --address 192.168.1.10 --port 8080 [--use-tls]'"); } process.exit(code); } @@ -56,16 +59,18 @@ getServerAddress(); (config.address && config.port) || fail(); + var prefix = config.tls ? "https://" : "http://"; // Only start the client if a non-local server was provided if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].indexOf(config.address) === -1) { - getServerConfig(`http://${config.address}:${config.port}/config/`) + getServerConfig(`${prefix}${config.address}:${config.port}/config/`) .then(function (configReturn) { // Pass along the server config via an environment variable var env = Object.create(process.env); var options = { env: env }; configReturn.address = config.address; configReturn.port = config.port; + configReturn.tls = config.tls; env.config = JSON.stringify(configReturn); // Spawn electron application @@ -91,7 +96,6 @@ console.log(`There something wrong. The clientonly is not running code ${code}`); } }); - }) .catch(function (reason) { fail(`Unable to connect to server: (${reason})`); @@ -99,4 +103,4 @@ } else { fail(); } -}()); +})(); diff --git a/config/config.js.sample b/config/config.js.sample index 414054da96..a016419832 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -1,6 +1,6 @@ /* Magic Mirror Config Sample * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. * * For more information on how you can configure this file @@ -9,30 +9,33 @@ */ 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 or empty, is "localhost" + 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 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 : - // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], - // 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"], + basePath: "/", // The URL path where MagicMirror is hosted. If you are using a Reverse proxy + // you must set the sub path here. basePath must end with a / + 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 : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], + // 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, 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", + logLevel: ["INFO", "LOG", "WARN", "ERROR"], timeFormat: 24, units: "metric", // serverOnly: true/false/"local" , - // 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 + // 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: [ { @@ -88,7 +91,7 @@ var config = { feeds: [ { title: "New York Times", - url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml" + url: "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml" } ], showSourceTitle: true, @@ -98,7 +101,6 @@ var config = { } }, ] - }; /*************** DO NOT EDIT THE LINE BELOW ***************/ diff --git a/css/main.css b/css/main.css index 84f8c4d26b..bca48f9e82 100644 --- a/css/main.css +++ b/css/main.css @@ -177,10 +177,6 @@ sup { .region.top.center, .region.bottom.center { left: 50%; - -moz-transform: translateX(-50%); - -o-transform: translateX(-50%); - -webkit-transform: translateX(-50%); - -ms-transform: translateX(-50%); transform: translateX(-50%); } @@ -213,10 +209,6 @@ sup { .region.middle.center { width: 100%; text-align: center; - -moz-transform: translateY(-50%); - -o-transform: translateY(-50%); - -webkit-transform: translateY(-50%); - -ms-transform: translateY(-50%); transform: translateY(-50%); } diff --git a/fonts/package-lock.json b/fonts/package-lock.json index c05e7b0dcf..960e793a97 100644 --- a/fonts/package-lock.json +++ b/fonts/package-lock.json @@ -4,9 +4,9 @@ "lockfileVersion": 1, "dependencies": { "roboto-fontface": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.8.0.tgz", - "integrity": "sha512-ZYzRkETgBrdEGzL5JSKimvjI2CX7ioyZCkX2BpcfyjqI+079W0wHAyj5W4rIZMcDSOHgLZtgz1IdDi/vU77KEQ==" + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/roboto-fontface/-/roboto-fontface-0.10.0.tgz", + "integrity": "sha512-OlwfYEgA2RdboZohpldlvJ1xngOins5d7ejqnIBWr9KaMxsnBqotpptRXTyfNRLnFpqzX6sTDt+X+a+6udnU8g==" } } } diff --git a/fonts/package.json b/fonts/package.json index a4fb07dee2..7cea509bea 100644 --- a/fonts/package.json +++ b/fonts/package.json @@ -1,15 +1,15 @@ { - "name": "magicmirror-fonts", - "description": "Package for fonts use by MagicMirror Core.", - "repository": { - "type": "git", - "url": "git+https://github.com/MichMich/MagicMirror.git" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/MichMich/MagicMirror/issues" - }, - "dependencies": { - "roboto-fontface": "^0.8.0" - } + "name": "magicmirror-fonts", + "description": "Package for fonts use by MagicMirror Core.", + "repository": { + "type": "git", + "url": "git+https://github.com/MichMich/MagicMirror.git" + }, + "license": "MIT", + "bugs": { + "url": "https://github.com/MichMich/MagicMirror/issues" + }, + "dependencies": { + "roboto-fontface": "^0.10.0" + } } diff --git a/fonts/roboto.css b/fonts/roboto.css index 11d3f41de2..9bf4fbc990 100644 --- a/fonts/roboto.css +++ b/fonts/roboto.css @@ -2,94 +2,57 @@ font-family: Roboto; font-style: normal; font-weight: 100; - src: - local("Roboto Thin"), - local("Roboto-Thin"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.ttf") format("truetype"); + src: local("Roboto Thin"), local("Roboto-Thin"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Thin.woff") format("woff"); } @font-face { font-family: "Roboto Condensed"; font-style: normal; font-weight: 300; - src: - local("Roboto Condensed Light"), - local("RobotoCondensed-Light"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.ttf") format("truetype"); + src: local("Roboto Condensed Light"), local("RobotoCondensed-Light"), url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff2") format("woff2"), + url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Light.woff") format("woff"); } @font-face { font-family: "Roboto Condensed"; font-style: normal; font-weight: 400; - src: - local("Roboto Condensed"), - local("RobotoCondensed-Regular"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.ttf") format("truetype"); + src: local("Roboto Condensed"), local("RobotoCondensed-Regular"), url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff2") format("woff2"), + url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Regular.woff") format("woff"); } @font-face { font-family: "Roboto Condensed"; font-style: normal; font-weight: 700; - src: - local("Roboto Condensed Bold"), - local("RobotoCondensed-Bold"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.ttf") format("truetype"); + src: local("Roboto Condensed Bold"), local("RobotoCondensed-Bold"), url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff2") format("woff2"), + url("node_modules/roboto-fontface/fonts/roboto-condensed/Roboto-Condensed-Bold.woff") format("woff"); } @font-face { font-family: Roboto; font-style: normal; font-weight: 400; - src: - local("Roboto"), - local("Roboto-Regular"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.ttf") format("truetype"); + src: local("Roboto"), local("Roboto-Regular"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff") format("woff"); } @font-face { font-family: Roboto; font-style: normal; font-weight: 500; - src: - local("Roboto Medium"), - local("Roboto-Medium"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.ttf") format("truetype"); + src: local("Roboto Medium"), local("Roboto-Medium"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Medium.woff") format("woff"); } @font-face { font-family: Roboto; font-style: normal; font-weight: 700; - src: - local("Roboto Bold"), - local("Roboto-Bold"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.ttf") format("truetype"); + src: local("Roboto Bold"), local("Roboto-Bold"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Bold.woff") format("woff"); } @font-face { font-family: Roboto; font-style: normal; font-weight: 300; - src: - local("Roboto Light"), - local("Roboto-Light"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff"), - url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.ttf") format("truetype"); + src: local("Roboto Light"), local("Roboto-Light"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff2") format("woff2"), url("node_modules/roboto-fontface/fonts/roboto/Roboto-Light.woff") format("woff"); } diff --git a/fonts/yarn.lock b/fonts/yarn.lock deleted file mode 100644 index ccb550f3c4..0000000000 --- a/fonts/yarn.lock +++ /dev/null @@ -1,7 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -roboto-fontface@^0.8.0: - version "0.8.0" - resolved "https://registry.yarnpkg.com/roboto-fontface/-/roboto-fontface-0.8.0.tgz#031a83c8f79932801a57d83bf743f37250163499" diff --git a/js/app.js b/js/app.js index b7c55ffa7a..7cf7dd2eee 100644 --- a/js/app.js +++ b/js/app.js @@ -1,24 +1,22 @@ /* Magic Mirror * The Core App (Server) * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ var fs = require("fs"); +var path = require("path"); +var Log = require(__dirname + "/logger.js"); var Server = require(__dirname + "/server.js"); var Utils = require(__dirname + "/utils.js"); var defaultModules = require(__dirname + "/../modules/default/defaultmodules.js"); -var path = require("path"); // Alias modules mentioned in package.js under _moduleAliases. require("module-alias/register"); -// add timestamps in front of log messages -require("console-stamp")(console, "yyyy-mm-dd HH:MM:ss.l"); - // Get version number. global.version = JSON.parse(fs.readFileSync("package.json", "utf8")).version; -console.log("Starting MagicMirror: v" + global.version); +Log.log("Starting MagicMirror: v" + global.version); // global absolute root path global.root_path = path.resolve(__dirname + "/../"); @@ -36,15 +34,15 @@ if (process.env.MM_PORT) { // The next part is here to prevent a major exception when there // is no internet connection. This could probable be solved better. process.on("uncaughtException", function (err) { - console.log("Whoops! There was an uncaught exception..."); - console.error(err); - console.log("MagicMirror will not quit, but it might be a good idea to check why this happened. Maybe no internet connection?"); - console.log("If you think this really is an issue, please open an issue on GitHub: https://github.com/MichMich/MagicMirror/issues"); + Log.error("Whoops! There was an uncaught exception..."); + Log.error(err); + Log.error("MagicMirror will not quit, but it might be a good idea to check why this happened. Maybe no internet connection?"); + Log.error("If you think this really is an issue, please open an issue on GitHub: https://github.com/MichMich/MagicMirror/issues"); }); /* App - The core app. */ -var App = function() { +var App = function () { var nodeHelpers = []; /* loadConfig(callback) @@ -53,15 +51,15 @@ var App = function() { * * argument callback function - The callback function. */ - var loadConfig = function(callback) { - console.log("Loading config ..."); + var loadConfig = function (callback) { + Log.log("Loading config ..."); var defaults = require(__dirname + "/defaults.js"); // For this check proposed to TestSuite // https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8 var configFilename = path.resolve(global.root_path + "/config/config.js"); - if (typeof(global.configuration_file) !== "undefined") { - configFilename = path.resolve(global.configuration_file); + if (typeof global.configuration_file !== "undefined") { + configFilename = path.resolve(global.configuration_file); } try { @@ -72,33 +70,29 @@ var App = function() { callback(config); } catch (e) { if (e.code === "ENOENT") { - console.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration.")); + Log.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration.")); } else if (e instanceof ReferenceError || e instanceof SyntaxError) { - console.error(Utils.colors.error("WARNING! Could not validate config file. Starting with default configuration. Please correct syntax errors at or above this line: " + e.stack)); + Log.error(Utils.colors.error("WARNING! Could not validate config file. Starting with default configuration. Please correct syntax errors at or above this line: " + e.stack)); } else { - console.error(Utils.colors.error("WARNING! Could not load config file. Starting with default configuration. Error found: " + e)); + Log.error(Utils.colors.error("WARNING! Could not load config file. Starting with default configuration. Error found: " + e)); } callback(defaults); } }; - var checkDeprecatedOptions = function(userConfig) { + var checkDeprecatedOptions = function (userConfig) { var deprecated = require(global.root_path + "/js/deprecated.js"); var deprecatedOptions = deprecated.configs; var usedDeprecated = []; - deprecatedOptions.forEach(function(option) { + deprecatedOptions.forEach(function (option) { if (userConfig.hasOwnProperty(option)) { usedDeprecated.push(option); } }); if (usedDeprecated.length > 0) { - console.warn(Utils.colors.warn( - "WARNING! Your config is using deprecated options: " + - usedDeprecated.join(", ") + - ". Check README and CHANGELOG for more up-to-date ways of getting the same functionality.") - ); + Log.warn(Utils.colors.warn("WARNING! Your config is using deprecated options: " + usedDeprecated.join(", ") + ". Check README and CHANGELOG for more up-to-date ways of getting the same functionality.")); } }; @@ -107,8 +101,7 @@ var App = function() { * * argument module string - The name of the module (including subpath). */ - var loadModule = function(module, callback) { - + var loadModule = function (module, callback) { var elements = module.split("/"); var moduleName = elements[elements.length - 1]; var moduleFolder = __dirname + "/../modules/" + module; @@ -124,7 +117,7 @@ var App = function() { fs.accessSync(helperPath, fs.R_OK); } catch (e) { loadModule = false; - console.log("No helper found for module: " + moduleName + "."); + Log.log("No helper found for module: " + moduleName + "."); } if (loadModule) { @@ -132,11 +125,11 @@ var App = function() { var m = new Module(); if (m.requiresVersion) { - console.log("Check MagicMirror version for node helper '" + moduleName + "' - Minimum version: " + m.requiresVersion + " - Current version: " + global.version); + Log.log("Check MagicMirror version for node helper '" + moduleName + "' - Minimum version: " + m.requiresVersion + " - Current version: " + global.version); if (cmpVersions(global.version, m.requiresVersion) >= 0) { - console.log("Version is ok!"); + Log.log("Version is ok!"); } else { - console.log("Version is incorrect. Skip module: '" + moduleName + "'"); + Log.log("Version is incorrect. Skip module: '" + moduleName + "'"); return; } } @@ -156,19 +149,19 @@ var App = function() { * * argument module string - The name of the module (including subpath). */ - var loadModules = function(modules, callback) { - console.log("Loading module helpers ..."); + var loadModules = function (modules, callback) { + Log.log("Loading module helpers ..."); - var loadNextModule = function() { + var loadNextModule = function () { if (modules.length > 0) { var nextModule = modules[0]; - loadModule(nextModule, function() { + loadModule(nextModule, function () { modules = modules.slice(1); loadNextModule(); }); } else { // All modules are loaded - console.log("All module helpers loaded."); + Log.log("All module helpers loaded."); callback(); } }; @@ -205,9 +198,8 @@ var App = function() { * * argument callback function - The callback function. */ - this.start = function(callback) { - - loadConfig(function(c) { + this.start = function (callback) { + loadConfig(function (c) { config = c; var modules = []; @@ -219,9 +211,9 @@ var App = function() { } } - loadModules(modules, function() { - var server = new Server(config, function(app, io) { - console.log("Server started ..."); + loadModules(modules, function () { + var server = new Server(config, function (app, io) { + Log.log("Server started ..."); for (var h in nodeHelpers) { var nodeHelper = nodeHelpers[h]; @@ -230,7 +222,7 @@ var App = function() { nodeHelper.start(); } - console.log("Sockets connected & modules started ..."); + Log.log("Sockets connected & modules started ..."); if (typeof callback === "function") { callback(config); @@ -245,7 +237,7 @@ var App = function() { * This calls each node_helper's STOP() function, if it exists. * Added to fix #1056 */ - this.stop = function() { + this.stop = function () { for (var h in nodeHelpers) { var nodeHelper = nodeHelpers[h]; if (typeof nodeHelper.stop === "function") { @@ -261,8 +253,10 @@ var App = function() { * this.stop() is called by app.on("before-quit"... in `electron.js` */ process.on("SIGINT", () => { - console.log("[SIGINT] Received. Shutting down server..."); - setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds + Log.log("[SIGINT] Received. Shutting down server..."); + setTimeout(() => { + process.exit(0); + }, 3000); // Force quit after 3 seconds this.stop(); process.exit(0); }); @@ -270,8 +264,10 @@ var App = function() { /* We also need to listen to SIGTERM signals so we stop everything when we are asked to stop by the OS. */ process.on("SIGTERM", () => { - console.log("[SIGTERM] Received. Shutting down server..."); - setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds + Log.log("[SIGTERM] Received. Shutting down server..."); + setTimeout(() => { + process.exit(0); + }, 3000); // Force quit after 3 seconds this.stop(); process.exit(0); }); diff --git a/js/check_config.js b/js/check_config.js new file mode 100644 index 0000000000..cfd56824ad --- /dev/null +++ b/js/check_config.js @@ -0,0 +1,71 @@ +/* Magic Mirror + * + * Check the configuration file for errors + * + * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com + * MIT Licensed. + */ +const Linter = require("eslint").Linter; +const linter = new Linter(); + +const path = require("path"); +const fs = require("fs"); + +const rootPath = path.resolve(__dirname + "/../"); +const config = require(rootPath + "/.eslintrc.json"); +const Log = require(rootPath + "/js/logger.js"); +const Utils = require(rootPath + "/js/utils.js"); + +/* getConfigFile() + * Return string with path of configuration file + * Check if set by environment variable MM_CONFIG_FILE + */ +function getConfigFile() { + // FIXME: This function should be in core. Do you want refactor me ;) ?, be good! + let configFileName = path.resolve(rootPath + "/config/config.js"); + if (process.env.MM_CONFIG_FILE) { + configFileName = path.resolve(process.env.MM_CONFIG_FILE); + } + return configFileName; +} + +function checkConfigFile() { + const configFileName = getConfigFile(); + + // Check if file is present + if (fs.existsSync(configFileName) === false) { + Log.error(Utils.colors.error("File not found: "), configFileName); + throw new Error("No config file present!"); + } + + // check permission + try { + fs.accessSync(configFileName, fs.F_OK); + } catch (e) { + Log.log(Utils.colors.error(e)); + throw new Error("No permission to access config file!"); + } + + // Validate syntax of the configuration file. + Log.info(Utils.colors.info("Checking file... "), configFileName); + + // I'm not sure if all ever is utf-8 + fs.readFile(configFileName, "utf-8", function (err, data) { + if (err) { + throw err; + } + const messages = linter.verify(data, config); + if (messages.length === 0) { + Log.log("Your configuration file doesn't contain syntax errors :)"); + return true; + } else { + // In case the there errors show messages and return + messages.forEach((error) => { + Log.log("Line", error.line, "col", error.column, error.message); + }); + throw new Error("Wrong syntax in config file!"); + } + }); +} + +checkConfigFile(); diff --git a/js/class.js b/js/class.js index 39cd2962bd..f52ac40550 100644 --- a/js/class.js +++ b/js/class.js @@ -1,15 +1,22 @@ +/* global Class, xyz */ + /* Simple JavaScript Inheritance - * By John Resig http://ejohn.org/ + * By John Resig https://johnresig.com/ + * + * Inspired by base2 and Prototype + * * MIT Licensed. */ - -// Inspired by base2 and Prototype (function () { var initializing = false; - var fnTest = /xyz/.test(function () { xyz; }) ? /\b_super\b/ : /.*/; + var fnTest = /xyz/.test(function () { + xyz; + }) + ? /\b_super\b/ + : /.*/; // The base Class implementation (does nothing) - this.Class = function () { }; + this.Class = function () {}; // Create a new Class that inherits from this class Class.extend = function (prop) { @@ -22,30 +29,32 @@ initializing = false; // Make a copy of all prototype properties, to prevent reference issues. - for (var name in prototype) { - prototype[name] = cloneObject(prototype[name]); + for (var p in prototype) { + prototype[p] = cloneObject(prototype[p]); } // Copy the properties over onto the new prototype for (var name in prop) { // Check if we're overwriting an existing function - prototype[name] = typeof prop[name] === "function" && - typeof _super[name] === "function" && fnTest.test(prop[name]) ? (function (name, fn) { - return function () { - var tmp = this._super; - - // Add a new ._super() method that is the same method - // but on the super-class - this._super = _super[name]; - - // The method only need to be bound temporarily, so we - // remove it when we're done executing - var ret = fn.apply(this, arguments); - this._super = tmp; - - return ret; - }; - })(name, prop[name]) : prop[name]; + prototype[name] = + typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name]) + ? (function (name, fn) { + return function () { + var tmp = this._super; + + // Add a new ._super() method that is the same method + // but on the super-class + this._super = _super[name]; + + // The method only need to be bound temporarily, so we + // remove it when we're done executing + var ret = fn.apply(this, arguments); + this._super = tmp; + + return ret; + }; + })(name, prop[name]) + : prop[name]; } // The dummy class constructor diff --git a/js/defaults.js b/js/defaults.js index 08c4d94510..c1a5339617 100644 --- a/js/defaults.js +++ b/js/defaults.js @@ -1,20 +1,20 @@ -/* exported defaults */ +/* global mmPort */ /* Magic Mirror - * Config Defauls + * Config Defaults * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -var port = 8080; var address = "localhost"; -if (typeof(mmPort) !== "undefined") { +var port = 8080; +if (typeof mmPort !== "undefined") { port = mmPort; } var defaults = { address: address, port: port, + basePath: "/", kioskmode: false, electronOptions: {}, ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], @@ -68,14 +68,16 @@ var defaults = { config: { text: "www.michaelteeuw.nl" } - }, + } ], paths: { modules: "modules", vendor: "vendor" - }, + } }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = defaults;} +if (typeof module !== "undefined") { + module.exports = defaults; +} diff --git a/js/deprecated.js b/js/deprecated.js index 96f081cdf3..4f56b41d3f 100644 --- a/js/deprecated.js +++ b/js/deprecated.js @@ -1,14 +1,16 @@ /* Magic Mirror Deprecated Config Options List * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. * * Olex S. original idea this deprecated option */ var deprecated = { - configs: ["kioskmode"], + configs: ["kioskmode"] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = deprecated;} +if (typeof module !== "undefined") { + module.exports = deprecated; +} diff --git a/js/electron.js b/js/electron.js index f7615b1c48..0978cd0da9 100644 --- a/js/electron.js +++ b/js/electron.js @@ -1,7 +1,8 @@ "use strict"; const electron = require("electron"); -const core = require(__dirname + "/app.js"); +const core = require("./app.js"); +const Log = require("./logger.js"); // Config var config = process.env.config ? JSON.parse(process.env.config) : {}; @@ -45,8 +46,16 @@ function createWindow() { // and load the index.html of the app. // If config.address is not defined or is an empty string (listening on all interfaces), connect to localhost + + var prefix; + if (config["tls"] !== null && config["tls"]) { + prefix = "https://"; + } else { + prefix = "http://"; + } + var address = (config.address === void 0) | (config.address === "") ? (config.address = "localhost") : config.address; - mainWindow.loadURL(`http://${address}:${config.port}`); + mainWindow.loadURL(`${prefix}${address}:${config.port}`); // Open the DevTools if run with "npm start dev" if (process.argv.includes("dev")) { @@ -54,21 +63,21 @@ function createWindow() { } // Set responders for window events. - mainWindow.on("closed", function() { + mainWindow.on("closed", function () { mainWindow = null; }); if (config.kioskmode) { - mainWindow.on("blur", function() { + mainWindow.on("blur", function () { mainWindow.focus(); }); - mainWindow.on("leave-full-screen", function() { + mainWindow.on("leave-full-screen", function () { mainWindow.setFullScreen(true); }); - mainWindow.on("resize", function() { - setTimeout(function() { + mainWindow.on("resize", function () { + setTimeout(function () { mainWindow.reload(); }, 1000); }); @@ -77,17 +86,17 @@ function createWindow() { // This method will be called when Electron has finished // initialization and is ready to create browser windows. -app.on("ready", function() { - console.log("Launching application."); +app.on("ready", function () { + Log.log("Launching application."); createWindow(); }); // Quit when all windows are closed. -app.on("window-all-closed", function() { +app.on("window-all-closed", function () { createWindow(); }); -app.on("activate", function() { +app.on("activate", function () { // On OS X it's common to re-create a window in the app when the // dock icon is clicked and there are no other windows open. if (mainWindow === null) { @@ -102,9 +111,11 @@ app.on("activate", function() { * core.stop() is called by process.on("SIGINT"... in `app.js` */ app.on("before-quit", (event) => { - console.log("Shutting down server..."); + Log.log("Shutting down server..."); event.preventDefault(); - setTimeout(() => { process.exit(0); }, 3000); // Force-quit after 3 seconds. + setTimeout(() => { + process.exit(0); + }, 3000); // Force-quit after 3 seconds. core.stop(); process.exit(0); }); @@ -112,7 +123,7 @@ app.on("before-quit", (event) => { // Start the core application if server is run on localhost // This starts all node helpers and starts the webserver. if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].indexOf(config.address) > -1) { - core.start(function(c) { + core.start(function (c) { config = c; }); } diff --git a/js/loader.js b/js/loader.js index 6db46ad5a9..bc376bd91f 100644 --- a/js/loader.js +++ b/js/loader.js @@ -1,13 +1,12 @@ -/* global config, vendor, MM, Log, Module */ +/* global defaultModules, vendor */ + /* Magic Mirror * Module and File loaders. * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -var Loader = (function() { - +var Loader = (function () { /* Create helper variables */ var loadedModuleFiles = []; @@ -19,14 +18,13 @@ var Loader = (function() { /* loadModules() * Loops thru all modules and requests load for every module. */ - var loadModules = function() { - + var loadModules = function () { var moduleData = getModuleData(); - var loadNextModule = function() { + var loadNextModule = function () { if (moduleData.length > 0) { var nextModule = moduleData[0]; - loadModule(nextModule, function() { + loadModule(nextModule, function () { moduleData = moduleData.slice(1); loadNextModule(); }); @@ -35,11 +33,10 @@ var Loader = (function() { // This is done after all the modules so we can // overwrite all the defined styles. - loadFile(config.customCss, function() { + loadFile(config.customCss, function () { // custom.css loaded. Start all modules. startModules(); }); - } }; @@ -49,7 +46,7 @@ var Loader = (function() { /* startModules() * Loops thru all modules and requests start for every module. */ - var startModules = function() { + var startModules = function () { for (var m in moduleObjects) { var module = moduleObjects[m]; module.start(); @@ -64,7 +61,7 @@ var Loader = (function() { * * return array - module data as configured in config */ - var getAllModules = function() { + var getAllModules = function () { return config.modules; }; @@ -73,7 +70,7 @@ var Loader = (function() { * * return array - Module information. */ - var getModuleData = function() { + var getModuleData = function () { var modules = getAllModules(); var moduleFiles = []; @@ -97,12 +94,12 @@ var Loader = (function() { index: m, identifier: "module_" + m + "_" + module, name: moduleName, - path: moduleFolder + "/" , + path: moduleFolder + "/", file: moduleName + ".js", position: moduleData.position, header: moduleData.header, config: moduleData.config, - classes: (typeof moduleData.classes !== "undefined") ? moduleData.classes + " " + module : module + classes: typeof moduleData.classes !== "undefined" ? moduleData.classes + " " + module : module }); } @@ -115,13 +112,13 @@ var Loader = (function() { * argument callback function - Function called when done. * argument module object - Information about the module we want to load. */ - var loadModule = function(module, callback) { + var loadModule = function (module, callback) { var url = module.path + "/" + module.file; - var afterLoad = function() { + var afterLoad = function () { var moduleObject = Module.create(module.name); if (moduleObject) { - bootstrapModule(module, moduleObject, function() { + bootstrapModule(module, moduleObject, function () { callback(); }); } else { @@ -132,7 +129,7 @@ var Loader = (function() { if (loadedModuleFiles.indexOf(url) !== -1) { afterLoad(); } else { - loadFile(url, function() { + loadFile(url, function () { loadedModuleFiles.push(url); afterLoad(); }); @@ -146,16 +143,16 @@ var Loader = (function() { * argument mObj object - Modules instance. * argument callback function - Function called when done. */ - var bootstrapModule = function(module, mObj, callback) { + var bootstrapModule = function (module, mObj, callback) { Log.info("Bootstrapping module: " + module.name); mObj.setData(module); - mObj.loadScripts(function() { + mObj.loadScripts(function () { Log.log("Scripts loaded for: " + module.name); - mObj.loadStyles(function() { + mObj.loadStyles(function () { Log.log("Styles loaded for: " + module.name); - mObj.loadTranslations(function() { + mObj.loadTranslations(function () { Log.log("Translations loaded for: " + module.name); moduleObjects.push(mObj); callback(); @@ -170,52 +167,58 @@ var Loader = (function() { * argument fileName string - Path of the file we want to load. * argument callback function - Function called when done. */ - var loadFile = function(fileName, callback) { - + var loadFile = function (fileName, callback) { var extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); switch (extension.toLowerCase()) { - case "js": - Log.log("Load script: " + fileName); - var script = document.createElement("script"); - script.type = "text/javascript"; - script.src = fileName; - script.onload = function() { - if (typeof callback === "function") {callback();} - }; - script.onerror = function() { - console.error("Error on loading script:", fileName); - if (typeof callback === "function") {callback();} - }; - - document.getElementsByTagName("body")[0].appendChild(script); - break; - case "css": - Log.log("Load stylesheet: " + fileName); - var stylesheet = document.createElement("link"); - stylesheet.rel = "stylesheet"; - stylesheet.type = "text/css"; - stylesheet.href = fileName; - stylesheet.onload = function() { - if (typeof callback === "function") {callback();} - }; - stylesheet.onerror = function() { - console.error("Error on loading stylesheet:", fileName); - if (typeof callback === "function") {callback();} - }; - - document.getElementsByTagName("head")[0].appendChild(stylesheet); - break; + case "js": + Log.log("Load script: " + fileName); + var script = document.createElement("script"); + script.type = "text/javascript"; + script.src = fileName; + script.onload = function () { + if (typeof callback === "function") { + callback(); + } + }; + script.onerror = function () { + Log.error("Error on loading script:", fileName); + if (typeof callback === "function") { + callback(); + } + }; + + document.getElementsByTagName("body")[0].appendChild(script); + break; + case "css": + Log.log("Load stylesheet: " + fileName); + var stylesheet = document.createElement("link"); + stylesheet.rel = "stylesheet"; + stylesheet.type = "text/css"; + stylesheet.href = fileName; + stylesheet.onload = function () { + if (typeof callback === "function") { + callback(); + } + }; + stylesheet.onerror = function () { + Log.error("Error on loading stylesheet:", fileName); + if (typeof callback === "function") { + callback(); + } + }; + + document.getElementsByTagName("head")[0].appendChild(stylesheet); + break; } }; /* Public Methods */ return { - /* loadModules() * Load all modules as defined in the config. */ - loadModules: function() { + loadModules: function () { loadModules(); }, @@ -227,8 +230,7 @@ var Loader = (function() { * argument module Module Object - the module that calls the loadFile function. * argument callback function - Function called when done. */ - loadFile: function(fileName, module, callback) { - + loadFile: function (fileName, module, callback) { if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) { Log.log("File already loaded: " + fileName); callback(); diff --git a/js/logger.js b/js/logger.js index 1392a72ba1..157420a7f2 100644 --- a/js/logger.js +++ b/js/logger.js @@ -1,20 +1,27 @@ -/* global console */ -/* exported Log */ - /* Magic Mirror - * Logger + * Log + * + * This logger is very simple, but needs to be extended. + * This system can eventually be used to push the log messages to an external target. * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ +(function (root, factory) { + if (typeof exports === "object") { + // add timestamps in front of log messages + require("console-stamp")(console, "yyyy-mm-dd HH:MM:ss.l"); -// This logger is very simple, but needs to be extended. -// This system can eventually be used to push the log messages to an external target. - -var Log = (function() { - return { + // Node, CommonJS-like + module.exports = factory(root.config); + } else { + // Browser globals (root is window) + root.Log = factory(root.config); + } +})(this, function (config) { + let logLevel = { info: Function.prototype.bind.call(console.info, console), - log: Function.prototype.bind.call(console.log, console), + log: Function.prototype.bind.call(console.log, console), error: Function.prototype.bind.call(console.error, console), warn: Function.prototype.bind.call(console.warn, console), group: Function.prototype.bind.call(console.group, console), @@ -24,4 +31,14 @@ var Log = (function() { timeEnd: Function.prototype.bind.call(console.timeEnd, console), timeStamp: Function.prototype.bind.call(console.timeStamp, console) }; -})(); + + if (config && config.logLevel) { + Object.keys(logLevel).forEach(function (key, index) { + if (!config.logLevel.includes(key.toLocaleUpperCase())) { + logLevel[key] = function () {}; + } + }); + } + + return logLevel; +}); diff --git a/js/main.js b/js/main.js index 465f1d45c8..07459f0f11 100644 --- a/js/main.js +++ b/js/main.js @@ -1,14 +1,12 @@ -/* global Log, Loader, Module, config, defaults */ +/* global Loader, defaults, Translator */ /* Magic Mirror * Main System * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -var MM = (function() { - +var MM = (function () { var modules = []; /* Private Methods */ @@ -17,10 +15,10 @@ var MM = (function() { * Create dom objects for all modules that * are configured for a specific position. */ - var createDomObjects = function() { + var createDomObjects = function () { var domCreationPromises = []; - modules.forEach(function(module) { + modules.forEach(function (module) { if (typeof module.data.position !== "string") { return; } @@ -53,14 +51,16 @@ var MM = (function() { var domCreationPromise = updateDom(module, 0); domCreationPromises.push(domCreationPromise); - domCreationPromise.then(function() { - sendNotification("MODULE_DOM_CREATED", null, null, module); - }).catch(Log.error); + domCreationPromise + .then(function () { + sendNotification("MODULE_DOM_CREATED", null, null, module); + }) + .catch(Log.error); }); updateWrapperStates(); - Promise.all(domCreationPromises).then(function() { + Promise.all(domCreationPromises).then(function () { sendNotification("DOM_OBJECTS_CREATED"); }); }; @@ -70,8 +70,8 @@ var MM = (function() { * * argument position string - The name of the position. */ - var selectWrapper = function(position) { - var classes = position.replace("_"," "); + var selectWrapper = function (position) { + var classes = position.replace("_", " "); var parentWrapper = document.getElementsByClassName(classes); if (parentWrapper.length > 0) { var wrapper = parentWrapper[0].getElementsByClassName("container"); @@ -89,7 +89,7 @@ var MM = (function() { * argument sender Module - The module that sent the notification. * argument sendTo Module - The module to send the notification to. (optional) */ - var sendNotification = function(notification, payload, sender, sendTo) { + var sendNotification = function (notification, payload, sender, sendTo) { for (var m in modules) { var module = modules[m]; if (module !== sender && (!sendTo || module === sendTo)) { @@ -106,8 +106,8 @@ var MM = (function() { * * return Promise - Resolved when the dom is fully updated. */ - var updateDom = function(module, speed) { - return new Promise(function(resolve) { + var updateDom = function (module, speed) { + return new Promise(function (resolve) { var newContentPromise = module.getDom(); var newHeader = module.getHeader(); @@ -116,11 +116,13 @@ var MM = (function() { newContentPromise = Promise.resolve(newContentPromise); } - newContentPromise.then(function(newContent) { - var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); + newContentPromise + .then(function (newContent) { + var updatePromise = updateDomWithContent(module, speed, newHeader, newContent); - updatePromise.then(resolve).catch(Log.error); - }).catch(Log.error); + updatePromise.then(resolve).catch(Log.error); + }) + .catch(Log.error); }); }; @@ -134,8 +136,8 @@ var MM = (function() { * * return Promise - Resolved when the module dom has been updated. */ - var updateDomWithContent = function(module, speed, newHeader, newContent) { - return new Promise(function(resolve) { + var updateDomWithContent = function (module, speed, newHeader, newContent) { + return new Promise(function (resolve) { if (module.hidden || !speed) { updateModuleContent(module, newHeader, newContent); resolve(); @@ -153,7 +155,7 @@ var MM = (function() { return; } - hideModule(module, speed / 2, function() { + hideModule(module, speed / 2, function () { updateModuleContent(module, newHeader, newContent); if (!module.hidden) { showModule(module, speed / 2); @@ -172,7 +174,7 @@ var MM = (function() { * * return bool - Does the module need an update? */ - var moduleNeedsUpdate = function(module, newHeader, newContent) { + var moduleNeedsUpdate = function (module, newHeader, newContent) { var moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper === null) { return false; @@ -202,9 +204,11 @@ var MM = (function() { * argument newHeader String - The new header that is generated. * argument newContent Domobject - The new content that is generated. */ - var updateModuleContent = function(module, newHeader, newContent) { + var updateModuleContent = function (module, newHeader, newContent) { var moduleWrapper = document.getElementById(module.identifier); - if (moduleWrapper === null) {return;} + if (moduleWrapper === null) { + return; + } var headerWrapper = moduleWrapper.getElementsByClassName("module-header"); var contentWrapper = moduleWrapper.getElementsByClassName("module-content"); @@ -222,7 +226,7 @@ var MM = (function() { * argument speed Number - The speed of the hide animation. * argument callback function - Called when the animation is done. */ - var hideModule = function(module, speed, callback, options) { + var hideModule = function (module, speed, callback, options) { options = options || {}; // set lockString if set in options. @@ -239,7 +243,7 @@ var MM = (function() { moduleWrapper.style.opacity = 0; clearTimeout(module.showHideTimer); - module.showHideTimer = setTimeout(function() { + module.showHideTimer = setTimeout(function () { // To not take up any space, we just make the position absolute. // since it's fade out anyway, we can see it lay above or // below other modules. This works way better than adjusting @@ -248,11 +252,15 @@ var MM = (function() { updateWrapperStates(); - if (typeof callback === "function") { callback(); } + if (typeof callback === "function") { + callback(); + } }, speed); } else { // invoke callback even if no content, issue 1308 - if (typeof callback === "function") { callback(); } + if (typeof callback === "function") { + callback(); + } } }; @@ -263,13 +271,13 @@ var MM = (function() { * argument speed Number - The speed of the show animation. * argument callback function - Called when the animation is done. */ - var showModule = function(module, speed, callback, options) { + var showModule = function (module, speed, callback, options) { options = options || {}; // remove lockString if set in options. if (options.lockString) { var index = module.lockStrings.indexOf(options.lockString); - if ( index !== -1) { + if (index !== -1) { module.lockStrings.splice(index, 1); } } @@ -302,12 +310,16 @@ var MM = (function() { moduleWrapper.style.opacity = 1; clearTimeout(module.showHideTimer); - module.showHideTimer = setTimeout(function() { - if (typeof callback === "function") { callback(); } + module.showHideTimer = setTimeout(function () { + if (typeof callback === "function") { + callback(); + } }, speed); } else { // invoke callback - if (typeof callback === "function") { callback(); } + if (typeof callback === "function") { + callback(); + } } }; @@ -322,15 +334,15 @@ var MM = (function() { * an ugly top margin. By using this function, the top bar will be hidden if the * update notification is not visible. */ - var updateWrapperStates = function() { + var updateWrapperStates = function () { var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; - positions.forEach(function(position) { + positions.forEach(function (position) { var wrapper = selectWrapper(position); var moduleWrappers = wrapper.getElementsByClassName("module"); var showWrapper = false; - Array.prototype.forEach.call(moduleWrappers, function(moduleWrapper) { + Array.prototype.forEach.call(moduleWrappers, function (moduleWrapper) { if (moduleWrapper.style.position === "" || moduleWrapper.style.position === "static") { showWrapper = true; } @@ -343,7 +355,9 @@ var MM = (function() { /* loadConfig() * Loads the core config and combines it with de system defaults. */ - var loadConfig = function() { + var loadConfig = function () { + // FIXME: Think about how to pass config around without breaking tests + /* eslint-disable */ if (typeof config === "undefined") { config = defaults; Log.error("Config file is missing! Please create a config file."); @@ -351,6 +365,7 @@ var MM = (function() { } config = Object.assign({}, defaults, config); + /* eslint-enable */ }; /* setSelectionMethodsForModules() @@ -358,8 +373,7 @@ var MM = (function() { * * argument modules array - Array of modules. */ - var setSelectionMethodsForModules = function(modules) { - + var setSelectionMethodsForModules = function (modules) { /* withClass(className) * calls modulesByClass to filter modules with the specified classes. * @@ -367,7 +381,7 @@ var MM = (function() { * * return array - Filtered collection of modules. */ - var withClass = function(className) { + var withClass = function (className) { return modulesByClass(className, true); }; @@ -378,7 +392,7 @@ var MM = (function() { * * return array - Filtered collection of modules. */ - var exceptWithClass = function(className) { + var exceptWithClass = function (className) { return modulesByClass(className, false); }; @@ -390,13 +404,13 @@ var MM = (function() { * * return array - Filtered collection of modules. */ - var modulesByClass = function(className, include) { + var modulesByClass = function (className, include) { var searchClasses = className; if (typeof className === "string") { searchClasses = className.split(" "); } - var newModules = modules.filter(function(module) { + var newModules = modules.filter(function (module) { var classes = module.data.classes.toLowerCase().split(" "); for (var c in searchClasses) { @@ -420,8 +434,8 @@ var MM = (function() { * * return array - Filtered collection of modules. */ - var exceptModule = function(module) { - var newModules = modules.filter(function(mod) { + var exceptModule = function (module) { + var newModules = modules.filter(function (mod) { return mod.identifier !== module.identifier; }); @@ -434,16 +448,24 @@ var MM = (function() { * * argument callback function - The function to execute with the module as an argument. */ - var enumerate = function(callback) { - modules.map(function(module) { + var enumerate = function (callback) { + modules.map(function (module) { callback(module); }); }; - 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 { @@ -452,7 +474,7 @@ var MM = (function() { /* init() * Main init method. */ - init: function() { + init: function () { Log.info("Initializing MagicMirror."); loadConfig(); Translator.loadCoreTranslations(config.language); @@ -464,7 +486,7 @@ var MM = (function() { * * argument moduleObjects array - All module instances. */ - modulesStarted: function(moduleObjects) { + modulesStarted: function (moduleObjects) { modules = []; for (var m in moduleObjects) { var module = moduleObjects[m]; @@ -484,7 +506,7 @@ var MM = (function() { * argument payload mixed - The payload of the notification. * argument sender Module - The module that sent the notification. */ - sendNotification: function(notification, payload, sender) { + sendNotification: function (notification, payload, sender) { if (arguments.length < 3) { Log.error("sendNotification: Missing arguments."); return; @@ -510,7 +532,7 @@ var MM = (function() { * argument module Module - The module that needs an update. * argument speed Number - The number of microseconds for the animation. (optional) */ - updateDom: function(module, speed) { + updateDom: function (module, speed) { if (!(module instanceof Module)) { Log.error("updateDom: Sender should be a module."); return; @@ -525,7 +547,7 @@ var MM = (function() { * * return array - A collection of all modules currently active. */ - getModules: function() { + getModules: function () { setSelectionMethodsForModules(modules); return modules; }, @@ -538,7 +560,7 @@ var MM = (function() { * argument callback function - Called when the animation is done. * argument options object - Optional settings for the hide method. */ - hideModule: function(module, speed, callback, options) { + hideModule: function (module, speed, callback, options) { module.hidden = true; hideModule(module, speed, callback, options); }, @@ -551,18 +573,17 @@ var MM = (function() { * argument callback function - Called when the animation is done. * argument options object - Optional settings for the hide method. */ - showModule: function(module, speed, callback, options) { + showModule: function (module, speed, callback, options) { // do not change module.hidden yet, only if we really show it later showModule(module, speed, callback, options); } }; - })(); // Add polyfill for Object.assign. if (typeof Object.assign !== "function") { - (function() { - Object.assign = function(target) { + (function () { + Object.assign = function (target) { "use strict"; if (target === undefined || target === null) { throw new TypeError("Cannot convert undefined or null to object"); diff --git a/js/module.js b/js/module.js index e456e6a862..4aa26a80fa 100644 --- a/js/module.js +++ b/js/module.js @@ -1,15 +1,12 @@ -/* global Log, Class, Loader, Class , MM */ -/* exported Module */ +/* global Class, cloneObject, Loader, MMSocket, nunjucks, Translator */ /* Magic Mirror * Module Blueprint. * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - var Module = Class.extend({ - /********************************************************* * All methods (and properties) below can be subclassed. * *********************************************************/ @@ -82,7 +79,7 @@ var Module = Class.extend({ */ getDom: function () { var self = this; - return new Promise(function(resolve) { + return new Promise(function (resolve) { var div = document.createElement("div"); var template = self.getTemplate(); var templateData = self.getTemplateData(); @@ -128,7 +125,7 @@ var Module = Class.extend({ * return string - The template string of filename. */ getTemplate: function () { - return "
" + this.name + "
" + this.identifier + "
"; + return '
' + this.name + '
' + this.identifier + "
"; }, /* getTemplateData() @@ -163,18 +160,18 @@ var Module = Class.extend({ * @returns Nunjucks Environment */ - nunjucksEnvironment: function() { + nunjucksEnvironment: function () { if (this._nunjucksEnvironment !== null) { return this._nunjucksEnvironment; } var self = this; - this._nunjucksEnvironment = new nunjucks.Environment(new nunjucks.WebLoader(this.file(""), {async: true}), { + this._nunjucksEnvironment = new nunjucks.Environment(new nunjucks.WebLoader(this.file(""), { async: true }), { trimBlocks: true, lstripBlocks: true }); - this._nunjucksEnvironment.addFilter("translate", function(str) { + this._nunjucksEnvironment.addFilter("translate", function (str) { return self.translate(str); }); @@ -238,7 +235,7 @@ var Module = Class.extend({ */ socket: function () { if (typeof this._socket === "undefined") { - this._socket = this._socket = new MMSocket(this.name); + this._socket = new MMSocket(this.name); } var self = this; @@ -315,7 +312,9 @@ var Module = Class.extend({ // The variable `first` will contain the first // defined translation after the following line. - for (var first in translations) { break; } + for (var first in translations) { + break; + } if (translations) { var translationFile = translations[lang] || undefined; @@ -339,11 +338,11 @@ var Module = Class.extend({ * Request the translation for a given key with optional variables and default value. * * argument key string - The key of the string to translate - * argument defaultValueOrVariables string/object - The default value or variables for translating. (Optional) - * argument defaultValue string - The default value with variables. (Optional) + * argument defaultValueOrVariables string/object - The default value or variables for translating. (Optional) + * argument defaultValue string - The default value with variables. (Optional) */ translate: function (key, defaultValueOrVariables, defaultValue) { - if(typeof defaultValueOrVariables === "object") { + if (typeof defaultValueOrVariables === "object") { return Translator.translate(this, key, defaultValueOrVariables) || defaultValue || ""; } return Translator.translate(this, key) || defaultValueOrVariables || ""; @@ -388,17 +387,22 @@ var Module = Class.extend({ hide: function (speed, callback, options) { if (typeof callback === "object") { options = callback; - callback = function () { }; + callback = function () {}; } - callback = callback || function () { }; + callback = callback || function () {}; options = options || {}; var self = this; - MM.hideModule(self, speed, function () { - self.suspend(); - callback(); - }, options); + MM.hideModule( + self, + speed, + function () { + self.suspend(); + callback(); + }, + options + ); }, /* showModule(module, speed, callback) @@ -411,24 +415,28 @@ var Module = Class.extend({ show: function (speed, callback, options) { if (typeof callback === "object") { options = callback; - callback = function () { }; + callback = function () {}; } - callback = callback || function () { }; + callback = callback || function () {}; options = options || {}; var self = this; - MM.showModule(this, speed, function () { - self.resume(); - callback; - }, options); + MM.showModule( + this, + speed, + function () { + self.resume(); + callback; + }, + options + ); } }); Module.definitions = {}; Module.create = function (name) { - // Make sure module definition is available. if (!Module.definitions[name]) { return; @@ -444,11 +452,11 @@ Module.create = function (name) { }; /* cmpVersions(a,b) -* Compare two semantic version numbers and return the difference. -* -* argument a string - Version number a. -* argument a string - Version number b. -*/ + * Compare two semantic version numbers and return the difference. + * + * argument a string - Version number a. + * argument a string - Version number b. + */ function cmpVersions(a, b) { var i, diff; var regExStrip0 = /(\.0+)+$/; @@ -466,10 +474,9 @@ function cmpVersions(a, b) { } Module.register = function (name, moduleDefinition) { - if (moduleDefinition.requiresVersion) { - Log.log("Check MagicMirror version for module '" + name + "' - Minimum version: " + moduleDefinition.requiresVersion + " - Current version: " + version); - if (cmpVersions(version, moduleDefinition.requiresVersion) >= 0) { + Log.log("Check MagicMirror version for module '" + name + "' - Minimum version: " + moduleDefinition.requiresVersion + " - Current version: " + window.version); + if (cmpVersions(window.version, moduleDefinition.requiresVersion) >= 0) { Log.log("Version is ok!"); } else { Log.log("Version is incorrect. Skip module: '" + name + "'"); diff --git a/js/node_helper.js b/js/node_helper.js index 326a8ccea4..4a31fdee0a 100644 --- a/js/node_helper.js +++ b/js/node_helper.js @@ -1,26 +1,25 @@ /* Magic Mirror * Node Helper Superclass * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ +const Class = require("./class.js"); +const Log = require("./logger.js"); +const express = require("express"); -var Class = require("./class.js"); -var express = require("express"); -var path = require("path"); - -NodeHelper = Class.extend({ - init: function() { - console.log("Initializing new module helper ..."); +var NodeHelper = Class.extend({ + init: function () { + Log.log("Initializing new module helper ..."); }, - loaded: function(callback) { - console.log("Module helper loaded: " + this.name); + loaded: function (callback) { + Log.log("Module helper loaded: " + this.name); callback(); }, - start: function() { - console.log("Starting module helper: " + this.name); + start: function () { + Log.log("Starting module helper: " + this.name); }, /* stop() @@ -29,8 +28,8 @@ NodeHelper = Class.extend({ * gracefully exit the module. * */ - stop: function() { - console.log("Stopping module helper: " + this.name); + stop: function () { + Log.log("Stopping module helper: " + this.name); }, /* socketNotificationReceived(notification, payload) @@ -39,8 +38,8 @@ NodeHelper = Class.extend({ * argument notification string - The identifier of the notification. * argument payload mixed - The payload of the notification. */ - socketNotificationReceived: function(notification, payload) { - console.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); + socketNotificationReceived: function (notification, payload) { + Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); }, /* setName(name) @@ -48,7 +47,7 @@ NodeHelper = Class.extend({ * * argument name string - Module name. */ - setName: function(name) { + setName: function (name) { this.name = name; }, @@ -57,7 +56,7 @@ NodeHelper = Class.extend({ * * argument path string - Module path. */ - setPath: function(path) { + setPath: function (path) { this.path = path; }, @@ -67,7 +66,7 @@ NodeHelper = Class.extend({ * argument notification string - The identifier of the notification. * argument payload mixed - The payload of the notification. */ - sendSocketNotification: function(notification, payload) { + sendSocketNotification: function (notification, payload) { this.io.of(this.name).emit(notification, payload); }, @@ -77,7 +76,7 @@ NodeHelper = Class.extend({ * * argument app Express app - The Express app object. */ - setExpressApp: function(app) { + setExpressApp: function (app) { this.expressApp = app; var publicPath = this.path + "/public"; @@ -90,16 +89,16 @@ NodeHelper = Class.extend({ * * argument io Socket.io - The Socket io object. */ - setSocketIO: function(io) { + setSocketIO: function (io) { var self = this; self.io = io; - console.log("Connecting socket for: " + this.name); + Log.log("Connecting socket for: " + this.name); var namespace = this.name; - io.of(namespace).on("connection", function(socket) { + io.of(namespace).on("connection", function (socket) { // add a catch all event. var onevent = socket.onevent; - socket.onevent = function(packet) { + socket.onevent = function (packet) { var args = packet.data || []; onevent.call(this, packet); // original call packet.data = ["*"].concat(args); @@ -107,19 +106,21 @@ NodeHelper = Class.extend({ }; // register catch all. - socket.on("*", function(notification, payload) { + socket.on("*", function (notification, payload) { if (notification !== "*") { - //console.log('received message in namespace: ' + namespace); + //Log.log('received message in namespace: ' + namespace); self.socketNotificationReceived(notification, payload); } }); }); - } }); -NodeHelper.create = function(moduleDefinition) { +NodeHelper.create = function (moduleDefinition) { return NodeHelper.extend(moduleDefinition); }; -module.exports = NodeHelper; +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = NodeHelper; +} diff --git a/js/server.js b/js/server.js index 185790af75..5116de5300 100644 --- a/js/server.js +++ b/js/server.js @@ -1,51 +1,51 @@ /* Magic Mirror * Server * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - var express = require("express"); var app = require("express")(); var path = require("path"); var ipfilter = require("express-ipfilter").IpFilter; var fs = require("fs"); var helmet = require("helmet"); -var Utils = require(__dirname + "/utils.js"); -var Server = function(config, callback) { +var Log = require("./logger.js"); +var Utils = require("./utils.js"); +var Server = function (config, callback) { var port = config.port; if (process.env.MM_PORT) { port = process.env.MM_PORT; } var server = null; - if(config.useHttps){ + if (config.useHttps) { var options = { key: fs.readFileSync(config.httpsPrivateKey), cert: fs.readFileSync(config.httpsCertificate) }; server = require("https").Server(options, app); - }else{ + } else { server = require("http").Server(app); } var io = require("socket.io")(server); - console.log("Starting server on port " + port + " ... "); + Log.log("Starting server on port " + port + " ... "); server.listen(port, config.address ? config.address : "localhost"); if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) { - console.info(Utils.colors.warn("You're using a full whitelist configuration to allow for all IPs")); + Log.info(Utils.colors.warn("You're using a full whitelist configuration to allow for all IPs")); } - app.use(function(req, res, next) { - var result = ipfilter(config.ipWhitelist, {mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false})(req, res, function(err) { + app.use(function (req, res, next) { + var result = ipfilter(config.ipWhitelist, { mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false })(req, res, function (err) { if (err === undefined) { return next(); } - console.log(err.message); + Log.log(err.message); res.status(403).send("This device is not allowed to access your mirror.
Please check your config.js or config.js.sample to change this."); }); }); @@ -59,21 +59,21 @@ var Server = function(config, callback) { app.use(directory, express.static(path.resolve(global.root_path + directory))); } - app.get("/version", function(req,res) { + app.get("/version", function (req, res) { res.send(global.version); }); - app.get("/config", function(req,res) { + app.get("/config", function (req, res) { res.send(config); }); - app.get("/", function(req, res) { - var html = fs.readFileSync(path.resolve(global.root_path + "/index.html"), {encoding: "utf8"}); + app.get("/", function (req, res) { + var html = fs.readFileSync(path.resolve(global.root_path + "/index.html"), { encoding: "utf8" }); html = html.replace("#VERSION#", global.version); - configFile = "config/config.js"; - if (typeof(global.configuration_file) !== "undefined") { - configFile = global.configuration_file; + var configFile = "config/config.js"; + if (typeof global.configuration_file !== "undefined") { + configFile = global.configuration_file; } html = html.replace("#CONFIG_FILE#", configFile); diff --git a/js/socket.js b/js/socket.js deleted file mode 100644 index c62c24daca..0000000000 --- a/js/socket.js +++ /dev/null @@ -1,35 +0,0 @@ -/* exported Log */ - -/* Magic Mirror - * Socket Connection - * - * By Michael Teeuw http://michaelteeuw.nl - * MIT Licensed. - */ - -var MMSocket = function(moduleName) { - - var self = this; - - if (typeof moduleName !== "string") { - throw new Error("Please set the module name for the MMSocket."); - } - - self.moduleName = moduleName; - - self.socket = io("http://localhost:8080"); - self.socket.on("notification", function(data) { - MM.sendNotification(data.notification, data.payload, Socket); - }); - - return { - sendMessage: function(notification, payload, sender) { - Log.log("Send socket message: " + notification); - self.socket.emit("notification", { - notification: notification, - sender: sender, - payload: payload - }); - } - }; -}; diff --git a/js/socketclient.js b/js/socketclient.js index ee30f2677f..2a50083f6f 100644 --- a/js/socketclient.js +++ b/js/socketclient.js @@ -1,4 +1,12 @@ -var MMSocket = function(moduleName) { +/* global io */ + +/* Magic Mirror + * TODO add description + * + * By Michael Teeuw https://michaelteeuw.nl + * MIT Licensed. + */ +var MMSocket = function (moduleName) { var self = this; if (typeof moduleName !== "string") { @@ -8,13 +16,17 @@ var MMSocket = function(moduleName) { self.moduleName = moduleName; // Private Methods + var base = "/"; + if (typeof config !== "undefined" && typeof config.basePath !== "undefined") { + base = config.basePath; + } self.socket = io("/" + self.moduleName, { - path: window.location.pathname + "socket.io" + path: base + "socket.io" }); - var notificationCallback = function() {}; + var notificationCallback = function () {}; var onevent = self.socket.onevent; - self.socket.onevent = function(packet) { + self.socket.onevent = function (packet) { var args = packet.data || []; onevent.call(this, packet); // original call packet.data = ["*"].concat(args); @@ -22,18 +34,18 @@ var MMSocket = function(moduleName) { }; // register catch all. - self.socket.on("*", function(notification, payload) { + self.socket.on("*", function (notification, payload) { if (notification !== "*") { notificationCallback(notification, payload); } }); // Public Methods - this.setNotificationCallback = function(callback) { + this.setNotificationCallback = function (callback) { notificationCallback = callback; }; - this.sendNotification = function(notification, payload) { + this.sendNotification = function (notification, payload) { if (typeof payload === "undefined") { payload = {}; } diff --git a/js/translator.js b/js/translator.js index 08a80c1436..3a09fe0b2a 100644 --- a/js/translator.js +++ b/js/translator.js @@ -1,12 +1,12 @@ -/* exported Translator */ +/* global translations */ + /* Magic Mirror * Translator (l10n) * - * By Christopher Fenner http://github.com/CFenner + * By Christopher Fenner https://github.com/CFenner * MIT Licensed. */ -var Translator = (function() { - +var Translator = (function () { /* loadJSON(file, callback) * Load a JSON file via XHR. * @@ -61,7 +61,7 @@ var Translator = (function() { currentChar = str[i]; nextChar = str[i + 1]; - if (!insideComment && currentChar === "\"") { + if (!insideComment && currentChar === '"') { var escaped = str[i - 1] === "\\" && str[i - 2] !== "\\"; if (!escaped) { insideString = !insideString; @@ -118,7 +118,7 @@ var Translator = (function() { * argument key string - The key of the text to translate. * argument variables - The variables to use within the translation template (optional) */ - translate: function(module, key, variables) { + translate: function (module, key, variables) { variables = variables || {}; //Empty object by default // Combines template and variables like: @@ -126,18 +126,18 @@ var Translator = (function() { // variables: {timeToWait: "2 hours", work: "painting"} // to: "Please wait for 2 hours before continuing with painting." function createStringFromTemplate(template, variables) { - if(Object.prototype.toString.call(template) !== "[object String]") { + if (Object.prototype.toString.call(template) !== "[object String]") { return template; } - if(variables.fallback && !template.match(new RegExp("\{.+\}"))) { + if (variables.fallback && !template.match(new RegExp("{.+}"))) { template = variables.fallback; } - return template.replace(new RegExp("\{([^\}]+)\}", "g"), function(_unused, varName){ - return variables[varName] || "{"+varName+"}"; + return template.replace(new RegExp("{([^}]+)}", "g"), function (_unused, varName) { + return variables[varName] || "{" + varName + "}"; }); } - if(this.translations[module.name] && key in this.translations[module.name]) { + if (this.translations[module.name] && key in this.translations[module.name]) { // Log.log("Got translation for " + key + " from module translation: "); return createStringFromTemplate(this.translations[module.name][key], variables); } @@ -168,7 +168,7 @@ var Translator = (function() { * argument isFallback boolean - Flag to indicate fallback translations. * argument callback function - Function called when done. */ - load: function(module, file, isFallback, callback) { + load: function (module, file, isFallback, callback) { if (!isFallback) { Log.log(module.name + " - Load translation: " + file); } else { @@ -176,8 +176,8 @@ var Translator = (function() { } var self = this; - if(!this.translationsFallback[module.name]) { - loadJSON(module.file(file), function(json) { + if (!this.translationsFallback[module.name]) { + loadJSON(module.file(file), function (json) { if (!isFallback) { self.translations[module.name] = json; } else { @@ -195,12 +195,12 @@ var Translator = (function() { * * argument lang String - The language identifier of the core language. */ - loadCoreTranslations: function(lang) { + loadCoreTranslations: function (lang) { var self = this; if (lang in translations) { Log.log("Loading core translation file: " + translations[lang]); - loadJSON(translations[lang], function(translations) { + loadJSON(translations[lang], function (translations) { self.coreTranslations = translations; }); } else { @@ -214,19 +214,21 @@ var Translator = (function() { * Load the core translations fallback. * The first language defined in translations.js will be used. */ - loadCoreTranslationsFallback: function() { + loadCoreTranslationsFallback: function () { var self = this; // The variable `first` will contain the first // defined translation after the following line. - for (var first in translations) {break;} + for (var first in translations) { + break; + } if (first) { Log.log("Loading core translation fallback file: " + translations[first]); - loadJSON(translations[first], function(translations) { + loadJSON(translations[first], function (translations) { self.coreTranslationsFallback = translations; }); } - }, + } }; })(); diff --git a/js/utils.js b/js/utils.js index 3f6234993f..74553f0692 100644 --- a/js/utils.js +++ b/js/utils.js @@ -1,11 +1,9 @@ -/* exported Utils */ /* Magic Mirror * Utils * * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ - var colors = require("colors/safe"); var Utils = { @@ -16,4 +14,6 @@ var Utils = { } }; -if (typeof module !== "undefined") {module.exports = Utils;} +if (typeof module !== "undefined") { + module.exports = Utils; +} diff --git a/jsconfig.json b/jsconfig.json index 2b354edc00..6ae848fc38 100644 --- a/jsconfig.json +++ b/jsconfig.json @@ -6,8 +6,5 @@ "module": "commonjs", "allowSyntheticDefaultImports": true }, - "exclude": [ - "modules", - "node_modules" - ] + "exclude": ["modules", "node_modules"] } diff --git a/modules/default/alert/README.md b/modules/default/alert/README.md index 4d3c6a6531..2e7973a33a 100644 --- a/modules/default/alert/README.md +++ b/modules/default/alert/README.md @@ -1,4 +1,5 @@ # 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). diff --git a/modules/default/alert/alert.js b/modules/default/alert/alert.js index d316b3eaeb..b2eb2eb2e5 100644 --- a/modules/default/alert/alert.js +++ b/modules/default/alert/alert.js @@ -1,13 +1,12 @@ -/* global Module */ +/* global NotificationFx */ /* Magic Mirror * Module: alert * - * By Paul-Vincent Roll http://paulvincentroll.com + * By Paul-Vincent Roll https://paulvincentroll.com/ * MIT Licensed. */ - -Module.register("alert",{ +Module.register("alert", { defaults: { // scale|slide|genie|jelly|flip|bouncyflip|exploader effect: "slide", @@ -18,31 +17,33 @@ Module.register("alert",{ //Position position: "center", //shown at startup - welcome_message: false, + welcome_message: false }, - getScripts: function() { - return ["classie.js", "modernizr.custom.js", "notificationFx.js"]; + getScripts: function () { + return ["notificationFx.js"]; }, - getStyles: function() { - return ["ns-default.css", "font-awesome.css"]; + getStyles: function () { + return ["notificationFx.css", "font-awesome.css"]; }, // Define required translations. - getTranslations: function() { + getTranslations: function () { return { en: "translations/en.json", de: "translations/de.json", - nl: "translations/nl.json", + nl: "translations/nl.json" }; }, - show_notification: function(message) { - if (this.config.effect === "slide") {this.config.effect = this.config.effect + "-" + this.config.position;} - msg = ""; + show_notification: function (message) { + if (this.config.effect === "slide") { + this.config.effect = this.config.effect + "-" + this.config.position; + } + let msg = ""; if (message.title) { msg += "" + message.title + ""; } - if (message.message){ - if (msg !== ""){ - msg+= "
"; + if (message.message) { + if (msg !== "") { + msg += "
"; } msg += "" + message.message + ""; } @@ -54,23 +55,26 @@ Module.register("alert",{ ttl: message.timer !== undefined ? message.timer : this.config.display_time }).show(); }, - show_alert: function(params, sender) { - var self = this; + show_alert: function (params, sender) { + let image = ""; //Set standard params if not provided by module - if (typeof params.timer === "undefined") { params.timer = null; } - if (typeof params.imageHeight === "undefined") { params.imageHeight = "80px"; } + if (typeof params.timer === "undefined") { + params.timer = null; + } + if (typeof params.imageHeight === "undefined") { + params.imageHeight = "80px"; + } if (typeof params.imageUrl === "undefined" && typeof params.imageFA === "undefined") { params.imageUrl = null; - image = ""; - } else if (typeof params.imageFA === "undefined"){ - image = "
"; - } else if (typeof params.imageUrl === "undefined"){ - image = "
"; + } else if (typeof params.imageFA === "undefined") { + image = "
"; + } else if (typeof params.imageUrl === "undefined") { + image = "
"; } //Create overlay - var overlay = document.createElement("div"); + const overlay = document.createElement("div"); overlay.id = "overlay"; - overlay.innerHTML += "
"; + overlay.innerHTML += '
'; document.body.insertBefore(overlay, document.body.firstChild); //If module already has an open alert close it @@ -79,12 +83,12 @@ Module.register("alert",{ } //Display title and message only if they are provided in notification parameters - var message = ""; + let message = ""; if (params.title) { message += "" + params.title + ""; } if (params.message) { - if (message !== ""){ + if (message !== "") { message += "
"; } @@ -102,34 +106,40 @@ Module.register("alert",{ this.alerts[sender.name].show(); //Add timer to dismiss alert and overlay if (params.timer) { - setTimeout(function() { - self.hide_alert(sender); + setTimeout(() => { + this.hide_alert(sender); }, params.timer); } - }, - hide_alert: function(sender) { + hide_alert: function (sender) { //Dismiss alert and remove from this.alerts if (this.alerts[sender.name]) { this.alerts[sender.name].dismiss(); this.alerts[sender.name] = null; //Remove overlay - var overlay = document.getElementById("overlay"); + const overlay = document.getElementById("overlay"); overlay.parentNode.removeChild(overlay); } }, - setPosition: function(pos) { + setPosition: function (pos) { //Add css to body depending on the set position for notifications - var sheet = document.createElement("style"); - if (pos === "center") {sheet.innerHTML = ".ns-box {margin-left: auto; margin-right: auto;text-align: center;}";} - if (pos === "right") {sheet.innerHTML = ".ns-box {margin-left: auto;text-align: right;}";} - if (pos === "left") {sheet.innerHTML = ".ns-box {margin-right: auto;text-align: left;}";} + const sheet = document.createElement("style"); + if (pos === "center") { + sheet.innerHTML = ".ns-box {margin-left: auto; margin-right: auto;text-align: center;}"; + } + if (pos === "right") { + sheet.innerHTML = ".ns-box {margin-left: auto;text-align: right;}"; + } + if (pos === "left") { + sheet.innerHTML = ".ns-box {margin-right: auto;text-align: left;}"; + } document.body.appendChild(sheet); - }, - notificationReceived: function(notification, payload, sender) { + notificationReceived: function (notification, payload, sender) { if (notification === "SHOW_ALERT") { - if (typeof payload.type === "undefined") { payload.type = "alert"; } + if (typeof payload.type === "undefined") { + payload.type = "alert"; + } if (payload.type === "alert") { this.show_alert(payload, sender); } else if (payload.type === "notification") { @@ -139,15 +149,14 @@ Module.register("alert",{ this.hide_alert(sender); } }, - start: function() { + start: function () { this.alerts = {}; this.setPosition(this.config.position); if (this.config.welcome_message) { - if (this.config.welcome_message === true){ - this.show_notification({title: this.translate("sysTitle"), message: this.translate("welcome")}); - } - else{ - this.show_notification({title: this.translate("sysTitle"), message: this.config.welcome_message}); + if (this.config.welcome_message === true) { + this.show_notification({ title: this.translate("sysTitle"), message: this.translate("welcome") }); + } else { + this.show_notification({ title: this.translate("sysTitle"), message: this.config.welcome_message }); } } Log.info("Starting module: " + this.name); diff --git a/modules/default/alert/classie.js b/modules/default/alert/classie.js deleted file mode 100644 index 4a096f1ee6..0000000000 --- a/modules/default/alert/classie.js +++ /dev/null @@ -1,79 +0,0 @@ -/*! - * classie - class helper functions - * from bonzo https://github.com/ded/bonzo - * - * classie.has( elem, 'my-class' ) -> true/false - * classie.add( elem, 'my-new-class' ) - * classie.remove( elem, 'my-unwanted-class' ) - * classie.toggle( elem, 'my-class' ) - */ -// jscs:disable -/*jshint browser: true, strict: true, undef: true */ -/*global define: false */ - -(function(window) { - -"use strict"; - -// class helper functions from bonzo https://github.com/ded/bonzo - -function classReg(className) { - return new RegExp("(^|\\s+)" + className + "(\\s+|$)"); -} - -// classList support for class management -// altho to be fair, the api sucks because it won't accept multiple classes at once -var hasClass, addClass, removeClass; - -if ("classList" in document.documentElement) { - hasClass = function(elem, c) { - return elem.classList.contains(c); - }; - addClass = function(elem, c) { - elem.classList.add(c); - }; - removeClass = function(elem, c) { - elem.classList.remove(c); - }; -} else { - hasClass = function(elem, c) { - return classReg(c).test(elem.className); - }; - addClass = function(elem, c) { - if (!hasClass(elem, c)) { - elem.className = elem.className + " " + c; - } - }; - removeClass = function(elem, c) { - elem.className = elem.className.replace(classReg(c), " "); - }; -} - -function toggleClass(elem, c) { - var fn = hasClass(elem, c) ? removeClass : addClass; - fn(elem, c); -} - -var classie = { - // full names - hasClass: hasClass, - addClass: addClass, - removeClass: removeClass, - toggleClass: toggleClass, - // short names - has: hasClass, - add: addClass, - remove: removeClass, - toggle: toggleClass -}; - -// transport -if (typeof define === "function" && define.amd) { - // AMD - define(classie); -} else { - // browser global - window.classie = classie; -} - -})(window); diff --git a/modules/default/alert/modernizr.custom.js b/modules/default/alert/modernizr.custom.js deleted file mode 100644 index 83c3d3f183..0000000000 --- a/modules/default/alert/modernizr.custom.js +++ /dev/null @@ -1,3 +0,0 @@ -/*! modernizr 3.7.0 (Custom Build) | MIT * - * https://modernizr.com/download/?-cssanimations-domprefixes-prefixed-setclasses-shiv-testallprops-testprop !*/ -!function(e,t,n){function r(e,t){return typeof e===t}function o(e,t){return!!~(""+e).indexOf(t)}function i(){return"function"!=typeof t.createElement?t.createElement(arguments[0]):E?t.createElementNS.call(t,"http://www.w3.org/2000/svg",arguments[0]):t.createElement.apply(t,arguments)}function a(){var e=t.body;return e||(e=i(E?"svg":"body"),e.fake=!0),e}function s(e,n,r,o){var s,l,c,u,f="modernizr",d=i("div"),p=a();if(parseInt(r,10))for(;r--;)c=i("div"),c.id=o?o[r]:f+(r+1),d.appendChild(c);return s=i("style"),s.type="text/css",s.id="s"+f,(p.fake?p:d).appendChild(s),p.appendChild(d),s.styleSheet?s.styleSheet.cssText=e:s.appendChild(t.createTextNode(e)),d.id=f,p.fake&&(p.style.background="",p.style.overflow="hidden",u=S.style.overflow,S.style.overflow="hidden",S.appendChild(p)),l=n(d,e),p.fake?(p.parentNode.removeChild(p),S.style.overflow=u,S.offsetHeight):d.parentNode.removeChild(d),!!l}function l(e){return e.replace(/([A-Z])/g,function(e,t){return"-"+t.toLowerCase()}).replace(/^ms-/,"-ms-")}function c(t,n,r){var o;if("getComputedStyle"in e){o=getComputedStyle.call(e,t,n);var i=e.console;if(null!==o)r&&(o=o.getPropertyValue(r));else if(i){var a=i.error?"error":"log";i[a].call(i,"getComputedStyle returning null, its possible modernizr test results are inaccurate")}}else o=!n&&t.currentStyle&&t.currentStyle[r];return o}function u(t,r){var o=t.length;if("CSS"in e&&"supports"in e.CSS){for(;o--;)if(e.CSS.supports(l(t[o]),r))return!0;return!1}if("CSSSupportsRule"in e){for(var i=[];o--;)i.push("("+l(t[o])+":"+r+")");return i=i.join(" or "),s("@supports ("+i+") { #modernizr { position: absolute; } }",function(e){return"absolute"===c(e,null,"position")})}return n}function f(e){return e.replace(/([a-z])-([a-z])/g,function(e,t,n){return t+n.toUpperCase()}).replace(/^-/,"")}function d(e,t,a,s){function l(){d&&(delete N.style,delete N.modElem)}if(s=!r(s,"undefined")&&s,!r(a,"undefined")){var c=u(e,a);if(!r(c,"undefined"))return c}for(var d,p,m,h,v,g=["modernizr","tspan","samp"];!N.style&&g.length;)d=!0,N.modElem=i(g.shift()),N.style=N.modElem.style;for(m=e.length,p=0;p",r.insertBefore(n.lastChild,r.firstChild)}function r(){var e=y.elements;return"string"==typeof e?e.split(" "):e}function o(e,t){var n=y.elements;"string"!=typeof n&&(n=n.join(" ")),"string"!=typeof e&&(e=e.join(" ")),y.elements=n+" "+e,c(t)}function i(e){var t=g[e[h]];return t||(t={},v++,e[h]=v,g[v]=t),t}function a(e,n,r){if(n||(n=t),f)return n.createElement(e);r||(r=i(n));var o;return o=r.cache[e]?r.cache[e].cloneNode():m.test(e)?(r.cache[e]=r.createElem(e)).cloneNode():r.createElem(e),!o.canHaveChildren||p.test(e)||o.tagUrn?o:r.frag.appendChild(o)}function s(e,n){if(e||(e=t),f)return e.createDocumentFragment();n=n||i(e);for(var o=n.frag.cloneNode(),a=0,s=r(),l=s.length;a",u="hidden"in e,f=1==e.childNodes.length||function(){t.createElement("a");var e=t.createDocumentFragment();return void 0===e.cloneNode||void 0===e.createDocumentFragment||void 0===e.createElement}()}catch(e){u=!0,f=!0}}();var y={elements:d.elements||"abbr article aside audio bdi canvas data datalist details dialog figcaption figure footer header hgroup main mark meter nav output picture progress section summary template time video",version:"3.7.3",shivCSS:!1!==d.shivCSS,supportsUnknownElements:f,shivMethods:!1!==d.shivMethods,type:"default",shivDocument:c,createElement:a,createDocumentFragment:s,addElements:o};e.html5=y,c(t),"object"==typeof module&&module.exports&&(module.exports=y)}(void 0!==e?e:this,t);var w=y._config.usePrefixes?x.split(" "):[];y._cssomPrefixes=w;var _={elem:i("modernizr")};Modernizr._q.push(function(){delete _.elem});var N={style:_.elem.style};Modernizr._q.unshift(function(){delete N.style}),y.testAllProps=h;var j=function(t){var r,o=prefixes.length,i=e.CSSRule;if(void 0===i)return n;if(!t)return!1;if(t=t.replace(/^@/,""),(r=t.replace(/-/g,"_").toUpperCase()+"_RULE")in i)return"@"+t;for(var a=0;a0&&(t+=" "+n+e.join(" "+n)),E?S.className.baseVal=t:S.className=t)}(C),delete y.addTest,delete y.addAsyncTest;for(var z=0;z"; + this.ntf.className = this.options.al_no + " ns-" + this.options.layout + " ns-effect-" + this.options.effect + " ns-type-" + this.options.type; + let strinner = '
'; strinner += this.options.message; strinner += "
"; this.ntf.innerHTML = strinner; @@ -91,13 +82,12 @@ this.options.wrapper.insertBefore(this.ntf, this.options.wrapper.nextSibling); // dismiss after [options.ttl]ms - var self = this; if (this.options.ttl) { - this.dismissttl = setTimeout(function() { - if (self.active) { - self.dismiss(); - } - }, this.options.ttl); + this.dismissttl = setTimeout(() => { + if (this.active) { + this.dismiss(); + } + }, this.options.ttl); } // init events @@ -107,59 +97,54 @@ /** * init events */ - NotificationFx.prototype._initEvents = function() { - var self = this; + NotificationFx.prototype._initEvents = function () { // dismiss notification by tapping on it if someone has a touchscreen - this.ntf.querySelector(".ns-box-inner").addEventListener("click", function() { self.dismiss(); }); + this.ntf.querySelector(".ns-box-inner").addEventListener("click", () => { + this.dismiss(); + }); }; /** * show the notification */ - NotificationFx.prototype.show = function() { + NotificationFx.prototype.show = function () { this.active = true; - classie.remove(this.ntf, "ns-hide"); - classie.add(this.ntf, "ns-show"); + this.ntf.classList.remove("ns-hide"); + this.ntf.classList.add("ns-show"); this.options.onOpen(); }; /** * dismiss the notification */ - NotificationFx.prototype.dismiss = function() { - var self = this; + NotificationFx.prototype.dismiss = function () { this.active = false; clearTimeout(this.dismissttl); - classie.remove(this.ntf, "ns-show"); - setTimeout(function() { - classie.add(self.ntf, "ns-hide"); + this.ntf.classList.remove("ns-show"); + setTimeout(() => { + this.ntf.classList.add("ns-hide"); // callback - self.options.onClose(); + this.options.onClose(); }, 25); // after animation ends remove ntf from the DOM - var onEndAnimationFn = function(ev) { - if (support.animations) { - if (ev.target !== self.ntf) return false; - this.removeEventListener(animEndEventName, onEndAnimationFn); + const onEndAnimationFn = (ev) => { + if (ev.target !== this.ntf) { + return false; } + this.ntf.removeEventListener("animationend", onEndAnimationFn); - if (this.parentNode === self.options.wrapper) { - self.options.wrapper.removeChild(this); + if (ev.target.parentNode === this.options.wrapper) { + this.options.wrapper.removeChild(this.ntf); } }; - if (support.animations) { - this.ntf.addEventListener(animEndEventName, onEndAnimationFn); - } else { - onEndAnimationFn(); - } + this.ntf.addEventListener("animationend", onEndAnimationFn); }; /** * add to global namespace */ window.NotificationFx = NotificationFx; - })(window); diff --git a/modules/default/alert/ns-default.css b/modules/default/alert/ns-default.css deleted file mode 100644 index 73b8740d20..0000000000 --- a/modules/default/alert/ns-default.css +++ /dev/null @@ -1,1742 +0,0 @@ -/* Based on work by http://tympanus.net/codrops/licensing/ */ - -.ns-box { - background-color: rgba(0, 0, 0, 0.93); - padding: 17px; - line-height: 1.4; - margin-bottom: 10px; - z-index: 1; - color: black; - font-size: 70%; - position: relative; - display: table; - word-wrap: break-word; - max-width: 100%; - border-width: 1px; - border-radius: 5px; - border-style: solid; - border-color: #666; -} - -.ns-alert { - border-style: solid; - border-color: #fff; - padding: 17px; - line-height: 1.4; - margin-bottom: 10px; - z-index: 3; - color: white; - font-size: 70%; - position: fixed; - text-align: center; - right: 0; - left: 0; - margin-right: auto; - margin-left: auto; - top: 40%; - width: 40%; - height: auto; - word-wrap: break-word; - border-radius: 20px; -} - -.black_overlay { - position: fixed; - z-index: 2; - background-color: rgba(0, 0, 0, 0.93); - width: 100%; - height: 100%; -} - -[class^="ns-effect-"].ns-growl.ns-hide, -[class*=" ns-effect-"].ns-growl.ns-hide { - -webkit-animation-direction: reverse; - animation-direction: reverse; -} - -.ns-effect-flip { - -webkit-transform-origin: 50% 100%; - transform-origin: 50% 100%; - backface-visibility: hidden; -} - -.ns-effect-flip.ns-show, -.ns-effect-flip.ns-hide { - -webkit-animation-name: animFlipFront; - animation-name: animFlipFront; - -webkit-animation-duration: 0.3s; - animation-duration: 0.3s; -} - -.ns-effect-flip.ns-hide { - -webkit-animation-name: animFlipBack; - animation-name: animFlipBack; -} - -@-webkit-keyframes animFlipFront { - 0% { - -webkit-transform: perspective(1000px) rotate3d(1, 0, 0, -90deg); - } - 100% { - -webkit-transform: perspective(1000px); - } -} - -@keyframes animFlipFront { - 0% { - -webkit-transform: perspective(1000px) rotate3d(1, 0, 0, -90deg); - transform: perspective(1000px) rotate3d(1, 0, 0, -90deg); - } - 100% { - -webkit-transform: perspective(1000px); - transform: perspective(1000px); - } -} - -@-webkit-keyframes animFlipBack { - 0% { - -webkit-transform: perspective(1000px) rotate3d(1, 0, 0, 90deg); - } - 100% { - -webkit-transform: perspective(1000px); - } -} - -@keyframes animFlipBack { - 0% { - -webkit-transform: perspective(1000px) rotate3d(1, 0, 0, 90deg); - transform: perspective(1000px) rotate3d(1, 0, 0, 90deg); - } - 100% { - -webkit-transform: perspective(1000px); - transform: perspective(1000px); - } -} - -.ns-effect-bouncyflip.ns-show, -.ns-effect-bouncyflip.ns-hide { - -webkit-animation-name: flipInX; - animation-name: flipInX; - -webkit-animation-duration: 0.8s; - animation-duration: 0.8s; -} - -@-webkit-keyframes flipInX { - 0% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -90deg); - -webkit-transition-timing-function: ease-in; - } - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 20deg); - -webkit-transition-timing-function: ease-out; - } - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -10deg); - -webkit-transition-timing-function: ease-in; - opacity: 1; - } - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 5deg); - -webkit-transition-timing-function: ease-out; - } - 100% { - -webkit-transform: perspective(400px); - } -} - -@keyframes flipInX { - 0% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -90deg); - transform: perspective(400px) rotate3d(1, 0, 0, -90deg); - -webkit-transition-timing-function: ease-in; - transition-timing-function: ease-in; - } - 40% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 20deg); - transform: perspective(400px) rotate3d(1, 0, 0, 20deg); - -webkit-transition-timing-function: ease-out; - transition-timing-function: ease-out; - } - 60% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -10deg); - transform: perspective(400px) rotate3d(1, 0, 0, -10deg); - -webkit-transition-timing-function: ease-in; - transition-timing-function: ease-in; - opacity: 1; - } - 80% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, 5deg); - transform: perspective(400px) rotate3d(1, 0, 0, 5deg); - -webkit-transition-timing-function: ease-out; - transition-timing-function: ease-out; - } - 100% { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.ns-effect-bouncyflip.ns-hide { - -webkit-animation-name: flipInXSimple; - animation-name: flipInXSimple; - -webkit-animation-duration: 0.3s; - animation-duration: 0.3s; -} - -@-webkit-keyframes flipInXSimple { - 0% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -90deg); - -webkit-transition-timing-function: ease-in; - } - 100% { - -webkit-transform: perspective(400px); - } -} - -@keyframes flipInXSimple { - 0% { - -webkit-transform: perspective(400px) rotate3d(1, 0, 0, -90deg); - transform: perspective(400px) rotate3d(1, 0, 0, -90deg); - -webkit-transition-timing-function: ease-in; - transition-timing-function: ease-in; - } - 100% { - -webkit-transform: perspective(400px); - transform: perspective(400px); - } -} - -.ns-effect-exploader { - -webkit-transform-origin: 0 0; - transform-origin: 0 0; -} - -.ns-effect-exploader p { - padding: 0.25em 2em 0.25em 3em; -} - -.ns-effect-exploader.ns-show { - -webkit-animation-name: animLoad; - animation-name: animLoad; - -webkit-animation-duration: 1s; - animation-duration: 1s; -} - -@-webkit-keyframes animLoad { - 0% { - opacity: 1; - -webkit-transform: scale3d(0, 0.3, 1); - } - 100% { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - } -} - -@keyframes animLoad { - 0% { - opacity: 1; - -webkit-transform: scale3d(0, 0.3, 1); - transform: scale3d(0, 0.3, 1); - } - 100% { - opacity: 1; - -webkit-transform: scale3d(1, 1, 1); - transform: scale3d(1, 1, 1); - } -} - -.ns-effect-exploader.ns-hide { - -webkit-animation-name: animFade; - animation-name: animFade; - -webkit-animation-duration: 0.3s; - animation-duration: 0.3s; -} - -.ns-effect-exploader.ns-show .ns-box-inner, -.ns-effect-exploader.ns-show .ns-close { - -webkit-animation-fill-mode: both; - animation-fill-mode: both; - -webkit-animation-duration: 0.3s; - animation-duration: 0.3s; - -webkit-animation-delay: 0.6s; - animation-delay: 0.6s; -} - -.ns-effect-exploader.ns-show .ns-close { - -webkit-animation-name: animFade; - animation-name: animFade; -} - -.ns-effect-exploader.ns-show .ns-box-inner { - -webkit-animation-name: animFadeMove; - animation-name: animFadeMove; - -webkit-animation-timing-function: ease-out; - animation-timing-function: ease-out; -} - -@-webkit-keyframes animFadeMove { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, 10px, 0); - } - 100% { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0); - } -} - -@keyframes animFadeMove { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, 10px, 0); - transform: translate3d(0, 10px, 0); - } - 100% { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -@-webkit-keyframes animFade { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -@keyframes animFade { - 0% { - opacity: 0; - } - 100% { - opacity: 1; - } -} - -.ns-effect-scale.ns-show, -.ns-effect-scale.ns-hide { - -webkit-animation-name: animScale; - animation-name: animScale; - -webkit-animation-duration: 0.25s; - animation-duration: 0.25s; -} - -@-webkit-keyframes animScale { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, 40px, 0) scale3d(0.1, 0.6, 1); - } - 100% { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1); - } -} - -@keyframes animScale { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, 40px, 0) scale3d(0.1, 0.6, 1); - transform: translate3d(0, 40px, 0) scale3d(0.1, 0.6, 1); - } - 100% { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1); - transform: translate3d(0, 0, 0) scale3d(1, 1, 1); - } -} - -.ns-effect-jelly.ns-show { - -webkit-animation-name: animJelly; - animation-name: animJelly; - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-timing-function: linear; - animation-timing-function: linear; -} - -.ns-effect-jelly.ns-hide { - -webkit-animation-name: animFade; - animation-name: animFade; - -webkit-animation-duration: 0.3s; - animation-duration: 0.3s; -} - -@-webkit-keyframes animFade { - 0% { opacity: 0; } - 100% { opacity: 1; } -} - -@keyframes animFade { - 0% { opacity: 0; } - 100% { opacity: 1; } -} - -@-webkit-keyframes animJelly { - 0% { - -webkit-transform: matrix3d(0.7, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.7, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 2.083333% { - -webkit-transform: matrix3d(0.75266, 0, 0, 0, 0, 0.76342, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.75266, 0, 0, 0, 0, 0.76342, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 4.166667% { - -webkit-transform: matrix3d(0.81071, 0, 0, 0, 0, 0.84545, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.81071, 0, 0, 0, 0, 0.84545, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 6.25% { - -webkit-transform: matrix3d(0.86808, 0, 0, 0, 0, 0.9286, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.86808, 0, 0, 0, 0, 0.9286, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 8.333333% { - -webkit-transform: matrix3d(0.92038, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.92038, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 10.416667% { - -webkit-transform: matrix3d(0.96482, 0, 0, 0, 0, 1.05202, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.96482, 0, 0, 0, 0, 1.05202, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 12.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.08204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.08204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 14.583333% { - -webkit-transform: matrix3d(1.02563, 0, 0, 0, 0, 1.09149, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.02563, 0, 0, 0, 0, 1.09149, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 16.666667% { - -webkit-transform: matrix3d(1.04227, 0, 0, 0, 0, 1.08453, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.04227, 0, 0, 0, 0, 1.08453, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 18.75% { - -webkit-transform: matrix3d(1.05102, 0, 0, 0, 0, 1.06666, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.05102, 0, 0, 0, 0, 1.06666, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 20.833333% { - -webkit-transform: matrix3d(1.05334, 0, 0, 0, 0, 1.04355, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.05334, 0, 0, 0, 0, 1.04355, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 22.916667% { - -webkit-transform: matrix3d(1.05078, 0, 0, 0, 0, 1.02012, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.05078, 0, 0, 0, 0, 1.02012, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 25% { - -webkit-transform: matrix3d(1.04487, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.04487, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 27.083333% { - -webkit-transform: matrix3d(1.03699, 0, 0, 0, 0, 0.98534, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.03699, 0, 0, 0, 0, 0.98534, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 29.166667% { - -webkit-transform: matrix3d(1.02831, 0, 0, 0, 0, 0.97688, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.02831, 0, 0, 0, 0, 0.97688, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 31.25% { - -webkit-transform: matrix3d(1.01973, 0, 0, 0, 0, 0.97422, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.01973, 0, 0, 0, 0, 0.97422, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 33.333333% { - -webkit-transform: matrix3d(1.01191, 0, 0, 0, 0, 0.97618, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.01191, 0, 0, 0, 0, 0.97618, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 35.416667% { - -webkit-transform: matrix3d(1.00526, 0, 0, 0, 0, 0.98122, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00526, 0, 0, 0, 0, 0.98122, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 37.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.98773, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.98773, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 39.583333% { - -webkit-transform: matrix3d(0.99617, 0, 0, 0, 0, 0.99433, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99617, 0, 0, 0, 0, 0.99433, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 41.666667% { - -webkit-transform: matrix3d(0.99368, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99368, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 43.75% { - -webkit-transform: matrix3d(0.99237, 0, 0, 0, 0, 1.00413, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99237, 0, 0, 0, 0, 1.00413, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 45.833333% { - -webkit-transform: matrix3d(0.99202, 0, 0, 0, 0, 1.00651, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99202, 0, 0, 0, 0, 1.00651, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 47.916667% { - -webkit-transform: matrix3d(0.99241, 0, 0, 0, 0, 1.00726, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99241, 0, 0, 0, 0, 1.00726, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 50% { - -webkit-transform: matrix3d(0.99329, 0, 0, 0, 0, 1.00671, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99329, 0, 0, 0, 0, 1.00671, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 52.083333% { - -webkit-transform: matrix3d(0.99447, 0, 0, 0, 0, 1.00529, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99447, 0, 0, 0, 0, 1.00529, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 54.166667% { - -webkit-transform: matrix3d(0.99577, 0, 0, 0, 0, 1.00346, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99577, 0, 0, 0, 0, 1.00346, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 56.25% { - -webkit-transform: matrix3d(0.99705, 0, 0, 0, 0, 1.0016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99705, 0, 0, 0, 0, 1.0016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 58.333333% { - -webkit-transform: matrix3d(0.99822, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99822, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 60.416667% { - -webkit-transform: matrix3d(0.99921, 0, 0, 0, 0, 0.99884, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99921, 0, 0, 0, 0, 0.99884, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 62.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.99816, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.99816, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 64.583333% { - -webkit-transform: matrix3d(1.00057, 0, 0, 0, 0, 0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00057, 0, 0, 0, 0, 0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 66.666667% { - -webkit-transform: matrix3d(1.00095, 0, 0, 0, 0, 0.99811, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00095, 0, 0, 0, 0, 0.99811, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 68.75% { - -webkit-transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 70.833333% { - -webkit-transform: matrix3d(1.00119, 0, 0, 0, 0, 0.99903, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00119, 0, 0, 0, 0, 0.99903, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 72.916667% { - -webkit-transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99955, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99955, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 75% { - -webkit-transform: matrix3d(1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 77.083333% { - -webkit-transform: matrix3d(1.00083, 0, 0, 0, 0, 1.00033, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00083, 0, 0, 0, 0, 1.00033, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 79.166667% { - -webkit-transform: matrix3d(1.00063, 0, 0, 0, 0, 1.00052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00063, 0, 0, 0, 0, 1.00052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 81.25% { - -webkit-transform: matrix3d(1.00044, 0, 0, 0, 0, 1.00058, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00044, 0, 0, 0, 0, 1.00058, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 83.333333% { - -webkit-transform: matrix3d(1.00027, 0, 0, 0, 0, 1.00053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00027, 0, 0, 0, 0, 1.00053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 85.416667% { - -webkit-transform: matrix3d(1.00012, 0, 0, 0, 0, 1.00042, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00012, 0, 0, 0, 0, 1.00042, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 87.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.00027, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.00027, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 89.583333% { - -webkit-transform: matrix3d(0.99991, 0, 0, 0, 0, 1.00013, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99991, 0, 0, 0, 0, 1.00013, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 91.666667% { - -webkit-transform: matrix3d(0.99986, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99986, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 93.75% { - -webkit-transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 95.833333% { - -webkit-transform: matrix3d(0.99982, 0, 0, 0, 0, 0.99985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99982, 0, 0, 0, 0, 0.99985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 97.916667% { - -webkit-transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99984, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99984, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -@keyframes animJelly { - 0% { - -webkit-transform: matrix3d(0.7, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.7, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 2.083333% { - -webkit-transform: matrix3d(0.75266, 0, 0, 0, 0, 0.76342, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.75266, 0, 0, 0, 0, 0.76342, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 4.166667% { - -webkit-transform: matrix3d(0.81071, 0, 0, 0, 0, 0.84545, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.81071, 0, 0, 0, 0, 0.84545, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 6.25% { - -webkit-transform: matrix3d(0.86808, 0, 0, 0, 0, 0.9286, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.86808, 0, 0, 0, 0, 0.9286, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 8.333333% { - -webkit-transform: matrix3d(0.92038, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.92038, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 10.416667% { - -webkit-transform: matrix3d(0.96482, 0, 0, 0, 0, 1.05202, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.96482, 0, 0, 0, 0, 1.05202, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 12.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.08204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.08204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 14.583333% { - -webkit-transform: matrix3d(1.02563, 0, 0, 0, 0, 1.09149, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.02563, 0, 0, 0, 0, 1.09149, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 16.666667% { - -webkit-transform: matrix3d(1.04227, 0, 0, 0, 0, 1.08453, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.04227, 0, 0, 0, 0, 1.08453, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 18.75% { - -webkit-transform: matrix3d(1.05102, 0, 0, 0, 0, 1.06666, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.05102, 0, 0, 0, 0, 1.06666, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 20.833333% { - -webkit-transform: matrix3d(1.05334, 0, 0, 0, 0, 1.04355, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.05334, 0, 0, 0, 0, 1.04355, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 22.916667% { - -webkit-transform: matrix3d(1.05078, 0, 0, 0, 0, 1.02012, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.05078, 0, 0, 0, 0, 1.02012, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 25% { - -webkit-transform: matrix3d(1.04487, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.04487, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 27.083333% { - -webkit-transform: matrix3d(1.03699, 0, 0, 0, 0, 0.98534, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.03699, 0, 0, 0, 0, 0.98534, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 29.166667% { - -webkit-transform: matrix3d(1.02831, 0, 0, 0, 0, 0.97688, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.02831, 0, 0, 0, 0, 0.97688, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 31.25% { - -webkit-transform: matrix3d(1.01973, 0, 0, 0, 0, 0.97422, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.01973, 0, 0, 0, 0, 0.97422, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 33.333333% { - -webkit-transform: matrix3d(1.01191, 0, 0, 0, 0, 0.97618, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.01191, 0, 0, 0, 0, 0.97618, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 35.416667% { - -webkit-transform: matrix3d(1.00526, 0, 0, 0, 0, 0.98122, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00526, 0, 0, 0, 0, 0.98122, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 37.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.98773, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.98773, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 39.583333% { - -webkit-transform: matrix3d(0.99617, 0, 0, 0, 0, 0.99433, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99617, 0, 0, 0, 0, 0.99433, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 41.666667% { - -webkit-transform: matrix3d(0.99368, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99368, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 43.75% { - -webkit-transform: matrix3d(0.99237, 0, 0, 0, 0, 1.00413, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99237, 0, 0, 0, 0, 1.00413, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 45.833333% { - -webkit-transform: matrix3d(0.99202, 0, 0, 0, 0, 1.00651, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99202, 0, 0, 0, 0, 1.00651, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 47.916667% { - -webkit-transform: matrix3d(0.99241, 0, 0, 0, 0, 1.00726, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99241, 0, 0, 0, 0, 1.00726, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 50% { - -webkit-transform: matrix3d(0.99329, 0, 0, 0, 0, 1.00671, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99329, 0, 0, 0, 0, 1.00671, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 52.083333% { - -webkit-transform: matrix3d(0.99447, 0, 0, 0, 0, 1.00529, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99447, 0, 0, 0, 0, 1.00529, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 54.166667% { - -webkit-transform: matrix3d(0.99577, 0, 0, 0, 0, 1.00346, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99577, 0, 0, 0, 0, 1.00346, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 56.25% { - -webkit-transform: matrix3d(0.99705, 0, 0, 0, 0, 1.0016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99705, 0, 0, 0, 0, 1.0016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 58.333333% { - -webkit-transform: matrix3d(0.99822, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99822, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 60.416667% { - -webkit-transform: matrix3d(0.99921, 0, 0, 0, 0, 0.99884, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99921, 0, 0, 0, 0, 0.99884, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 62.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.99816, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.99816, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 64.583333% { - -webkit-transform: matrix3d(1.00057, 0, 0, 0, 0, 0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00057, 0, 0, 0, 0, 0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 66.666667% { - -webkit-transform: matrix3d(1.00095, 0, 0, 0, 0, 0.99811, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00095, 0, 0, 0, 0, 0.99811, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 68.75% { - -webkit-transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 70.833333% { - -webkit-transform: matrix3d(1.00119, 0, 0, 0, 0, 0.99903, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00119, 0, 0, 0, 0, 0.99903, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 72.916667% { - -webkit-transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99955, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99955, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 75% { - -webkit-transform: matrix3d(1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 77.083333% { - -webkit-transform: matrix3d(1.00083, 0, 0, 0, 0, 1.00033, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00083, 0, 0, 0, 0, 1.00033, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 79.166667% { - -webkit-transform: matrix3d(1.00063, 0, 0, 0, 0, 1.00052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00063, 0, 0, 0, 0, 1.00052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 81.25% { - -webkit-transform: matrix3d(1.00044, 0, 0, 0, 0, 1.00058, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00044, 0, 0, 0, 0, 1.00058, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 83.333333% { - -webkit-transform: matrix3d(1.00027, 0, 0, 0, 0, 1.00053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00027, 0, 0, 0, 0, 1.00053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 85.416667% { - -webkit-transform: matrix3d(1.00012, 0, 0, 0, 0, 1.00042, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1.00012, 0, 0, 0, 0, 1.00042, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 87.5% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.00027, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.00027, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 89.583333% { - -webkit-transform: matrix3d(0.99991, 0, 0, 0, 0, 1.00013, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99991, 0, 0, 0, 0, 1.00013, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 91.666667% { - -webkit-transform: matrix3d(0.99986, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99986, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 93.75% { - -webkit-transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 95.833333% { - -webkit-transform: matrix3d(0.99982, 0, 0, 0, 0, 0.99985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99982, 0, 0, 0, 0, 0.99985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 97.916667% { - -webkit-transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99984, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99984, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -.ns-effect-slide-left.ns-show { - -webkit-animation-name: animSlideElasticLeft; - animation-name: animSlideElasticLeft; - -webkit-animation-duration: 1s; - animation-duration: 1s; - -webkit-animation-timing-function: linear; - animation-timing-function: linear; -} - -@-webkit-keyframes animSlideElasticLeft { - 0% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); - } - 1.666667% { - -webkit-transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); - transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); - } - 3.333333% { - -webkit-transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); - transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); - } - 5% { - -webkit-transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); - transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); - } - 6.666667% { - -webkit-transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); - transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); - } - 8.333333% { - -webkit-transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); - transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); - } - 10% { - -webkit-transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); - transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); - } - 11.666667% { - -webkit-transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); - transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); - } - 13.333333% { - -webkit-transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); - transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); - } - 15% { - -webkit-transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); - transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); - } - 16.666667% { - -webkit-transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); - transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); - } - 18.333333% { - -webkit-transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); - transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); - } - 20% { - -webkit-transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); - transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); - } - 21.666667% { - -webkit-transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); - transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); - } - 23.333333% { - -webkit-transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); - transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); - } - 25% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); - } - 26.666667% { - -webkit-transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); - transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); - } - 28.333333% { - -webkit-transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); - transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); - } - 30% { - -webkit-transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); - transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); - } - 31.666667% { - -webkit-transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); - transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); - } - 33.333333% { - -webkit-transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); - transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); - } - 35% { - -webkit-transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); - transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); - } - 36.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); - } - 38.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); - } - 40% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); - } - 41.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); - } - 43.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); - } - 45% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); - } - 46.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); - } - 48.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); - } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); - } - 51.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); - } - 53.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); - } - 55% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); - } - 56.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); - } - 58.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); - } - 60% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); - } - 61.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); - } - 63.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); - } - 65% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); - } - 66.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); - } - 68.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); - } - 70% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); - } - 71.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); - } - 73.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); - } - 75% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); - } - 76.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); - } - 78.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); - } - 80% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); - } - 81.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); - } - 83.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); - } - 85% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); - } - 86.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); - } - 88.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); - } - 90% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - } - 91.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - } - 93.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - } - 95% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); - } - 96.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - } - 98.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -@keyframes animSlideElasticLeft { - 0% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); - } - 1.666667% { - -webkit-transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); - transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); - } - 3.333333% { - -webkit-transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); - transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); - } - 5% { - -webkit-transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); - transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); - } - 6.666667% { - -webkit-transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); - transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); - } - 8.333333% { - -webkit-transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); - transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); - } - 10% { - -webkit-transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); - transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); - } - 11.666667% { - -webkit-transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); - transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); - } - 13.333333% { - -webkit-transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); - transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); - } - 15% { - -webkit-transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); - transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); - } - 16.666667% { - -webkit-transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); - transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); - } - 18.333333% { - -webkit-transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); - transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); - } - 20% { - -webkit-transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); - transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); - } - 21.666667% { - -webkit-transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); - transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); - } - 23.333333% { - -webkit-transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); - transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); - } - 25% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); - } - 26.666667% { - -webkit-transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); - transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); - } - 28.333333% { - -webkit-transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); - transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); - } - 30% { - -webkit-transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); - transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); - } - 31.666667% { - -webkit-transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); - transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); - } - 33.333333% { - -webkit-transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); - transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); - } - 35% { - -webkit-transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); - transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); - } - 36.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); - } - 38.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); - } - 40% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); - } - 41.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); - } - 43.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); - } - 45% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); - } - 46.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); - } - 48.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); - } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); - } - 51.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); - } - 53.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); - } - 55% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); - } - 56.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); - } - 58.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); - } - 60% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); - } - 61.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); - } - 63.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); - } - 65% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); - } - 66.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); - } - 68.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); - } - 70% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); - } - 71.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); - } - 73.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); - } - 75% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); - } - 76.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); - } - 78.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); - } - 80% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); - } - 81.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); - } - 83.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); - } - 85% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); - } - 86.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); - } - 88.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); - } - 90% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - } - 91.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - } - 93.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); - } - 95% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); - } - 96.666667% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); - } - 98.333333% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -.ns-effect-slide-left.ns-hide { - -webkit-animation-name: animSlideLeft; - animation-name: animSlideLeft; - -webkit-animation-duration: 0.25s; - animation-duration: 0.25s; -} - -@-webkit-keyframes animSlideLeft { - 0% { - -webkit-transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); - } - 100% { - -webkit-transform: translate3d(0, 0, 0); - } -} - -@keyframes animSlideLeft { - 0% { - -webkit-transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); - transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); - } - 100% { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.ns-effect-slide-right.ns-show { - -webkit-animation: animSlideElasticRight 2000ms linear both; - animation: animSlideElasticRight 2000ms linear both; -} - -@-webkit-keyframes animSlideElasticRight { - 0% { - -webkit-transform: matrix3d(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1000, 0, 0, 1); - transform: matrix3d(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1000, 0, 0, 1); - } - 2.15% { - -webkit-transform: matrix3d(1.486, 0, 0, 0, 0, 0.514, 0, 0, 0, 0, 1, 0, 664.594, 0, 0, 1); - transform: matrix3d(1.486, 0, 0, 0, 0, 0.514, 0, 0, 0, 0, 1, 0, 664.594, 0, 0, 1); - } - 4.1% { - -webkit-transform: matrix3d(1.147, 0, 0, 0, 0, 0.853, 0, 0, 0, 0, 1, 0, 419.708, 0, 0, 1); - transform: matrix3d(1.147, 0, 0, 0, 0, 0.853, 0, 0, 0, 0, 1, 0, 419.708, 0, 0, 1); - } - 4.3% { - -webkit-transform: matrix3d(1.121, 0, 0, 0, 0, 0.879, 0, 0, 0, 0, 1, 0, 398.136, 0, 0, 1); - transform: matrix3d(1.121, 0, 0, 0, 0, 0.879, 0, 0, 0, 0, 1, 0, 398.136, 0, 0, 1); - } - 6.46% { - -webkit-transform: matrix3d(0.948, 0, 0, 0, 0, 1.052, 0, 0, 0, 0, 1, 0, 206.714, 0, 0, 1); - transform: matrix3d(0.948, 0, 0, 0, 0, 1.052, 0, 0, 0, 0, 1, 0, 206.714, 0, 0, 1); - } - 8.11% { - -webkit-transform: matrix3d(0.908, 0, 0, 0, 0, 1.092, 0, 0, 0, 0, 1, 0, 105.491, 0, 0, 1); - transform: matrix3d(0.908, 0, 0, 0, 0, 1.092, 0, 0, 0, 0, 1, 0, 105.491, 0, 0, 1); - } - 8.61% { - -webkit-transform: matrix3d(0.907, 0, 0, 0, 0, 1.093, 0, 0, 0, 0, 1, 0, 81.572, 0, 0, 1); - transform: matrix3d(0.907, 0, 0, 0, 0, 1.093, 0, 0, 0, 0, 1, 0, 81.572, 0, 0, 1); - } - 12.11% { - -webkit-transform: matrix3d(0.95, 0, 0, 0, 0, 1.05, 0, 0, 0, 0, 1, 0, -18.434, 0, 0, 1); - transform: matrix3d(0.95, 0, 0, 0, 0, 1.05, 0, 0, 0, 0, 1, 0, -18.434, 0, 0, 1); - } - 14.16% { - -webkit-transform: matrix3d(0.979, 0, 0, 0, 0, 1.021, 0, 0, 0, 0, 1, 0, -38.734, 0, 0, 1); - transform: matrix3d(0.979, 0, 0, 0, 0, 1.021, 0, 0, 0, 0, 1, 0, -38.734, 0, 0, 1); - } - 16.12% { - -webkit-transform: matrix3d(0.997, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, -43.356, 0, 0, 1); - transform: matrix3d(0.997, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, -43.356, 0, 0, 1); - } - 19.72% { - -webkit-transform: matrix3d(1.006, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, -34.155, 0, 0, 1); - transform: matrix3d(1.006, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, -34.155, 0, 0, 1); - } - 27.23% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7.839, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7.839, 0, 0, 1); - } - 30.83% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1.951, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1.951, 0, 0, 1); - } - 38.34% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.037, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.037, 0, 0, 1); - } - 41.99% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.812, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.812, 0, 0, 1); - } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.159, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.159, 0, 0, 1); - } - 60.56% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.025, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.025, 0, 0, 1); - } - 82.78% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.001, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -@keyframes animSlideElasticRight { - 0% { - -webkit-transform: matrix3d(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1000, 0, 0, 1); - transform: matrix3d(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1000, 0, 0, 1); - } - 2.15% { - -webkit-transform: matrix3d(1.486, 0, 0, 0, 0, 0.514, 0, 0, 0, 0, 1, 0, 664.594, 0, 0, 1); - transform: matrix3d(1.486, 0, 0, 0, 0, 0.514, 0, 0, 0, 0, 1, 0, 664.594, 0, 0, 1); - } - 4.1% { - -webkit-transform: matrix3d(1.147, 0, 0, 0, 0, 0.853, 0, 0, 0, 0, 1, 0, 419.708, 0, 0, 1); - transform: matrix3d(1.147, 0, 0, 0, 0, 0.853, 0, 0, 0, 0, 1, 0, 419.708, 0, 0, 1); - } - 4.3% { - -webkit-transform: matrix3d(1.121, 0, 0, 0, 0, 0.879, 0, 0, 0, 0, 1, 0, 398.136, 0, 0, 1); - transform: matrix3d(1.121, 0, 0, 0, 0, 0.879, 0, 0, 0, 0, 1, 0, 398.136, 0, 0, 1); - } - 6.46% { - -webkit-transform: matrix3d(0.948, 0, 0, 0, 0, 1.052, 0, 0, 0, 0, 1, 0, 206.714, 0, 0, 1); - transform: matrix3d(0.948, 0, 0, 0, 0, 1.052, 0, 0, 0, 0, 1, 0, 206.714, 0, 0, 1); - } - 8.11% { - -webkit-transform: matrix3d(0.908, 0, 0, 0, 0, 1.092, 0, 0, 0, 0, 1, 0, 105.491, 0, 0, 1); - transform: matrix3d(0.908, 0, 0, 0, 0, 1.092, 0, 0, 0, 0, 1, 0, 105.491, 0, 0, 1); - } - 8.61% { - -webkit-transform: matrix3d(0.907, 0, 0, 0, 0, 1.093, 0, 0, 0, 0, 1, 0, 81.572, 0, 0, 1); - transform: matrix3d(0.907, 0, 0, 0, 0, 1.093, 0, 0, 0, 0, 1, 0, 81.572, 0, 0, 1); - } - 12.11% { - -webkit-transform: matrix3d(0.95, 0, 0, 0, 0, 1.05, 0, 0, 0, 0, 1, 0, -18.434, 0, 0, 1); - transform: matrix3d(0.95, 0, 0, 0, 0, 1.05, 0, 0, 0, 0, 1, 0, -18.434, 0, 0, 1); - } - 14.16% { - -webkit-transform: matrix3d(0.979, 0, 0, 0, 0, 1.021, 0, 0, 0, 0, 1, 0, -38.734, 0, 0, 1); - transform: matrix3d(0.979, 0, 0, 0, 0, 1.021, 0, 0, 0, 0, 1, 0, -38.734, 0, 0, 1); - } - 16.12% { - -webkit-transform: matrix3d(0.997, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, -43.356, 0, 0, 1); - transform: matrix3d(0.997, 0, 0, 0, 0, 1.003, 0, 0, 0, 0, 1, 0, -43.356, 0, 0, 1); - } - 19.72% { - -webkit-transform: matrix3d(1.006, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, -34.155, 0, 0, 1); - transform: matrix3d(1.006, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, -34.155, 0, 0, 1); - } - 27.23% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7.839, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -7.839, 0, 0, 1); - } - 30.83% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1.951, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1.951, 0, 0, 1); - } - 38.34% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.037, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.037, 0, 0, 1); - } - 41.99% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.812, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.812, 0, 0, 1); - } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.159, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.159, 0, 0, 1); - } - 60.56% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.025, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.025, 0, 0, 1); - } - 82.78% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.001, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.001, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -.ns-effect-slide-right.ns-hide { - -webkit-animation-name: animSlideRight; - animation-name: animSlideRight; - -webkit-animation-duration: 0.25s; - animation-duration: 0.25s; -} - -@-webkit-keyframes animSlideRight { - 0% { - -webkit-transform: translate3d(30px, 0, 0) translate3d(100%, 0, 0); - } - 100% { - -webkit-transform: translate3d(0, 0, 0); - } -} - -@keyframes animSlideRight { - 0% { - -webkit-transform: translate3d(30px, 0, 0) translate3d(100%, 0, 0); - transform: translate3d(30px, 0, 0) translate3d(100%, 0, 0); - } - 100% { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.ns-effect-slide-center.ns-show { - -webkit-animation: animSlideElasticCenter 2000ms linear both; - animation: animSlideElasticCenter 2000ms linear both; -} - -@-webkit-keyframes animSlideElasticCenter { - 0% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, -300, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, -300, 0, 1); - } - 2.15% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.971, 0, 0, 0, 0, 1, 0, 0, -199.378, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.971, 0, 0, 0, 0, 1, 0, 0, -199.378, 0, 1); - } - 4.1% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.294, 0, 0, 0, 0, 1, 0, 0, -125.912, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.294, 0, 0, 0, 0, 1, 0, 0, -125.912, 0, 1); - } - 4.3% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.243, 0, 0, 0, 0, 1, 0, 0, -119.441, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.243, 0, 0, 0, 0, 1, 0, 0, -119.441, 0, 1); - } - 6.46% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.895, 0, 0, 0, 0, 1, 0, 0, -62.014, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.895, 0, 0, 0, 0, 1, 0, 0, -62.014, 0, 1); - } - 8.11% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.817, 0, 0, 0, 0, 1, 0, 0, -31.647, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.817, 0, 0, 0, 0, 1, 0, 0, -31.647, 0, 1); - } - 8.61% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.813, 0, 0, 0, 0, 1, 0, 0, -24.472, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.813, 0, 0, 0, 0, 1, 0, 0, -24.472, 0, 1); - } - 12.11% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.9, 0, 0, 0, 0, 1, 0, 0, 5.53, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.9, 0, 0, 0, 0, 1, 0, 0, 5.53, 0, 1); - } - 14.16% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.959, 0, 0, 0, 0, 1, 0, 0, 11.62, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.959, 0, 0, 0, 0, 1, 0, 0, 11.62, 0, 1); - } - 16.12% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, 0, 13.007, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, 0, 13.007, 0, 1); - } - 19.72% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.012, 0, 0, 0, 0, 1, 0, 0, 10.247, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.012, 0, 0, 0, 0, 1, 0, 0, 10.247, 0, 1); - } - 27.23% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2.352, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2.352, 0, 1); - } - 30.83% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0.585, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0.585, 0, 1); - } - 38.34% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.311, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.311, 0, 1); - } - 41.99% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.244, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.244, 0, 1); - } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.048, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.048, 0, 1); - } - 60.56% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0.007, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0.007, 0, 1); - } - 82.78% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -@keyframes animSlideElasticCenter { - 0% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, -300, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, -300, 0, 1); - } - 2.15% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.971, 0, 0, 0, 0, 1, 0, 0, -199.378, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.971, 0, 0, 0, 0, 1, 0, 0, -199.378, 0, 1); - } - 4.1% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.294, 0, 0, 0, 0, 1, 0, 0, -125.912, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.294, 0, 0, 0, 0, 1, 0, 0, -125.912, 0, 1); - } - 4.3% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.243, 0, 0, 0, 0, 1, 0, 0, -119.441, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.243, 0, 0, 0, 0, 1, 0, 0, -119.441, 0, 1); - } - 6.46% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.895, 0, 0, 0, 0, 1, 0, 0, -62.014, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.895, 0, 0, 0, 0, 1, 0, 0, -62.014, 0, 1); - } - 8.11% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.817, 0, 0, 0, 0, 1, 0, 0, -31.647, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.817, 0, 0, 0, 0, 1, 0, 0, -31.647, 0, 1); - } - 8.61% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.813, 0, 0, 0, 0, 1, 0, 0, -24.472, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.813, 0, 0, 0, 0, 1, 0, 0, -24.472, 0, 1); - } - 12.11% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.9, 0, 0, 0, 0, 1, 0, 0, 5.53, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.9, 0, 0, 0, 0, 1, 0, 0, 5.53, 0, 1); - } - 14.16% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.959, 0, 0, 0, 0, 1, 0, 0, 11.62, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.959, 0, 0, 0, 0, 1, 0, 0, 11.62, 0, 1); - } - 16.12% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, 0, 13.007, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.994, 0, 0, 0, 0, 1, 0, 0, 13.007, 0, 1); - } - 19.72% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1.012, 0, 0, 0, 0, 1, 0, 0, 10.247, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1.012, 0, 0, 0, 0, 1, 0, 0, 10.247, 0, 1); - } - 27.23% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2.352, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 2.352, 0, 1); - } - 30.83% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0.585, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0.585, 0, 1); - } - 38.34% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.311, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.311, 0, 1); - } - 41.99% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.244, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.244, 0, 1); - } - 50% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.048, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -0.048, 0, 1); - } - 60.56% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0.007, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0.007, 0, 1); - } - 82.78% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } - 100% { - -webkit-transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); - } -} - -.ns-effect-slide-center.ns-hide { - -webkit-animation-name: animSlideCenter; - animation-name: animSlideCenter; - -webkit-animation-duration: 0.25s; - animation-duration: 0.25s; -} - -@-webkit-keyframes animSlideCenter { - 0% { -webkit-transform: translate3d(0, -30px, 0) translate3d(0, -100%, 0); } - 100% { -webkit-transform: translate3d(0, 0, 0); } -} - -@keyframes animSlideCenter { - 0% { - -webkit-transform: translate3d(0, -30px, 0) translate3d(0, -100%, 0); - transform: translate3d(0, -30px, 0) translate3d(0, -100%, 0); - } - 100% { - -webkit-transform: translate3d(0, 0, 0); - transform: translate3d(0, 0, 0); - } -} - -.ns-effect-genie.ns-show, -.ns-effect-genie.ns-hide { - -webkit-animation-name: animGenie; - animation-name: animGenie; - -webkit-animation-duration: 0.4s; - animation-duration: 0.4s; -} - -@-webkit-keyframes animGenie { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, calc(200% + 30px), 0) scale3d(0, 1, 1); - -webkit-animation-timing-function: ease-in; - } - - 40% { - opacity: 0.5; - -webkit-transform: translate3d(0, 0, 0) scale3d(0.02, 1.1, 1); - -webkit-animation-timing-function: ease-out; - } - - 70% { - opacity: 0.6; - -webkit-transform: translate3d(0, -40px, 0) scale3d(0.8, 1.1, 1); - } - - 100% { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1); - } -} - -@keyframes animGenie { - 0% { - opacity: 0; - -webkit-transform: translate3d(0, calc(200% + 30px), 0) scale3d(0, 1, 1); - -webkit-animation-timing-function: ease-in; - transform: translate3d(0, calc(200% + 30px), 0) scale3d(0, 1, 1); - animation-timing-function: ease-in; - } - - 40% { - opacity: 0.5; - -webkit-transform: translate3d(0, 0, 0) scale3d(0.02, 1.1, 1); - -webkit-animation-timing-function: ease-out; - transform: translate3d(0, 0, 0) scale3d(0.02, 1.1, 1); - animation-timing-function: ease-out; - } - - 70% { - opacity: 0.6; - -webkit-transform: translate3d(0, -40px, 0) scale3d(0.8, 1.1, 1); - transform: translate3d(0, -40px, 0) scale3d(0.8, 1.1, 1); - } - - 100% { - opacity: 1; - -webkit-transform: translate3d(0, 0, 0) scale3d(1, 1, 1); - transform: translate3d(0, 0, 0) scale3d(1, 1, 1); - } -} diff --git a/modules/default/alert/translations/bg.json b/modules/default/alert/translations/bg.json index abf0c96fd3..e97844c85b 100644 --- a/modules/default/alert/translations/bg.json +++ b/modules/default/alert/translations/bg.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror нотификация", - "welcome": "Добре дошли, стартирането беше успешно" + "sysTitle": "MagicMirror нотификация", + "welcome": "Добре дошли, стартирането беше успешно" } diff --git a/modules/default/alert/translations/da.json b/modules/default/alert/translations/da.json index 234f22b15d..f79a50110c 100644 --- a/modules/default/alert/translations/da.json +++ b/modules/default/alert/translations/da.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror Notifikation", - "welcome": "Velkommen, modulet er succesfuldt startet!" + "sysTitle": "MagicMirror Notifikation", + "welcome": "Velkommen, modulet er succesfuldt startet!" } diff --git a/modules/default/alert/translations/de.json b/modules/default/alert/translations/de.json index 4ab7edbb18..6a0340f2d3 100644 --- a/modules/default/alert/translations/de.json +++ b/modules/default/alert/translations/de.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror Benachrichtigung", - "welcome": "Willkommen, Start war erfolgreich!" + "sysTitle": "MagicMirror Benachrichtigung", + "welcome": "Willkommen, Start war erfolgreich!" } diff --git a/modules/default/alert/translations/en.json b/modules/default/alert/translations/en.json index a8589a6791..9854d518b0 100644 --- a/modules/default/alert/translations/en.json +++ b/modules/default/alert/translations/en.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror Notification", - "welcome": "Welcome, start was successful!" + "sysTitle": "MagicMirror Notification", + "welcome": "Welcome, start was successful!" } diff --git a/modules/default/alert/translations/es.json b/modules/default/alert/translations/es.json index 39478251bf..843392338f 100644 --- a/modules/default/alert/translations/es.json +++ b/modules/default/alert/translations/es.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror Notificaciones", - "welcome": "Bienvenido, ¡se iniciado correctamente!" + "sysTitle": "MagicMirror Notificaciones", + "welcome": "Bienvenido, ¡se iniciado correctamente!" } diff --git a/modules/default/alert/translations/fr.json b/modules/default/alert/translations/fr.json index c89417f2b4..6ed40c6292 100644 --- a/modules/default/alert/translations/fr.json +++ b/modules/default/alert/translations/fr.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror Notification", - "welcome": "Bienvenue, le démarrage a été un succès!" + "sysTitle": "MagicMirror Notification", + "welcome": "Bienvenue, le démarrage a été un succès!" } diff --git a/modules/default/alert/translations/hu.json b/modules/default/alert/translations/hu.json index be61836578..332458b54e 100644 --- a/modules/default/alert/translations/hu.json +++ b/modules/default/alert/translations/hu.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror értesítés", - "welcome": "Üdvözöljük, indulás sikeres!" + "sysTitle": "MagicMirror értesítés", + "welcome": "Üdvözöljük, indulás sikeres!" } diff --git a/modules/default/alert/translations/nl.json b/modules/default/alert/translations/nl.json index 9cda90892e..3997819147 100644 --- a/modules/default/alert/translations/nl.json +++ b/modules/default/alert/translations/nl.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror Notificatie", - "welcome": "Welkom, Succesvol gestart!" + "sysTitle": "MagicMirror Notificatie", + "welcome": "Welkom, Succesvol gestart!" } diff --git a/modules/default/alert/translations/ru.json b/modules/default/alert/translations/ru.json index 60ddf3d820..fe535c2de5 100644 --- a/modules/default/alert/translations/ru.json +++ b/modules/default/alert/translations/ru.json @@ -1,4 +1,4 @@ { - "sysTitle": "MagicMirror Уведомление", - "welcome": "Добро пожаловать, старт был успешным!" + "sysTitle": "MagicMirror Уведомление", + "welcome": "Добро пожаловать, старт был успешным!" } diff --git a/modules/default/calendar/README.md b/modules/default/calendar/README.md index 5c8f187bcf..3583aa1881 100755 --- a/modules/default/calendar/README.md +++ b/modules/default/calendar/README.md @@ -1,4 +1,5 @@ # Module: Calendar + 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. diff --git a/modules/default/calendar/calendar.css b/modules/default/calendar/calendar.css index 6bc5762db1..65908a70ac 100644 --- a/modules/default/calendar/calendar.css +++ b/modules/default/calendar/calendar.css @@ -7,8 +7,6 @@ .calendar .symbol span { display: inline-block; - -ms-transform: translate(0, 2px); /* IE 9 */ - -webkit-transform: translate(0, 2px); /* Safari */ transform: translate(0, 2px); } diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index d93f570c2f..bba7565d2b 100755 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -1,26 +1,27 @@ -/* global Module */ +/* global cloneObject */ /* Magic Mirror * Module: Calendar * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - Module.register("calendar", { - // Define module defaults defaults: { maximumEntries: 10, // Total Maximum Entries maximumNumberOfDays: 365, displaySymbol: true, - defaultSymbol: "calendar", // Fontawesome Symbol see http://fontawesome.io/cheatsheet/ + defaultSymbol: "calendar", // Fontawesome Symbol see https://fontawesome.com/cheatsheet?from=io showLocation: false, displayRepeatingCountTitle: false, defaultRepeatingCountTitle: "", maxTitleLength: 25, + maxLocationTitleLength: 25, wrapEvents: false, // wrap events to multiple lines breaking at maxTitleLength + wrapLocationEvents: false, maxTitleLines: 3, + maxEventTitleLines: 3, fetchInterval: 5 * 60 * 1000, // Update every 5 minutes. animationSpeed: 2000, fade: true, @@ -40,13 +41,16 @@ Module.register("calendar", { calendars: [ { symbol: "calendar", - url: "http://www.calendarlabs.com/templates/ical/US-Holidays.ics", - }, + url: "https://www.calendarlabs.com/templates/ical/US-Holidays.ics" + } ], titleReplace: { "De verjaardag van ": "", "'s birthday": "" }, + locationTitleReplace: { + "street ": "" + }, broadcastEvents: true, excludedEvents: [], sliceMultiDayEvents: false, @@ -86,7 +90,7 @@ Module.register("calendar", { var calendarConfig = { maximumEntries: calendar.maximumEntries, maximumNumberOfDays: calendar.maximumNumberOfDays, - broadcastPastEvents: calendar.broadcastPastEvents, + broadcastPastEvents: calendar.broadcastPastEvents }; if (calendar.symbolClass === "undefined" || calendar.symbolClass === null) { calendarConfig.symbolClass = ""; @@ -99,7 +103,7 @@ Module.register("calendar", { } // we check user and password here for backwards compatibility with old configs - if(calendar.user && calendar.pass) { + if (calendar.user && calendar.pass) { Log.warn("Deprecation warning: Please update your calendar authentication configuration."); Log.warn("https://github.com/MichMich/MagicMirror/tree/v2.1.2/modules/default/calendar#calendar-authentication-options"); calendar.auth = { @@ -113,7 +117,7 @@ Module.register("calendar", { // Trigger ADD_CALENDAR every fetchInterval to make sure there is always a calendar // fetcher running on the server side. var self = this; - setInterval(function() { + setInterval(function () { self.addCalendar(calendar.url, calendar.auth, calendarConfig); }, self.config.fetchInterval); } @@ -124,6 +128,10 @@ Module.register("calendar", { // Override socket notification handler. socketNotificationReceived: function (notification, payload) { + if (this.identifier !== payload.id) { + return; + } + if (notification === "CALENDAR_EVENTS") { if (this.hasCalendarURL(payload.url)) { this.calendarData[payload.url] = payload.events; @@ -145,13 +153,12 @@ Module.register("calendar", { // Override dom generator. getDom: function () { - var events = this.createEventList(); var wrapper = document.createElement("table"); wrapper.className = this.config.tableClass; if (events.length === 0) { - wrapper.innerHTML = (this.loaded) ? this.translate("EMPTY") : this.translate("LOADING"); + wrapper.innerHTML = this.loaded ? this.translate("EMPTY") : this.translate("LOADING"); wrapper.className = this.config.tableClass + " dimmed"; return wrapper; } @@ -170,8 +177,8 @@ Module.register("calendar", { for (var e in events) { var event = events[e]; var dateAsString = moment(event.startDate, "x").format(this.config.dateFormat); - if(this.config.timeFormat === "dateheaders"){ - if(lastSeenDate !== dateAsString){ + if (this.config.timeFormat === "dateheaders") { + if (lastSeenDate !== dateAsString) { var dateRow = document.createElement("tr"); dateRow.className = "normal"; var dateCell = document.createElement("td"); @@ -182,9 +189,10 @@ Module.register("calendar", { dateRow.appendChild(dateCell); wrapper.appendChild(dateRow); - if (e >= startFade) { //fading + if (e >= startFade) { + //fading currentFadeStep = e - startFade; - dateRow.style.opacity = 1 - (1 / fadeSteps * currentFadeStep); + dateRow.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep; } lastSeenDate = dateAsString; @@ -210,20 +218,20 @@ Module.register("calendar", { symbolWrapper.className = "symbol align-right " + symbolClass; var symbols = this.symbolsForUrl(event.url); - if(typeof symbols === "string") { + if (typeof symbols === "string") { symbols = [symbols]; } - for(var i = 0; i < symbols.length; i++) { + for (var i = 0; i < symbols.length; i++) { var symbol = document.createElement("span"); symbol.className = "fa fa-fw fa-" + symbols[i]; - if(i > 0){ + if (i > 0) { symbol.style.paddingLeft = "5px"; } symbolWrapper.appendChild(symbol); } eventWrapper.appendChild(symbolWrapper); - } else if(this.config.timeFormat === "dateheaders"){ + } else if (this.config.timeFormat === "dateheaders") { var blankCell = document.createElement("td"); blankCell.innerHTML = "   "; eventWrapper.appendChild(blankCell); @@ -233,7 +241,6 @@ Module.register("calendar", { repeatingCountTitle = ""; if (this.config.displayRepeatingCountTitle && event.firstYear !== undefined) { - repeatingCountTitle = this.countTitleForUrl(event.url); if (repeatingCountTitle !== "") { @@ -244,7 +251,7 @@ Module.register("calendar", { } } - titleWrapper.innerHTML = this.titleTransform(event.title) + repeatingCountTitle; + titleWrapper.innerHTML = this.titleTransform(event.title, this.config.titleReplace, this.config.wrapEvents, this.config.maxTitleLength, this.config.maxTitleLines) + repeatingCountTitle; var titleClass = this.titleClassForUrl(event.url); @@ -254,17 +261,15 @@ Module.register("calendar", { titleWrapper.className = "title " + titleClass; } - if(this.config.timeFormat === "dateheaders"){ + var timeWrapper; + if (this.config.timeFormat === "dateheaders") { if (event.fullDayEvent) { titleWrapper.colSpan = "2"; titleWrapper.align = "left"; - } else { - - var timeClass = this.timeClassForUrl(event.url); - var timeWrapper = document.createElement("td"); - timeWrapper.className = "time light " + timeClass; + timeWrapper = document.createElement("td"); + timeWrapper.className = "time light " + this.timeClassForUrl(event.url); timeWrapper.align = "left"; timeWrapper.style.paddingLeft = "2px"; timeWrapper.innerHTML = moment(event.startDate, "x").format("LT"); @@ -274,10 +279,9 @@ Module.register("calendar", { eventWrapper.appendChild(titleWrapper); } else { - var timeWrapper = document.createElement("td"); + timeWrapper = document.createElement("td"); eventWrapper.appendChild(titleWrapper); - //console.log(event.today); var now = new Date(); // Define second, minute, hour, and day variables var oneSecond = 1000; // 1,000 milliseconds @@ -299,14 +303,14 @@ Module.register("calendar", { } } else { /* Check to see if the user displays absolute or relative dates with their events - * Also check to see if an event is happening within an 'urgency' time frameElement - * For example, if the user set an .urgency of 7 days, those events that fall within that - * time frame will be displayed with 'in xxx' time format or moment.fromNow() - * - * Note: this needs to be put in its own function, as the whole thing repeats again verbatim - */ + * Also check to see if an event is happening within an 'urgency' time frameElement + * For example, if the user set an .urgency of 7 days, those events that fall within that + * time frame will be displayed with 'in xxx' time format or moment.fromNow() + * + * Note: this needs to be put in its own function, as the whole thing repeats again verbatim + */ if (this.config.timeFormat === "absolute") { - if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) { + if (this.config.urgency > 1 && event.startDate - now < this.config.urgency * oneDay) { // This event falls within the config.urgency period that the user has set timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").from(moment().format("YYYYMMDD"))); } else { @@ -316,9 +320,9 @@ Module.register("calendar", { timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").from(moment().format("YYYYMMDD"))); } } - if(this.config.showEnd){ - timeWrapper.innerHTML += "-" ; - timeWrapper.innerHTML += this.capFirst(moment(event.endDate , "x").format(this.config.fullDayEventDateFormat)); + if (this.config.showEnd) { + timeWrapper.innerHTML += "-"; + timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.fullDayEventDateFormat)); } } else { if (event.startDate >= new Date()) { @@ -328,7 +332,7 @@ Module.register("calendar", { // If event is within 6 hour, display 'in xxx' time format or moment.fromNow() timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } else { - if(this.config.timeFormat === "absolute" && !this.config.nextDaysRelative) { + if (this.config.timeFormat === "absolute" && !this.config.nextDaysRelative) { timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat)); } else { // Otherwise just say 'Today/Tomorrow at such-n-such time' @@ -337,14 +341,14 @@ Module.register("calendar", { } } else { /* Check to see if the user displays absolute or relative dates with their events - * Also check to see if an event is happening within an 'urgency' time frameElement - * For example, if the user set an .urgency of 7 days, those events that fall within that - * time frame will be displayed with 'in xxx' time format or moment.fromNow() - * - * Note: this needs to be put in its own function, as the whole thing repeats again verbatim - */ + * Also check to see if an event is happening within an 'urgency' time frameElement + * For example, if the user set an .urgency of 7 days, those events that fall within that + * time frame will be displayed with 'in xxx' time format or moment.fromNow() + * + * Note: this needs to be put in its own function, as the whole thing repeats again verbatim + */ if (this.config.timeFormat === "absolute") { - if ((this.config.urgency > 1) && (event.startDate - now < (this.config.urgency * oneDay))) { + if (this.config.urgency > 1 && event.startDate - now < this.config.urgency * oneDay) { // This event falls within the config.urgency period that the user has set timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } else { @@ -365,13 +369,10 @@ Module.register("calendar", { if (this.config.showEnd) { timeWrapper.innerHTML += "-"; timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat)); - } } //timeWrapper.innerHTML += ' - '+ moment(event.startDate,'x').format('lll'); - //console.log(event); - var timeClass = this.timeClassForUrl(event.url); - timeWrapper.className = "time light " + timeClass; + timeWrapper.className = "time light " + this.timeClassForUrl(event.url); eventWrapper.appendChild(timeWrapper); } @@ -380,7 +381,7 @@ Module.register("calendar", { // Create fade effect. if (e >= startFade) { currentFadeStep = e - startFade; - eventWrapper.style.opacity = 1 - (1 / fadeSteps * currentFadeStep); + eventWrapper.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep; } if (this.config.showLocation) { @@ -396,14 +397,14 @@ Module.register("calendar", { var descCell = document.createElement("td"); descCell.className = "location"; descCell.colSpan = "2"; - descCell.innerHTML = event.location; + descCell.innerHTML = this.titleTransform(event.location, this.config.locationTitleReplace, this.config.wrapLocationEvents, this.config.maxLocationTitleLength, this.config.maxEventTitleLines); locationRow.appendChild(descCell); wrapper.appendChild(locationRow); if (e >= startFade) { currentFadeStep = e - startFade; - locationRow.style.opacity = 1 - (1 / fadeSteps * currentFadeStep); + locationRow.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep; } } } @@ -420,20 +421,17 @@ Module.register("calendar", { * @param {number} timeFormat Specifies either 12 or 24 hour time format * @returns {moment.LocaleSpecification} */ - getLocaleSpecification: function(timeFormat) { + getLocaleSpecification: function (timeFormat) { switch (timeFormat) { - case 12: { - return { longDateFormat: {LT: "h:mm A"} }; - break; - } - case 24: { - return { longDateFormat: {LT: "HH:mm"} }; - break; - } - default: { - return { longDateFormat: {LT: moment.localeData().longDateFormat("LT")} }; - break; - } + case 12: { + return { longDateFormat: { LT: "h:mm A" } }; + } + case 24: { + return { longDateFormat: { LT: "HH:mm" } }; + } + default: { + return { longDateFormat: { LT: moment.localeData().longDateFormat("LT") } }; + } } }, @@ -469,37 +467,37 @@ Module.register("calendar", { var calendar = this.calendarData[c]; for (var e in calendar) { var event = JSON.parse(JSON.stringify(calendar[e])); // clone object - if(event.endDate < now) { + if (event.endDate < now) { continue; } - if(this.config.hidePrivate) { - if(event.class === "PRIVATE") { - // do not add the current event, skip it - continue; + if (this.config.hidePrivate) { + if (event.class === "PRIVATE") { + // do not add the current event, skip it + continue; } } - if(this.config.hideOngoing) { - if(event.startDate < now) { + if (this.config.hideOngoing) { + if (event.startDate < now) { continue; } } - if(this.listContainsEvent(events,event)){ + if (this.listContainsEvent(events, event)) { continue; } event.url = c; - event.today = event.startDate >= today && event.startDate < (today + 24 * 60 * 60 * 1000); + event.today = event.startDate >= today && event.startDate < today + 24 * 60 * 60 * 1000; /* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, - * otherwise, esp. in dateheaders mode it is not clear how long these events are. - */ - var maxCount = Math.ceil(((event.endDate - 1) - moment(event.startDate, "x").endOf("day").format("x"))/(1000*60*60*24)) + 1; + * otherwise, esp. in dateheaders mode it is not clear how long these events are. + */ + var maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / (1000 * 60 * 60 * 24)) + 1; if (this.config.sliceMultiDayEvents && maxCount > 1) { var splitEvents = []; var midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x"); var count = 1; while (event.endDate > midnight) { var thisEvent = JSON.parse(JSON.stringify(event)); // clone object - thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < (today + 24 * 60 * 60 * 1000); + thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + 24 * 60 * 60 * 1000; thisEvent.endDate = midnight; thisEvent.title += " (" + count + "/" + maxCount + ")"; splitEvents.push(thisEvent); @@ -509,11 +507,11 @@ Module.register("calendar", { midnight = moment(midnight, "x").add(1, "day").format("x"); // next day } // Last day - event.title += " ("+count+"/"+maxCount+")"; + event.title += " (" + count + "/" + maxCount + ")"; splitEvents.push(event); for (event of splitEvents) { - if ((event.endDate > now) && (event.endDate <= future)) { + if (event.endDate > now && event.endDate <= future) { events.push(event); } } @@ -529,9 +527,9 @@ Module.register("calendar", { return events.slice(0, this.config.maximumEntries); }, - listContainsEvent: function(eventList, event){ - for(var evt of eventList){ - if(evt.title === event.title && parseInt(evt.startDate) === parseInt(event.startDate)){ + listContainsEvent: function (eventList, event) { + for (var evt of eventList) { + if (evt.title === event.title && parseInt(evt.startDate) === parseInt(event.startDate)) { return true; } } @@ -545,6 +543,7 @@ Module.register("calendar", { */ addCalendar: function (url, auth, calendarConfig) { this.sendSocketNotification("ADD_CALENDAR", { + id: this.identifier, url: url, excludedEvents: calendarConfig.excludedEvents || this.config.excludedEvents, maximumEntries: calendarConfig.maximumEntries || this.config.maximumEntries, @@ -554,7 +553,7 @@ Module.register("calendar", { titleClass: calendarConfig.titleClass, timeClass: calendarConfig.timeClass, auth: auth, - broadcastPastEvents: calendarConfig.broadcastPastEvents || this.config.broadcastPastEvents, + broadcastPastEvents: calendarConfig.broadcastPastEvents || this.config.broadcastPastEvents }); }, @@ -681,8 +680,9 @@ Module.register("calendar", { for (var i = 0; i < words.length; i++) { var word = words[i]; - if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { // max - 1 to account for a space - currentLine += (word + " "); + if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { + // max - 1 to account for a space + currentLine += word + " "; } else { line++; if (line > maxTitleLines - 1) { @@ -693,9 +693,9 @@ Module.register("calendar", { } if (currentLine.length > 0) { - temp += (currentLine + "
" + word + " "); + temp += currentLine + "
" + word + " "; } else { - temp += (word + "
"); + temp += word + "
"; } currentLine = ""; } @@ -728,20 +728,20 @@ Module.register("calendar", { * * return string - The transformed title. */ - titleTransform: function (title) { - for (var needle in this.config.titleReplace) { - var replacement = this.config.titleReplace[needle]; + titleTransform: function (title, titleReplace, wrapEvents, maxTitleLength, maxTitleLines) { + for (var needle in titleReplace) { + var replacement = titleReplace[needle]; var regParts = needle.match(/^\/(.+)\/([gim]*)$/); if (regParts) { - // the parsed pattern is a regexp. - needle = new RegExp(regParts[1], regParts[2]); + // the parsed pattern is a regexp. + needle = new RegExp(regParts[1], regParts[2]); } title = title.replace(needle, replacement); } - title = this.shorten(title, this.config.maxTitleLength, this.config.wrapEvents, this.config.maxTitleLines); + title = this.shorten(title, maxTitleLength, wrapEvents, maxTitleLines); return title; }, @@ -763,11 +763,10 @@ Module.register("calendar", { } } - eventList.sort(function(a,b) { + eventList.sort(function (a, b) { return a.startDate - b.startDate; }); this.sendNotification("CALENDAR_EVENTS", eventList); - } }); diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index c393d5d6bc..4a6fb0e64a 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -1,90 +1,88 @@ /* Magic Mirror * Node Helper: Calendar - CalendarFetcher * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ +const Log = require("../../../js/logger.js"); +const ical = require("ical"); +const moment = require("moment"); +const request = require("request"); -var ical = require("./vendor/ical.js"); -var moment = require("moment"); +const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumNumberOfDays, auth, includePastEvents) { + const self = this; -var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, includePastEvents) { - var self = this; + let reloadTimer = null; + let events = []; - var reloadTimer = null; - var events = []; - - var fetchFailedCallback = function() {}; - var eventsReceivedCallback = function() {}; + let fetchFailedCallback = function () {}; + let eventsReceivedCallback = function () {}; /* fetchCalendar() * Initiates calendar fetch. */ - var fetchCalendar = function() { - + const fetchCalendar = function () { clearTimeout(reloadTimer); reloadTimer = null; - nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); - var opts = { + const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); + const 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 }; if (auth) { - if(auth.method === "bearer"){ + if (auth.method === "bearer") { opts.auth = { bearer: auth.pass }; - } else { opts.auth = { user: auth.user, - pass: auth.pass + pass: auth.pass, + sendImmediately: auth.method !== "digest" }; - - if(auth.method === "digest"){ - opts.auth.sendImmediately = false; - } else { - opts.auth.sendImmediately = true; - } } } - ical.fromURL(url, opts, function(err, data) { + request(url, opts, function (err, r, requestData) { if (err) { fetchFailedCallback(self, err); scheduleTimer(); return; + } else if (r.statusCode !== 200) { + fetchFailedCallback(self, r.statusCode + ": " + r.statusMessage); + scheduleTimer(); + return; } - // console.log(data); - newEvents = []; + const data = ical.parseICS(requestData); + const newEvents = []; // limitFunction doesn't do much limiting, see comment re: the dates array in rrule section below as to why we need to do the filtering ourselves - var limitFunction = function(date, i) {return true;}; + const limitFunction = function (date, i) { + return true; + }; - var eventDate = function(event, time) { - return (event[time].length === 8) ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time])); + const eventDate = function (event, time) { + return event[time].length === 8 ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time])); }; - for (var e in data) { - var event = data[e]; - var now = new Date(); - var today = moment().startOf("day").toDate(); - var future = moment().startOf("day").add(maximumNumberOfDays, "days").subtract(1,"seconds").toDate(); // Subtract 1 second so that events that start on the middle of the night will not repeat. - var past = today; + Object.entries(data).forEach(([key, event]) => { + const now = new Date(); + const today = moment().startOf("day").toDate(); + const future = moment().startOf("day").add(maximumNumberOfDays, "days").subtract(1, "seconds").toDate(); // Subtract 1 second so that events that start on the middle of the night will not repeat. + let past = today; if (includePastEvents) { past = moment().startOf("day").subtract(maximumNumberOfDays, "days").toDate(); } - // FIXME: - // Ugly fix to solve the facebook birthday issue. + // FIXME: Ugly fix to solve the facebook birthday issue. // Otherwise, the recurring events only show the birthday for next year. - var isFacebookBirthday = false; + let isFacebookBirthday = false; if (typeof event.uid !== "undefined") { if (event.uid.indexOf("@facebook.com") !== -1) { isFacebookBirthday = true; @@ -92,14 +90,13 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri } if (event.type === "VEVENT") { + let startDate = eventDate(event, "start"); + let endDate; - var startDate = eventDate(event, "start"); - var endDate; if (typeof event.end !== "undefined") { endDate = eventDate(event, "end"); - } else if(typeof event.duration !== "undefined") { - dur=moment.duration(event.duration); - endDate = startDate.clone().add(dur); + } else if (typeof event.duration !== "undefined") { + endDate = startDate.clone().add(moment.duration(event.duration)); } else { if (!isFacebookBirthday) { endDate = startDate; @@ -108,20 +105,20 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri } } - // calculate the duration f the event for use with recurring events. - var duration = parseInt(endDate.format("x")) - parseInt(startDate.format("x")); + // calculate the duration of the event for use with recurring events. + let duration = parseInt(endDate.format("x")) - parseInt(startDate.format("x")); if (event.start.length === 8) { startDate = startDate.startOf("day"); } - var title = getTitleFromEvent(event); + const title = getTitleFromEvent(event); - var excluded = false, + let excluded = false, dateFilter = null; - for (var f in excludedEvents) { - var filter = excludedEvents[f], + for (let f in excludedEvents) { + let filter = excludedEvents[f], testTitle = title.toLowerCase(), until = null, useRegex = false, @@ -164,97 +161,84 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri } if (excluded) { - continue; + return; } - var location = event.location || false; - var geo = event.geo || false; - var description = event.description || false; + const location = event.location || false; + const geo = event.geo || false; + const description = event.description || false; if (typeof event.rrule !== "undefined" && event.rrule !== null && !isFacebookBirthday) { - var rule = event.rrule; - var addedEvents = 0; + const rule = event.rrule; + let addedEvents = 0; + + const pastMoment = moment(past); + const futureMoment = moment(future); // can cause problems with e.g. birthdays before 1900 - if(rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900 || - rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900){ + if ((rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900) || (rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900)) { rule.origOptions.dtstart.setYear(1900); rule.options.dtstart.setYear(1900); } // For recurring events, get the set of start dates that fall within the range - // of dates we"re looking for. + // 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(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(); - return date; + const pastLocal = pastMoment.subtract(past.getTimezoneOffset(), "minutes").toDate(); + const futureLocal = futureMoment.subtract(future.getTimezoneOffset(), "minutes").toDate(); + const datesLocal = rule.between(pastLocal, futureLocal, true, limitFunction); + const dates = datesLocal.map(function (dateLocal) { + return moment(dateLocal).add(dateLocal.getTimezoneOffset(), "minutes").toDate(); }); // 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 + // for the recurrence rule. *However*, it's possible for us to have a specific recurrence that // had its date changed from outside the range to inside the range. For the time being, - // we"ll handle this by adding *all* recurrence entries into the set of dates that we check, - // because the logic below will filter out any recurrences that don"t actually belong within + // we'll handle this by adding *all* recurrence entries into the set of dates that we check, + // because the logic below will filter out any recurrences that don't actually belong within // our display range. // Would be great if there was a better way to handle this. - if (event.recurrences != undefined) - { - var pastMoment = moment(past); - var futureMoment = moment(future); - - for (var r in event.recurrences) - { + if (event.recurrences !== undefined) { + for (let r in event.recurrences) { // Only add dates that weren't already in the range we added from the rrule so that // we don"t double-add those events. - if (moment(new Date(r)).isBetween(pastMoment, futureMoment) != true) - { + if (moment(new Date(r)).isBetween(pastMoment, futureMoment) !== true) { dates.push(new Date(r)); } } } // Loop through the set of date entries to see which recurrences should be added to our event list. - for (var d in dates) { - var date = dates[d]; + for (let d in dates) { + const date = dates[d]; // ical.js started returning recurrences and exdates as ISOStrings without time information. // .toISOString().substring(0,10) is the method they use to calculate keys, so we'll do the same // (see https://github.com/peterbraden/ical.js/pull/84 ) - var dateKey = date.toISOString().substring(0,10); - var curEvent = event; - var showRecurrence = true; - - // Stop parsing this event's recurrences if we've already found maximumEntries worth of recurrences. - // (The logic below would still filter the extras, but the check is simple since we're already tracking the count) - if (addedEvents >= maximumEntries) { - break; - } + const dateKey = date.toISOString().substring(0, 10); + let curEvent = event; + let showRecurrence = true; startDate = moment(date); - // For each date that we"re checking, it"s possible that there is a recurrence override for that one day. - if ((curEvent.recurrences != undefined) && (curEvent.recurrences[dateKey] != undefined)) - { + // For each date that we're checking, it's possible that there is a recurrence override for that one day. + if (curEvent.recurrences !== undefined && curEvent.recurrences[dateKey] !== undefined) { // We found an override, so for this recurrence, use a potentially different title, start date, and duration. curEvent = curEvent.recurrences[dateKey]; startDate = moment(curEvent.start); duration = parseInt(moment(curEvent.end).format("x")) - parseInt(startDate.format("x")); } - // If there"s no recurrence override, check for an exception date. Exception dates represent exceptions to the rule. - else if ((curEvent.exdate != undefined) && (curEvent.exdate[dateKey] != undefined)) - { + // If there's no recurrence override, check for an exception date. Exception dates represent exceptions to the rule. + else if (curEvent.exdate !== undefined && curEvent.exdate[dateKey] !== undefined) { // This date is an exception date, which means we should skip it in the recurrence pattern. showRecurrence = false; } endDate = moment(parseInt(startDate.format("x")) + duration, "x"); - if (startDate.format("x") == endDate.format("x")) { + if (startDate.format("x") === endDate.format("x")) { endDate = endDate.endOf("day"); } - var recurrenceTitle = getTitleFromEvent(curEvent); + const recurrenceTitle = getTitleFromEvent(curEvent); // If this recurrence ends before the start of the date range, or starts after the end of the date range, don"t add // it to the event list. @@ -266,7 +250,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri showRecurrence = false; } - if ((showRecurrence === true) && (addedEvents < maximumEntries)) { + if (showRecurrence === true) { addedEvents++; newEvents.push({ title: recurrenceTitle, @@ -283,43 +267,41 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri } // end recurring event parsing } else { - // console.log("Single event ..."); // Single event. - var fullDayEvent = (isFacebookBirthday) ? true : isFullDayEvent(event); + const fullDayEvent = isFacebookBirthday ? true : isFullDayEvent(event); if (includePastEvents) { + // Past event is too far in the past, so skip. if (endDate < past) { - //console.log("Past event is too far in the past. So skip: " + title); - continue; + return; } } else { + // It's not a fullday event, and it is in the past, so skip. if (!fullDayEvent && endDate < new Date()) { - //console.log("It's not a fullday event, and it is in the past. So skip: " + title); - continue; + return; } + // It's a fullday event, and it is before today, So skip. if (fullDayEvent && endDate <= today) { - //console.log("It's a fullday event, and it is before today. So skip: " + title); - continue; + return; } } + // It exceeds the maximumNumberOfDays limit, so skip. if (startDate > future) { - //console.log("It exceeds the maximumNumberOfDays limit. So skip: " + title); - continue; + return; } if (timeFilterApplies(now, endDate, dateFilter)) { - continue; + return; } - // adjust start date so multiple day events will be displayed as happening today even though they started some days ago already + // Adjust start date so multiple day events will be displayed as happening today even though they started some days ago already if (fullDayEvent && startDate <= today) { startDate = moment(today); } // Every thing is good. Add it to the list. - newEvents.push({ title: title, startDate: startDate.format("x"), @@ -330,18 +312,15 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri geo: geo, description: description }); - } } - } + }); - newEvents.sort(function(a, b) { + newEvents.sort(function (a, b) { return a.startDate - b.startDate; }); - //console.log(newEvents); - - events = newEvents.slice(0, maximumEntries); + events = newEvents; self.broadcastEvents(); scheduleTimer(); @@ -351,10 +330,9 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri /* scheduleTimer() * Schedule the timer for the next update. */ - var scheduleTimer = function() { - //console.log('Schedule update timer.'); + const scheduleTimer = function () { clearTimeout(reloadTimer); - reloadTimer = setTimeout(function() { + reloadTimer = setTimeout(function () { fetchCalendar(); }, reloadInterval); }; @@ -366,15 +344,15 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri * * return bool - The event is a fullday event. */ - var isFullDayEvent = function(event) { + const isFullDayEvent = function (event) { if (event.start.length === 8 || event.start.dateOnly) { return true; } - var start = event.start || 0; - var startDate = new Date(start); - var end = event.end || 0; - if (((end - start) % (24 * 60 * 60 * 1000)) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) { + const start = event.start || 0; + const startDate = new Date(start); + const end = event.end || 0; + if ((end - start) % (24 * 60 * 60 * 1000) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) { // Is 24 hours, and starts on the middle of the night. return true; } @@ -391,11 +369,11 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri * * return bool - The event should be filtered out */ - var timeFilterApplies = function(now, endDate, filter) { + const timeFilterApplies = function (now, endDate, filter) { if (filter) { - var until = filter.split(" "), + const until = filter.split(" "), value = parseInt(until[0]), - increment = until[1].slice("-1") === "s" ? until[1] : until[1] + "s", // Massage the data for moment js + increment = until[1].slice(-1) === "s" ? until[1] : until[1] + "s", // Massage the data for moment js filterUntil = moment(endDate.format()).subtract(value, increment); return now < filterUntil.format("x"); @@ -405,16 +383,16 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri }; /* getTitleFromEvent(event) - * Gets the title from the event. - * - * argument event object - The event object to check. - * - * return string - The title of the event, or "Event" if no title is found. - */ - var getTitleFromEvent = function (event) { - var title = "Event"; + * Gets the title from the event. + * + * argument event object - The event object to check. + * + * return string - The title of the event, or "Event" if no title is found. + */ + const getTitleFromEvent = function (event) { + let title = "Event"; if (event.summary) { - title = (typeof event.summary.val !== "undefined") ? event.summary.val : event.summary; + title = typeof event.summary.val !== "undefined" ? event.summary.val : event.summary; } else if (event.description) { title = event.description; } @@ -422,7 +400,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri return title; }; - var testTitleByFilter = function (title, filter, useRegex, regexFlags) { + const testTitleByFilter = function (title, filter, useRegex, regexFlags) { if (useRegex) { // Assume if leading slash, there is also trailing slash if (filter[0] === "/") { @@ -443,15 +421,15 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri /* startFetch() * Initiate fetchCalendar(); */ - this.startFetch = function() { + this.startFetch = function () { fetchCalendar(); }; /* broadcastItems() * Broadcast the existing events. */ - this.broadcastEvents = function() { - //console.log('Broadcasting ' + events.length + ' events.'); + this.broadcastEvents = function () { + Log.info("Calendar-Fetcher: Broadcasting " + events.length + " events."); eventsReceivedCallback(self); }; @@ -460,7 +438,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri * * argument callback function - The on success callback. */ - this.onReceive = function(callback) { + this.onReceive = function (callback) { eventsReceivedCallback = callback; }; @@ -469,7 +447,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri * * argument callback function - The on error callback. */ - this.onError = function(callback) { + this.onError = function (callback) { fetchFailedCallback = callback; }; @@ -478,7 +456,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri * * return string - The url of this fetcher. */ - this.url = function() { + this.url = function () { return url; }; @@ -487,7 +465,7 @@ var CalendarFetcher = function(url, reloadInterval, excludedEvents, maximumEntri * * return array - The current available events for this fetcher. */ - this.events = function() { + this.events = function () { return events; }; }; diff --git a/modules/default/calendar/debug.js b/modules/default/calendar/debug.js index 84fc2f86b1..f01bcc0dc3 100644 --- a/modules/default/calendar/debug.js +++ b/modules/default/calendar/debug.js @@ -2,36 +2,33 @@ * use this script with `node debug.js` to test the fetcher without the need * of starting the MagicMirror core. Adjust the values below to your desire. * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -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://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; -var maximumNumberOfDays = 365; -var user = "magicmirror"; -var pass = "MyStrongPass"; -var broadcastPastEvents = false; - -var auth = { +const CalendarFetcher = require("./calendarfetcher.js"); + +const url = "https://calendar.google.com/calendar/ical/pkm1t2uedjbp0uvq1o7oj1jouo%40group.calendar.google.com/private-08ba559f89eec70dd74bbd887d0a3598/basic.ics"; // Standard test URL +//const url = "https://www.googleapis.com/calendar/v3/calendars/primary/events/"; // URL for Bearer auth (must be configured in Google OAuth2 first) +const fetchInterval = 60 * 60 * 1000; +const maximumEntries = 10; +const maximumNumberOfDays = 365; +const user = "magicmirror"; +const pass = "MyStrongPass"; +const auth = { user: user, pass: pass }; console.log("Create fetcher ..."); -fetcher = new CalendarFetcher(url, fetchInterval, [], maximumEntries, maximumNumberOfDays, auth); +const fetcher = new CalendarFetcher(url, fetchInterval, [], maximumEntries, maximumNumberOfDays, auth); -fetcher.onReceive(function(fetcher) { +fetcher.onReceive(function (fetcher) { console.log(fetcher.events()); console.log("------------------------------------------------------------"); }); -fetcher.onError(function(fetcher, error) { +fetcher.onError(function (fetcher, error) { console.log("Fetcher error:"); console.log(error); }); diff --git a/modules/default/calendar/node_helper.js b/modules/default/calendar/node_helper.js index 00cb949923..5248919bf5 100644 --- a/modules/default/calendar/node_helper.js +++ b/modules/default/calendar/node_helper.js @@ -1,30 +1,26 @@ /* Magic Mirror * Node Helper: Calendar * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -var NodeHelper = require("node_helper"); -var validUrl = require("valid-url"); -var CalendarFetcher = require("./calendarfetcher.js"); +const NodeHelper = require("node_helper"); +const validUrl = require("valid-url"); +const CalendarFetcher = require("./calendarfetcher.js"); +const Log = require("../../../js/logger"); module.exports = NodeHelper.create({ // Override start method. - start: function() { - var events = []; - + start: function () { + Log.log("Starting node helper for: " + this.name); this.fetchers = []; - - console.log("Starting node helper for: " + this.name); - }, // Override socketNotificationReceived method. - socketNotificationReceived: function(notification, payload) { + socketNotificationReceived: function (notification, payload) { if (notification === "ADD_CALENDAR") { - //console.log('ADD_CALENDAR: '); - this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth, payload.broadcastPastEvents); + this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumNumberOfDays, payload.auth, payload.broadcastPastEvents, payload.id); } }, @@ -35,42 +31,40 @@ module.exports = NodeHelper.create({ * attribute url string - URL of the news feed. * attribute reloadInterval number - Reload interval in milliseconds. */ - - createFetcher: function(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents) { + createFetcher: function (url, fetchInterval, excludedEvents, maximumNumberOfDays, auth, broadcastPastEvents, identifier) { var self = this; if (!validUrl.isUri(url)) { - self.sendSocketNotification("INCORRECT_URL", {url: url}); + self.sendSocketNotification("INCORRECT_URL", { id: identifier, url: url }); return; } var fetcher; - if (typeof self.fetchers[url] === "undefined") { - console.log("Create new calendar fetcher for url: " + url + " - Interval: " + fetchInterval); - fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents); - - fetcher.onReceive(function(fetcher) { - //console.log('Broadcast events.'); - //console.log(fetcher.events()); + if (typeof self.fetchers[identifier + url] === "undefined") { + Log.log("Create new calendar fetcher for url: " + url + " - Interval: " + fetchInterval); + fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumNumberOfDays, auth, broadcastPastEvents); + fetcher.onReceive(function (fetcher) { self.sendSocketNotification("CALENDAR_EVENTS", { + id: identifier, url: fetcher.url(), events: fetcher.events() }); }); - fetcher.onError(function(fetcher, error) { - console.error("Calendar Error. Could not fetch calendar: ", fetcher.url(), error); + fetcher.onError(function (fetcher, error) { + Log.error("Calendar Error. Could not fetch calendar: ", fetcher.url(), error); self.sendSocketNotification("FETCH_ERROR", { + id: identifier, url: fetcher.url(), error: error }); }); - self.fetchers[url] = fetcher; + self.fetchers[identifier + url] = fetcher; } else { - //console.log('Use existing news fetcher for url: ' + url); - fetcher = self.fetchers[url]; + Log.log("Use existing calendar fetcher for url: " + url); + fetcher = self.fetchers[identifier + url]; fetcher.broadcastEvents(); } diff --git a/modules/default/calendar/vendor/ical.js/.travis.yml b/modules/default/calendar/vendor/ical.js/.travis.yml deleted file mode 100644 index d5d4c1e3e2..0000000000 --- a/modules/default/calendar/vendor/ical.js/.travis.yml +++ /dev/null @@ -1,4 +0,0 @@ -language: node_js -node_js: - - "8.9" -install: npm install diff --git a/modules/default/calendar/vendor/ical.js/LICENSE b/modules/default/calendar/vendor/ical.js/LICENSE deleted file mode 100644 index e454a52586..0000000000 --- a/modules/default/calendar/vendor/ical.js/LICENSE +++ /dev/null @@ -1,178 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - diff --git a/modules/default/calendar/vendor/ical.js/NOTICE b/modules/default/calendar/vendor/ical.js/NOTICE deleted file mode 100644 index d5f926dbc8..0000000000 --- a/modules/default/calendar/vendor/ical.js/NOTICE +++ /dev/null @@ -1,13 +0,0 @@ -Copyright 2012 Peter Braden - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. diff --git a/modules/default/calendar/vendor/ical.js/example.js b/modules/default/calendar/vendor/ical.js/example.js deleted file mode 100644 index 7b41f1ad39..0000000000 --- a/modules/default/calendar/vendor/ical.js/example.js +++ /dev/null @@ -1,16 +0,0 @@ -'use strict'; - -const ical = require('ical'); -const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - -ical.fromURL('http://lanyrd.com/topics/nodejs/nodejs.ics', {}, function (err, data) { - for (let k in data) { - if (data.hasOwnProperty(k)) { - var ev = data[k]; - if (data[k].type == 'VEVENT') { - console.log(`${ev.summary} is in ${ev.location} on the ${ev.start.getDate()} of ${months[ev.start.getMonth()]} at ${ev.start.toLocaleTimeString('en-GB')}`); - - } - } - } -}); diff --git a/modules/default/calendar/vendor/ical.js/example_rrule.js b/modules/default/calendar/vendor/ical.js/example_rrule.js deleted file mode 100644 index 6233c4b289..0000000000 --- a/modules/default/calendar/vendor/ical.js/example_rrule.js +++ /dev/null @@ -1,118 +0,0 @@ -var ical = require('./node-ical') -var moment = require('moment') - -var data = ical.parseFile('./examples/example_rrule.ics'); - -// Complicated example demonstrating how to handle recurrence rules and exceptions. - -for (var k in data) { - - // When dealing with calendar recurrences, you need a range of dates to query against, - // because otherwise you can get an infinite number of calendar events. - var rangeStart = moment("2017-01-01"); - var rangeEnd = moment("2017-12-31"); - - - var event = data[k] - if (event.type === 'VEVENT') { - - var title = event.summary; - var startDate = moment(event.start); - var endDate = moment(event.end); - - // Calculate the duration of the event for use with recurring events. - var duration = parseInt(endDate.format("x")) - parseInt(startDate.format("x")); - - // Simple case - no recurrences, just print out the calendar event. - if (typeof event.rrule === 'undefined') - { - console.log('title:' + title); - console.log('startDate:' + startDate.format('MMMM Do YYYY, h:mm:ss a')); - console.log('endDate:' + endDate.format('MMMM Do YYYY, h:mm:ss a')); - console.log('duration:' + moment.duration(duration).humanize()); - console.log(); - } - - // Complicated case - if an RRULE exists, handle multiple recurrences of the event. - else if (typeof event.rrule !== 'undefined') - { - // For recurring events, get the set of event start dates that fall within the range - // of dates we're looking for. - var dates = event.rrule.between( - rangeStart.toDate(), - rangeEnd.toDate(), - true, - function(date, i) {return true;} - ) - - // 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 - // had its date changed from outside the range to inside the range. One way to handle this is - // to add *all* recurrence override entries into the set of dates that we check, and then later - // filter out any recurrences that don't actually belong within our range. - if (event.recurrences != undefined) - { - for (var r in event.recurrences) - { - // Only add dates that weren't already in the range we added from the rrule so that - // we don't double-add those events. - if (moment(new Date(r)).isBetween(rangeStart, rangeEnd) != true) - { - dates.push(new Date(r)); - } - } - } - - // Loop through the set of date entries to see which recurrences should be printed. - for(var i in dates) { - - var date = dates[i]; - var curEvent = event; - var showRecurrence = true; - var curDuration = duration; - - startDate = moment(date); - - // Use just the date of the recurrence to look up overrides and exceptions (i.e. chop off time information) - var dateLookupKey = date.toISOString().substring(0, 10); - - // For each date that we're checking, it's possible that there is a recurrence override for that one day. - if ((curEvent.recurrences != undefined) && (curEvent.recurrences[dateLookupKey] != undefined)) - { - // We found an override, so for this recurrence, use a potentially different title, start date, and duration. - curEvent = curEvent.recurrences[dateLookupKey]; - startDate = moment(curEvent.start); - curDuration = parseInt(moment(curEvent.end).format("x")) - parseInt(startDate.format("x")); - } - // If there's no recurrence override, check for an exception date. Exception dates represent exceptions to the rule. - else if ((curEvent.exdate != undefined) && (curEvent.exdate[dateLookupKey] != undefined)) - { - // This date is an exception date, which means we should skip it in the recurrence pattern. - showRecurrence = false; - } - - // Set the the title and the end date from either the regular event or the recurrence override. - var recurrenceTitle = curEvent.summary; - endDate = moment(parseInt(startDate.format("x")) + curDuration, 'x'); - - // If this recurrence ends before the start of the date range, or starts after the end of the date range, - // don't process it. - if (endDate.isBefore(rangeStart) || startDate.isAfter(rangeEnd)) { - showRecurrence = false; - } - - if (showRecurrence === true) { - - console.log('title:' + recurrenceTitle); - console.log('startDate:' + startDate.format('MMMM Do YYYY, h:mm:ss a')); - console.log('endDate:' + endDate.format('MMMM Do YYYY, h:mm:ss a')); - console.log('duration:' + moment.duration(curDuration).humanize()); - console.log(); - } - - } - } - } -} - - diff --git a/modules/default/calendar/vendor/ical.js/examples/example_rrule.ics b/modules/default/calendar/vendor/ical.js/examples/example_rrule.ics deleted file mode 100644 index 4f72c0ecb4..0000000000 --- a/modules/default/calendar/vendor/ical.js/examples/example_rrule.ics +++ /dev/null @@ -1,40 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//Google Inc//Google Calendar 70.9054//EN -VERSION:2.0 -CALSCALE:GREGORIAN -METHOD:PUBLISH -X-WR-CALNAME:ical -X-WR-TIMEZONE:US/Central -X-WR-CALDESC: -BEGIN:VEVENT -UID:98765432-ABCD-DCBB-999A-987765432123 -DTSTART;TZID=US/Central:20170601T090000 -DTEND;TZID=US/Central:20170601T170000 -DTSTAMP:20170727T044436Z -EXDATE;TZID=US/Central:20170706T090000,20170713T090000,20170720T090000,20 - 170803T090000 -LAST-MODIFIED:20170727T044435Z -RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20170814T045959Z;BYDAY=TH -SEQUENCE:0 -SUMMARY:Recurring weekly meeting from June 1 - Aug 14 (except July 6, July 13, July 20, Aug 3) -END:VEVENT -BEGIN:VEVENT -UID:98765432-ABCD-DCBB-999A-987765432123 -RECURRENCE-ID;TZID=US/Central:20170629T090000 -DTSTART;TZID=US/Central:20170703T090000 -DTEND;TZID=US/Central:20170703T120000 -DTSTAMP:20170727T044436Z -LAST-MODIFIED:20170216T143445Z -SEQUENCE:0 -SUMMARY:Last meeting in June moved to Monday July 3 and shortened to half day -END:VEVENT -BEGIN:VEVENT -UID:12354454-ABCD-DCBB-999A-2349872354897 -DTSTART;TZID=US/Central:20171201T130000 -DTEND;TZID=US/Central:20171201T150000 -DTSTAMP:20170727T044436Z -LAST-MODIFIED:20170727T044435Z -SEQUENCE:0 -SUMMARY:Single event on Dec 1 -END:VEVENT -END:VCALENDAR \ No newline at end of file diff --git a/modules/default/calendar/vendor/ical.js/ical.js b/modules/default/calendar/vendor/ical.js/ical.js deleted file mode 100644 index 024625b750..0000000000 --- a/modules/default/calendar/vendor/ical.js/ical.js +++ /dev/null @@ -1,452 +0,0 @@ -(function(name, definition) { - -/**************** - * A tolerant, minimal icalendar parser - * (http://tools.ietf.org/html/rfc5545) - * - * - * **************/ - - if (typeof module !== 'undefined') { - module.exports = definition(); - } else if (typeof define === 'function' && typeof define.amd === 'object'){ - define(definition); - } else { - this[name] = definition(); - } - -}('ical', function(){ - - // Unescape Text re RFC 4.3.11 - var text = function(t){ - t = t || ""; - return (t - .replace(/\\\,/g, ',') - .replace(/\\\;/g, ';') - .replace(/\\[nN]/g, '\n') - .replace(/\\\\/g, '\\') - ) - } - - var parseParams = function(p){ - var out = {} - for (var i = 0; i 0) { - //trimming the leading and perform storeParam - name = name.substring(2); - return (storeParam(name))(val, params, ctx, stack, line); - } - - return storeParam(name.toLowerCase())(val, params, ctx); - }, - - - parseICS : function(str){ - var self = this - var lines = str.split(/\r?\n/) - var ctx = {} - var stack = [] - - for (var i = 0, ii = lines.length, l = lines[0]; i (peterbraden.co.uk)", - "license": "Apache-2.0", - "repository": { - "type": "git", - "url": "git://github.com/peterbraden/ical.js.git" - }, - "dependencies": { - "request": "^2.88.0", - "rrule": "2.4.1" - }, - "devDependencies": { - "vows": "0.8.2", - "underscore": "1.9.1" - }, - "scripts": { - "test": "./node_modules/vows/bin/vows ./test/test.js" - } -} diff --git a/modules/default/calendar/vendor/ical.js/readme.md b/modules/default/calendar/vendor/ical.js/readme.md deleted file mode 100644 index 5f05643605..0000000000 --- a/modules/default/calendar/vendor/ical.js/readme.md +++ /dev/null @@ -1,62 +0,0 @@ -# ical.js # -(Formerly node-ical) - -[![Build Status](https://travis-ci.org/peterbraden/ical.js.png)](https://travis-ci.org/peterbraden/ical.js) - -A tolerant, minimal icalendar parser for javascript/node -(http://tools.ietf.org/html/rfc5545) - - - -## Install - Node.js ## - -ical.js is availble on npm: - - npm install ical - - - -## API ## - - ical.parseICS(str) - -Parses a string with an ICS File - - var data = ical.parseFile(filename) - -Reads in the specified iCal file, parses it and returns the parsed data - - ical.fromURL(url, options, function(err, data) {} ) - -Use the request library to fetch the specified URL (```opts``` gets passed on to the ```request()``` call), and call the function with the result (either an error or the data). - - - -## Example 1 - Print list of upcoming node conferences (see example.js) -```javascript -'use strict'; - -const ical = require('ical'); -const months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec']; - -ical.fromURL('http://lanyrd.com/topics/nodejs/nodejs.ics', {}, function (err, data) { - for (let k in data) { - if (data.hasOwnProperty(k)) { - var ev = data[k]; - if (data[k].type == 'VEVENT') { - console.log(`${ev.summary} is in ${ev.location} on the ${ev.start.getDate()} of ${months[ev.start.getMonth()]} at ${ev.start.toLocaleTimeString('en-GB')}`); - - } - } - } -}); -``` - -## Recurrences and Exceptions ## -Calendar events with recurrence rules can be significantly more complicated to handle correctly. There are three parts to handling them: - - 1. rrule - the recurrence rule specifying the pattern of recurring dates and times for the event. - 2. recurrences - an optional array of event data that can override specific occurrences of the event. - 3. exdate - an optional array of dates that should be excluded from the recurrence pattern. - -See example_rrule.js for an example of handling recurring calendar events. diff --git a/modules/default/calendar/vendor/ical.js/test/test.js b/modules/default/calendar/vendor/ical.js/test/test.js deleted file mode 100644 index c20587a409..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test.js +++ /dev/null @@ -1,500 +0,0 @@ -/**** - * Tests - * - * - ***/ -process.env.TZ = 'America/San_Francisco'; -var ical = require('../index') - -var vows = require('vows') - , assert = require('assert') - , _ = require('underscore') - -vows.describe('node-ical').addBatch({ - 'when parsing test1.ics (node conferences schedule from lanyrd.com, modified)': { - topic: function () { - return ical.parseFile('./test/test1.ics') - } - - ,'we get 9 events': function (topic) { - var events = _.select(_.values(topic), function(x){ return x.type==='VEVENT'}) - assert.equal (events.length, 9); - } - - ,'event 47f6e' : { - topic: function(events){ - return _.select(_.values(events), - function(x){ - return x.uid ==='47f6ea3f28af2986a2192fa39a91fa7d60d26b76'})[0] - } - ,'is in fort lauderdale' : function(topic){ - assert.equal(topic.location, "Fort Lauderdale, United States") - } - ,'starts Tue, 29 Nov 2011' : function(topic){ - assert.equal(topic.start.toDateString(), new Date(2011,10,29).toDateString()) - } - } - , 'event 480a' : { - topic: function(events){ - return _.select(_.values(events), - function(x){ - return x.uid ==='480a3ad48af5ed8965241f14920f90524f533c18'})[0] - } - , 'has a summary (invalid colon handling tolerance)' : function(topic){ - assert.equal(topic.summary, '[Async]: Everything Express') - } - , 'has a date only start datetime' : function(topic){ - assert.equal(topic.start.dateOnly, true) - } - , 'has a date only end datetime' : function(topic){ - assert.equal(topic.end.dateOnly, true) - } - } - , 'event d4c8' :{ - topic : function(events){ - return _.select(_.values(events), - function(x){ - return x.uid === 'd4c826dfb701f611416d69b4df81caf9ff80b03a'})[0] - } - , 'has a start datetime' : function(topic){ - assert.equal(topic.start.toDateString(), new Date(Date.UTC(2011, 2, 12, 20, 0, 0)).toDateString()) - } - } - - , 'event sdfkf09fsd0 (Invalid Date)' :{ - topic : function(events){ - return _.select(_.values(events), - function(x){ - return x.uid === 'sdfkf09fsd0'})[0] - } - , 'has a start datetime' : function(topic){ - assert.equal(topic.start, "Next Year") - } - } - } - , 'with test2.ics (testing ical features)' : { - topic: function () { - return ical.parseFile('./test/test2.ics') - } - , 'todo item uid4@host1.com' : { - topic : function(items){ - return items['uid4@host1.com'] - } - , 'is a VTODO' : function(topic){ - assert.equal(topic.type, 'VTODO') - } - } - , 'vfreebusy' : { - topic: function(events) { - return _.select(_.values(events), function(x) { - return x.type === 'VFREEBUSY'; - })[0]; - } - , 'has a URL' : function(topic) { - assert.equal(topic.url, 'http://www.host.com/calendar/busytime/jsmith.ifb'); - } - } - , 'vfreebusy first freebusy' : { - topic: function(events) { - return _.select(_.values(events), function(x) { - return x.type === 'VFREEBUSY'; - })[0].freebusy[0]; - } - , 'has undefined type defaulting to busy' : function(topic) { - assert.equal(topic.type, "BUSY"); - } - , 'has an start datetime' : function(topic) { - assert.equal(topic.start.getFullYear(), 1998); - assert.equal(topic.start.getUTCMonth(), 2); - assert.equal(topic.start.getUTCDate(), 14); - assert.equal(topic.start.getUTCHours(), 23); - assert.equal(topic.start.getUTCMinutes(), 30); - } - , 'has an end datetime' : function(topic) { - assert.equal(topic.end.getFullYear(), 1998); - assert.equal(topic.end.getUTCMonth(), 2); - assert.equal(topic.end.getUTCDate(), 15); - assert.equal(topic.end.getUTCHours(), 00); - assert.equal(topic.end.getUTCMinutes(), 30); - } - } - } - , 'with test3.ics (testing tvcountdown.com)' : { - topic: function() { - return ical.parseFile('./test/test3.ics'); - } - , 'event -83' : { - topic: function(events) { - return _.select(_.values(events), function(x) { - return x.uid === '20110505T220000Z-83@tvcountdown.com'; - })[0]; - } - , 'has a start datetime' : function(topic) { - assert.equal(topic.start.getFullYear(), 2011); - assert.equal(topic.start.getMonth(), 4); - } - , 'has an end datetime' : function(topic) { - assert.equal(topic.end.getFullYear(), 2011); - assert.equal(topic.end.getMonth(), 4); - } - } - } - - , 'with test4.ics (testing tripit.com)' : { - topic: function() { - return ical.parseFile('./test/test4.ics'); - } - , 'event c32a5...' : { - topic: function(events) { - return _.select(_.values(events), function(x) { - return x.uid === 'c32a5eaba2354bb29e012ec18da827db90550a3b@tripit.com'; - })[0]; - } - , 'has a start datetime' : function(topic) { - assert.equal(topic.start.getFullYear(), 2011); - assert.equal(topic.start.getMonth(), 09); - assert.equal(topic.start.getDate(), 11); - } - - , 'has a summary' : function(topic){ - // escaped commas and semicolons should be replaced - assert.equal(topic.summary, 'South San Francisco, CA, October 2011;') - - } - - , 'has a description' : function(topic){ - var desired = 'John Doe is in South San Francisco, CA from Oct 11 ' + - 'to Oct 13, 2011\nView and/or edit details in TripIt : http://www.tripit.c' + - 'om/trip/show/id/23710889\nTripIt - organize your travel at http://www.trip' + - 'it.com\n' - assert.equal(topic.description, desired) - - } - - , 'has a geolocation' : function(topic){ - assert.ok(topic.geo, 'no geo param') - assert.equal(topic.geo.lat, 37.654656) - assert.equal(topic.geo.lon, -122.40775) - } - - , 'has transparency' : function(topic){ - assert.equal(topic.transparency, 'TRANSPARENT') - } - - } - } - - - - , 'with test5.ics (testing meetup.com)' : { - topic: function () { - return ical.parseFile('./test/test5.ics') - } - , 'event nsmxnyppbfc@meetup.com' : { - topic: function(events) { - return _.select(_.values(events), function(x) { - return x.uid === 'event_nsmxnyppbfc@meetup.com'; - })[0]; - } - , 'has a start' : function(topic){ - assert.equal(topic.start.tz, 'America/Phoenix') - assert.equal(topic.start.toISOString(), new Date(2011, 10, 09, 19, 0,0).toISOString()) - } - } - } - - , 'with test6.ics (testing assembly.org)': { - topic: function () { - return ical.parseFile('./test/test6.ics') - } - , 'event with no ID' : { - topic: function(events) { - return _.select(_.values(events), function(x) { - return x.summary === 'foobar Summer 2011 starts!'; - })[0]; - } - , 'has a start' : function(topic){ - assert.equal(topic.start.toISOString(), new Date(2011, 07, 04, 12, 0,0).toISOString()) - } - } - , 'event with rrule' :{ - topic: function(events){ - return _.select(_.values(events), function(x){ - return x.summary === "foobarTV broadcast starts" - })[0]; - } - , "Has an RRULE": function(topic){ - assert.notEqual(topic.rrule, undefined); - } - , "RRule text": function(topic){ - assert.equal(topic.rrule.toText(), "every 5 weeks on Monday, Friday until January 30, 2013") - } - } - } - , 'with test7.ics (testing dtstart of rrule)' :{ - topic: function() { - return ical.parseFile('./test/test7.ics'); - }, - 'recurring yearly event (14 july)': { - topic: function(events){ - var ev = _.values(events)[0]; - return ev.rrule.between(new Date(2013, 0, 1), new Date(2014, 0, 1)); - }, - 'dt start well set': function(topic) { - assert.equal(topic[0].toDateString(), new Date(2013, 6, 14).toDateString()); - } - } - } - , "with test 8.ics (VTODO completion)": { - topic: function() { - return ical.parseFile('./test/test8.ics'); - }, - 'grabbing VTODO task': { - topic: function(topic) { - return _.values(topic)[0]; - }, - 'task completed': function(task){ - assert.equal(task.completion, 100); - assert.equal(task.completed.toISOString(), new Date(2013, 06, 16, 10, 57, 45).toISOString()); - } - } - } - , "with test 9.ics (VEVENT with VALARM)": { - topic: function() { - return ical.parseFile('./test/test9.ics'); - }, - 'grabbing VEVENT task': { - topic: function(topic) { - return _.values(topic)[0]; - }, - 'task completed': function(task){ - assert.equal(task.summary, "Event with an alarm"); - } - } - } - , 'with test 11.ics (VEVENT with custom properties)': { - topic: function() { - return ical.parseFile('./test10.ics'); - }, - 'grabbing custom properties': { - topic: function(topic) { - - } - } - }, - - 'with test10.ics': { - topic: function () { - return ical.parseFile('./test/test10.ics'); - }, - - 'when categories present': { - topic: function (t) {return _.values(t)[0]}, - - 'should be a list': function (e) { - assert(e.categories instanceof [].constructor); - }, - - 'should contain individual category values': function (e) { - assert.deepEqual(e.categories, ['cat1', 'cat2', 'cat3']); - } - }, - - 'when categories present with trailing whitespace': { - topic: function (t) {return _.values(t)[1]}, - - 'should contain individual category values without whitespace': function (e) { - assert.deepEqual(e.categories, ['cat1', 'cat2', 'cat3']); - } - }, - - 'when categories present but empty': { - topic: function (t) {return _.values(t)[2]}, - - 'should be an empty list': function (e) { - assert.deepEqual(e.categories, []); - } - }, - - 'when categories present but singular': { - topic: function (t) {return _.values(t)[3]}, - - 'should be a list of single item': function (e) { - assert.deepEqual(e.categories, ['lonely-cat']); - } - }, - - 'when categories present on multiple lines': { - topic: function (t) {return _.values(t)[4]}, - - 'should contain the category values in an array': function (e) { - assert.deepEqual(e.categories, ['cat1', 'cat2', 'cat3']); - } - } - }, - - 'with test11.ics (testing zimbra freebusy)': { - topic: function () { - return ical.parseFile('./test/test11.ics'); - }, - - 'freebusy params' : { - topic: function(events) { - return _.values(events)[0]; - } - , 'has a URL' : function(topic) { - assert.equal(topic.url, 'http://mail.example.com/yvr-2a@example.com/20140416'); - } - , 'has an ORGANIZER' : function(topic) { - assert.equal(topic.organizer, 'mailto:yvr-2a@example.com'); - } - , 'has an start datetime' : function(topic) { - assert.equal(topic.start.getFullYear(), 2014); - assert.equal(topic.start.getMonth(), 3); - } - , 'has an end datetime' : function(topic) { - assert.equal(topic.end.getFullYear(), 2014); - assert.equal(topic.end.getMonth(), 6); - } - } - , 'freebusy busy events' : { - topic: function(events) { - return _.select(_.values(events)[0].freebusy, function(x) { - return x.type === 'BUSY'; - })[0]; - } - , 'has an start datetime' : function(topic) { - assert.equal(topic.start.getFullYear(), 2014); - assert.equal(topic.start.getMonth(), 3); - assert.equal(topic.start.getUTCHours(), 15); - assert.equal(topic.start.getUTCMinutes(), 15); - } - , 'has an end datetime' : function(topic) { - assert.equal(topic.end.getFullYear(), 2014); - assert.equal(topic.end.getMonth(), 3); - assert.equal(topic.end.getUTCHours(), 19); - assert.equal(topic.end.getUTCMinutes(), 00); - } - } - } - - , 'with test12.ics (testing recurrences and exdates)': { - topic: function () { - return ical.parseFile('./test/test12.ics') - } - , 'event with rrule': { - topic: function (events) { - return _.select(_.values(events), function (x) { - return x.uid === '0000001'; - })[0]; - } - , "Has an RRULE": function (topic) { - assert.notEqual(topic.rrule, undefined); - } - , "Has summary Treasure Hunting": function (topic) { - assert.equal(topic.summary, 'Treasure Hunting'); - } - , "Has two EXDATES": function (topic) { - assert.notEqual(topic.exdate, undefined); - assert.notEqual(topic.exdate[new Date(2015, 06, 08, 12, 0, 0).toISOString().substring(0, 10)], undefined); - assert.notEqual(topic.exdate[new Date(2015, 06, 10, 12, 0, 0).toISOString().substring(0, 10)], undefined); - } - , "Has a RECURRENCE-ID override": function (topic) { - assert.notEqual(topic.recurrences, undefined); - assert.notEqual(topic.recurrences[new Date(2015, 06, 07, 12, 0, 0).toISOString().substring(0, 10)], undefined); - assert.equal(topic.recurrences[new Date(2015, 06, 07, 12, 0, 0).toISOString().substring(0, 10)].summary, 'More Treasure Hunting'); - } - } - } - - , 'with test13.ics (testing recurrence-id before rrule)': { - topic: function () { - return ical.parseFile('./test/test13.ics') - } - , 'event with rrule': { - topic: function (events) { - return _.select(_.values(events), function (x) { - return x.uid === '6m2q7kb2l02798oagemrcgm6pk@google.com'; - })[0]; - } - , "Has an RRULE": function (topic) { - assert.notEqual(topic.rrule, undefined); - } - , "Has summary 'repeated'": function (topic) { - assert.equal(topic.summary, 'repeated'); - } - , "Has a RECURRENCE-ID override": function (topic) { - assert.notEqual(topic.recurrences, undefined); - assert.notEqual(topic.recurrences[new Date(2016, 7, 26, 14, 0, 0).toISOString().substring(0, 10)], undefined); - assert.equal(topic.recurrences[new Date(2016, 7, 26, 14, 0, 0).toISOString().substring(0, 10)].summary, 'bla bla'); - } - } - } - - , 'with test14.ics (testing comma-separated exdates)': { - topic: function () { - return ical.parseFile('./test/test14.ics') - } - , 'event with comma-separated exdate': { - topic: function (events) { - return _.select(_.values(events), function (x) { - return x.uid === '98765432-ABCD-DCBB-999A-987765432123'; - })[0]; - } - , "Has summary 'Example of comma-separated exdates'": function (topic) { - assert.equal(topic.summary, 'Example of comma-separated exdates'); - } - , "Has four comma-separated EXDATES": function (topic) { - assert.notEqual(topic.exdate, undefined); - // Verify the four comma-separated EXDATES are there - assert.notEqual(topic.exdate[new Date(2017, 6, 6, 12, 0, 0).toISOString().substring(0, 10)], undefined); - assert.notEqual(topic.exdate[new Date(2017, 6, 17, 12, 0, 0).toISOString().substring(0, 10)], undefined); - assert.notEqual(topic.exdate[new Date(2017, 6, 20, 12, 0, 0).toISOString().substring(0, 10)], undefined); - assert.notEqual(topic.exdate[new Date(2017, 7, 3, 12, 0, 0).toISOString().substring(0, 10)], undefined); - // Verify an arbitrary date isn't there - assert.equal(topic.exdate[new Date(2017, 4, 5, 12, 0, 0).toISOString().substring(0, 10)], undefined); - } - } - } - - , 'with test14.ics (testing exdates with bad times)': { - topic: function () { - return ical.parseFile('./test/test14.ics') - } - , 'event with exdates with bad times': { - topic: function (events) { - return _.select(_.values(events), function (x) { - return x.uid === '1234567-ABCD-ABCD-ABCD-123456789012'; - })[0]; - } - , "Has summary 'Example of exdate with bad times'": function (topic) { - assert.equal(topic.summary, 'Example of exdate with bad times'); - } - , "Has two EXDATES even though they have bad times": function (topic) { - assert.notEqual(topic.exdate, undefined); - // Verify the two EXDATES are there, even though they have bad times - assert.notEqual(topic.exdate[new Date(2017, 11, 18, 12, 0, 0).toISOString().substring(0, 10)], undefined); - assert.notEqual(topic.exdate[new Date(2017, 11, 19, 12, 0, 0).toISOString().substring(0, 10)], undefined); - } - } - } - - , 'url request errors': { - topic : function () { - ical.fromURL('http://255.255.255.255/', {}, this.callback); - } - , 'are passed back to the callback' : function (err, result) { - assert.instanceOf(err, Error); - if (!err){ - console.log(">E:", err, result) - } - } - } -}).export(module) - - -//ical.fromURL('http://lanyrd.com/topics/nodejs/nodejs.ics', -// {}, -// function(err, data){ -// console.log("OUT:", data) -// }) diff --git a/modules/default/calendar/vendor/ical.js/test/test1.ics b/modules/default/calendar/vendor/ical.js/test/test1.ics deleted file mode 100644 index ff8cc076af..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test1.ics +++ /dev/null @@ -1,78 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//lanyrd.com//Lanyrd//EN -X-ORIGINAL-URL:http://lanyrd.com/topics/nodejs/nodejs.ics -X-WR-CALNAME;CHARSET=utf-8:Node.js conferences -VERSION:2.0 -METHOD:PUBLISH -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:Dyncon 2011 -LOCATION;CHARSET=utf-8:Stockholm, Sweden -URL:http://lanyrd.com/2011/dyncon/ -UID:d4c826dfb701f611416d69b4df81caf9ff80b03a -DTSTART:20110312T200000Z -DTEND;VALUE=DATE:20110314 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:[Async]: Everything Express -LOCATION;CHARSET=utf-8:Brighton, United Kingdom -URL:http://lanyrd.com/2011/asyncjs-express/ -UID:480a3ad48af5ed8965241f14920f90524f533c18 -DTSTART;VALUE=DATE:20110324 -DTEND;VALUE=DATE:20110325 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:JSConf US 2011 -LOCATION;CHARSET=utf-8:Portland, United States -URL:http://lanyrd.com/2011/jsconf/ -UID:ed334cc85db5ebdff5ff5a630a7a48631a677dbe -DTSTART;VALUE=DATE:20110502 -DTEND;VALUE=DATE:20110504 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:NodeConf 2011 -LOCATION;CHARSET=utf-8:Portland, United States -URL:http://lanyrd.com/2011/nodeconf/ -UID:25169a7b1ba5c248278f47120a40878055dc8c15 -DTSTART;VALUE=DATE:20110505 -DTEND;VALUE=DATE:20110506 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:BrazilJS -LOCATION;CHARSET=utf-8:Fortaleza, Brazil -URL:http://lanyrd.com/2011/braziljs/ -UID:dafee3be83624f3388c5635662229ff11766bb9c -DTSTART;VALUE=DATE:20110513 -DTEND;VALUE=DATE:20110515 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:Falsy Values -LOCATION;CHARSET=utf-8:Warsaw, Poland -URL:http://lanyrd.com/2011/falsy-values/ -UID:73cad6a09ac4e7310979c6130f871d17d990b5ad -DTSTART;VALUE=DATE:20110518 -DTEND;VALUE=DATE:20110521 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:nodecamp.eu -LOCATION;CHARSET=utf-8:Cologne, Germany -URL:http://lanyrd.com/2011/nodecampde/ -UID:b728a5fdb5f292b6293e4a2fd97a1ccfc69e9d6f -DTSTART;VALUE=DATE:20110611 -DTEND;VALUE=DATE:20110613 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:Rich Web Experience 2011 -LOCATION;CHARSET=utf-8:Fort Lauderdale, United States -URL:http://lanyrd.com/2011/rich-web-experience/ -UID:47f6ea3f28af2986a2192fa39a91fa7d60d26b76 -DTSTART;VALUE=DATE:20111129 -DTEND;VALUE=DATE:20111203 -END:VEVENT -BEGIN:VEVENT -SUMMARY;CHARSET=utf-8:Foobar -UID:sdfkf09fsd0 -DTSTART;VALUE=DATE:Next Year -DTEND;VALUE=DATE:20111203 -END:VEVENT - -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test10.ics b/modules/default/calendar/vendor/ical.js/test/test10.ics deleted file mode 100644 index 40763b3b4c..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test10.ics +++ /dev/null @@ -1,34 +0,0 @@ -BEGIN:VCALENDAR -BEGIN:VEVENT -UID:1 -SUMMARY:Event with a category -DESCRIPTION:Details for an event with a category -CATEGORIES:cat1,cat2,cat3 -END:VEVENT -BEGIN:VEVENT -UID:2 -SUMMARY:Event with a category -DESCRIPTION:Details for an event with a category -CATEGORIES:cat1 , cat2, cat3 -END:VEVENT -BEGIN:VEVENT -UID:3 -SUMMARY:Event with a category -DESCRIPTION:Details for an event with a category -CATEGORIES: -END:VEVENT -BEGIN:VEVENT -UID:4 -SUMMARY:Event with a category -DESCRIPTION:Details for an event with a category -CATEGORIES:lonely-cat -END:VEVENT -BEGIN:VEVENT -UID:5 -SUMMARY:Event with a category -DESCRIPTION:Details for an event with a category -CATEGORIES:cat1 -CATEGORIES:cat2 -CATEGORIES:cat3 -END:VEVENT -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test11.ics b/modules/default/calendar/vendor/ical.js/test/test11.ics deleted file mode 100644 index 3a7e80de9a..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test11.ics +++ /dev/null @@ -1,41 +0,0 @@ -BEGIN:VCALENDAR -PRODID:Zimbra-Calendar-Provider -VERSION:2.0 -METHOD:PUBLISH -BEGIN:VFREEBUSY -ORGANIZER:mailto:yvr-2a@example.com -DTSTAMP:20140516T235436Z -DTSTART:20140415T235436Z -DTEND:20140717T235436Z -URL:http://mail.example.com/yvr-2a@example.com/20140416 -FREEBUSY;FBTYPE=BUSY:20140416T151500Z/20140416T190000Z -FREEBUSY;FBTYPE=BUSY:20140416T195500Z/20140416T231500Z -FREEBUSY;FBTYPE=BUSY:20140417T193000Z/20140417T203000Z -FREEBUSY;FBTYPE=BUSY:20140421T210000Z/20140421T213000Z -FREEBUSY;FBTYPE=BUSY:20140423T180000Z/20140423T190000Z -FREEBUSY;FBTYPE=BUSY:20140423T200000Z/20140423T210000Z -FREEBUSY;FBTYPE=BUSY:20140423T223500Z/20140423T231500Z -FREEBUSY;FBTYPE=BUSY:20140424T155000Z/20140424T165500Z -FREEBUSY;FBTYPE=BUSY:20140424T170000Z/20140424T183000Z -FREEBUSY;FBTYPE=BUSY:20140424T195000Z/20140424T230000Z -FREEBUSY;FBTYPE=BUSY:20140425T144500Z/20140425T161500Z -FREEBUSY;FBTYPE=BUSY:20140425T180000Z/20140425T194500Z -FREEBUSY;FBTYPE=BUSY:20140425T223000Z/20140425T230000Z -FREEBUSY;FBTYPE=BUSY:20140428T151500Z/20140428T163000Z -FREEBUSY;FBTYPE=BUSY:20140428T170000Z/20140428T173000Z -FREEBUSY;FBTYPE=BUSY:20140428T195500Z/20140428T213000Z -FREEBUSY;FBTYPE=BUSY:20140428T231000Z/20140428T234000Z -FREEBUSY;FBTYPE=BUSY:20140429T152500Z/20140429T170000Z -FREEBUSY;FBTYPE=BUSY:20140429T180000Z/20140429T183000Z -FREEBUSY;FBTYPE=BUSY:20140429T201500Z/20140429T230000Z -FREEBUSY;FBTYPE=BUSY:20140430T162500Z/20140430T165500Z -FREEBUSY;FBTYPE=BUSY:20140430T180000Z/20140430T190000Z -FREEBUSY;FBTYPE=BUSY:20140501T170000Z/20140501T173000Z -FREEBUSY;FBTYPE=BUSY:20140501T175000Z/20140501T190000Z -FREEBUSY;FBTYPE=BUSY:20140501T232000Z/20140501T235000Z -FREEBUSY;FBTYPE=BUSY:20140502T163500Z/20140502T173000Z -FREEBUSY;FBTYPE=BUSY:20140505T165500Z/20140505T173000Z -FREEBUSY;FBTYPE=BUSY:20140505T201500Z/20140505T203000Z -FREEBUSY;FBTYPE=BUSY:20140505T210000Z/20140505T213000Z -END:VFREEBUSY -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test12.ics b/modules/default/calendar/vendor/ical.js/test/test12.ics deleted file mode 100644 index 4e78603b03..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test12.ics +++ /dev/null @@ -1,19 +0,0 @@ -BEGIN:VCALENDAR -BEGIN:VEVENT -UID:0000001 -SUMMARY:Treasure Hunting -DTSTART;TZID=America/Los_Angeles:20150706T120000 -DTEND;TZID=America/Los_Angeles:20150706T130000 -RRULE:FREQ=DAILY;COUNT=10 -EXDATE;TZID=America/Los_Angeles:20150708T120000 -EXDATE;TZID=America/Los_Angeles:20150710T120000 -END:VEVENT -BEGIN:VEVENT -UID:0000001 -SUMMARY:More Treasure Hunting -LOCATION:The other island -DTSTART;TZID=America/Los_Angeles:20150709T150000 -DTEND;TZID=America/Los_Angeles:20150707T160000 -RECURRENCE-ID;TZID=America/Los_Angeles:20150707T120000 -END:VEVENT -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test13.ics b/modules/default/calendar/vendor/ical.js/test/test13.ics deleted file mode 100644 index 3118186bed..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test13.ics +++ /dev/null @@ -1,57 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//Google Inc//Google Calendar 70.9054//EN -VERSION:2.0 -CALSCALE:GREGORIAN -METHOD:PUBLISH -X-WR-CALNAME:ical -X-WR-TIMEZONE:Europe/Kiev -X-WR-CALDESC: -BEGIN:VTIMEZONE -TZID:Europe/Kiev -X-LIC-LOCATION:Europe/Kiev -BEGIN:DAYLIGHT -TZOFFSETFROM:+0200 -TZOFFSETTO:+0300 -TZNAME:EEST -DTSTART:19700329T030000 -RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU -END:DAYLIGHT -BEGIN:STANDARD -TZOFFSETFROM:+0300 -TZOFFSETTO:+0200 -TZNAME:EET -DTSTART:19701025T040000 -RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU -END:STANDARD -END:VTIMEZONE -BEGIN:VEVENT -DTSTART;TZID=Europe/Kiev:20160826T140000 -DTEND;TZID=Europe/Kiev:20160826T150000 -DTSTAMP:20160825T061505Z -UID:6m2q7kb2l02798oagemrcgm6pk@google.com -RECURRENCE-ID;TZID=Europe/Kiev:20160826T140000 -CREATED:20160823T125221Z -DESCRIPTION: -LAST-MODIFIED:20160823T130320Z -LOCATION: -SEQUENCE:0 -STATUS:CONFIRMED -SUMMARY:bla bla -TRANSP:OPAQUE -END:VEVENT -BEGIN:VEVENT -DTSTART;TZID=Europe/Kiev:20160825T140000 -DTEND;TZID=Europe/Kiev:20160825T150000 -RRULE:FREQ=DAILY;UNTIL=20160828T110000Z -DTSTAMP:20160825T061505Z -UID:6m2q7kb2l02798oagemrcgm6pk@google.com -CREATED:20160823T125221Z -DESCRIPTION: -LAST-MODIFIED:20160823T125221Z -LOCATION: -SEQUENCE:0 -STATUS:CONFIRMED -SUMMARY:repeated -TRANSP:OPAQUE -END:VEVENT -END:VCALENDAR \ No newline at end of file diff --git a/modules/default/calendar/vendor/ical.js/test/test14.ics b/modules/default/calendar/vendor/ical.js/test/test14.ics deleted file mode 100644 index 5c4f5cafb8..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test14.ics +++ /dev/null @@ -1,33 +0,0 @@ -BEGIN:VCALENDAR -PRODID:-//Google Inc//Google Calendar 70.9054//EN -VERSION:2.0 -CALSCALE:GREGORIAN -METHOD:PUBLISH -X-WR-CALNAME:ical -X-WR-TIMEZONE:Europe/Kiev -X-WR-CALDESC: -BEGIN:VEVENT -UID:98765432-ABCD-DCBB-999A-987765432123 -DTSTART;TZID=US/Central:20170216T090000 -DTEND;TZID=US/Central:20170216T190000 -DTSTAMP:20170727T044436Z -EXDATE;TZID=US/Central:20170706T090000,20170717T090000,20170720T090000,20 - 170803T090000 -LAST-MODIFIED:20170727T044435Z -RRULE:FREQ=WEEKLY;WKST=SU;UNTIL=20170814T045959Z;INTERVAL=2;BYDAY=MO,TH -SEQUENCE:0 -SUMMARY:Example of comma-separated exdates -END:VEVENT -BEGIN:VEVENT -UID:1234567-ABCD-ABCD-ABCD-123456789012 -DTSTART:20170814T140000Z -DTEND:20170815T000000Z -DTSTAMP:20171204T134925Z -EXDATE:20171219T060000 -EXDATE:20171218T060000 -LAST-MODIFIED:20171024T140004Z -RRULE:FREQ=WEEKLY;WKST=SU;INTERVAL=2;BYDAY=MO,TU -SEQUENCE:0 -SUMMARY:Example of exdate with bad times -END:VEVENT -END:VCALENDAR \ No newline at end of file diff --git a/modules/default/calendar/vendor/ical.js/test/test2.ics b/modules/default/calendar/vendor/ical.js/test/test2.ics deleted file mode 100644 index 29baf8cd92..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test2.ics +++ /dev/null @@ -1,83 +0,0 @@ -BEGIN:VCALENDAR -CALSCALE:GREGORIAN -X-WR-TIMEZONE;VALUE=TEXT:US/Pacific -METHOD:PUBLISH -PRODID:-//Apple Computer\, Inc//iCal 1.0//EN -X-WR-CALNAME;VALUE=TEXT:Example -VERSION:2.0 -BEGIN:VEVENT -SEQUENCE:5 -DTSTART;TZID=US/Pacific:20021028T140000 -DTSTAMP:20021028T011706Z -SUMMARY:Coffee with Jason -UID:EC9439B1-FF65-11D6-9973-003065F99D04 -DTEND;TZID=US/Pacific:20021028T150000 -END:VEVENT -BEGIN:VALARM -TRIGGER;VALUE=DURATION:-P1D -ACTION:DISPLAY -DESCRIPTION:Event reminder -END:VALARM -BEGIN:VEVENT -SEQUENCE:1 -DTSTAMP:20021128T012034Z -SUMMARY:Code Review -UID:EC944331-FF65-11D6-9973-003065F99D04 -DTSTART;TZID=US/Pacific:20021127T120000 -DURATION:PT1H -END:VEVENT -BEGIN:VEVENT -SEQUENCE:1 -DTSTAMP:20021028T012034Z -SUMMARY:Dinner with T -UID:EC944CFA-FF65-11D6-9973-003065F99D04 -DTSTART;TZID=US/Pacific:20021216T200000 -DURATION:PT1H -END:VEVENT -BEGIN:VTODO -DTSTAMP:19980130T134500Z -SEQUENCE:2 -UID:uid4@host1.com -ORGANIZER:MAILTO:unclesam@us.gov -ATTENDEE;PARTSTAT=ACCEPTED:MAILTO:jqpublic@host.com -DUE:19980415T235959 -STATUS:NEEDS-ACTION -SUMMARY:Submit Income Taxes -END:VTODO -BEGIN:VALARM -ACTION:AUDIO -TRIGGER:19980403T120000 -ATTACH;FMTTYPE=audio/basic:http://host.com/pub/audio- - files/ssbanner.aud -REPEAT:4 -DURATION:PT1H -END:VALARM -BEGIN:VJOURNAL -DTSTAMP:19970324T120000Z -UID:uid5@host1.com -ORGANIZER:MAILTO:jsmith@host.com -STATUS:DRAFT -CLASS:PUBLIC -CATEGORY:Project Report, XYZ, Weekly Meeting -DESCRIPTION:Project xyz Review Meeting Minutes\n - Agenda\n1. Review of project version 1.0 requirements.\n2. - Definition - of project processes.\n3. Review of project schedule.\n - Participants: John Smith, Jane Doe, Jim Dandy\n-It was - decided that the requirements need to be signed off by - product marketing.\n-Project processes were accepted.\n - -Project schedule needs to account for scheduled holidays - and employee vacation time. Check with HR for specific - dates.\n-New schedule will be distributed by Friday.\n- - Next weeks meeting is cancelled. No meeting until 3/23. -END:VJOURNAL -BEGIN:VFREEBUSY -ORGANIZER:MAILTO:jsmith@host.com -DTSTART:19980313T141711Z -DTEND:19980410T141711Z -FREEBUSY:19980314T233000Z/19980315T003000Z -FREEBUSY:19980316T153000Z/19980316T163000Z -FREEBUSY:19980318T030000Z/19980318T040000Z -URL:http://www.host.com/calendar/busytime/jsmith.ifb -END:VFREEBUSY -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test3.ics b/modules/default/calendar/vendor/ical.js/test/test3.ics deleted file mode 100644 index ee7111e7a4..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test3.ics +++ /dev/null @@ -1,226 +0,0 @@ -BEGIN:VCALENDAR -CALSCALE:GREGORIAN -PRODID:tvcountdown.com -X-WR-CALNAME:tvcountdown.com -VERSION:2.0 -METHOD:PUBLISH -X-WR-TIMEZONE:US/Eastern -X-WR-CALNAME;VALUE=TEXT:tvcountdown.com -X-WR-CALDESC: -BEGIN:VEVENT -UID:20110519T200000Z-79@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110519T200000 -DTEND;VALUE=DATE-TIME:20110519T203000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Big Bang Theory - S04E24 - The Roomate Transmogrfication -END:VEVENT -BEGIN:VEVENT -UID:20110512T200000Z-79@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110512T200000 -DTEND;VALUE=DATE-TIME:20110512T203000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Big Bang Theory - S04E23 - The Engagement Reaction -END:VEVENT -BEGIN:VEVENT -UID:20110505T220000Z-83@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110505T220000 -DTEND;VALUE=DATE-TIME:20110505T223000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:30 Rock - S05E23 - Respawn -END:VEVENT -BEGIN:VEVENT -UID:20110505T200000Z-79@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110505T200000 -DTEND;VALUE=DATE-TIME:20110505T203000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Big Bang Theory - S04E22 - The Wildebeest Implementation -END:VEVENT -BEGIN:VEVENT -UID:20110504T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110504T230000 -DTEND;VALUE=DATE-TIME:20110504T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E59 - David Barton -END:VEVENT -BEGIN:VEVENT -UID:20110503T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110503T230000 -DTEND;VALUE=DATE-TIME:20110503T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E58 - Rachel Maddow -END:VEVENT -BEGIN:VEVENT -UID:20110502T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110502T230000 -DTEND;VALUE=DATE-TIME:20110502T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E57 - Philip K. Howard -END:VEVENT -BEGIN:VEVENT -UID:20110428T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110428T230000 -DTEND;VALUE=DATE-TIME:20110428T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E56 - William Cohan -END:VEVENT -BEGIN:VEVENT -UID:20110428T220000Z-83@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110428T220000 -DTEND;VALUE=DATE-TIME:20110428T223000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:30 Rock - S05E22 - Everything Sunny All the Time Always -END:VEVENT -BEGIN:VEVENT -UID:20110428T200000Z-79@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110428T200000 -DTEND;VALUE=DATE-TIME:20110428T203000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Big Bang Theory - S04E21 - The Agreement Dissection -END:VEVENT -BEGIN:VEVENT -UID:20110427T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110427T230000 -DTEND;VALUE=DATE-TIME:20110427T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E55 - Sen. Bernie Sanders -END:VEVENT -BEGIN:VEVENT -UID:20110426T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110426T230000 -DTEND;VALUE=DATE-TIME:20110426T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E54 - Elizabeth Warren -END:VEVENT -BEGIN:VEVENT -UID:20110425T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110425T230000 -DTEND;VALUE=DATE-TIME:20110425T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E53 - Gigi Ibrahim -END:VEVENT -BEGIN:VEVENT -UID:20110421T220000Z-83@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110421T220000 -DTEND;VALUE=DATE-TIME:20110421T223000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:30 Rock - S05E21 - 100th Episode Part 2 of 2 -END:VEVENT -BEGIN:VEVENT -UID:20110421T220000Z-83@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110421T220000 -DTEND;VALUE=DATE-TIME:20110421T223000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:30 Rock - S05E20 - 100th Episode Part 1 of 2 -END:VEVENT -BEGIN:VEVENT -UID:20110414T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110414T230000 -DTEND;VALUE=DATE-TIME:20110414T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E52 - Ricky Gervais -END:VEVENT -BEGIN:VEVENT -UID:20110414T220000Z-83@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110414T220000 -DTEND;VALUE=DATE-TIME:20110414T223000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:30 Rock - S05E19 - I Heart Connecticut -END:VEVENT -BEGIN:VEVENT -UID:20110413T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110413T230000 -DTEND;VALUE=DATE-TIME:20110413T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E51 - Tracy Morgan -END:VEVENT -BEGIN:VEVENT -UID:20110412T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110412T230000 -DTEND;VALUE=DATE-TIME:20110412T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E50 - Gov. Deval Patrick -END:VEVENT -BEGIN:VEVENT -UID:20110411T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110411T230000 -DTEND;VALUE=DATE-TIME:20110411T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E49 - Foo Fighters -END:VEVENT -BEGIN:VEVENT -UID:20110407T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110407T230000 -DTEND;VALUE=DATE-TIME:20110407T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E48 - Jamie Oliver -END:VEVENT -BEGIN:VEVENT -UID:20110407T200000Z-79@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110407T200000 -DTEND;VALUE=DATE-TIME:20110407T203000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Big Bang Theory - S04E20 - The Herb Garden Germination -END:VEVENT -BEGIN:VEVENT -UID:20110406T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110406T230000 -DTEND;VALUE=DATE-TIME:20110406T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E47 - Mike Huckabee -END:VEVENT -BEGIN:VEVENT -UID:20110405T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110405T230000 -DTEND;VALUE=DATE-TIME:20110405T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E46 - Colin Quinn -END:VEVENT -BEGIN:VEVENT -UID:20110404T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110404T230000 -DTEND;VALUE=DATE-TIME:20110404T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E45 - Billy Crystal -END:VEVENT -BEGIN:VEVENT -UID:20110331T230000Z-289@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110331T230000 -DTEND;VALUE=DATE-TIME:20110331T233000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Daily Show - S16E44 - Norm MacDonald -END:VEVENT -BEGIN:VEVENT -UID:20110331T200000Z-79@tvcountdown.com -DTSTART;VALUE=DATE-TIME:20110331T200000 -DTEND;VALUE=DATE-TIME:20110331T203000 -DTSTAMP:20110430T192946Z -URL;VALUE=URI: -SUMMARY:The Big Bang Theory - S04E19 - The Zarnecki Incursion -END:VEVENT -END:VCALENDAR \ No newline at end of file diff --git a/modules/default/calendar/vendor/ical.js/test/test4.ics b/modules/default/calendar/vendor/ical.js/test/test4.ics deleted file mode 100644 index 390a404c15..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test4.ics +++ /dev/null @@ -1,747 +0,0 @@ -BEGIN:VCALENDAR -X-WR-CALNAME:John Doe (TripIt) -X-WR-CALDESC:TripIt Calendar -X-PUBLISHED-TTL:PT15M -PRODID:-//John Doe/NONSGML Bennu 0.1//EN -VERSION:2.0 -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -UID:c32a5eaba2354bb29e012ec18da827db90550a3b@tripit.com -DTSTART;VALUE=DATE:20111011 -DTEND;VALUE=DATE:20111014 -SUMMARY:South San Francisco\, CA\, October 2011\; -LOCATION:South San Francisco\, CA -GEO:37.654656;-122.40775 -TRANSP:TRANSPARENT -DESCRIPTION:John Doe is in South San Francisco\, CA from Oct 11 - to Oct 13\, 2011\nView and/or edit details in TripIt : http://www.tripit.c - om/trip/show/id/23710889\nTripIt - organize your travel at http://www.trip - it.com\n -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -TRANSP:TRANSPARENT -UID:item-ee275ccffa83f492d9eb63b01953b39f18d4f944@tripit.com -DTSTART:20111011T100500 -DTEND:20111011T110500 -SUMMARY:Directions from SFO to Embassy Suites San Francisco Airport - Sout - h San Francisco -LOCATION:250 GATEWAY BLVD\, South San Francisco\, CA\, 94080 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/1234\n \n[Directions] 10/11/2011 10:05am - Directions from S - FO to Embassy Suites San Francisco Airport - South San Francisco \nfrom: S - FO \nto: 250 GATEWAY BLVD\, South San Francisco\, CA\, 94080 \nView direct - ions here: http://maps.google.com/maps?output=mobile&saddr=SFO&daddr=250+G - ATEWAY+BLVD%2C+South+San+Francisco%2C+CA%2C+94080 \n \n \n\nTripIt - organ - ize your travel at http://www.tripit.com -GEO:37.655634;-122.401273 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111011T165500Z -SUMMARY:US403 PHX to SFO -LOCATION:Phoenix (PHX) -UID:item-c576afd397cf1f90578b4ba35e781b61ba8897db@tripit.com -DTSTART:20111011T144500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/1234\n \n[Flight] 10/11/2011 US Airways(US) #403 dep PHX 7:4 - 5am MST arr SFO 9:55am PDT\; John Doe\; seat(s) 8B\; conf #DXH9K - Z\, BXQ9WH \nBooked on http://www.americanexpress-travel.com/\; Reference - #: 4127 8626 9715\; http://www.americanexpress-travel.com/\; US:1-800-297- - 2977\, Outside:210-582-2716 \n \n \n\nTripIt - organize your travel at htt - p://www.tripit.com -GEO:37.618889;-122.375 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Pick-up Rental Car: Dollar Rent A Car -TRANSP:TRANSPARENT -UID:item-e99a90ee1c7e4f5b68a4e551009e5bb6c475940c@tripit.com -DTSTART:20111011T172500Z -DTEND:20111011T182500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/1234\n \n[Car Rental] Dollar Rent A Car\; San Francisco Inte - rnational Airport\; primary driver John Doe\; conf #R9508361 \np - ickup 10/11/2011 10:25am\; dropoff 10/13/2011 6:49pm \nEconomy \nBooked on - http://www.americanexpress-travel.com/\; Reference #: 4127 8626 9715\; ht - tp://www.americanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582 - -2716 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-in: Embassy Suites San Francisco Airport - South San Francis - co -TRANSP:TRANSPARENT -UID:item-7f3288d418bed063cc82b4512e792fbb5d8ae761@tripit.com -DTSTART:20111011T185500Z -DTEND:20111011T195500Z -LOCATION:250 GATEWAY BLVD\, South San Francisco\, CA\, 94080 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/23710889\n \n[Lodging] Embassy Suites San Francisco Airport - So - uth San Francisco\; primary guest John Doe\; conf #R9508361 \n25 - 0 GATEWAY BLVD\, South San Francisco\, CA\, 94080\; tel 1.650.589.3400 \na - rrive 10/11/2011\; depart 10/13/2011\; rooms: 1 \nBooked on http://www.ame - ricanexpress-travel.com/\; Reference #: 4127 8626 9715\; http://www.americ - anexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582-2716 \n \n \n\ - nTripIt - organize your travel at http://www.tripit.com -GEO:37.655634;-122.401273 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-out: Embassy Suites San Francisco Airport - South San Franci - sco -TRANSP:TRANSPARENT -UID:item-5eb4cb5fc25c55b0423921e18336e57f8c34598d@tripit.com -DTSTART:20111014T011900Z -DTEND:20111014T021900Z -LOCATION:250 GATEWAY BLVD\, South San Francisco\, CA\, 94080 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/23710889\n \n[Lodging] Embassy Suites San Francisco Airport - So - uth San Francisco\; primary guest John Doe\; conf #R9508361 \n25 - 0 GATEWAY BLVD\, South San Francisco\, CA\, 94080\; tel 1.650.589.3400 \na - rrive 10/11/2011\; depart 10/13/2011\; rooms: 1 \nBooked on http://www.ame - ricanexpress-travel.com/\; Reference #: 4127 8626 9715\; http://www.americ - anexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582-2716 \n \n \n\ - nTripIt - organize your travel at http://www.tripit.com -GEO:37.655634;-122.401273 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Drop-off Rental Car: Dollar Rent A Car -TRANSP:TRANSPARENT -UID:item-11fdbf5d02e84646025716d9f9c7a4158e1fb025@tripit.com -DTSTART:20111014T014900Z -DTEND:20111014T024900Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/23710889\n \n[Car Rental] Dollar Rent A Car\; San Francisco Inte - rnational Airport\; primary driver John Doe\; conf #R9508361 \np - ickup 10/11/2011 10:25am\; dropoff 10/13/2011 6:49pm \nEconomy \nBooked on - http://www.americanexpress-travel.com/\; Reference #: 4127 8626 9715\; ht - tp://www.americanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582 - -2716 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111014T051900Z -SUMMARY:CO6256 SFO to PHX -LOCATION:San Francisco (SFO) -UID:item-cb485a571a01972d6bdc74c2b829905d6e3786bf@tripit.com -DTSTART:20111014T031900Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/23710889\n \n[Flight] 10/13/2011 Continental Airlines(CO) #6256 - dep SFO 8:19pm PDT arr PHX 10:19pm MST\; John Doe\; conf #DXH9KZ - \, BXQ9WH(Operated by United Airlines flight 6256) \nBooked on http://www. - americanexpress-travel.com/\; Reference #: 4127 8626 9715\; http://www.ame - ricanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582-2716 \n \n - \n\nTripIt - organize your travel at http://www.tripit.com -GEO:33.436111;-112.009444 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -UID:c7b133db1e7be2713a4a63b75dcbad209690cab5@tripit.com -DTSTART;VALUE=DATE:20111023 -DTEND;VALUE=DATE:20111028 -SUMMARY:Santa Barbara\, CA\, October 2011 -LOCATION:Santa Barbara\, CA -GEO:34.420831;-119.69819 -TRANSP:TRANSPARENT -DESCRIPTION:John Doe is in Santa Barbara\, CA from Oct 23 to Oct - 27\, 2011\nView and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\nTripIt - organize your travel at http://www.tripit.com - \n -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111023T191200Z -SUMMARY:US2719 PHX to SBA -LOCATION:Phoenix (PHX) -UID:item-c4375369e9070fcc04df39ed18c4d93087577591@tripit.com -DTSTART:20111023T173500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Flight] 10/23/2011 US Airways(US) #2719 dep PHX 10 - :35am MST arr SBA 12:12pm PDT\; John Doe Ticket #0378717202638\; - conf #A44XS5\, PRX98G\, FYYJZ4 \nBooked on http://www.americanexpress-tra - vel.com/\; Reference #: 7128 8086 8504\; http://www.americanexpress-travel - .com/\; US:1-800-297-2977\, Outside:210-582-2716\; Total Cost: $699.99 \n - \n \n\nTripIt - organize your travel at http://www.tripit.com -GEO:34.427778;-119.839444 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -TRANSP:TRANSPARENT -UID:item-962e4f045d12149319d1837ec096bf43770abd6e@tripit.com -DTSTART:20111025T094000 -DTEND:20111025T104000 -SUMMARY:Directions from Hertz to Sofitel San Francisco Bay -LOCATION:223 Twin Dolphin Drive\, Redwood City\, CA\, 94065 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Directions] 10/25/2011 9:40am - Directions from He - rtz to Sofitel San Francisco Bay \nfrom: 780 McDonnell Road\, San Francisc - o\, CA\, 94128 \nto: 223 Twin Dolphin Drive\, Redwood City\, CA\, 94065 \n - View directions here: http://maps.google.com/maps?output=mobile&saddr=780+ - McDonnell+Road%2C+San+Francisco%2C+CA%2C+94128&daddr=223+Twin+Dolphin+Driv - e%2C+Redwood+City%2C+CA%2C+94065 \n \n \n\nTripIt - organize your travel a - t http://www.tripit.com -GEO:37.5232475;-122.261296 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111025T162600Z -SUMMARY:UA5304 SBA to SFO -LOCATION:Santa Barbara (SBA) -UID:item-ae300a6934c3820974dba2c9c5b8fae843c67693@tripit.com -DTSTART:20111025T150900Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Flight] 10/25/2011 United Airlines(UA) #5304 dep S - BA 8:09am PDT arr SFO 9:26am PDT\; John Doe Ticket #037871720263 - 8\; seat(s) 11B\; conf #A44XS5\, PRX98G\, FYYJZ4 \nBooked on http://www.am - ericanexpress-travel.com/\; Reference #: 7128 8086 8504\; http://www.ameri - canexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582-2716\; Total - Cost: $699.99 \n \n \n\nTripIt - organize your travel at http://www.tripit - .com -GEO:37.618889;-122.375 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Pick-up Rental Car: Hertz -TRANSP:TRANSPARENT -UID:item-2a9fd5a57a4cdda4677fc6ce23738e1954fdbe2a@tripit.com -DTSTART:20111025T163000Z -DTEND:20111025T173000Z -LOCATION:780 McDonnell Road\, San Francisco\, CA\, 94128 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Car Rental] Hertz\; San Francisco International Ai - rport\; primary driver John Doe\; conf #F2633064194 \n780 McDonn - ell Road\, San Francisco\, CA\, 94128 \npickup 10/25/2011 9:30am\; dropoff - 10/27/2011 7:00pm \nToyota Corolla or similar\; 84.57 USD \nBooked on htt - p://www.hertz.com/\; Reference #: F2633064194\; http://www.hertz.com/\; 80 - 0-654-3131\; Booking Rate: 84.57 USD\; Total Cost: 333.76 USD \n \n \n\nTr - ipIt - organize your travel at http://www.tripit.com -GEO:37.6297569;-122.4000351 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -TRANSP:TRANSPARENT -UID:item-98dfcb0bcfdcffcce9c58a84947212ed67cadda6@tripit.com -DTSTART:20111025T163600Z -DTEND:20111025T173600Z -SUMMARY:Directions from SFO to Sofitel San Francisco Bay -LOCATION:223 Twin Dolphin Drive\, Redwood City\, CA\, 94065 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Directions] 10/25/2011 9:36am - Directions from SF - O to Sofitel San Francisco Bay \nfrom: SFO \nto: 223 Twin Dolphin Drive\, - Redwood City\, CA\, 94065 \nView directions here: http://maps.google.com/m - aps?output=mobile&saddr=SFO&daddr=223+Twin+Dolphin+Drive%2C+Redwood+City%2 - C+CA%2C+94065 \n \n \n\nTripIt - organize your travel at http://www.tripit - .com -GEO:37.5232475;-122.261296 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-in: Sofitel San Francisco Bay -TRANSP:TRANSPARENT -UID:item-8de3937b336c333faf2d55ad0a41c5ca6cc02393@tripit.com -DTSTART:20111025T220000Z -DTEND:20111025T230000Z -LOCATION:223 Twin Dolphin Drive\, Redwood City\, CA\, 94065 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Lodging] Sofitel San Francisco Bay\; primary guest - John Doe\; conf #F80-0GMW \n223 Twin Dolphin Drive\, Redwood Ci - ty\, CA\, 94065\; tel (+1)650/598-9000 \narrive 10/25/2011\; depart 10/27/ - 2011\; rooms: 1 \nBooked on http://www.sofitel.com/\; http://www.sofitel.c - om/\; Total Cost: 564.00 USD \n \n \n\nTripIt - organize your travel at ht - tp://www.tripit.com -GEO:37.5232475;-122.261296 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-out: Sofitel San Francisco Bay -TRANSP:TRANSPARENT -UID:item-f3ade58646964bde101616a6d26ea7784a1a81e8@tripit.com -DTSTART:20111027T190000Z -DTEND:20111027T200000Z -LOCATION:223 Twin Dolphin Drive\, Redwood City\, CA\, 94065 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Lodging] Sofitel San Francisco Bay\; primary guest - John Doe\; conf #F80-0GMW \n223 Twin Dolphin Drive\, Redwood Ci - ty\, CA\, 94065\; tel (+1)650/598-9000 \narrive 10/25/2011\; depart 10/27/ - 2011\; rooms: 1 \nBooked on http://www.sofitel.com/\; http://www.sofitel.c - om/\; Total Cost: 564.00 USD \n \n \n\nTripIt - organize your travel at ht - tp://www.tripit.com -GEO:37.5232475;-122.261296 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Drop-off Rental Car: Hertz -TRANSP:TRANSPARENT -UID:item-50620273fea0614d37775649034d5e1de92ae361@tripit.com -DTSTART:20111028T020000Z -DTEND:20111028T030000Z -LOCATION:780 McDonnell Road\, San Francisco\, CA\, 94128 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Car Rental] Hertz\; San Francisco International Ai - rport\; primary driver John Doe\; conf #F2633064194 \n780 McDonn - ell Road\, San Francisco\, CA\, 94128 \npickup 10/25/2011 9:30am\; dropoff - 10/27/2011 7:00pm \nToyota Corolla or similar\; 84.57 USD \nBooked on htt - p://www.hertz.com/\; Reference #: F2633064194\; http://www.hertz.com/\; 80 - 0-654-3131\; Booking Rate: 84.57 USD\; Total Cost: 333.76 USD \n \n \n\nTr - ipIt - organize your travel at http://www.tripit.com -GEO:37.6297569;-122.4000351 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111028T051900Z -SUMMARY:CO6256 SFO to PHX -LOCATION:San Francisco (SFO) -UID:item-71d327f30d8beeaf7bf50c8fa63ce16005b9b0df@tripit.com -DTSTART:20111028T031900Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24259445\n \n[Flight] 10/27/2011 Continental Airlines(CO) #6256 - dep SFO 8:19pm PDT arr PHX 10:19pm MST\; John Doe Ticket #037871 - 7202638\; seat(s) 17D\; conf #A44XS5\, PRX98G\, FYYJZ4(Operated by United - Airlines flight 6256) \nBooked on http://www.americanexpress-travel.com/\; - Reference #: 7128 8086 8504\; http://www.americanexpress-travel.com/\; US - :1-800-297-2977\, Outside:210-582-2716\; Total Cost: $699.99 \n \n \n\nTri - pIt - organize your travel at http://www.tripit.com -GEO:33.436111;-112.009444 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -UID:2d4b446e63a94ade7dab0f0e9546b2d1965f011c@tripit.com -DTSTART;VALUE=DATE:20111108 -DTEND;VALUE=DATE:20111111 -SUMMARY:Redwood City\, CA\, November 2011 -LOCATION:Redwood City\, CA -GEO:37.485215;-122.236355 -TRANSP:TRANSPARENT -DESCRIPTION:John Doe is in Redwood City\, CA from Nov 8 to Nov 1 - 0\, 2011\nView and/or edit details in TripIt : http://www.tripit.com/trip/ - show/id/24913749\nTripIt - organize your travel at http://www.tripit.com\n -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111108T175700Z -SUMMARY:US403 PHX to SFO -LOCATION:Phoenix (PHX) -UID:item-7de7d829b2f95991de6d01c3d68f24b84770168c@tripit.com -DTSTART:20111108T154500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24913749\n \n[Flight] 11/8/2011 US Airways(US) #403 dep PHX 8:45 - am MST arr SFO 9:57am PST\; John Doe\; seat(s) 21C\; conf #FJDX0 - J\, I2W8HW \nBooked on http://www.americanexpress-travel.com/\; Reference - #: 4129 9623 4732\; http://www.americanexpress-travel.com/\; US:1-800-297- - 2977\, Outside:210-582-2716 \n \n \n\nTripIt - organize your travel at htt - p://www.tripit.com -GEO:37.618889;-122.375 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Pick-up Rental Car: Dollar Rent A Car -TRANSP:TRANSPARENT -UID:item-1ac6982fefdd79bc5ea849785f415a6291c450b1@tripit.com -DTSTART:20111108T182700Z -DTEND:20111108T192700Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24913749\n \n[Car Rental] Dollar Rent A Car\; San Francisco Inte - rnational Airport\; primary driver John Doe\; conf #Q0058133 \np - ickup 11/8/2011 10:27am\; dropoff 11/10/2011 6:25pm \nEconomy \nBooked on - http://www.americanexpress-travel.com/\; Reference #: 4129 9623 4732\; htt - p://www.americanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582- - 2716 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-in: Sofitel San Francisco Bay -TRANSP:TRANSPARENT -UID:item-126e584ffbefbec32a15ca503f0bdf8d3f9cc2f4@tripit.com -DTSTART:20111108T195700Z -DTEND:20111108T205700Z -LOCATION:223 TWIN DOLPHIN DR\, Redwood City\, CA\, 94065-1514 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24913749\n \n[Lodging] Sofitel San Francisco Bay\; primary guest - John Doe\; conf #Q0058133 \n223 TWIN DOLPHIN DR\, Redwood City\ - , CA\, 94065-1514\; tel 1.650.598.9000 \narrive 11/8/2011\; depart 11/10/2 - 011\; rooms: 1 \nBooked on http://www.americanexpress-travel.com/\; Refere - nce #: 4129 9623 4732\; http://www.americanexpress-travel.com/\; US:1-800- - 297-2977\, Outside:210-582-2716 \n \n \n\nTripIt - organize your travel at - http://www.tripit.com -GEO:37.5232475;-122.261296 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-out: Sofitel San Francisco Bay -TRANSP:TRANSPARENT -UID:item-ff48c502022356ccaa862ebb61761a0de08a1ce9@tripit.com -DTSTART:20111111T015500Z -DTEND:20111111T025500Z -LOCATION:223 TWIN DOLPHIN DR\, Redwood City\, CA\, 94065-1514 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24913749\n \n[Lodging] Sofitel San Francisco Bay\; primary guest - John Doe\; conf #Q0058133 \n223 TWIN DOLPHIN DR\, Redwood City\ - , CA\, 94065-1514\; tel 1.650.598.9000 \narrive 11/8/2011\; depart 11/10/2 - 011\; rooms: 1 \nBooked on http://www.americanexpress-travel.com/\; Refere - nce #: 4129 9623 4732\; http://www.americanexpress-travel.com/\; US:1-800- - 297-2977\, Outside:210-582-2716 \n \n \n\nTripIt - organize your travel at - http://www.tripit.com -GEO:37.5232475;-122.261296 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Drop-off Rental Car: Dollar Rent A Car -TRANSP:TRANSPARENT -UID:item-c0273c03ddbb68a9b05d5d43a489bc318136ca42@tripit.com -DTSTART:20111111T022500Z -DTEND:20111111T032500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24913749\n \n[Car Rental] Dollar Rent A Car\; San Francisco Inte - rnational Airport\; primary driver John Doe\; conf #Q0058133 \np - ickup 11/8/2011 10:27am\; dropoff 11/10/2011 6:25pm \nEconomy \nBooked on - http://www.americanexpress-travel.com/\; Reference #: 4129 9623 4732\; htt - p://www.americanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582- - 2716 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111111T055400Z -SUMMARY:CO496 SFO to PHX -LOCATION:San Francisco (SFO) -UID:item-3473cf9275326ac393b37859df3b04306b4849aa@tripit.com -DTSTART:20111111T035500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/24913749\n \n[Flight] 11/10/2011 Continental Airlines(CO) #496 d - ep SFO 7:55pm PST arr PHX 10:54pm MST\; John Doe\; seat(s) 26B\; - conf #FJDX0J\, I2W8HW(Operated by United Airlines flight 496) \nBooked on - http://www.americanexpress-travel.com/\; Reference #: 4129 9623 4732\; ht - tp://www.americanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582 - -2716 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -GEO:33.436111;-112.009444 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -UID:4ee5ded058432990e3d8808f48ca851e04923b6d@tripit.com -DTSTART;VALUE=DATE:20111129 -DTEND;VALUE=DATE:20111202 -SUMMARY:Milpitas\, CA\, November 2011 -LOCATION:Milpitas\, CA -GEO:37.428272;-121.906624 -TRANSP:TRANSPARENT -DESCRIPTION:John Doe is in Milpitas\, CA from Nov 29 to Dec 1\, - 2011\nView and/or edit details in TripIt : http://www.tripit.com/trip/show - /id/25671681\nTripIt - organize your travel at http://www.tripit.com\n -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111129T172400Z -SUMMARY:US282 PHX to SJC -LOCATION:Phoenix (PHX) -UID:item-644d5973b50d521d50e475ccf5321605d54bd0d5@tripit.com -DTSTART:20111129T152500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/25671681\n \n[Flight] 11/29/2011 US Airways(US) #282 dep PHX 8:2 - 5am MST arr SJC 9:24am PST\; John Doe\; seat(s) 17C\; conf #DQKD - GY \nBooked on http://www.americanexpress-travel.com/\; Reference #: 4131 - 3301 9911\; http://www.americanexpress-travel.com/\; US:1-800-297-2977\, O - utside:210-582-2716 \n \n \n\nTripIt - organize your travel at http://www. - tripit.com -GEO:37.361111;-121.925556 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Pick-up Rental Car: Alamo -TRANSP:TRANSPARENT -UID:item-10368bbdbc9b6f26f83098500633cc4eb604c751@tripit.com -DTSTART:20111129T175400Z -DTEND:20111129T185400Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/25671681\n \n[Car Rental] Alamo\; San Jose International Airport - \; primary driver John Doe\; conf #372828149COUNT \npickup 11/29 - /2011 9:54am\; dropoff 12/1/2011 5:45pm \nIntermediate \nBooked on http:// - www.americanexpress-travel.com/\; Reference #: 4131 3301 9911\; http://www - .americanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582-2716 \n - \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-in: The Beverly Heritage Hotel -TRANSP:TRANSPARENT -UID:item-98d8638d3f1c011d03cb8f58b3a14a0f1203339b@tripit.com -DTSTART:20111129T192400Z -DTEND:20111129T202400Z -LOCATION:1820 Barber Lane\, Milpitas\, CA\, 95035 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/25671681\n \n[Lodging] The Beverly Heritage Hotel\; primary gues - t John Doe\; conf #372828149COUNT \n1820 Barber Lane\, Milpitas\ - , CA\, 95035\; tel 1.408.943.9080 \narrive 11/29/2011\; depart 12/1/2011\; - rooms: 1 \nBooked on http://www.americanexpress-travel.com/\; Reference # - : 4131 3301 9911\; http://www.americanexpress-travel.com/\; US:1-800-297-2 - 977\, Outside:210-582-2716 \n \n \n\nTripIt - organize your travel at http - ://www.tripit.com -GEO:37.4010467;-121.9116284 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111201T194400Z -SUMMARY:US273 SJC to PHX -LOCATION:San Jose (SJC) -UID:item-7b9ee9bb4edfe69743e32b33f9be55753956a883@tripit.com -DTSTART:20111201T175900Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/25671681\n \n[Flight] 12/1/2011 US Airways(US) #273 dep SJC 9:59 - am PST arr PHX 12:44pm MST\; John Doe Ticket #0378727451156\; co - nf #EMF71T \nBooked on http://www.americanexpress-travel.com/\; Reference - #: 5133 5264 1627\; http://www.americanexpress-travel.com/\; US:1-800-297- - 2977\, Outside:210-582-2716\; Total Cost: $316.69 \n \n \n\nTripIt - organ - ize your travel at http://www.tripit.com -GEO:33.436111;-112.009444 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-out: The Beverly Heritage Hotel -TRANSP:TRANSPARENT -UID:item-f79f203072002b8f06598dcb2be0e36af17b625b@tripit.com -DTSTART:20111202T011500Z -DTEND:20111202T021500Z -LOCATION:1820 Barber Lane\, Milpitas\, CA\, 95035 -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/25671681\n \n[Lodging] The Beverly Heritage Hotel\; primary gues - t John Doe\; conf #372828149COUNT \n1820 Barber Lane\, Milpitas\ - , CA\, 95035\; tel 1.408.943.9080 \narrive 11/29/2011\; depart 12/1/2011\; - rooms: 1 \nBooked on http://www.americanexpress-travel.com/\; Reference # - : 4131 3301 9911\; http://www.americanexpress-travel.com/\; US:1-800-297-2 - 977\, Outside:210-582-2716 \n \n \n\nTripIt - organize your travel at http - ://www.tripit.com -GEO:37.4010467;-121.9116284 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Drop-off Rental Car: Alamo -TRANSP:TRANSPARENT -UID:item-69f526ad49fa8ca0a74486f4fc77cc3f9d23a72f@tripit.com -DTSTART:20111202T014500Z -DTEND:20111202T024500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/25671681\n \n[Car Rental] Alamo\; San Jose International Airport - \; primary driver John Doe\; conf #372828149COUNT \npickup 11/29 - /2011 9:54am\; dropoff 12/1/2011 5:45pm \nIntermediate \nBooked on http:// - www.americanexpress-travel.com/\; Reference #: 4131 3301 9911\; http://www - .americanexpress-travel.com/\; US:1-800-297-2977\, Outside:210-582-2716 \n - \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111202T045900Z -SUMMARY:US288 SJC to PHX -LOCATION:San Jose (SJC) -UID:item-dab68a87c8dd49064ab0ba1dec5ba75ba46ff1d3@tripit.com -DTSTART:20111202T031500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/25671681\n \n[Flight] 12/1/2011 US Airways(US) #288 dep SJC 7:15 - pm PST arr PHX 9:59pm MST\; John Doe\; seat(s) 13C\; conf #DQKDG - Y \nBooked on http://www.americanexpress-travel.com/\; Reference #: 4131 3 - 301 9911\; http://www.americanexpress-travel.com/\; US:1-800-297-2977\, Ou - tside:210-582-2716 \n \n \n\nTripIt - organize your travel at http://www.t - ripit.com -GEO:33.436111;-112.009444 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -UID:67d48ddde166a2e9bbac2cf7d93fe493b0860008@tripit.com -DTSTART;VALUE=DATE:20111213 -DTEND;VALUE=DATE:20111216 -SUMMARY:San Jose\, CA\, December 2011 -LOCATION:San Jose\, CA -GEO:37.339386;-121.894955 -TRANSP:TRANSPARENT -DESCRIPTION:John Doe is in San Jose\, CA from Dec 13 to Dec 15\, - 2011\nView and/or edit details in TripIt : http://www.tripit.com/trip/sho - w/id/27037117\nTripIt - organize your travel at http://www.tripit.com\n -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111213T172400Z -SUMMARY:US282 PHX to SJC -LOCATION:Phoenix (PHX) -UID:item-2b1b9021be548a87dd335f190b60ab78c33b619d@tripit.com -DTSTART:20111213T152500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27037117\n \n[Flight] 12/13/2011 US Airways(US) #282 dep PHX 8:2 - 5am MST arr SJC 9:24am PST\; John Doe Ticket #0378728465928\; se - at(s) 15C\; conf #GGNV29 \nBooked on http://www.americanexpress-travel.com - /\; Reference #: 3134 0525 5102\; http://www.americanexpress-travel.com/\; - US:1-800-297-2977\, Outside:210-582-2716\; Total Cost: $406.39 \n \n \n\n - TripIt - organize your travel at http://www.tripit.com -GEO:37.361111;-121.925556 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Pick-up Rental Car: Advantage -TRANSP:TRANSPARENT -UID:item-619d345bb08aaef68e8767b672277243697f5bff@tripit.com -DTSTART:20111213T180000Z -DTEND:20111213T190000Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27037117\n \n[Car Rental] Advantage\; San Jose International Air - port\; primary driver John Doe\; conf #F31539020E7 \npickup 12/1 - 3/2011 10:00am\; dropoff 12/15/2011 7:00pm \nStandard Convertible \nRefere - nce #: 3134 0526 3890 \n \n \n\nTripIt - organize your travel at http://ww - w.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-in: Crestview Hotel: -TRANSP:TRANSPARENT -UID:item-fbe6c08e7523c82fac69b40ad1d0899f3d8d5982@tripit.com -DTSTART:20111213T192400Z -DTEND:20111213T202400Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27037117\n \n[Lodging] Crestview Hotel:\; conf #CR31342159 \ntel - 650-966-8848 \narrive 12/13/2011\; depart 12/15/2011 \nBooking Rate: 153. - 30 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-out: Crestview Hotel: -TRANSP:TRANSPARENT -UID:item-7ed8b84628e650a6b37161c7825bac9e72add49f@tripit.com -DTSTART:20111216T011500Z -DTEND:20111216T021500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27037117\n \n[Lodging] Crestview Hotel:\; conf #CR31342159 \ntel - 650-966-8848 \narrive 12/13/2011\; depart 12/15/2011 \nBooking Rate: 153. - 30 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Drop-off Rental Car: Advantage -TRANSP:TRANSPARENT -UID:item-623b54ebe07ffd48845f1a120a86940ce79c698b@tripit.com -DTSTART:20111216T030000Z -DTEND:20111216T040000Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27037117\n \n[Car Rental] Advantage\; San Jose International Air - port\; primary driver John Doe\; conf #F31539020E7 \npickup 12/1 - 3/2011 10:00am\; dropoff 12/15/2011 7:00pm \nStandard Convertible \nRefere - nce #: 3134 0526 3890 \n \n \n\nTripIt - organize your travel at http://ww - w.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20111216T045900Z -SUMMARY:US288 SJC to PHX -LOCATION:San Jose (SJC) -UID:item-52481e672972d2e88d5eaa5cf49bb801562c6014@tripit.com -DTSTART:20111216T031500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27037117\n \n[Flight] 12/15/2011 US Airways(US) #288 dep SJC 7:1 - 5pm PST arr PHX 9:59pm MST\; John Doe Ticket #0378728465928\; se - at(s) 7B\; conf #GGNV29 \nBooked on http://www.americanexpress-travel.com/ - \; Reference #: 3134 0525 5102\; http://www.americanexpress-travel.com/\; - US:1-800-297-2977\, Outside:210-582-2716\; Total Cost: $406.39 \n \n \n\nT - ripIt - organize your travel at http://www.tripit.com -GEO:33.436111;-112.009444 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -UID:7299ff29daed7d5c3e2ed4acc74deec5b7942bd5@tripit.com -DTSTART;VALUE=DATE:20120103 -DTEND;VALUE=DATE:20120106 -SUMMARY:San Francisco\, CA\, January 2012 -LOCATION:San Francisco\, CA -GEO:37.774929;-122.419415 -TRANSP:TRANSPARENT -DESCRIPTION:John Doe is in San Francisco\, CA from Jan 3 to Jan - 5\, 2012\nView and/or edit details in TripIt : http://www.tripit.com/trip/ - show/id/27863159\nTripIt - organize your travel at http://www.tripit.com\n -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20120103T175700Z -SUMMARY:US403 PHX to SFO -LOCATION:Phoenix (PHX) -UID:item-f099e76114bf43ef3b122432579d8b40995412a7@tripit.com -DTSTART:20120103T154500Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27863159\n \n[Flight] 1/3/2012 US Airways(US) #403 dep PHX 8:45a - m MST arr SFO 9:57am PST\; John Doe Ticket #0378731791515\; conf - #FH9B72\, L4F9M5 \nBooked on http://www.americanexpress-travel.com/\; Ref - erence #: 6135 7391 6119\; http://www.americanexpress-travel.com/\; US:1-8 - 00-297-2977\, Outside:210-582-2716\; Total Cost: $668.39 \n \n \n\nTripIt - - organize your travel at http://www.tripit.com -GEO:37.618889;-122.375 -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Pick-up Rental Car: Alamo -TRANSP:TRANSPARENT -UID:item-fae4b4b07b66fc87df125238e0aaf645106cf4f3@tripit.com -DTSTART:20120103T180000Z -DTEND:20120103T190000Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27863159\n \n[Car Rental] Alamo\; San Francisco International Ai - rport\; primary driver John Doe\; conf #373525981COUNT \npickup - 1/3/2012 10:00am\; dropoff 1/5/2012 6:00pm \nCompact \nReference #: 6135 7 - 391 6898 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-in: Grand Hotel Sunnyvale -TRANSP:TRANSPARENT -UID:item-d89a856eb9da9dfdcb4da46f42e49af3a838fcbb@tripit.com -DTSTART:20120103T195700Z -DTEND:20120103T205700Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27863159\n \n[Lodging] Grand Hotel Sunnyvale\; conf #22084SY0361 - 18 \ntel 1-408-7208500 \narrive 1/3/2012\; depart 1/5/2012 \nBooking Rate: - USD 169.00 \nPolicies: Guarantee to valid form of payment is required at - time of booking\; Cancel 1 day prior to arrival date to avoid penalty of 1 - Nights Room Charge. Change fee may apply for early departures and changes - made to confirmed reservations.\; \n \n \n\nTripIt - organize your travel - at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Check-out: Grand Hotel Sunnyvale -TRANSP:TRANSPARENT -UID:item-6edc82f6411fd0b66f2f7f6baafa41623a8623a9@tripit.com -DTSTART:20120106T010900Z -DTEND:20120106T020900Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27863159\n \n[Lodging] Grand Hotel Sunnyvale\; conf #22084SY0361 - 18 \ntel 1-408-7208500 \narrive 1/3/2012\; depart 1/5/2012 \nBooking Rate: - USD 169.00 \nPolicies: Guarantee to valid form of payment is required at - time of booking\; Cancel 1 day prior to arrival date to avoid penalty of 1 - Nights Room Charge. Change fee may apply for early departures and changes - made to confirmed reservations.\; \n \n \n\nTripIt - organize your travel - at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -SUMMARY:Drop-off Rental Car: Alamo -TRANSP:TRANSPARENT -UID:item-58a31b96066ffd09b800af49de59a84f7b7a3a06@tripit.com -DTSTART:20120106T020000Z -DTEND:20120106T030000Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27863159\n \n[Car Rental] Alamo\; San Francisco International Ai - rport\; primary driver John Doe\; conf #373525981COUNT \npickup - 1/3/2012 10:00am\; dropoff 1/5/2012 6:00pm \nCompact \nReference #: 6135 7 - 391 6898 \n \n \n\nTripIt - organize your travel at http://www.tripit.com -END:VEVENT -BEGIN:VEVENT -DTSTAMP:20120101T215311Z -DTEND:20120106T050500Z -SUMMARY:CO496 SFO to PHX -LOCATION:San Francisco (SFO) -UID:item-7884351ce42d503b90ccc48c33c7c30bd4f44767@tripit.com -DTSTART:20120106T030900Z -DESCRIPTION:View and/or edit details in TripIt : http://www.tripit.com/tri - p/show/id/27863159\n \n[Flight] 1/5/2012 Continental Airlines(CO) #496 dep - SFO 7:09pm PST arr PHX 10:05pm MST\; John Doe Ticket #037873179 - 1515\; conf #FH9B72\, L4F9M5(Operated by United Airlines flight 496) \nBoo - ked on http://www.americanexpress-travel.com/\; Reference #: 6135 7391 611 - 9\; http://www.americanexpress-travel.com/\; US:1-800-297-2977\, Outside:2 - 10-582-2716\; Total Cost: $668.39 \n \n \n\nTripIt - organize your travel - at http://www.tripit.com -GEO:33.436111;-112.009444 -END:VEVENT -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test5.ics b/modules/default/calendar/vendor/ical.js/test/test5.ics deleted file mode 100644 index c51f25eec4..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test5.ics +++ /dev/null @@ -1,41 +0,0 @@ -BEGIN:VCALENDAR -VERSION:2.0 -PRODID:-//Meetup//RemoteApi//EN -CALSCALE:GREGORIAN -METHOD:PUBLISH -X-ORIGINAL-URL:http://www.meetup.com/events/ical/8333638/dfdba2e469216075 - 3404f737feace78d526ff0ce/going -X-WR-CALNAME:My Meetups -X-MS-OLK-FORCEINSPECTOROPEN:TRUE -BEGIN:VTIMEZONE -TZID:America/Phoenix -TZURL:http://tzurl.org/zoneinfo-outlook/America/Phoenix -X-LIC-LOCATION:America/Phoenix -BEGIN:STANDARD -TZOFFSETFROM:-0700 -TZOFFSETTO:-0700 -TZNAME:MST -DTSTART:19700101T000000 -END:STANDARD -END:VTIMEZONE -BEGIN:VEVENT -DTSTAMP:20111106T155927Z -DTSTART;TZID=America/Phoenix:20111109T190000 -DTEND;TZID=America/Phoenix:20111109T210000 -STATUS:CONFIRMED -SUMMARY:Phoenix Drupal User Group Monthly Meetup -DESCRIPTION:Phoenix Drupal User Group\nWednesday\, November 9 at 7:00 PM\ - n\nCustomizing node display with template pages in Drupal 6\n\n Jon Shee - han and Matthew Berry of the Office of Knowledge Enterprise Development - (OKED) Knowledge...\n\nDetails: http://www.meetup.com/Phoenix-Drupal-Use - r-Group/events/33627272/ -CLASS:PUBLIC -CREATED:20100630T083023Z -GEO:33.56;-111.90 -LOCATION:Open Source Project Tempe (1415 E University Dr. #103A\, Tempe\, - AZ 85281) -URL:http://www.meetup.com/Phoenix-Drupal-User-Group/events/33627272/ -LAST-MODIFIED:20111102T213309Z -UID:event_nsmxnyppbfc@meetup.com -END:VEVENT -END:VCALENDAR \ No newline at end of file diff --git a/modules/default/calendar/vendor/ical.js/test/test6.ics b/modules/default/calendar/vendor/ical.js/test/test6.ics deleted file mode 100644 index 3762d02b9f..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test6.ics +++ /dev/null @@ -1,1170 +0,0 @@ -BEGIN:VCALENDAR -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110804T120000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:All Areas -SUMMARY:foobar Summer 2011 starts! -URL:F -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110804T120000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:Main entrance -SUMMARY:Main entrance opened -URL:http://www.foobar.org/summer11/come-to-party/entry-setup -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110804T120000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:Loading entrances #1 and #2 -SUMMARY:Loading doors are opened -URL:http://www.foobar.org/summer11/come-to-party/entry-setup -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110804T120000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:foobarTV -SUMMARY:foobarTV broadcast starts -RRULE:FREQ=WEEKLY;BYDAY=MO,FR;INTERVAL=5;UNTIL=20130130T230000Z -URL:http://www.foobartv.net -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110804T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T180000 -LOCATION:Loading entrances #1 and #2 -SUMMARY:Loading doors close -URL:http://www.foobar.org/summer11/come-to-party/entry-setup -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110805T120000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T120000 -LOCATION:Loading entrance #1 -SUMMARY:Loading doors are opened -URL:http://www.foobar.org/summer11/come-to-party/entry-setup -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110805T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T180000 -LOCATION:Loading entrance #1 -SUMMARY:Loading doors close -URL:http://www.foobar.org/summer11/come-to-party/entry-setup -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_deadline -DTEND;VALUE=DATE:20110804T220000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T220000 -LOCATION:PMS -SUMMARY:Oldskool demo\, individual and 4k intro compo deadline -URL:http://www.foobar.org/summer11/compos/how-to/submit-entry -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_deadline -DTEND;VALUE=DATE:20110805T200000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T200000 -LOCATION:PMS -SUMMARY:Group compo deadline -URL:http://www.foobar.org/summer11/compos/how-to/submit-entry -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110804T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:PMS -SUMMARY:Sign-up for street basketball & Guitar Hero solo guitar -URL:http://www.foobar.org/summer11/compos/gaming-sports -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110805T110000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:PMS -SUMMARY:Sign-up for sports and machine dance compos -URL:http://www.foobar.org/summer11/compos/gaming-sports -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110806T160000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:PMS -SUMMARY:Sign-up for poker tournament -URL:http://www.foobar.org/summer11/compos/sponsored-unofficial/poker -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110804T220000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T200000 -LOCATION:Outside main entrance -SUMMARY:Street basketball -URL:http://www.foobar.org/summer11/compos/sports-competitions/team/#stre - etbasketball -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110805T124500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T123000 -LOCATION:Infodesk -SUMMARY:Sport compos - gather up at the infodesk -URL:http://www.foobar.org/summer11/compos/gaming-sports -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110805T140000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T130000 -LOCATION:Grass fields by Messukeskus -SUMMARY:Disk throwing -URL:http://www.foobar.org/summer11/compos/sports-competitions/individual - /#disk -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110805T140000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T130000 -LOCATION:Grass fields by Messukeskus -SUMMARY:CD throwing -URL:http://www.foobar.org/summer11/compos/sports-competitions/individual - /#cd -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110805T160000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T140000 -LOCATION:Grass fields by Messukeskus -SUMMARY:ASUS soccer tournament -URL:http://www.foobar.org/summer11/compos/sports-competitions/team/#socc - er -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110805T000000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T180000 -LOCATION:Guitar Hero -SUMMARY:Guitar Hero: Guitar tournament - qualifying round #1 -URL:http://www.foobar.org/summer11/compos/gaming-sports/individual -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110805T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T120000 -LOCATION:Guitar Hero -SUMMARY:Guitar Hero: Guitar tournament - qualifying round #2 -URL:http://www.foobar.org/summer11/compos/gaming-sports/individual -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110806T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T120000 -LOCATION:Guitar Hero -SUMMARY:Guitar Hero: Guitar tournament - semifinal -URL:http://www.foobar.org/summer11/compos/gaming-sports/individual -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110807T130000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T120000 -LOCATION:Stage -SUMMARY:Guitar Hero: Guitar Tournament final -URL:http://www.foobar.org/summer11/compos/gaming-sports/individual -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110805T210000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T160000 -LOCATION:Third floor -SUMMARY:Machine Dance tournament -URL:http://www.foobar.org/summer11/compos/gaming-sports/individual/#danc - e -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110807T120000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T110000 -LOCATION:Stage -SUMMARY:Machine Dance tournament finals -URL:http://www.foobar.org/summer11/compos/gaming-sports/individual/#danc - e -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110807T000000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T200000 -LOCATION:Seminar area -SUMMARY:Poker tournament -URL:http://www.foobar.org/summer11/compos/sponsored-unofficial/poker -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110804T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T150000 -LOCATION:Infodesk -SUMMARY:GameDev compo recording - come to Infodesk -URL:http://www.foobar.org/summer11/compos/realtime/gamedev -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_showing -DTEND;VALUE=DATE:20110805T010000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T000000 -LOCATION:Big screen -SUMMARY:GameDev compo -URL:http://www.foobar.org/summer11/compos/realtime/gamedev -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110804T190000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T190000 -LOCATION:Website -SUMMARY:Fast music - sample set released -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#music -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_deadline -DTEND;VALUE=DATE:20110804T203000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T203000 -LOCATION:PMS -SUMMARY:Fast music - deadline -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#music -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T003000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T223000 -LOCATION:Infodesk -SUMMARY:Fast music - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#music -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110805T161500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T153000 -LOCATION:Big screen -SUMMARY:Fast music compo -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#music -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110804T203000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T203000 -LOCATION:Website -SUMMARY:Fast graphics - objectives released -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#graphics -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_deadline -DTEND;VALUE=DATE:20110804T220000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T220000 -LOCATION:PMS -SUMMARY:Fast graphics - deadline -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#graphics -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T001500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T233000 -LOCATION:Infodesk -SUMMARY:Fast graphics - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#graphics -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110805T164500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T163000 -LOCATION:Big screen -SUMMARY:Fast graphics compo -URL:http://www.foobar.org/summer11/compos/sound-vision/fast#graphics -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T021500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T221500 -LOCATION:Infodesk -SUMMARY:Extreme music and Oldskool demo - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/realtime/oldskool -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110805T150000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T110000 -LOCATION:Infodesk -SUMMARY:Extreme music and Oldskool demo - compo entry recording\, come to - Infodesk -URL:http://www.foobar.org/summer11/compos/realtime/oldskool -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T144500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T140000 -LOCATION:Big screen -SUMMARY:Extreme music compo -URL:http://www.foobar.org/summer11/compos/realtime/extreme#music -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T171500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T163000 -LOCATION:Big screen -SUMMARY:Oldskool demo compo -URL:http://www.foobar.org/summer11/compos/realtime/oldskool -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T130000 -LOCATION:Infodesk -SUMMARY:Music compo - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/sound-vision/music#freestyle -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T161500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T153000 -LOCATION:Big screen -SUMMARY:Music compo -URL:http://www.foobar.org/summer11/compos/sound-vision/music#freestyle -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T163000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T140000 -LOCATION:Infodesk -SUMMARY:Graphics compo - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/sound-vision/graphics#freestyl - e -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T151500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T150000 -LOCATION:Big screen -SUMMARY:Graphics compo -URL:http://www.foobar.org/summer11/compos/sound-vision/graphics#freestyl - e -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110805T110000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T090000 -LOCATION:Infodesk -SUMMARY:Real wild demo - recording assistance - come to Infodesk -URL:http://www.foobar.org/summer11/compos/realtime/demo#mobile -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T223000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T203000 -LOCATION:Infodesk -SUMMARY:Real wild demo - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/realtime/demo#mobile -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T181500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T173000 -LOCATION:Big screen -SUMMARY:Real wild demo compo -URL:http://www.foobar.org/summer11/compos/realtime/demo#mobile -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T013000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T220000 -LOCATION:Infodesk -SUMMARY:Short film & Real Wild demo - format conversions help - come to In - fodesk -URL:http://www.foobar.org/summer11/compos/sound-vision/short-film -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110806T123000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T100000 -LOCATION:Infodesk -SUMMARY:Short film - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/sound-vision/short-film -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T204500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T194500 -LOCATION:Big screen -SUMMARY:Short film compo -URL:http://www.foobar.org/summer11/compos/sound-vision/short-film -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110805T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T160000 -LOCATION:Infodesk -SUMMARY:4k intro - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/realtime/demo#64k -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T214500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T210000 -LOCATION:Big screen -SUMMARY:4k intro compo -URL:http://www.foobar.org/summer11/compos/realtime/demo#64k -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110806T010000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T230000 -LOCATION:Infodesk -SUMMARY:64k intro - jury - come to Infodesk -URL:http://www.foobar.org/summer11/compos/realtime/demo#64k -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T224500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T220000 -LOCATION:Big screen -SUMMARY:64k intro compo -URL:http://www.foobar.org/summer11/compos/realtime/demo#64k -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_jury -DTEND;VALUE=DATE:20110806T160000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T130000 -LOCATION:Infodesk -SUMMARY:Demo - jury -URL:http://www.foobar.org/summer11/compos/realtime/demo#demo -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_show -DTEND;VALUE=DATE:20110806T230000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T220000 -LOCATION:Big screen -SUMMARY:Demo compo -URL:http://www.foobar.org/summer11/compos/realtime/demo#demo -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110804T160000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T120000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Brackets D\, E\, F -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110804T210000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T170000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Brackets C\, G\, H -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T020000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T220000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Brackets A\, B -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T140000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T110000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Single elimination 16 players -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T153000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T140000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Single elimination 6 players -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T193000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T180000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Semifinal 1 -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T210000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T193000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Semifinal 2 -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T223000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T210000 -LOCATION:Powerplay -SUMMARY:ASUS ROG Starcraft 2 - Bronze match -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T003000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T230000 -LOCATION:Stage -SUMMARY:ASUS ROG Starcraft 2 - Final -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T160000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T130000 -LOCATION:Game hall -SUMMARY:WCG.fi Starcraft 2 – Brackets -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T193000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T173000 -LOCATION:Game hall -SUMMARY:WCG.fi Starcraft 2 - Single elimination 8 players -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T210000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T200000 -LOCATION:Game hall -SUMMARY:WCG.fi Starcraft 2 - Semifinal 1 -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T220000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T210000 -LOCATION:Game hall -SUMMARY:WCG.fi Starcraft 2 - Semifinal 2 -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110807T003000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T223000 -LOCATION:Game hall -SUMMARY:WCG.fi Starcraft 2 - Bronze match -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110807T023000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T000000 -LOCATION:Stage -SUMMARY:WCG.fi Starcraft 2 - Final -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T003000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T193000 -LOCATION:Game hall -SUMMARY:Brink - Brackets -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T140000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T120000 -LOCATION:Game hall -SUMMARY:Brink - Bronze match -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T190000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T173000 -LOCATION:Stage -SUMMARY:Brink - Final -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T190000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T120000 -LOCATION:Game hall -SUMMARY:Team Fortress 2 - Brackets -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T230000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T210000 -LOCATION:Game hall -SUMMARY:Team Fortress 2 - Semifinal 1 -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T230000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T210000 -LOCATION:Game hall -SUMMARY:Team Fortress 2 - Semifinal 2 -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T170000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T150000 -LOCATION:Game hall -SUMMARY:Team Fortress 2 - Bronze match -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T130000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T110000 -LOCATION:Stage -SUMMARY:Team Fortress 2 - Final -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T003000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T180000 -LOCATION:Game hall -SUMMARY:FIFA 2011 - tournament -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110805T230000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T190000 -LOCATION:Game hall -SUMMARY:NHL 2011 - tournament -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T140000 -LOCATION:Game hall -SUMMARY:Tekken 6 - tournament -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110806T190000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T150000 -LOCATION:Game hall -SUMMARY:Super Street Fighter - tournament -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo_game -DTEND;VALUE=DATE:20110807T060000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T180000 -LOCATION:Own computer place -SUMMARY:Heroes of Newerth - Tournament -URL:http://www.peliliiga.fi -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110804T213000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T210000 -LOCATION:Stage -SUMMARY:Opening ceremony -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T170000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T170000 -LOCATION:PMS -SUMMARY:Voting closes for individual and Game development compos -URL:http://www.foobar.org/summer11/party_manual/intranet/vote -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110806T193000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T183000 -LOCATION:Stage -SUMMARY:Prize ceremony 1 -URL:http://www.foobar.org/summer11/compos/prizes/ -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T120000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T120000 -LOCATION:PMS -SUMMARY:Voting closes -URL:http://www.foobar.org/summer11/party_manual/intranet/vote -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Compo -DTEND;VALUE=DATE:20110807T143000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T140000 -LOCATION:Stage -SUMMARY:Prize ceremony 2 -URL:http://www.foobar.org/summer11/compos/prizes/ -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T150000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T143000 -LOCATION:Stage -SUMMARY:Closing ceremony -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T130000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T110000 -LOCATION:Outside loading door #1 -SUMMARY:Robowar tournament qualifier -URL:http://www.foobar.org/summer11/program/robosota -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T160000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T150000 -LOCATION:Outside loading door #1 -SUMMARY:Robowar tournament final -URL:http://www.foobar.org/summer11/program/robosota -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110804T233000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T220000 -LOCATION:Main stage -SUMMARY:Concert - Machinae Supremacy -URL:http://www.foobar.org/summer11/program/concerts -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110805T220000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T203000 -LOCATION:Main stage -SUMMARY:Concert - Press Play on Tape -URL:http://www.foobar.org/summer11/program/concerts -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110805T143000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T140000 -LOCATION:Stage -SUMMARY:Cosplay event presented by BatMud -URL:http://www.foobar.org/summer11/program/ -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T190000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T140000 -LOCATION:Powerplay -SUMMARY:ASUS presents - Paragon WOW raiding -URL:http://www.foobar.org/summer11/program/ -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110804T184500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T180000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Digital resistance\, East European demo art -URL:http://www.foobar.org/summer11/seminars/sessions#demoart -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110804T194500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T190000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Why Being Poor and Having No Budget is Good For - Making Game -URL:http://www.foobar.org/summer11/seminars/sessions#constraints -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110804T204500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T200000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Remix Culture In The Demoscene -URL:http://www.foobar.org/summer11/seminars/sessions#remix -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110804T214500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110804T210000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - DRM of Pacman -URL:http://www.foobar.org/summer11/seminars/sessions#drmpacman -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T104500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T100000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Perfect harmony: crowdsourcing matches musician - s and sound designers to game developers -URL:http://www.foobar.org/summer11/seminars/sessions#music -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T124500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T120000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Browserscene: Creating demos on the Web -URL:http://www.foobar.org/summer11/seminars/sessions#webgl2 -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T144500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T140000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Fumbling my way through pixel-based effects mad - e learning WebGL a lot easier -URL:http://www.foobar.org/summer11/seminars/sessions#webgl1 -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T154500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T150000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - The Making of RO.ME -URL:http://www.foobar.org/summer11/seminars/sessions#rome -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T164500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T160000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Developing next generation of online games -URL:http://www.foobar.org/summer11/seminars/sessions#nextgenonline -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T174500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T170000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Developing Games for Nokia Phones -URL:http://www.foobar.org/summer11/seminars/sessions#nokia_games -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T184500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T180000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Rocking your socks off with Windows Phone 7 -URL:http://www.foobar.org/summer11/seminars/sessions#wp7 -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T194500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T190000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Wonders of Kinect Windows SDK -URL:http://www.foobar.org/summer11/seminars/sessions#kinect -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T114500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T110000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Basics of demo programming -URL:http://www.foobar.org/summer11/seminars/sessions#demoprogramming -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T124500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T120000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Kajak3D\, an open source multiplatform game eng - ine -URL:http://www.foobar.org/summer11/seminars/sessions#kajak3d -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T134500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T130000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Adventures in multithreaded gameplay coding -URL:http://www.foobar.org/summer11/seminars/sessions#threaded -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T144500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T140000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - The art and design of Ridge Racer Unbounded -URL:http://www.foobar.org/summer11/seminars/sessions#ridgeracer -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T154500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T150000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Future of location based mobile games -URL:http://www.foobar.org/summer11/seminars/sessions#location -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T184500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T180000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Robowar -URL:http://www.foobar.org/summer11/seminars/sessions#robosota -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T100000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T100000 -LOCATION:Loading entrances #1 and #2 -SUMMARY:Loading doors open -URL:http://www.foobar.org/summer11/come-to-party/leaving -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T161500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T161500 -LOCATION:All areas -SUMMARY:Lights go on -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T163000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T163000 -LOCATION:All areas -SUMMARY:Party network goes down -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T170000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T170000 -LOCATION:All areas -SUMMARY:Electricity is cut -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T161500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T161500 -LOCATION:foobarTV -SUMMARY:foobarTV broadcast ends -URL:http://www.foobartv.net -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T180000 -LOCATION:Loading entrances #1\, #2 and #3 -SUMMARY:Loading doors closed -URL:http://www.foobar.org/summer11/come-to-party/leaving -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110807T180000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110807T180000 -LOCATION:All areas -SUMMARY:foobar Summer 2011 is over - see you next year! -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110805T153000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T150000 -LOCATION:Outside main entrance -SUMMARY:RC helicopters: flying demonstration with T-REX 600N -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110805T173000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T170000 -LOCATION:Outside main entrance -SUMMARY:RC helicopters: flying demonstration with T-REX 600N -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T133000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T130000 -LOCATION:Outside main entrance -SUMMARY:RC helicopters: flying demonstration with T-REX 600N -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T163000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T160000 -LOCATION:Outside main entrance -SUMMARY:RC helicopters: flying demonstration with T-REX 600N -URL: -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T164500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T160000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars – All aboard to the Dark side of the Moon (Iron - Sky) -URL:http://www.foobar.org/summer11/seminars/sessions#ironsky -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110806T174500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T170000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars – Angry Birds on the web -URL:http://www.foobar.org/summer11/seminars/sessions#angrybirds -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T230000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T120000 -LOCATION:Pelitalo stand -SUMMARY:Pelitalo events begin -URL:http://pelitalo.nettiareena.fi/foobar/ohjelma/ -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Event -DTEND;VALUE=DATE:20110806T210000 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110806T200000 -LOCATION:Pelitalo stand -SUMMARY:Bomberman tournament -URL:http://pelitalo.nettiareena.fi/foobar/ohjelma/ -END:VEVENT -BEGIN:VEVENT -CATEGORIES:Seminar -DTEND;VALUE=DATE:20110805T134500 -DTSTAMP;VALUE=DATE:20120214T224612 -DTSTART;VALUE=DATE:20110805T130000 -LOCATION:Seminar area -SUMMARY:ARTtech seminars - Deconstructing a browserscene demo -URL:http://www.foobar.org/summer11/seminars/sessions#webgl2 -END:VEVENT -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test7.ics b/modules/default/calendar/vendor/ical.js/test/test7.ics deleted file mode 100644 index 4379cd0e7d..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test7.ics +++ /dev/null @@ -1,16 +0,0 @@ -BEGIN:VCALENDAR -VERSION:2.0 -PRODID:ownCloud Calendar 0.6.3 -X-WR-CALNAME:Fête Nationale - Férié -BEGIN:VEVENT -CREATED:20090502T140513Z -DTSTAMP:20111106T124709Z -UID:FA9831E7-C238-4FEC-95E5-CD46BD466421 -SUMMARY:Fête Nationale - Férié -RRULE:FREQ=YEARLY -DTSTART;VALUE=DATE:20120714 -DTEND;VALUE=DATE:20120715 -TRANSP:OPAQUE -SEQUENCE:5 -END:VEVENT -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test8.ics b/modules/default/calendar/vendor/ical.js/test/test8.ics deleted file mode 100644 index e7b2f50f4b..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test8.ics +++ /dev/null @@ -1,23 +0,0 @@ -BEGIN:VCALENDAR -VERSION:2.0 -PRODID:ownCloud Calendar 0.6.3 -X-WR-CALNAME:Default calendar -BEGIN:VTODO -CREATED;VALUE=DATE-TIME:20130714T092804Z -UID:0aa462f13c -LAST-MODIFIED;VALUE=DATE-TIME:20130714T092804Z -DTSTAMP;VALUE=DATE-TIME:20130714T092804Z -CATEGORIES:Projets -SUMMARY:Migrer le blog -PERCENT-COMPLETE:100 -COMPLETED;VALUE=DATE-TIME;TZID=Europe/Monaco:20130716T105745 -END:VTODO -BEGIN:VTODO -CREATED;VALUE=DATE-TIME:20130714T092912Z -UID:5e05bbcf34 -LAST-MODIFIED;VALUE=DATE-TIME:20130714T092912Z -DTSTAMP;VALUE=DATE-TIME:20130714T092912Z -SUMMARY:Créer test unitaire erreur ical -CATEGORIES:Projets -END:VTODO -END:VCALENDAR diff --git a/modules/default/calendar/vendor/ical.js/test/test9.ics b/modules/default/calendar/vendor/ical.js/test/test9.ics deleted file mode 100644 index 76a1d7b99f..0000000000 --- a/modules/default/calendar/vendor/ical.js/test/test9.ics +++ /dev/null @@ -1,21 +0,0 @@ -BEGIN:VCALENDAR -BEGIN:VEVENT -UID:eb9e1bd2-ceba-499f-be77-f02773954c72 -SUMMARY:Event with an alarm -DESCRIPTION:This is an event with an alarm. -ORGANIZER="mailto:stomlinson@mozilla.com" -DTSTART;TZID="America/Los_Angeles":20130418T110000 -DTEND;TZID="America/Los_Angeles":20130418T120000 -STATUS:CONFIRMED -CLASS:PUBLIC -TRANSP:OPAQUE -LAST-MODIFIED:20130418T175632Z -DTSTAMP:20130418T175632Z -SEQUENCE:3 -BEGIN:VALARM -ACTION:DISPLAY -TRIGGER;RELATED=START:-PT5M -DESCRIPTION:Reminder -END:VALARM -END:VEVENT -END:VCALENDAR diff --git a/modules/default/clock/README.md b/modules/default/clock/README.md index 34a1448d04..30019e006d 100644 --- a/modules/default/clock/README.md +++ b/modules/default/clock/README.md @@ -1,4 +1,5 @@ # Module: Clock + 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. diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 08dcced06c..cfcd1e40b3 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -1,11 +1,12 @@ -/* global Log, Module, moment, config */ +/* global SunCalc */ + /* Magic Mirror * Module: Clock * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -Module.register("clock",{ +Module.register("clock", { // Module config defaults. defaults: { displayType: "digital", // options: digital, analog, both @@ -30,18 +31,18 @@ Module.register("clock",{ showSunTimes: false, showMoonTimes: false, lat: 47.630539, - lon: -122.344147, + lon: -122.344147 }, // Define required scripts. - getScripts: function() { + getScripts: function () { return ["moment.js", "moment-timezone.js", "suncalc.js"]; }, // Define styles. - getStyles: function() { + getStyles: function () { return ["clock_styles.css"]; }, // Define start sequence. - start: function() { + start: function () { Log.info("Starting module: " + this.name); // Schedule update interval. @@ -50,21 +51,23 @@ Module.register("clock",{ self.minute = moment().minute(); //Calculate how many ms should pass until next update depending on if seconds is displayed or not - var delayCalculator = function(reducedSeconds) { + var delayCalculator = function (reducedSeconds) { + var EXTRA_DELAY = 50; //Deliberate imperceptable delay to prevent off-by-one timekeeping errors + if (self.config.displaySeconds) { - return 1000 - moment().milliseconds(); + return 1000 - moment().milliseconds() + EXTRA_DELAY; } else { - return ((60 - reducedSeconds) * 1000) - moment().milliseconds(); + return (60 - reducedSeconds) * 1000 - moment().milliseconds() + EXTRA_DELAY; } }; //A recursive timeout function instead of interval to avoid drifting - var notificationTimer = function() { + var notificationTimer = function () { self.updateDom(); //If seconds is displayed CLOCK_SECOND-notification should be sent (but not when CLOCK_MINUTE-notification is sent) if (self.config.displaySeconds) { - self.second = (self.second + 1) % 60; + self.second = moment().second(); if (self.second !== 0) { self.sendNotification("CLOCK_SECOND", self.second); setTimeout(notificationTimer, delayCalculator(0)); @@ -73,7 +76,7 @@ Module.register("clock",{ } //If minute changed or seconds isn't displayed send CLOCK_MINUTE-notification - self.minute = (self.minute + 1) % 60; + self.minute = moment().minute(); self.sendNotification("CLOCK_MINUTE", self.minute); setTimeout(notificationTimer, delayCalculator(0)); }; @@ -83,11 +86,9 @@ Module.register("clock",{ // Set locale. moment.locale(config.language); - }, // Override dom generator. - getDom: function() { - + getDom: function () { var wrapper = document.createElement("div"); /************************************ @@ -126,12 +127,12 @@ Module.register("clock",{ } if (this.config.clockBold === true) { - timeString = now.format(hourSymbol + "[]mm[]"); + timeString = now.format(hourSymbol + '[]mm[]'); } else { timeString = now.format(hourSymbol + ":mm"); } - if(this.config.showDate){ + if (this.config.showDate) { dateWrapper.innerHTML = now.format(this.config.dateFormat); } if (this.config.showWeek) { @@ -172,9 +173,18 @@ Module.register("clock",{ } 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) + ""; + sunWrapper.innerHTML = + ' ' + + untilNextEventString + + "" + + '' + + formatTime(this.config, sunTimes.sunrise) + + "" + + '' + + formatTime(this.config, sunTimes.sunset) + + ""; } if (this.config.showMoonTimes) { const moonIllumination = SunCalc.getMoonIllumination(now.toDate()); @@ -189,24 +199,32 @@ Module.register("clock",{ } 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) : "...") + ""; + moonWrapper.innerHTML = + ' ' + + illuminatedFractionString + + "" + + ' ' + + (moonRise ? formatTime(this.config, moonRise) : "...") + + "" + + ' ' + + (moonSet ? formatTime(this.config, moonSet) : "...") + + ""; } /**************************************************************** * Create wrappers for ANALOG clock, only if specified in config */ - if (this.config.displayType !== "digital") { + if (this.config.displayType !== "digital") { // If it isn't 'digital', then an 'analog' clock was also requested // Calculate the degree offset for each hand of the clock - var now = moment(); if (this.config.timezone) { now.tz(this.config.timezone); } - var second = now.seconds() * 6, + var second = now.seconds() * 6, minute = now.minute() * 6 + second / 60, hour = ((now.hours() % 12) / 12) * 360 + 90 + minute / 12; @@ -217,13 +235,12 @@ Module.register("clock",{ clockCircle.style.height = this.config.analogSize; if (this.config.analogFace !== "" && this.config.analogFace !== "simple" && this.config.analogFace !== "none") { - clockCircle.style.background = "url("+ this.data.path + "faces/" + this.config.analogFace + ".svg)"; + clockCircle.style.background = "url(" + this.data.path + "faces/" + this.config.analogFace + ".svg)"; clockCircle.style.backgroundSize = "100%"; // The following line solves issue: https://github.com/MichMich/MagicMirror/issues/611 // clockCircle.style.border = "1px solid black"; clockCircle.style.border = "rgba(0, 0, 0, 0.1)"; //Updated fix for Issue 611 where non-black backgrounds are used - } else if (this.config.analogFace !== "none") { clockCircle.style.border = "2px solid white"; } @@ -289,11 +306,12 @@ Module.register("clock",{ // Both clocks have been configured, check position var placement = this.config.analogPlacement; - analogWrapper = document.createElement("div"); + var analogWrapper = document.createElement("div"); analogWrapper.id = "analog"; analogWrapper.style.cssFloat = "none"; analogWrapper.appendChild(clockCircle); - digitalWrapper = document.createElement("div"); + + var digitalWrapper = document.createElement("div"); digitalWrapper.id = "digital"; digitalWrapper.style.cssFloat = "none"; digitalWrapper.appendChild(dateWrapper); @@ -302,9 +320,9 @@ Module.register("clock",{ digitalWrapper.appendChild(moonWrapper); digitalWrapper.appendChild(weekWrapper); - var appendClocks = function(condition, pos1, pos2) { - var padding = [0,0,0,0]; - padding[(placement === condition) ? pos1 : pos2] = "20px"; + var appendClocks = function (condition, pos1, pos2) { + var padding = [0, 0, 0, 0]; + padding[placement === condition ? pos1 : pos2] = "20px"; analogWrapper.style.padding = padding.join(" "); if (placement === condition) { wrapper.appendChild(analogWrapper); diff --git a/modules/default/clock/clock_styles.css b/modules/default/clock/clock_styles.css index fa6c2d5d91..839336be9a 100644 --- a/modules/default/clock/clock_styles.css +++ b/modules/default/clock/clock_styles.css @@ -1,78 +1,72 @@ -.clockCircle { - margin: 0 auto; - position: relative; - border-radius: 50%; - background-size: 100%; -} - -.clockFace { - width: 100%; - height: 100%; -} - -.clockFace::after { - position: absolute; - top: 50%; - left: 50%; - width: 6px; - height: 6px; - margin: -3px 0 0 -3px; - background: white; - border-radius: 3px; - content: ""; - display: block; -} - -.clockHour { - width: 0; - height: 0; - position: absolute; - top: 50%; - left: 50%; - margin: -2px 0 -2px -25%; /* numbers much match negative length & thickness */ - padding: 2px 0 2px 25%; /* indicator length & thickness */ - background: white; - -webkit-transform-origin: 100% 50%; - -ms-transform-origin: 100% 50%; - transform-origin: 100% 50%; - border-radius: 3px 0 0 3px; -} - -.clockMinute { - width: 0; - height: 0; - position: absolute; - top: 50%; - left: 50%; - margin: -35% -2px 0; /* numbers must match negative length & thickness */ - padding: 35% 2px 0; /* indicator length & thickness */ - background: white; - -webkit-transform-origin: 50% 100%; - -ms-transform-origin: 50% 100%; - transform-origin: 50% 100%; - border-radius: 3px 0 0 3px; -} - -.clockSecond { - width: 0; - height: 0; - position: absolute; - top: 50%; - left: 50%; - margin: -38% -1px 0 0; /* numbers must match negative length & thickness */ - padding: 38% 1px 0 0; /* indicator length & thickness */ - background: #888; - -webkit-transform-origin: 50% 100%; - -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; -} +.clockCircle { + margin: 0 auto; + position: relative; + border-radius: 50%; + background-size: 100%; +} + +.clockFace { + width: 100%; + height: 100%; +} + +.clockFace::after { + position: absolute; + top: 50%; + left: 50%; + width: 6px; + height: 6px; + margin: -3px 0 0 -3px; + background: white; + border-radius: 3px; + content: ""; + display: block; +} + +.clockHour { + width: 0; + height: 0; + position: absolute; + top: 50%; + left: 50%; + margin: -2px 0 -2px -25%; /* numbers much match negative length & thickness */ + padding: 2px 0 2px 25%; /* indicator length & thickness */ + background: white; + transform-origin: 100% 50%; + border-radius: 3px 0 0 3px; +} + +.clockMinute { + width: 0; + height: 0; + position: absolute; + top: 50%; + left: 50%; + margin: -35% -2px 0; /* numbers must match negative length & thickness */ + padding: 35% 2px 0; /* indicator length & thickness */ + background: white; + transform-origin: 50% 100%; + border-radius: 3px 0 0 3px; +} + +.clockSecond { + width: 0; + height: 0; + position: absolute; + top: 50%; + left: 50%; + margin: -38% -1px 0 0; /* numbers must match negative length & thickness */ + padding: 38% 1px 0 0; /* indicator length & thickness */ + background: #888; + transform-origin: 50% 100%; +} + +.module.clock .sun, +.module.clock .moon { + display: flex; +} + +.module.clock .sun > *, +.module.clock .moon > * { + flex: 1; +} diff --git a/modules/default/clock/faces/face-001.svg b/modules/default/clock/faces/face-001.svg index 6d1c17f30f..13436c76f8 100644 --- a/modules/default/clock/faces/face-001.svg +++ b/modules/default/clock/faces/face-001.svg @@ -1 +1 @@ -face-001 \ No newline at end of file +face-001 diff --git a/modules/default/clock/faces/face-002.svg b/modules/default/clock/faces/face-002.svg index a56210c01d..a3ee36823a 100644 --- a/modules/default/clock/faces/face-002.svg +++ b/modules/default/clock/faces/face-002.svg @@ -1 +1 @@ -face-002 \ No newline at end of file +face-002 diff --git a/modules/default/clock/faces/face-003.svg b/modules/default/clock/faces/face-003.svg index 38191df6de..d3fc32dedc 100644 --- a/modules/default/clock/faces/face-003.svg +++ b/modules/default/clock/faces/face-003.svg @@ -1 +1 @@ -face-003 \ No newline at end of file +face-003 diff --git a/modules/default/clock/faces/face-004.svg b/modules/default/clock/faces/face-004.svg index f69781aa17..140955d769 100644 --- a/modules/default/clock/faces/face-004.svg +++ b/modules/default/clock/faces/face-004.svg @@ -1 +1 @@ -face-004 \ No newline at end of file +face-004 diff --git a/modules/default/clock/faces/face-005.svg b/modules/default/clock/faces/face-005.svg index 577c4f5326..fb52a43529 100644 --- a/modules/default/clock/faces/face-005.svg +++ b/modules/default/clock/faces/face-005.svg @@ -1 +1 @@ -faces \ No newline at end of file +faces diff --git a/modules/default/clock/faces/face-006.svg b/modules/default/clock/faces/face-006.svg index 665e9ccdce..a9eff82686 100644 --- a/modules/default/clock/faces/face-006.svg +++ b/modules/default/clock/faces/face-006.svg @@ -1 +1 @@ -face-006 \ No newline at end of file +face-006 diff --git a/modules/default/clock/faces/face-007.svg b/modules/default/clock/faces/face-007.svg index 2dc41971c9..b0dde8340d 100644 --- a/modules/default/clock/faces/face-007.svg +++ b/modules/default/clock/faces/face-007.svg @@ -1 +1 @@ -face-007 \ No newline at end of file +face-007 diff --git a/modules/default/clock/faces/face-008.svg b/modules/default/clock/faces/face-008.svg index b5ea16ede9..551ea7df18 100644 --- a/modules/default/clock/faces/face-008.svg +++ b/modules/default/clock/faces/face-008.svg @@ -1 +1 @@ -face-008 \ No newline at end of file +face-008 diff --git a/modules/default/clock/faces/face-009.svg b/modules/default/clock/faces/face-009.svg index a498d853f0..cd3720f2e3 100644 --- a/modules/default/clock/faces/face-009.svg +++ b/modules/default/clock/faces/face-009.svg @@ -1 +1 @@ -face-009 \ No newline at end of file +face-009 diff --git a/modules/default/clock/faces/face-010.svg b/modules/default/clock/faces/face-010.svg index 2367959813..d0af3acb1a 100644 --- a/modules/default/clock/faces/face-010.svg +++ b/modules/default/clock/faces/face-010.svg @@ -1 +1 @@ -face-010 \ No newline at end of file +face-010 diff --git a/modules/default/clock/faces/face-011.svg b/modules/default/clock/faces/face-011.svg index 493c75c2d3..2d5f27ba6b 100644 --- a/modules/default/clock/faces/face-011.svg +++ b/modules/default/clock/faces/face-011.svg @@ -1 +1 @@ -face-011 \ No newline at end of file +face-011 diff --git a/modules/default/clock/faces/face-012.svg b/modules/default/clock/faces/face-012.svg index a1a0fdd88a..8096d49290 100644 --- a/modules/default/clock/faces/face-012.svg +++ b/modules/default/clock/faces/face-012.svg @@ -1 +1 @@ -face-012 \ No newline at end of file +face-012 diff --git a/modules/default/compliments/README.md b/modules/default/compliments/README.md index c746f3185a..e1360f2e9c 100644 --- a/modules/default/compliments/README.md +++ b/modules/default/compliments/README.md @@ -1,4 +1,5 @@ # Module: Compliments + The `compliments` module is one of the default modules of the MagicMirror. This module displays a random compliment. diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index bf7bca9f08..412fe1704d 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -1,37 +1,18 @@ -/* global Log, Module, moment */ - /* Magic Mirror * Module: Compliments * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ Module.register("compliments", { - // Module config defaults. defaults: { 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!" - ], - "....-01-01": [ - "Happy new year!" - ] + 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!"], + "....-01-01": ["Happy new year!"] }, updateInterval: 30000, remoteFile: null, @@ -43,31 +24,31 @@ Module.register("compliments", { random: true, mockDate: null }, - lastIndexUsed:-1, + lastIndexUsed: -1, // Set currentweather from module currentWeatherType: "", // Define required scripts. - getScripts: function() { + getScripts: function () { return ["moment.js"]; }, // Define start sequence. - start: function() { + start: function () { Log.info("Starting module: " + this.name); this.lastComplimentIndex = -1; var self = this; if (this.config.remoteFile !== null) { - this.complimentFile(function(response) { + this.complimentFile(function (response) { self.config.compliments = JSON.parse(response); self.updateDom(); }); } // Schedule update timer. - setInterval(function() { + setInterval(function () { self.updateDom(self.config.fadeSpeed); }, this.config.updateInterval); }, @@ -79,12 +60,12 @@ Module.register("compliments", { * * return Number - Random index. */ - randomIndex: function(compliments) { + randomIndex: function (compliments) { if (compliments.length === 1) { return 0; } - var generate = function() { + var generate = function () { return Math.floor(Math.random() * compliments.length); }; @@ -104,7 +85,7 @@ Module.register("compliments", { * * return compliments Array - Array with compliments for the time of the day. */ - complimentArray: function() { + complimentArray: function () { var hour = moment().hour(); var date = this.config.mockDate ? this.config.mockDate : moment().format("YYYY-MM-DD"); var compliments; @@ -113,7 +94,7 @@ Module.register("compliments", { compliments = this.config.compliments.morning.slice(0); } else if (hour >= this.config.afternoonStartTime && hour < this.config.afternoonEndTime && this.config.compliments.hasOwnProperty("afternoon")) { compliments = this.config.compliments.afternoon.slice(0); - } else if(this.config.compliments.hasOwnProperty("evening")) { + } else if (this.config.compliments.hasOwnProperty("evening")) { compliments = this.config.compliments.evening.slice(0); } @@ -127,7 +108,7 @@ Module.register("compliments", { compliments.push.apply(compliments, this.config.compliments.anytime); - for (entry in this.config.compliments) { + for (var entry in this.config.compliments) { if (new RegExp(entry).test(date)) { compliments.push.apply(compliments, this.config.compliments[entry]); } @@ -139,13 +120,13 @@ Module.register("compliments", { /* complimentFile(callback) * Retrieve a file from the local filesystem */ - complimentFile: function(callback) { + complimentFile: function (callback) { var xobj = new XMLHttpRequest(), isRemote = this.config.remoteFile.indexOf("http://") === 0 || this.config.remoteFile.indexOf("https://") === 0, path = isRemote ? this.config.remoteFile : this.file(this.config.remoteFile); xobj.overrideMimeType("application/json"); xobj.open("GET", path, true); - xobj.onreadystatechange = function() { + xobj.onreadystatechange = function () { if (xobj.readyState === 4 && xobj.status === 200) { callback(xobj.responseText); } @@ -158,27 +139,26 @@ Module.register("compliments", { * * return compliment string - A compliment. */ - randomCompliment: function() { + randomCompliment: function () { // get the current time of day compliments list var compliments = this.complimentArray(); // variable for index to next message to display let index = 0; // are we randomizing - if(this.config.random){ + if (this.config.random) { // yes index = this.randomIndex(compliments); - } - else{ + } else { // no, sequential // 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. - getDom: function() { + getDom: function () { var wrapper = document.createElement("div"); wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright pre-line"; // get the compliment text @@ -188,7 +168,7 @@ Module.register("compliments", { // create a span to hold it all var compliment = document.createElement("span"); // process all the parts of the compliment text - for (part of parts){ + for (var part of parts) { // create a text element for each part compliment.appendChild(document.createTextNode(part)); // add a break ` @@ -202,7 +182,7 @@ Module.register("compliments", { }, // From data currentweather set weather type - setCurrentWeatherType: function(data) { + setCurrentWeatherType: function (data) { var weatherIconTable = { "01d": "day_sunny", "02d": "day_cloudy", @@ -227,10 +207,9 @@ Module.register("compliments", { }, // Override notification handler. - notificationReceived: function(notification, payload, sender) { + notificationReceived: function (notification, payload, sender) { if (notification === "CURRENTWEATHER_DATA") { this.setCurrentWeatherType(payload.data); } - }, - + } }); diff --git a/modules/default/currentweather/README.md b/modules/default/currentweather/README.md index 27b047da7e..d4db59ea72 100644 --- a/modules/default/currentweather/README.md +++ b/modules/default/currentweather/README.md @@ -1,4 +1,5 @@ # Module: Current Weather + 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. diff --git a/modules/default/currentweather/currentweather.css b/modules/default/currentweather/currentweather.css index b7669bdad3..3930c88585 100644 --- a/modules/default/currentweather/currentweather.css +++ b/modules/default/currentweather/currentweather.css @@ -3,8 +3,6 @@ font-size: 75%; line-height: 65px; display: inline-block; - -ms-transform: translate(0, -3px); /* IE 9 */ - -webkit-transform: translate(0, -3px); /* Safari */ transform: translate(0, -3px); } diff --git a/modules/default/currentweather/currentweather.js b/modules/default/currentweather/currentweather.js index 7f7c805dcf..d9d06ccb49 100644 --- a/modules/default/currentweather/currentweather.js +++ b/modules/default/currentweather/currentweather.js @@ -1,14 +1,10 @@ -/* global Module */ - /* Magic Mirror * Module: CurrentWeather * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -Module.register("currentweather",{ - +Module.register("currentweather", { // Default module config. defaults: { location: false, @@ -23,11 +19,11 @@ Module.register("currentweather",{ showWindDirection: true, showWindDirectionAsArrow: false, useBeaufort: true, - appendLocationNameToHeader: false, useKMPHwind: false, lang: config.language, decimalSymbol: ".", showHumidity: false, + showSun: true, degreeLabel: false, showIndoorTemperature: false, showIndoorHumidity: false, @@ -67,7 +63,7 @@ Module.register("currentweather",{ "11n": "wi-night-thunderstorm", "13n": "wi-night-snow", "50n": "wi-night-alt-cloudy-windy" - }, + } }, // create a variable for the first upcoming calendar event. Used if no location is specified. @@ -77,17 +73,17 @@ Module.register("currentweather",{ fetchedLocationName: "", // Define required scripts. - getScripts: function() { + getScripts: function () { return ["moment.js"]; }, // Define required scripts. - getStyles: function() { + getStyles: function () { return ["weather-icons.css", "currentweather.css"]; }, // Define required translations. - getTranslations: function() { + getTranslations: function () { // The translations for the default modules are defined in the core translation files. // Therefor we can just return false. Otherwise we should have returned a dictionary. // If you're trying to build your own module including translations, check out the documentation. @@ -95,7 +91,7 @@ Module.register("currentweather",{ }, // Define start sequence. - start: function() { + start: function () { Log.info("Starting module: " + this.name); // Set locale. @@ -113,13 +109,11 @@ Module.register("currentweather",{ this.feelsLike = null; this.loaded = false; this.scheduleUpdate(this.config.initialLoadDelay); - }, // add extra information of current weather // windDirection, humidity, sunrise and sunset - addExtraInfoWeather: function(wrapper) { - + addExtraInfoWeather: function (wrapper) { var small = document.createElement("div"); small.className = "normal medium"; @@ -134,8 +128,8 @@ Module.register("currentweather",{ if (this.config.showWindDirection) { var windDirection = document.createElement("sup"); if (this.config.showWindDirectionAsArrow) { - if(this.windDeg !== null) { - windDirection.innerHTML = "   "; + if (this.windDeg !== null) { + windDirection.innerHTML = '   '; } } else { windDirection.innerHTML = " " + this.translate(this.windDirection); @@ -150,31 +144,33 @@ Module.register("currentweather",{ var humidity = document.createElement("span"); humidity.innerHTML = this.humidity; - var spacer = document.createElement("sup"); - spacer.innerHTML = " "; + var supspacer = document.createElement("sup"); + supspacer.innerHTML = " "; var humidityIcon = document.createElement("sup"); humidityIcon.className = "wi wi-humidity humidityIcon"; humidityIcon.innerHTML = " "; small.appendChild(humidity); - small.appendChild(spacer); + small.appendChild(supspacer); small.appendChild(humidityIcon); } - var sunriseSunsetIcon = document.createElement("span"); - sunriseSunsetIcon.className = "wi dimmed " + this.sunriseSunsetIcon; - small.appendChild(sunriseSunsetIcon); + if (this.config.showSun) { + var sunriseSunsetIcon = document.createElement("span"); + sunriseSunsetIcon.className = "wi dimmed " + this.sunriseSunsetIcon; + small.appendChild(sunriseSunsetIcon); - var sunriseSunsetTime = document.createElement("span"); - sunriseSunsetTime.innerHTML = " " + this.sunriseSunsetTime; - small.appendChild(sunriseSunsetTime); + var sunriseSunsetTime = document.createElement("span"); + sunriseSunsetTime.innerHTML = " " + this.sunriseSunsetTime; + small.appendChild(sunriseSunsetTime); + } wrapper.appendChild(small); }, // Override dom generator. - getDom: function() { + getDom: function () { var wrapper = document.createElement("div"); wrapper.className = this.config.tableClass; @@ -201,17 +197,17 @@ Module.register("currentweather",{ 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.degreeLabel) { + switch (this.config.units) { + case "metric": + degreeLabel += "C"; + break; + case "imperial": + degreeLabel += "F"; + break; + case "default": + degreeLabel += "K"; + break; } } @@ -254,7 +250,7 @@ Module.register("currentweather",{ wrapper.appendChild(large); - if (this.config.showFeelsLike && this.config.onlyTemp === false){ + if (this.config.showFeelsLike && this.config.onlyTemp === false) { var small = document.createElement("div"); small.className = "normal medium"; @@ -270,7 +266,7 @@ Module.register("currentweather",{ }, // Override getHeader method. - getHeader: function() { + getHeader: function () { if (this.config.appendLocationNameToHeader && this.data.header !== undefined) { return this.data.header + " " + this.fetchedLocationName; } @@ -283,10 +279,10 @@ Module.register("currentweather",{ }, // Override notification handler. - notificationReceived: function(notification, payload, sender) { + notificationReceived: function (notification, payload, sender) { if (notification === "DOM_OBJECTS_CREATED") { if (this.config.appendLocationNameToHeader) { - this.hide(0, {lockString: this.identifier}); + this.hide(0, { lockString: this.identifier }); } } if (notification === "CALENDAR_EVENTS") { @@ -318,7 +314,7 @@ Module.register("currentweather",{ * Requests new data from openweather.org. * Calls processWeather on succesfull response. */ - updateWeather: function() { + updateWeather: function () { if (this.config.appid === "") { Log.error("CurrentWeather: APPID not set!"); return; @@ -330,7 +326,7 @@ Module.register("currentweather",{ var weatherRequest = new XMLHttpRequest(); weatherRequest.open("GET", url, true); - weatherRequest.onreadystatechange = function() { + weatherRequest.onreadystatechange = function () { if (this.readyState === 4) { if (this.status === 200) { self.processWeather(JSON.parse(this.response)); @@ -344,7 +340,7 @@ Module.register("currentweather",{ } if (retry) { - self.scheduleUpdate((self.loaded) ? -1 : self.config.retryDelay); + self.scheduleUpdate(self.loaded ? -1 : self.config.retryDelay); } } }; @@ -356,18 +352,18 @@ Module.register("currentweather",{ * * return String - URL params. */ - getParams: function() { + getParams: function () { var params = "?"; - if(this.config.locationID) { + if (this.config.locationID) { params += "id=" + this.config.locationID; - } else if(this.config.location) { + } else if (this.config.location) { params += "q=" + this.config.location; } else if (this.firstEvent && this.firstEvent.geo) { params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon; } else if (this.firstEvent && this.firstEvent.location) { params += "q=" + this.firstEvent.location; } else { - this.hide(this.config.animationSpeed, {lockString:this.identifier}); + this.hide(this.config.animationSpeed, { lockString: this.identifier }); return; } @@ -383,8 +379,7 @@ Module.register("currentweather",{ * * argument data object - Weather information received form openweather.org. */ - processWeather: function(data) { - + processWeather: function (data) { if (!data || !data.main || typeof data.main.temp === "undefined") { // Did not receive usable new data. // Maybe this needs a better check? @@ -396,7 +391,7 @@ Module.register("currentweather",{ this.fetchedLocationName = data.name; this.feelsLike = 0; - if (this.config.useBeaufort){ + if (this.config.useBeaufort) { this.windSpeed = this.ms2Beaufort(this.roundValue(data.wind.speed)); } else if (this.config.useKMPHwind) { this.windSpeed = parseFloat((data.wind.speed * 60 * 60) / 1000).toFixed(0); @@ -408,52 +403,59 @@ Module.register("currentweather",{ var windInMph = parseFloat(data.wind.speed * 2.23694); var tempInF = 0; - switch (this.config.units){ - case "metric": tempInF = 1.8 * this.temperature + 32; - break; - case "imperial": tempInF = this.temperature; - break; - case "default": - var tc = this.temperature - 273.15; - tempInF = 1.8 * tc + 32; - break; + switch (this.config.units) { + case "metric": + tempInF = 1.8 * this.temperature + 32; + break; + case "imperial": + tempInF = this.temperature; + break; + case "default": + tempInF = 1.8 * (this.temperature - 273.15) + 32; + break; } - if (windInMph > 3 && tempInF < 50){ + if (windInMph > 3 && tempInF < 50) { // windchill - var windChillInF = Math.round(35.74+0.6215*tempInF-35.75*Math.pow(windInMph,0.16)+0.4275*tempInF*Math.pow(windInMph,0.16)); - var windChillInC = (windChillInF - 32) * (5/9); + var windChillInF = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16)); + var windChillInC = (windChillInF - 32) * (5 / 9); // this.feelsLike = windChillInC.toFixed(0); - switch (this.config.units){ - case "metric": this.feelsLike = windChillInC.toFixed(0); - break; - case "imperial": this.feelsLike = windChillInF.toFixed(0); - break; - case "default": - var tc = windChillInC + 273.15; - this.feelsLike = tc.toFixed(0); - break; + switch (this.config.units) { + case "metric": + this.feelsLike = windChillInC.toFixed(0); + break; + case "imperial": + this.feelsLike = windChillInF.toFixed(0); + break; + case "default": + this.feelsLike = (windChillInC + 273.15).toFixed(0); + break; } - - } else if (tempInF > 80 && this.humidity > 40){ + } else if (tempInF > 80 && this.humidity > 40) { // heat index - var Hindex = -42.379 + 2.04901523*tempInF + 10.14333127*this.humidity - - 0.22475541*tempInF*this.humidity - 6.83783*Math.pow(10,-3)*tempInF*tempInF - - 5.481717*Math.pow(10,-2)*this.humidity*this.humidity - + 1.22874*Math.pow(10,-3)*tempInF*tempInF*this.humidity - + 8.5282*Math.pow(10,-4)*tempInF*this.humidity*this.humidity - - 1.99*Math.pow(10,-6)*tempInF*tempInF*this.humidity*this.humidity; - - switch (this.config.units){ - case "metric": this.feelsLike = parseFloat((Hindex - 32) / 1.8).toFixed(0); - break; - case "imperial": this.feelsLike = Hindex.toFixed(0); - break; - case "default": - var tc = parseFloat((Hindex - 32) / 1.8) + 273.15; - this.feelsLike = tc.toFixed(0); - break; + var Hindex = + -42.379 + + 2.04901523 * tempInF + + 10.14333127 * this.humidity - + 0.22475541 * tempInF * this.humidity - + 6.83783 * Math.pow(10, -3) * tempInF * tempInF - + 5.481717 * Math.pow(10, -2) * this.humidity * this.humidity + + 1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity + + 8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity - + 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; + + switch (this.config.units) { + case "metric": + this.feelsLike = parseFloat((Hindex - 32) / 1.8).toFixed(0); + break; + case "imperial": + this.feelsLike = Hindex.toFixed(0); + break; + case "default": + var tc = parseFloat((Hindex - 32) / 1.8) + 273.15; + this.feelsLike = tc.toFixed(0); + break; } } else { this.feelsLike = parseFloat(this.temperature).toFixed(0); @@ -470,7 +472,7 @@ Module.register("currentweather",{ // The moment().format('h') method has a bug on the Raspberry Pi. // So we need to generate the timestring manually. // See issue: https://github.com/MichMich/MagicMirror/issues/181 - var sunriseSunsetDateObject = (sunrise < now && sunset > now) ? sunset : sunrise; + var sunriseSunsetDateObject = sunrise < now && sunset > now ? sunset : sunrise; var timeString = moment(sunriseSunsetDateObject).format("HH:mm"); if (this.config.timeFormat !== 24) { //var hours = sunriseSunsetDateObject.getHours() % 12 || 12; @@ -489,12 +491,12 @@ Module.register("currentweather",{ } this.sunriseSunsetTime = timeString; - this.sunriseSunsetIcon = (sunrise < now && sunset > now) ? "wi-sunset" : "wi-sunrise"; + this.sunriseSunsetIcon = sunrise < now && sunset > now ? "wi-sunset" : "wi-sunrise"; - this.show(this.config.animationSpeed, {lockString:this.identifier}); + this.show(this.config.animationSpeed, { lockString: this.identifier }); this.loaded = true; this.updateDom(this.config.animationSpeed); - this.sendNotification("CURRENTWEATHER_DATA", {data: data}); + this.sendNotification("CURRENTWEATHER_DATA", { data: data }); }, /* scheduleUpdate() @@ -502,14 +504,14 @@ Module.register("currentweather",{ * * argument delay number - Milliseconds before next update. If empty, this.config.updateInterval is used. */ - scheduleUpdate: function(delay) { + scheduleUpdate: function (delay) { var nextLoad = this.config.updateInterval; if (typeof delay !== "undefined" && delay >= 0) { nextLoad = delay; } var self = this; - setTimeout(function() { + setTimeout(function () { self.updateWeather(); }, nextLoad); }, @@ -518,15 +520,15 @@ Module.register("currentweather",{ * Converts m2 to beaufort (windspeed). * * see: - * http://www.spc.noaa.gov/faq/tornado/beaufort.html + * https://www.spc.noaa.gov/faq/tornado/beaufort.html * https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale * * argument ms number - Windspeed in m/s. * * return number - Windspeed in beaufort. */ - ms2Beaufort: function(ms) { - var kmh = ms * 60 * 60 / 1000; + ms2Beaufort: function (ms) { + var kmh = (ms * 60 * 60) / 1000; var speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; for (var beaufort in speeds) { var speed = speeds[beaufort]; @@ -537,8 +539,8 @@ Module.register("currentweather",{ return 12; }, - deg2Cardinal: function(deg) { - if (deg>11.25 && deg<=33.75){ + deg2Cardinal: function (deg) { + if (deg > 11.25 && deg <= 33.75) { return "NNE"; } else if (deg > 33.75 && deg <= 56.25) { return "NE"; @@ -580,9 +582,8 @@ Module.register("currentweather",{ * * return string - Rounded Temperature. */ - roundValue: function(temperature) { + roundValue: function (temperature) { var decimals = this.config.roundTemp ? 0 : 1; return parseFloat(temperature).toFixed(decimals); } - }); diff --git a/modules/default/defaultmodules.js b/modules/default/defaultmodules.js index 656ba6b8af..9bdcbe958d 100644 --- a/modules/default/defaultmodules.js +++ b/modules/default/defaultmodules.js @@ -1,24 +1,15 @@ /* Magic Mirror * Default Modules List * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ // Modules listed below can be loaded without the 'default/' prefix. Omitting the default folder name. -var defaultModules = [ - "alert", - "calendar", - "clock", - "compliments", - "currentweather", - "helloworld", - "newsfeed", - "weatherforecast", - "updatenotification", - "weather" -]; +var defaultModules = ["alert", "calendar", "clock", "compliments", "currentweather", "helloworld", "newsfeed", "weatherforecast", "updatenotification", "weather"]; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = defaultModules;} +if (typeof module !== "undefined") { + module.exports = defaultModules; +} diff --git a/modules/default/helloworld/README.md b/modules/default/helloworld/README.md index 8ad06f77e2..5d5d3a17f7 100644 --- a/modules/default/helloworld/README.md +++ b/modules/default/helloworld/README.md @@ -1,4 +1,5 @@ # 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). diff --git a/modules/default/helloworld/helloworld.js b/modules/default/helloworld/helloworld.js index cf6cebfa56..68eb22fc09 100644 --- a/modules/default/helloworld/helloworld.js +++ b/modules/default/helloworld/helloworld.js @@ -1,14 +1,10 @@ -/* global Module */ - /* Magic Mirror * Module: HelloWorld * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -Module.register("helloworld",{ - +Module.register("helloworld", { // Default module config. defaults: { text: "Hello World!" diff --git a/modules/default/newsfeed/README.md b/modules/default/newsfeed/README.md index 33690aa601..484fedbab6 100644 --- a/modules/default/newsfeed/README.md +++ b/modules/default/newsfeed/README.md @@ -1,5 +1,6 @@ # Module: News Feed -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. + +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/newsfeed/fetcher.js b/modules/default/newsfeed/fetcher.js index 4e3bcca726..da9616dcc3 100644 --- a/modules/default/newsfeed/fetcher.js +++ b/modules/default/newsfeed/fetcher.js @@ -1,13 +1,14 @@ /* Magic Mirror * Fetcher * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -var FeedMe = require("feedme"); -var request = require("request"); -var iconv = require("iconv-lite"); +const Log = require("../../../js/logger.js"); +const FeedMe = require("feedme"); +const request = require("request"); +const iconv = require("iconv-lite"); /* Fetcher * Responsible for requesting an update on the set interval and broadcasting the data. @@ -17,7 +18,7 @@ var iconv = require("iconv-lite"); * attribute logFeedWarnings boolean - Log warnings when there is an error parsing a news article. */ -var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) { +var Fetcher = function (url, reloadInterval, encoding, logFeedWarnings) { var self = this; if (reloadInterval < 1000) { reloadInterval = 1000; @@ -26,83 +27,74 @@ var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) { var reloadTimer = null; var items = []; - var fetchFailedCallback = function() {}; - var itemsReceivedCallback = function() {}; + var fetchFailedCallback = function () {}; + var itemsReceivedCallback = function () {}; /* private methods */ /* fetchNews() * Request the new items. */ - - var fetchNews = function() { + var fetchNews = function () { clearTimeout(reloadTimer); reloadTimer = null; items = []; var parser = new FeedMe(); - parser.on("item", function(item) { - + parser.on("item", function (item) { var title = item.title; var description = item.description || item.summary || item.content || ""; var pubdate = item.pubdate || item.published || item.updated || item["dc:date"]; var url = item.url || item.link || ""; if (title && pubdate) { - - var regex = /(<([^>]+)>)/ig; + var regex = /(<([^>]+)>)/gi; description = description.toString().replace(regex, ""); items.push({ title: title, description: description, pubdate: pubdate, - url: url, + url: url }); - } else if (logFeedWarnings) { - console.log("Can't parse feed item:"); - console.log(item); - console.log("Title: " + title); - console.log("Description: " + description); - console.log("Pubdate: " + pubdate); + Log.warn("Can't parse feed item:"); + Log.warn(item); + Log.warn("Title: " + title); + Log.warn("Description: " + description); + Log.warn("Pubdate: " + pubdate); } }); - parser.on("end", function() { - //console.log("end parsing - " + url); + parser.on("end", function () { self.broadcastItems(); scheduleTimer(); }); - parser.on("error", function(error) { + parser.on("error", function (error) { fetchFailedCallback(self, error); scheduleTimer(); }); - nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); - headers = {"User-Agent": "Mozilla/5.0 (Node.js "+ nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)", - "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate", - "Pragma": "no-cache"}; + var nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); + var headers = { "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + " (https://github.com/MichMich/MagicMirror/)", "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate", Pragma: "no-cache" }; - request({uri: url, encoding: null, headers: headers}) - .on("error", function(error) { + request({ uri: url, encoding: null, headers: headers }) + .on("error", function (error) { fetchFailedCallback(self, error); scheduleTimer(); }) - .pipe(iconv.decodeStream(encoding)).pipe(parser); - + .pipe(iconv.decodeStream(encoding)) + .pipe(parser); }; /* scheduleTimer() * Schedule the timer for the next update. */ - - var scheduleTimer = function() { - //console.log('Schedule update timer.'); + var scheduleTimer = function () { clearTimeout(reloadTimer); - reloadTimer = setTimeout(function() { + reloadTimer = setTimeout(function () { fetchNews(); }, reloadInterval); }; @@ -114,7 +106,7 @@ var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) { * * attribute interval number - Interval for the update in milliseconds. */ - this.setReloadInterval = function(interval) { + this.setReloadInterval = function (interval) { if (interval > 1000 && interval < reloadInterval) { reloadInterval = interval; } @@ -123,35 +115,35 @@ var Fetcher = function(url, reloadInterval, encoding, logFeedWarnings) { /* startFetch() * Initiate fetchNews(); */ - this.startFetch = function() { + this.startFetch = function () { fetchNews(); }; /* broadcastItems() * Broadcast the existing items. */ - this.broadcastItems = function() { + this.broadcastItems = function () { if (items.length <= 0) { - //console.log('No items to broadcast yet.'); + Log.info("Newsfeed-Fetcher: No items to broadcast yet."); return; } - //console.log('Broadcasting ' + items.length + ' items.'); + Log.info("Newsfeed-Fetcher: Broadcasting " + items.length + " items."); itemsReceivedCallback(self); }; - this.onReceive = function(callback) { + this.onReceive = function (callback) { itemsReceivedCallback = callback; }; - this.onError = function(callback) { + this.onError = function (callback) { fetchFailedCallback = callback; }; - this.url = function() { + this.url = function () { return url; }; - this.items = function() { + this.items = function () { return items; }; }; diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index cb0e8ece3c..70809522cd 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -1,20 +1,16 @@ -/* global Module */ - /* Magic Mirror * Module: NewsFeed * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -Module.register("newsfeed",{ - +Module.register("newsfeed", { // Default module config. defaults: { feeds: [ { title: "New York Times", - url: "http://www.nytimes.com/services/xml/rss/nyt/HomePage.xml", + url: "https://rss.nytimes.com/services/xml/rss/nyt/HomePage.xml", encoding: "UTF-8" //ISO-8859-1 } ], @@ -44,12 +40,12 @@ Module.register("newsfeed",{ }, // Define required scripts. - getScripts: function() { + getScripts: function () { return ["moment.js"]; }, // Define required translations. - getTranslations: function() { + getTranslations: function () { // The translations for the default modules are defined in the core translation files. // Therefor we can just return false. Otherwise we should have returned a dictionary. // If you're trying to build your own module including translations, check out the documentation. @@ -57,7 +53,7 @@ Module.register("newsfeed",{ }, // Define start sequence. - start: function() { + start: function () { Log.info("Starting module: " + this.name); // Set locale. @@ -74,7 +70,7 @@ Module.register("newsfeed",{ }, // Override socket notification handler. - socketNotificationReceived: function(notification, payload) { + socketNotificationReceived: function (notification, payload) { if (notification === "NEWS_ITEMS") { this.generateFeed(payload); @@ -87,7 +83,7 @@ Module.register("newsfeed",{ }, // Override dom generator. - getDom: function() { + getDom: function () { var wrapper = document.createElement("div"); if (this.config.feedUrl) { @@ -101,7 +97,6 @@ Module.register("newsfeed",{ } if (this.newsItems.length > 0) { - // this.config.showFullArticle is a run-time configuration, triggered by optional notifications if (!this.config.showFullArticle && (this.config.showSourceTitle || this.config.showPublishDate)) { var sourceAndTimestamp = document.createElement("div"); @@ -116,7 +111,7 @@ Module.register("newsfeed",{ if (this.config.showPublishDate) { sourceAndTimestamp.innerHTML += moment(new Date(this.newsItems[this.activeItem].pubdate)).fromNow(); } - if (this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== "" || this.config.showPublishDate) { + if ((this.config.showSourceTitle && this.newsItems[this.activeItem].sourceTitle !== "") || this.config.showPublishDate) { sourceAndTimestamp.innerHTML += ":"; } @@ -126,47 +121,42 @@ Module.register("newsfeed",{ //Remove selected tags from the beginning of rss feed items (title or description) if (this.config.removeStartTags === "title" || this.config.removeStartTags === "both") { - - for (f=0; f this.config.lengthDescription ? txtDesc.substring(0, this.config.lengthDescription) + "..." : txtDesc) : txtDesc); + description.innerHTML = this.config.truncDescription ? (txtDesc.length > this.config.lengthDescription ? txtDesc.substring(0, this.config.lengthDescription) + "..." : txtDesc) : txtDesc; wrapper.appendChild(description); } @@ -199,7 +189,6 @@ Module.register("newsfeed",{ if (this.config.hideLoading) { this.show(); } - } else { if (this.config.hideLoading) { this.hide(); @@ -212,14 +201,14 @@ Module.register("newsfeed",{ return wrapper; }, - getActiveItemURL: function() { + getActiveItemURL: function () { return typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href; }, /* registerFeeds() * registers the feeds to be used by the backend. */ - registerFeeds: function() { + registerFeeds: function () { for (var f in this.config.feeds) { var feed = this.config.feeds[f]; this.sendSocketNotification("ADD_FEED", { @@ -234,7 +223,7 @@ Module.register("newsfeed",{ * * attribute feeds object - An object with feeds returned by the node helper. */ - generateFeed: function(feeds) { + generateFeed: function (feeds) { var newsItems = []; for (var feed in feeds) { var feedItems = feeds[feed]; @@ -242,24 +231,24 @@ Module.register("newsfeed",{ for (var i in feedItems) { var item = feedItems[i]; item.sourceTitle = this.titleForFeed(feed); - if (!(this.config.ignoreOldItems && ((Date.now() - new Date(item.pubdate)) > this.config.ignoreOlderThan))) { + if (!(this.config.ignoreOldItems && Date.now() - new Date(item.pubdate) > this.config.ignoreOlderThan)) { newsItems.push(item); } } } } - newsItems.sort(function(a,b) { + newsItems.sort(function (a, b) { var dateA = new Date(a.pubdate); var dateB = new Date(b.pubdate); return dateB - dateA; }); - if(this.config.maxNewsItems > 0) { + if (this.config.maxNewsItems > 0) { newsItems = newsItems.slice(0, this.config.maxNewsItems); } - if(this.config.prohibitedWords.length > 0) { - newsItems = newsItems.filter(function(value){ - for (var i=0; i < this.config.prohibitedWords.length; i++) { + if (this.config.prohibitedWords.length > 0) { + newsItems = newsItems.filter(function (value) { + for (var i = 0; i < this.config.prohibitedWords.length; i++) { if (value["title"].toLowerCase().indexOf(this.config.prohibitedWords[i].toLowerCase()) > -1) { return false; } @@ -270,8 +259,8 @@ Module.register("newsfeed",{ // get updated news items and broadcast them var updatedItems = []; - newsItems.forEach(value => { - if (this.newsItems.findIndex(value1 => value1 === value) === -1) { + newsItems.forEach((value) => { + if (this.newsItems.findIndex((value1) => value1 === value) === -1) { // Add item to updated items list updatedItems.push(value); } @@ -279,7 +268,7 @@ Module.register("newsfeed",{ // check if updated items exist, if so and if we should broadcast these updates, then lets do so if (this.config.broadcastNewsUpdates && updatedItems.length > 0) { - this.sendNotification("NEWS_FEED_UPDATE", {items: updatedItems}); + this.sendNotification("NEWS_FEED_UPDATE", { items: updatedItems }); } this.newsItems = newsItems; @@ -292,7 +281,7 @@ Module.register("newsfeed",{ * * returns bool */ - subscribedToFeed: function(feedUrl) { + subscribedToFeed: function (feedUrl) { for (var f in this.config.feeds) { var feed = this.config.feeds[f]; if (feed.url === feedUrl) { @@ -309,7 +298,7 @@ Module.register("newsfeed",{ * * returns string */ - titleForFeed: function(feedUrl) { + titleForFeed: function (feedUrl) { for (var f in this.config.feeds) { var feed = this.config.feeds[f]; if (feed.url === feedUrl) { @@ -322,23 +311,23 @@ Module.register("newsfeed",{ /* scheduleUpdateInterval() * Schedule visual update. */ - scheduleUpdateInterval: function() { + scheduleUpdateInterval: function () { var self = this; self.updateDom(self.config.animationSpeed); // Broadcast NewsFeed if needed if (self.config.broadcastNewsFeeds) { - self.sendNotification("NEWS_FEED", {items: self.newsItems}); + self.sendNotification("NEWS_FEED", { items: self.newsItems }); } - timer = setInterval(function() { + this.timer = setInterval(function () { self.activeItem++; self.updateDom(self.config.animationSpeed); // Broadcast NewsFeed if needed if (self.config.broadcastNewsFeeds) { - self.sendNotification("NEWS_FEED", {items: self.newsItems}); + self.sendNotification("NEWS_FEED", { items: self.newsItems }); } }, this.config.updateInterval); }, @@ -350,25 +339,25 @@ Module.register("newsfeed",{ * * return string - Capitalized output string. */ - capitalizeFirstLetter: function(string) { + capitalizeFirstLetter: function (string) { return string.charAt(0).toUpperCase() + string.slice(1); }, - resetDescrOrFullArticleAndTimer: function() { + resetDescrOrFullArticleAndTimer: function () { this.isShowingDescription = this.config.showDescription; this.config.showFullArticle = false; this.scrollPosition = 0; // reset bottom bar alignment document.getElementsByClassName("region bottom bar")[0].style.bottom = "0"; document.getElementsByClassName("region bottom bar")[0].style.top = "inherit"; - if(!timer){ + if (!this.timer) { this.scheduleUpdateInterval(); } }, - notificationReceived: function(notification, payload, sender) { - if(notification === "ARTICLE_NEXT"){ - var before = this.activeItem; + notificationReceived: function (notification, payload, sender) { + var before = this.activeItem; + if (notification === "ARTICLE_NEXT") { this.activeItem++; if (this.activeItem >= this.newsItems.length) { this.activeItem = 0; @@ -376,8 +365,7 @@ Module.register("newsfeed",{ this.resetDescrOrFullArticleAndTimer(); Log.info(this.name + " - going from article #" + before + " to #" + this.activeItem + " (of " + this.newsItems.length + ")"); this.updateDom(100); - } else if(notification === "ARTICLE_PREVIOUS"){ - var before = this.activeItem; + } else if (notification === "ARTICLE_PREVIOUS") { this.activeItem--; if (this.activeItem < 0) { this.activeItem = this.newsItems.length - 1; @@ -387,58 +375,56 @@ Module.register("newsfeed",{ this.updateDom(100); } // if "more details" is received the first time: show article summary, on second time show full article - else if(notification === "ARTICLE_MORE_DETAILS"){ + else if (notification === "ARTICLE_MORE_DETAILS") { // full article is already showing, so scrolling down - if(this.config.showFullArticle === true){ + if (this.config.showFullArticle === true) { this.scrollPosition += this.config.scrollLength; window.scrollTo(0, this.scrollPosition); Log.info(this.name + " - scrolling down"); Log.info(this.name + " - ARTICLE_MORE_DETAILS, scroll position: " + this.config.scrollLength); - } - else { + } else { this.showFullArticle(); } - } else if(notification === "ARTICLE_SCROLL_UP"){ - if(this.config.showFullArticle === true){ + } else if (notification === "ARTICLE_SCROLL_UP") { + if (this.config.showFullArticle === true) { this.scrollPosition -= this.config.scrollLength; window.scrollTo(0, this.scrollPosition); Log.info(this.name + " - scrolling up"); Log.info(this.name + " - ARTICLE_SCROLL_UP, scroll position: " + this.config.scrollLength); } - } else if(notification === "ARTICLE_LESS_DETAILS"){ + } else if (notification === "ARTICLE_LESS_DETAILS") { this.resetDescrOrFullArticleAndTimer(); Log.info(this.name + " - showing only article titles again"); this.updateDom(100); - } else if (notification === "ARTICLE_TOGGLE_FULL"){ - if (this.config.showFullArticle){ + } else if (notification === "ARTICLE_TOGGLE_FULL") { + if (this.config.showFullArticle) { this.activeItem++; this.resetDescrOrFullArticleAndTimer(); } else { this.showFullArticle(); } - } else if (notification === "ARTICLE_INFO_REQUEST"){ + } else if (notification === "ARTICLE_INFO_REQUEST") { this.sendNotification("ARTICLE_INFO_RESPONSE", { - title: this.newsItems[this.activeItem].title, + title: this.newsItems[this.activeItem].title, source: this.newsItems[this.activeItem].sourceTitle, - date: this.newsItems[this.activeItem].pubdate, - desc: this.newsItems[this.activeItem].description, - url: this.getActiveItemURL() + date: this.newsItems[this.activeItem].pubdate, + desc: this.newsItems[this.activeItem].description, + url: this.getActiveItemURL() }); } }, - showFullArticle: function() { + showFullArticle: function () { this.isShowingDescription = !this.isShowingDescription; this.config.showFullArticle = !this.isShowingDescription; // make bottom bar align to top to allow scrolling - if(this.config.showFullArticle === true){ + if (this.config.showFullArticle === true) { document.getElementsByClassName("region bottom bar")[0].style.bottom = "inherit"; document.getElementsByClassName("region bottom bar")[0].style.top = "-90px"; } - clearInterval(timer); - timer = null; + clearInterval(this.timer); + this.timer = null; Log.info(this.name + " - showing " + this.isShowingDescription ? "article description" : "full article"); this.updateDom(100); } - }); diff --git a/modules/default/newsfeed/node_helper.js b/modules/default/newsfeed/node_helper.js index 79c4d2fad2..4ccef9583d 100644 --- a/modules/default/newsfeed/node_helper.js +++ b/modules/default/newsfeed/node_helper.js @@ -1,26 +1,26 @@ /* Magic Mirror * Node Helper: Newsfeed * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ -var NodeHelper = require("node_helper"); -var validUrl = require("valid-url"); -var Fetcher = require("./fetcher.js"); +const NodeHelper = require("node_helper"); +const validUrl = require("valid-url"); +const Fetcher = require("./fetcher.js"); +const Log = require("../../../js/logger"); module.exports = NodeHelper.create({ - // Subclass start method. - start: function() { - console.log("Starting module: " + this.name); + // Override start method. + start: function () { + Log.log("Starting node helper for: " + this.name); this.fetchers = []; }, - // Subclass socketNotificationReceived received. - socketNotificationReceived: function(notification, payload) { + // Override socketNotificationReceived received. + socketNotificationReceived: function (notification, payload) { if (notification === "ADD_FEED") { this.createFetcher(payload.feed, payload.config); - return; } }, @@ -31,7 +31,7 @@ module.exports = NodeHelper.create({ * attribute feed object - A feed object. * attribute config object - A configuration object containing reload interval in milliseconds. */ - createFetcher: function(feed, config) { + createFetcher: function (feed, config) { var self = this; var url = feed.url || ""; @@ -45,14 +45,14 @@ module.exports = NodeHelper.create({ var fetcher; if (typeof self.fetchers[url] === "undefined") { - console.log("Create new news fetcher for url: " + url + " - Interval: " + reloadInterval); + Log.log("Create new news fetcher for url: " + url + " - Interval: " + reloadInterval); fetcher = new Fetcher(url, reloadInterval, encoding, config.logFeedWarnings); - fetcher.onReceive(function(fetcher) { + fetcher.onReceive(function (fetcher) { self.broadcastFeeds(); }); - fetcher.onError(function(fetcher, error) { + fetcher.onError(function (fetcher, error) { self.sendSocketNotification("FETCH_ERROR", { url: fetcher.url(), error: error @@ -61,7 +61,7 @@ module.exports = NodeHelper.create({ self.fetchers[url] = fetcher; } else { - console.log("Use existing news fetcher for url: " + url); + Log.log("Use existing news fetcher for url: " + url); fetcher = self.fetchers[url]; fetcher.setReloadInterval(reloadInterval); fetcher.broadcastItems(); @@ -74,7 +74,7 @@ module.exports = NodeHelper.create({ * Creates an object with all feed items of the different registered feeds, * and broadcasts these using sendSocketNotification. */ - broadcastFeeds: function() { + broadcastFeeds: function () { var feeds = {}; for (var f in this.fetchers) { feeds[f] = this.fetchers[f].items(); diff --git a/modules/default/newsfeed/translations/de.json b/modules/default/newsfeed/translations/de.json index 9ec3ef7b23..a11eb32373 100644 --- a/modules/default/newsfeed/translations/de.json +++ b/modules/default/newsfeed/translations/de.json @@ -1,3 +1,3 @@ { - "configuration_changed": "Die Konfigurationsoptionen für das Newsfeed-Modul haben sich geändert. \nBitte überprüfen Sie die Dokumentation." -} \ No newline at end of file + "configuration_changed": "Die Konfigurationsoptionen für das Newsfeed-Modul haben sich geändert. \nBitte überprüfen Sie die Dokumentation." +} diff --git a/modules/default/newsfeed/translations/en.json b/modules/default/newsfeed/translations/en.json index 23b6100d1b..9e804445e1 100644 --- a/modules/default/newsfeed/translations/en.json +++ b/modules/default/newsfeed/translations/en.json @@ -1,3 +1,3 @@ { - "configuration_changed": "The configuration options for the newsfeed module have changed.\nPlease check the documentation." -} \ No newline at end of file + "configuration_changed": "The configuration options for the newsfeed module have changed.\nPlease check the documentation." +} diff --git a/modules/default/newsfeed/translations/es.json b/modules/default/newsfeed/translations/es.json index 6143f68c8d..b1124b6e33 100644 --- a/modules/default/newsfeed/translations/es.json +++ b/modules/default/newsfeed/translations/es.json @@ -1,3 +1,3 @@ { - "configuration_changed": "Las opciones de configuración para el módulo de suministro de noticias han cambiado. \nVerifique la documentación." -} \ No newline at end of file + "configuration_changed": "Las opciones de configuración para el módulo de suministro de noticias han cambiado. \nVerifique la documentación." +} diff --git a/modules/default/newsfeed/translations/fr.json b/modules/default/newsfeed/translations/fr.json index 85c6b41254..fa6d522ebf 100644 --- a/modules/default/newsfeed/translations/fr.json +++ b/modules/default/newsfeed/translations/fr.json @@ -1,3 +1,3 @@ { - "configuration_changed": "Les options de configuration du module newsfeed ont changé. \nVeuillez consulter la documentation." -} \ No newline at end of file + "configuration_changed": "Les options de configuration du module newsfeed ont changé. \nVeuillez consulter la documentation." +} diff --git a/modules/default/updatenotification/README.md b/modules/default/updatenotification/README.md index af6305e6df..0ab6886a9b 100644 --- a/modules/default/updatenotification/README.md +++ b/modules/default/updatenotification/README.md @@ -1,4 +1,5 @@ # Module: Update Notification + 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. diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index 2d41626c21..0c206c5fec 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -1,39 +1,37 @@ -var SimpleGit = require("simple-git"); -var simpleGits = []; -var fs = require("fs"); -var path = require("path"); -var defaultModules = require(__dirname + "/../defaultmodules.js"); -var NodeHelper = require("node_helper"); +const SimpleGit = require("simple-git"); +const simpleGits = []; +const fs = require("fs"); +const path = require("path"); +const defaultModules = require(__dirname + "/../defaultmodules.js"); +const Log = require(__dirname + "/../../../js/logger.js"); +const NodeHelper = require("node_helper"); module.exports = NodeHelper.create({ - config: {}, updateTimer: null, updateProcessStarted: false, - start: function () { - }, - - configureModules: function(modules) { + start: function () {}, + configureModules: function (modules) { // Push MagicMirror itself , biggest chance it'll show up last in UI and isn't overwritten // others will be added in front // 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 + "/../../../"))}); + simpleGits.push({ module: "default", git: SimpleGit(path.normalize(__dirname + "/../../../")) }); var promises = []; - for (moduleName in modules) { + for (var moduleName in modules) { if (!this.ignoreUpdateChecking(moduleName)) { // Default modules are included in the main MagicMirror repo var moduleFolder = path.normalize(__dirname + "/../../" + moduleName); try { - //console.log("checking git for module="+moduleName) + Log.info("Checking git for module: " + moduleName); let stat = fs.statSync(path.join(moduleFolder, ".git")); promises.push(this.resolveRemote(moduleName, moduleFolder)); - } catch(err) { + } catch (err) { // Error when directory .git doesn't exist // This module is not managed with git, skip continue; @@ -47,7 +45,7 @@ module.exports = NodeHelper.create({ socketNotificationReceived: function (notification, payload) { if (notification === "CONFIG") { this.config = payload; - } else if(notification === "MODULES") { + } else if (notification === "MODULES") { // if this is the 1st time thru the update check process if (!this.updateProcessStarted) { this.updateProcessStarted = true; @@ -56,7 +54,7 @@ module.exports = NodeHelper.create({ } }, - resolveRemote: function(moduleName, moduleFolder) { + resolveRemote: function (moduleName, moduleFolder) { return new Promise((resolve, reject) => { var git = SimpleGit(moduleFolder); git.getRemotes(true, (err, remotes) => { @@ -65,19 +63,19 @@ module.exports = NodeHelper.create({ return resolve(); } // Folder has .git and has at least one git remote, watch this folder - simpleGits.unshift({"module": moduleName, "git": git}); + simpleGits.unshift({ module: moduleName, git: git }); resolve(); }); }); }, - performFetch: function() { + performFetch: function () { var self = this; simpleGits.forEach((sg) => { sg.git.fetch().status((err, data) => { data.module = sg.module; if (!err) { - sg.git.log({"-1": null}, (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); @@ -90,19 +88,19 @@ module.exports = NodeHelper.create({ this.scheduleNextFetch(this.config.updateInterval); }, - scheduleNextFetch: function(delay) { + scheduleNextFetch: function (delay) { if (delay < 60 * 1000) { delay = 60 * 1000; } var self = this; clearTimeout(this.updateTimer); - this.updateTimer = setTimeout(function() { + this.updateTimer = setTimeout(function () { self.performFetch(); }, delay); }, - ignoreUpdateChecking: function(moduleName) { + ignoreUpdateChecking: function (moduleName) { // Should not check for updates for default modules if (defaultModules.indexOf(moduleName) >= 0) { return true; @@ -116,5 +114,4 @@ module.exports = NodeHelper.create({ // 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 35a018bfef..3de82f1c79 100644 --- a/modules/default/updatenotification/updatenotification.js +++ b/modules/default/updatenotification/updatenotification.js @@ -1,5 +1,10 @@ +/* Magic Mirror + * Module: UpdateNotification + * + * By Michael Teeuw https://michaelteeuw.nl + * MIT Licensed. + */ Module.register("updatenotification", { - defaults: { updateInterval: 10 * 60 * 1000, // every 10 minutes refreshInterval: 24 * 60 * 60 * 1000, // one day @@ -12,7 +17,10 @@ Module.register("updatenotification", { start: function () { var self = this; Log.log("Start updatenotification"); - setInterval( () => { self.moduleList = {};self.updateDom(2); } , self.config.refreshInterval); + setInterval(() => { + self.moduleList = {}; + self.updateDom(2); + }, self.config.refreshInterval); }, notificationReceived: function (notification, payload, sender) { @@ -33,16 +41,15 @@ Module.register("updatenotification", { var self = this; if (payload && payload.behind > 0) { // if we haven't seen info for this module - if(this.moduleList[payload.module] == undefined){ + if (this.moduleList[payload.module] === undefined) { // save it - this.moduleList[payload.module]=payload; + this.moduleList[payload.module] = payload; self.updateDom(2); } //self.show(1000, { lockString: self.identifier }); - - } else if (payload && payload.behind == 0){ + } else if (payload && payload.behind === 0) { // if the module WAS in the list, but shouldn't be - if(this.moduleList[payload.module] != undefined){ + if (this.moduleList[payload.module] !== undefined) { // remove it delete this.moduleList[payload.module]; self.updateDom(2); @@ -50,24 +57,19 @@ Module.register("updatenotification", { } }, - diffLink: function(module, text) { + diffLink: function (module, text) { var localRef = module.hash; var remoteRef = module.tracking.replace(/.*\//, ""); - return "" + - text + - ""; + return '' + text + ""; }, // Override dom generator. getDom: function () { var wrapper = document.createElement("div"); - if(this.suspended==false){ + if (this.suspended === false) { // process the hash of module info found - for(key of Object.keys(this.moduleList)){ - let m= this.moduleList[key]; + for (var key of Object.keys(this.moduleList)) { + let m = this.moduleList[key]; var message = document.createElement("div"); message.className = "small bright"; @@ -77,7 +79,7 @@ Module.register("updatenotification", { icon.innerHTML = " "; message.appendChild(icon); - var updateInfoKeyName = m.behind == 1 ? "UPDATE_INFO_SINGLE" : "UPDATE_INFO_MULTIPLE"; + var updateInfoKeyName = m.behind === 1 ? "UPDATE_INFO_SINGLE" : "UPDATE_INFO_MULTIPLE"; var subtextHtml = this.translate(updateInfoKeyName, { COMMIT_COUNT: m.behind, @@ -85,9 +87,9 @@ Module.register("updatenotification", { }); var text = document.createElement("span"); - if (m.module == "default") { + if (m.module === "default") { text.innerHTML = this.translate("UPDATE_NOTIFICATION"); - subtextHtml = this.diffLink(m,subtextHtml); + subtextHtml = this.diffLink(m, subtextHtml); } else { text.innerHTML = this.translate("UPDATE_NOTIFICATION_MODULE", { MODULE_NAME: m.module @@ -106,11 +108,11 @@ Module.register("updatenotification", { return wrapper; }, - suspend: function() { - this.suspended=true; + suspend: function () { + this.suspended = true; }, - resume: function() { - this.suspended=false; + resume: function () { + this.suspended = false; this.updateDom(2); } }); diff --git a/modules/default/weather/README.md b/modules/default/weather/README.md index ebc301f401..93f1595ddb 100755 --- a/modules/default/weather/README.md +++ b/modules/default/weather/README.md @@ -1,5 +1,5 @@ # Weather Module -This module is aimed to be the replacement for the current `currentweather` and `weatherforcast` modules. The module will be configurable to be used as a current weather view, or to show the forecast. This way the module can be used twice to fullfil both purposes. +This module aims 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/weather/current.njk b/modules/default/weather/current.njk index 33dac07a66..d89c5f538b 100755 --- a/modules/default/weather/current.njk +++ b/modules/default/weather/current.njk @@ -22,14 +22,16 @@ {% if config.showHumidity and current.humidity %} {{ current.humidity | decimalSymbol }}  {% endif %} - - - {% if current.nextSunAction() === "sunset" %} - {{ current.sunset | formatTime }} - {% else %} - {{ current.sunrise | formatTime }} - {% endif %} - + {% if config.showSun %} + + + {% if current.nextSunAction() === "sunset" %} + {{ current.sunset | formatTime }} + {% else %} + {{ current.sunrise | formatTime }} + {% endif %} + + {% endif %} {% endif %}
diff --git a/modules/default/weather/providers/README.md b/modules/default/weather/providers/README.md index dad9ed4987..02cef8ddb3 100755 --- a/modules/default/weather/providers/README.md +++ b/modules/default/weather/providers/README.md @@ -13,17 +13,17 @@ Table of Contents: ## The weather provider file: yourprovider.js -This is the script in which the weather provider will be defined. In it's most simple form, the weather provider must implement the following: +This is the script in which the weather provider will be defined. In its most simple form, the weather provider must implement the following: -````javascript +```javascript WeatherProvider.register("yourprovider", { - providerName: "YourProvider", + providerName: "YourProvider", - fetchCurrentWeather() {}, + fetchCurrentWeather() {}, - fetchWeatherForecast() {} + fetchWeatherForecast() {} }); -```` +``` ### Weather provider methods to implement @@ -36,7 +36,7 @@ It will then automatically refresh the module DOM with the new data. #### `fetchWeatherForecast()` -This method is called when the weather module tries to fetch the weather weather of your provider. The implementation of this method is required. +This method is called when the weather module tries to fetch the weather of your provider. The implementation of this method is required. The implementation can make use of the already implemented function `this.fetchData(url, method, data);`, which is returning a promise. After the response is processed, the weather forecast information (as an array of [WeatherObject](#weatherobject)s) needs to be set with `this.setCurrentWeather(forecast);`. It will then automatically refresh the module DOM with the new data. @@ -89,24 +89,24 @@ A convenience function to make requests. It returns a promise. ### WeatherObject -| Property | Type | Value/Unit | -| --- | --- | --- | -| units | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| tempUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| windUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | -| date | `object` | [Moment.js](https://momentjs.com/) object of the time/date. | -| windSpeed |`number` | Metric: `meter/second`
Imperial: `miles/hour` | -| windDirection |`number` | Direction of the wind in degrees. | -| sunrise |`object` | [Moment.js](https://momentjs.com/) object of sunrise. | -| sunset |`object` | [Moment.js](https://momentjs.com/) object of sunset. | -| temperature | `number` | Current temperature | -| minTemperature | `number` | Lowest temperature of the day. | -| maxTemperature | `number` | Highest temperature of the day. | -| weatherType | `string` | Icon name of the weather type.
Possible values: [WeatherIcons](https://www.npmjs.com/package/weathericons) | -| humidity | `number` | Percentage of humidity | -| rain | `number` | Metric: `millimeters`
Imperial: `inches` | -| snow | `number` | Metric: `millimeters`
Imperial: `inches` | -| precipitation | `number` | Metric: `millimeters`
Imperial: `inches`
UK Met Office provider: `percent` | +| Property | Type | Value/Unit | +| -------------- | -------- | --------------------------------------------------------------------------------------------------------------- | +| units | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | +| tempUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | +| windUnits | `string` | Gets initialized with the constructor.
Possible values: `metric`, `imperial` | +| date | `object` | [Moment.js](https://momentjs.com/) object of the time/date. | +| windSpeed | `number` | Metric: `meter/second`
Imperial: `miles/hour` | +| windDirection | `number` | Direction of the wind in degrees. | +| sunrise | `object` | [Moment.js](https://momentjs.com/) object of sunrise. | +| sunset | `object` | [Moment.js](https://momentjs.com/) object of sunset. | +| temperature | `number` | Current temperature | +| minTemperature | `number` | Lowest temperature of the day. | +| maxTemperature | `number` | Highest temperature of the day. | +| weatherType | `string` | Icon name of the weather type.
Possible values: [WeatherIcons](https://www.npmjs.com/package/weathericons) | +| humidity | `number` | Percentage of humidity | +| rain | `number` | Metric: `millimeters`
Imperial: `inches` | +| snow | `number` | Metric: `millimeters`
Imperial: `inches` | +| precipitation | `number` | Metric: `millimeters`
Imperial: `inches`
UK Met Office provider: `percent` | #### Current weather diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index b24c4794bc..4ba9010584 100755 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherDay */ +/* global WeatherProvider, WeatherObject */ /* Magic Mirror * Module: Weather @@ -16,40 +16,42 @@ WeatherProvider.register("darksky", { providerName: "Dark Sky", units: { - imperial: 'us', - metric: 'si' + imperial: "us", + metric: "si" }, fetchCurrentWeather() { this.fetchData(this.getUrl()) - .then(data => { - if(!data || !data.currently || typeof data.currently.temperature === "undefined") { + .then((data) => { + if (!data || !data.currently || typeof data.currently.temperature === "undefined") { // No usable data? return; } const currentWeather = this.generateWeatherDayFromCurrentWeather(data); this.setCurrentWeather(currentWeather); - }).catch(function(request) { + }) + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, fetchWeatherForecast() { this.fetchData(this.getUrl()) - .then(data => { - if(!data || !data.daily || !data.daily.data.length) { + .then((data) => { + if (!data || !data.daily || !data.daily.data.length) { // No usable data? return; } const forecast = this.generateWeatherObjectsFromForecast(data.daily.data); this.setWeatherForecast(forecast); - }).catch(function(request) { + }) + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, // Create a URL from the config and base URL. @@ -109,12 +111,12 @@ WeatherProvider.register("darksky", { const weatherTypes = { "clear-day": "day-sunny", "clear-night": "night-clear", - "rain": "rain", - "snow": "snow", - "sleet": "snow", - "wind": "wind", - "fog": "fog", - "cloudy": "cloudy", + rain: "rain", + snow: "snow", + sleet: "snow", + wind: "wind", + fog: "fog", + cloudy: "cloudy", "partly-cloudy-day": "day-cloudy", "partly-cloudy-night": "night-cloudy" }; diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index e99dc476c8..70b715a038 100755 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -3,14 +3,12 @@ /* Magic Mirror * Module: Weather * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. * * This class is the blueprint for a weather provider. */ - WeatherProvider.register("openweathermap", { - // Set the name of the provider. // This isn't strictly necessary, since it will fallback to the provider identifier // But for debugging (and future alerts) it would be nice to have the real name. @@ -19,7 +17,7 @@ WeatherProvider.register("openweathermap", { // Overwrite the fetchCurrentWeather method. fetchCurrentWeather() { this.fetchData(this.getUrl()) - .then(data => { + .then((data) => { if (!data || !data.main || typeof data.main.temp === "undefined") { // Did not receive usable new data. // Maybe this needs a better check? @@ -31,16 +29,16 @@ WeatherProvider.register("openweathermap", { const currentWeather = this.generateWeatherObjectFromCurrentWeather(data); this.setCurrentWeather(currentWeather); }) - .catch(function(request) { + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, // Overwrite the fetchCurrentWeather method. fetchWeatherForecast() { this.fetchData(this.getUrl()) - .then(data => { + .then((data) => { if (!data || !data.list || !data.list.length) { // Did not receive usable new data. // Maybe this needs a better check? @@ -52,10 +50,10 @@ WeatherProvider.register("openweathermap", { const forecast = this.generateWeatherObjectsFromForecast(data.list); this.setWeatherForecast(forecast); }) - .catch(function(request) { + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, /** OpenWeatherMap Specific Methods - These are not part of the default provider methods */ @@ -87,7 +85,6 @@ WeatherProvider.register("openweathermap", { * Generate WeatherObjects based on forecast information */ generateWeatherObjectsFromForecast(forecasts) { - if (this.config.weatherEndpoint === "/forecast") { return this.fetchForecastHourly(forecasts); } else if (this.config.weatherEndpoint === "/forecast/daily") { @@ -114,7 +111,6 @@ WeatherProvider.register("openweathermap", { let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); for (const forecast of forecasts) { - if (date !== moment(forecast.dt, "X").format("YYYY-MM-DD")) { // calculate minimum/maximum temperature, specify rain amount weather.minTemperature = Math.min.apply(null, minTemp); @@ -140,7 +136,6 @@ WeatherProvider.register("openweathermap", { // If the first value of today is later than 17:00, we have an icon at least! weather.weatherType = this.convertWeatherType(forecast.weather[0].icon); - } if (moment(forecast.dt, "X").format("H") >= 8 && moment(forecast.dt, "X").format("H") <= 17) { @@ -223,7 +218,7 @@ WeatherProvider.register("openweathermap", { days.push(weather); } - return days; + return days; }, /* @@ -261,16 +256,16 @@ WeatherProvider.register("openweathermap", { */ getParams() { let params = "?"; - if(this.config.locationID) { + if (this.config.locationID) { params += "id=" + this.config.locationID; - } else if(this.config.location) { + } else if (this.config.location) { params += "q=" + this.config.location; } else if (this.firstEvent && this.firstEvent.geo) { params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon; } else if (this.firstEvent && this.firstEvent.location) { params += "q=" + this.firstEvent.location; } else { - this.hide(this.config.animationSpeed, {lockString:this.identifier}); + this.hide(this.config.animationSpeed, { lockString: this.identifier }); return; } diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index 47785b3b3a..f1a5007456 100755 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject */ +/* global WeatherProvider, WeatherObject, SunCalc */ /* Magic Mirror * Module: Weather @@ -8,10 +8,7 @@ * * This class is a provider for UK Met Office Datapoint. */ - - WeatherProvider.register("ukmetoffice", { - // Set the name of the provider. // This isn't strictly necessary, since it will fallback to the provider identifier // But for debugging (and future alerts) it would be nice to have the real name. @@ -25,9 +22,8 @@ WeatherProvider.register("ukmetoffice", { // Overwrite the fetchCurrentWeather method. fetchCurrentWeather() { this.fetchData(this.getUrl("3hourly")) - .then(data => { - if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || - !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length == 0) { + .then((data) => { + if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { // Did not receive usable new data. // Maybe this needs a better check? return; @@ -38,18 +34,17 @@ WeatherProvider.register("ukmetoffice", { const currentWeather = this.generateWeatherObjectFromCurrentWeather(data); this.setCurrentWeather(currentWeather); }) - .catch(function(request) { + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, // Overwrite the fetchCurrentWeather method. fetchWeatherForecast() { this.fetchData(this.getUrl("daily")) - .then(data => { - if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || - !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length == 0) { + .then((data) => { + if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { // Did not receive usable new data. // Maybe this needs a better check? return; @@ -60,14 +55,12 @@ WeatherProvider.register("ukmetoffice", { const forecast = this.generateWeatherObjectsFromForecast(data); this.setWeatherForecast(forecast); }) - .catch(function(request) { + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, - - /** UK Met Office Specific Methods - These are not part of the default provider methods */ /* * Gets the complete url for the request @@ -83,24 +76,23 @@ WeatherProvider.register("ukmetoffice", { const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // data times are always UTC - let nowUtc = moment.utc() - let midnightUtc = nowUtc.clone().startOf("day") + let nowUtc = moment.utc(); + let midnightUtc = nowUtc.clone().startOf("day"); let timeInMins = nowUtc.diff(midnightUtc, "minutes"); // loop round each of the (5) periods, look for today (the first period may be yesterday) - for (i in currentWeatherData.SiteRep.DV.Location.Period) { - let periodDate = moment.utc(currentWeatherData.SiteRep.DV.Location.Period[i].value.substr(0,10), "YYYY-MM-DD") + for (var i in currentWeatherData.SiteRep.DV.Location.Period) { + let periodDate = moment.utc(currentWeatherData.SiteRep.DV.Location.Period[i].value.substr(0, 10), "YYYY-MM-DD"); // ignore if period is before today if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { - // check this is the period we want, after today the diff will be -ve if (moment().diff(periodDate, "minutes") > 0) { // loop round the reports looking for the one we are in // $ value specifies the time in minutes-of-the-day: 0, 180, 360,...1260 - for (j in currentWeatherData.SiteRep.DV.Location.Period[i].Rep){ + for (var j in currentWeatherData.SiteRep.DV.Location.Period[i].Rep) { let p = currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].$; - if (timeInMins >= p && timeInMins-180 < p) { + if (timeInMins >= p && timeInMins - 180 < p) { // finally got the one we want, so populate weather object currentWeather.humidity = currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].H; currentWeather.temperature = this.convertTemp(currentWeatherData.SiteRep.DV.Location.Period[i].Rep[j].T); @@ -116,7 +108,7 @@ WeatherProvider.register("ukmetoffice", { } // determine the sunrise/sunset times - not supplied in UK Met Office data - let times = this.calcAstroData(currentWeatherData.SiteRep.DV.Location) + let times = this.calcAstroData(currentWeatherData.SiteRep.DV.Location); currentWeather.sunrise = times[0]; currentWeather.sunset = times[1]; @@ -127,22 +119,21 @@ WeatherProvider.register("ukmetoffice", { * Generate WeatherObjects based on forecast information */ generateWeatherObjectsFromForecast(forecasts) { - const days = []; // loop round the (5) periods getting the data // for each period array, Day is [0], Night is [1] - for (j in forecasts.SiteRep.DV.Location.Period) { + for (var j in forecasts.SiteRep.DV.Location.Period) { const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); // data times are always UTC - dateStr = forecasts.SiteRep.DV.Location.Period[j].value - let periodDate = moment.utc(dateStr.substr(0,10), "YYYY-MM-DD") + const dateStr = forecasts.SiteRep.DV.Location.Period[j].value; + let periodDate = moment.utc(dateStr.substr(0, 10), "YYYY-MM-DD"); // ignore if period is before today if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { // populate the weather object - weather.date = moment.utc(dateStr.substr(0,10), "YYYY-MM-DD"); + weather.date = moment.utc(dateStr.substr(0, 10), "YYYY-MM-DD"); weather.minTemperature = this.convertTemp(forecasts.SiteRep.DV.Location.Period[j].Rep[1].Nm); weather.maxTemperature = this.convertTemp(forecasts.SiteRep.DV.Location.Period[j].Rep[0].Dm); weather.weatherType = this.convertWeatherType(forecasts.SiteRep.DV.Location.Period[j].Rep[0].W); @@ -213,7 +204,7 @@ WeatherProvider.register("ukmetoffice", { * Convert temp (from degrees C) if required */ convertTemp(tempInC) { - return this.tempUnits === "imperial" ? tempInC * 9 / 5 + 32 : tempInC; + return this.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC; }, /* @@ -228,22 +219,22 @@ WeatherProvider.register("ukmetoffice", { */ convertWindDirection(windDirection) { const windCardinals = { - "N": 0, - "NNE": 22, - "NE": 45, - "ENE": 67, - "E": 90, - "ESE": 112, - "SE": 135, - "SSE": 157, - "S": 180, - "SSW": 202, - "SW": 225, - "WSW": 247, - "W": 270, - "WNW": 292, - "NW": 315, - "NNW": 337 + N: 0, + NNE: 22, + NE: 45, + ENE: 67, + E: 90, + ESE: 112, + SE: 135, + SSE: 157, + S: 180, + SSW: 202, + SW: 225, + WSW: 247, + W: 270, + WNW: 292, + NW: 315, + NNW: 337 }; return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js new file mode 100644 index 0000000000..9ed7468436 --- /dev/null +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -0,0 +1,303 @@ +/* Magic Mirror + * Module: Weather + * + * By Malcolm Oakes https://github.com/maloakes + * Existing Met Office provider edited for new MetOffice Data Hub by CreepinJesus http://github.com/XBCreepinJesus + * MIT Licensed. + * + * This class is a provider for UK Met Office Data Hub (the replacement for their Data Point services). + * For more information on Data Hub, see https://www.metoffice.gov.uk/services/data/datapoint/notifications/weather-datahub + * Data available: + * Hourly data for next 2 days ("hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-hourly.pdf + * 3-hourly data for the next 7 days ("3hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-3-hourly.pdf + * Daily data for the next 7 days ("daily") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-daily.pdf + */ + +/* NOTES + * This provider requires longitude/latitude coordinates, rather than a location ID (as with the previous Met Office provider) + * Provide the following in your config.js file: + * weatherProvider: "ukmetofficedatahub", + * apiBase: "https://api-metoffice.apiconnect.ibmcloud.com/metoffice/production/v0/forecasts/point/", + * apiKey: "[YOUR API KEY]", + * apiSecret: "[YOUR API SECRET]]", + * lat: [LATITUDE (DECIMAL)], + * lon: [LONGITUDE (DECIMAL)], + * windUnits: "mps" | "kph" | "mph" (default) + * tempUnits: "imperial" | "metric" (default) + * + * At time of writing, free accounts are limited to 360 requests a day per service (hourly, 3hourly, daily); take this in mind when + * setting your update intervals. For reference, 360 requests per day is once every 4 minutes. + * + * Pay attention to the units of the supplied data from the Met Office - it is given in SI/metric units where applicable: + * - Temperatures are in degrees Celsius (°C) + * - Wind speeds are in metres per second (m/s) + * - Wind direction given in degrees (°) + * - Pressures are in Pascals (Pa) + * - Distances are in metres (m) + * - Probabilities and humidity are given as percentages (%) + * - Precipitation is measured in millimetres (mm) with rates per hour (mm/h) + * + * See the PDFs linked above for more information on the data their corresponding units. + */ + +WeatherProvider.register("ukmetofficedatahub", { + // Set the name of the provider. + providerName: "UK Met Office (DataHub)", + + // Build URL with query strings according to DataHub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) + getUrl(forecastType) { + let queryStrings = "?"; + queryStrings += "latitude=" + this.config.lat; + queryStrings += "&longitude=" + this.config.lon; + if (this.config.appendLocationNameToHeader) { + queryStrings += "&includeLocationName=" + true; + } + + // Return URL, making sure there is a trailing "/" in the base URL. + return this.config.apiBase + (this.config.apiBase.endsWith("/") ? "" : "/") + forecastType + queryStrings; + }, + + // Build the list of headers for the request + // For DataHub requests, the API key/secret are sent in the headers rather than as query strings. + // Headers defined according to Data Hub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) + getHeaders() { + let headers = { + accept: "application/json", + "x-ibm-client-id": this.config.apiKey, + "x-ibm-client-secret": this.config.apiSecret + }; + + return headers; + }, + + // Fetch data using supplied URL and request headers + async fetchWeather(url, headers) { + const response = await fetch(url, { headers: headers }); + + // Return JSON data + return response.json(); + }, + + // Fetch hourly forecast data (to use for current weather) + fetchCurrentWeather() { + this.fetchWeather(this.getUrl("hourly"), this.getHeaders()) + .then((data) => { + // Check data is useable + if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length == 0) { + // Did not receive usable new data. + // Maybe this needs a better check? + Log.error("Possibly bad current/hourly data?"); + Log.info(data); + return; + } + + // Set location name + this.setFetchedLocation(`${data.features[0].properties.location.name}`); + + // Generate current weather data + const currentWeather = this.generateWeatherObjectFromCurrentWeather(data); + this.setCurrentWeather(currentWeather); + }) + + // Catch any error(s) + .catch((error) => Log.error("Could not load data: " + error.message)) + + // Let the module know there're new data available + .finally(() => this.updateAvailable()); + }, + + // Create a WeatherObject using current weather data (data for the current hour) + generateWeatherObjectFromCurrentWeather(currentWeatherData) { + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + + // Extract the actual forecasts + let forecastDataHours = currentWeatherData.features[0].properties.timeSeries; + + // Define now + let nowUtc = moment.utc(); + + // Find hour that contains the current time + for (hour in forecastDataHours) { + let forecastTime = moment.utc(forecastDataHours[hour].time); + if (nowUtc.isSameOrAfter(forecastTime) && nowUtc.isBefore(moment(forecastTime.add(1, "h")))) { + currentWeather.date = forecastTime; + currentWeather.windSpeed = this.convertWindSpeed(forecastDataHours[hour].windSpeed10m); + currentWeather.windDirection = forecastDataHours[hour].windDirectionFrom10m; + currentWeather.temperature = this.convertTemp(forecastDataHours[hour].screenTemperature); + currentWeather.minTemperature = this.convertTemp(forecastDataHours[hour].minScreenAirTemp); + currentWeather.maxTemperature = this.convertTemp(forecastDataHours[hour].maxScreenAirTemp); + currentWeather.weatherType = this.convertWeatherType(forecastDataHours[hour].significantWeatherCode); + currentWeather.humidity = forecastDataHours[hour].screenRelativeHumidity; + currentWeather.rain = forecastDataHours[hour].totalPrecipAmount; + currentWeather.snow = forecastDataHours[hour].totalSnowAmount; + currentWeather.precipitation = forecastDataHours[hour].probOfPrecipitation; + currentWeather.feelsLikeTemp = this.convertTemp(forecastDataHours[hour].feelsLikeTemperature); + + // Pass on full details so they can be used in custom templates + // Note the units of the supplied data when using this (see top of file) + currentWeather.rawData = forecastDataHours[hour]; + } + } + + // Determine the sunrise/sunset times - (still) not supplied in UK Met Office data + // Passes {longitude, latitude, height} to calcAstroData + // Could just pass lat/long from this.config, but returned data from MO also contains elevation + let times = this.calcAstroData(currentWeatherData.features[0].geometry.coordinates); + currentWeather.sunrise = times[0]; + currentWeather.sunset = times[1]; + + return currentWeather; + }, + + // Fetch daily forecast data + fetchWeatherForecast() { + this.fetchWeather(this.getUrl("daily"), this.getHeaders()) + .then((data) => { + // Check data is useable + if (!data || !data.features || !data.features[0].properties || !data.features[0].properties.timeSeries || data.features[0].properties.timeSeries.length == 0) { + // Did not receive usable new data. + // Maybe this needs a better check? + Log.error("Possibly bad forecast data?"); + Log.info(data); + return; + } + + // Set location name + this.setFetchedLocation(`${data.features[0].properties.location.name}`); + + // Generate the forecast data + const forecast = this.generateWeatherObjectsFromForecast(data); + this.setWeatherForecast(forecast); + }) + + // Catch any error(s) + .catch((error) => Log.error("Could not load data: " + error.message)) + + // Let the module know there're new data available + .finally(() => this.updateAvailable()); + }, + + // Create a WeatherObject for each day using daily forecast data + generateWeatherObjectsFromForecast(forecasts) { + const dailyForecasts = []; + + // Extract the actual forecasts + let forecastDataDays = forecasts.features[0].properties.timeSeries; + + // Define today + let today = moment.utc().startOf("date"); + + // Go through each day in the forecasts + for (day in forecastDataDays) { + const forecastWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + + // Get date of forecast + let forecastDate = moment.utc(forecastDataDays[day].time); + + // Check if forecast is for today or in the future (i.e., ignore yesterday's forecast) + if (forecastDate.isSameOrAfter(today)) { + forecastWeather.date = forecastDate; + forecastWeather.minTemperature = this.convertTemp(forecastDataDays[day].nightMinScreenTemperature); + forecastWeather.maxTemperature = this.convertTemp(forecastDataDays[day].dayMaxScreenTemperature); + + // Using daytime forecast values + forecastWeather.windSpeed = this.convertWindSpeed(forecastDataDays[day].midday10MWindSpeed); + forecastWeather.windDirection = forecastDataDays[day].midday10MWindDirection; + forecastWeather.weatherType = this.convertWeatherType(forecastDataDays[day].daySignificantWeatherCode); + forecastWeather.precipitation = forecastDataDays[day].dayProbabilityOfPrecipitation; + forecastWeather.temperature = forecastDataDays[day].dayMaxScreenTemperature; + forecastWeather.humidity = forecastDataDays[day].middayRelativeHumidity; + forecastWeather.rain = forecastDataDays[day].dayProbabilityOfRain; + forecastWeather.snow = forecastDataDays[day].dayProbabilityOfSnow; + forecastWeather.feelsLikeTemp = this.convertTemp(forecastDataDays[day].dayMaxFeelsLikeTemp); + + // Pass on full details so they can be used in custom templates + // Note the units of the supplied data when using this (see top of file) + + forecastWeather.rawData = forecastDataDays[day]; + + dailyForecasts.push(forecastWeather); + } + } + + return dailyForecasts; + }, + + // Set the fetched location name. + setFetchedLocation: function (name) { + this.fetchedLocationName = name; + }, + + // Calculate sunrise/sunset times + calcAstroData(location) { + const sunTimes = []; + + // Careful to pass values to SunCalc in correct order (latitude, longitude, elevation) + let times = SunCalc.getTimes(new Date(), location[1], location[0], location[2]); + sunTimes.push(moment(times.sunrise, "X")); + sunTimes.push(moment(times.sunset, "X")); + + return sunTimes; + }, + + // Convert temperatures to Fahrenheit (from degrees C), if required + convertTemp(tempInC) { + return this.config.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC; + }, + + // Convert wind speed from metres per second + // To keep the supplied metres per second units, use "mps" + // To use kilometres per hour, use "kph" + // Else assumed imperial and the value is returned in miles per hour (a Met Office user is likely to be UK-based) + convertWindSpeed(windInMpS) { + if (this.config.windUnits == "mps") { + return windInMpS; + } + + if (this.config.windUnits == "kph" || this.config.windUnits == "metric") { + return windInMpS * 3.6; + } + + return windInMpS * 2.23694; + }, + + // Match the Met Office "significant weather code" to a weathericons.css icon + // Use: https://metoffice.apiconnect.ibmcloud.com/metoffice/production/node/264 + // and: https://erikflowers.github.io/weather-icons/ + convertWeatherType(weatherType) { + const weatherTypes = { + 0: "night-clear", + 1: "day-sunny", + 2: "night-alt-cloudy", + 3: "day-cloudy", + 5: "fog", + 6: "fog", + 7: "cloudy", + 8: "cloud", + 9: "night-sprinkle", + 10: "day-sprinkle", + 11: "raindrops", + 12: "sprinkle", + 13: "night-alt-showers", + 14: "day-showers", + 15: "rain", + 16: "night-alt-sleet", + 17: "day-sleet", + 18: "sleet", + 19: "night-alt-hail", + 20: "day-hail", + 21: "hail", + 22: "night-alt-snow", + 23: "day-snow", + 24: "snow", + 25: "night-alt-snow", + 26: "day-snow", + 27: "snow", + 28: "night-alt-thunderstorm", + 29: "day-thunderstorm", + 30: "thunderstorm" + }; + + return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; + } +}); diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 74d9552217..c24e4de189 100755 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject */ +/* global WeatherProvider, WeatherObject, SunCalc */ /* Magic Mirror * Module: Weather @@ -11,9 +11,7 @@ * Note that this is only for US locations (lat and lon) and does not require an API key * Since it is free, there are some items missing - like sunrise, sunset, humidity, etc. */ - WeatherProvider.register("weathergov", { - // Set the name of the provider. // This isn't strictly necessary, since it will fallback to the provider identifier // But for debugging (and future alerts) it would be nice to have the real name. @@ -22,7 +20,7 @@ WeatherProvider.register("weathergov", { // Overwrite the fetchCurrentWeather method. fetchCurrentWeather() { this.fetchData(this.getUrl()) - .then(data => { + .then((data) => { if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) { // Did not receive usable new data. // Maybe this needs a better check? @@ -32,16 +30,16 @@ WeatherProvider.register("weathergov", { const currentWeather = this.generateWeatherObjectFromCurrentWeather(data.properties.periods[0]); this.setCurrentWeather(currentWeather); }) - .catch(function(request) { + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, // Overwrite the fetchCurrentWeather method. fetchWeatherForecast() { this.fetchData(this.getUrl()) - .then(data => { + .then((data) => { if (!data || !data.properties || !data.properties.periods || !data.properties.periods.length) { // Did not receive usable new data. // Maybe this needs a better check? @@ -51,10 +49,10 @@ WeatherProvider.register("weathergov", { const forecast = this.generateWeatherObjectsFromForecast(data.properties.periods); this.setWeatherForecast(forecast); }) - .catch(function(request) { + .catch(function (request) { Log.error("Could not load data ... ", request); }) - .finally(() => this.updateAvailable()) + .finally(() => this.updateAvailable()); }, /** Weather.gov Specific Methods - These are not part of the default provider methods */ @@ -77,7 +75,7 @@ WeatherProvider.register("weathergov", { currentWeather.weatherType = this.convertWeatherType(currentWeatherData.shortForecast, currentWeatherData.isDaytime); // determine the sunrise/sunset times - not supplied in weather.gov data - let times = this.calcAstroData(this.config.lat, this.config.lon) + let times = this.calcAstroData(this.config.lat, this.config.lon); currentWeather.sunrise = times[0]; currentWeather.sunset = times[1]; @@ -106,9 +104,7 @@ WeatherProvider.register("weathergov", { weather.precipitation = 0; for (const forecast of forecasts) { - if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) { - // calculate minimum/maximum temperature, specify rain amount weather.minTemperature = Math.min.apply(null, minTemp); weather.maxTemperature = Math.max.apply(null, maxTemp); @@ -241,22 +237,22 @@ WeatherProvider.register("weathergov", { */ convertWindDirection(windDirection) { const windCardinals = { - "N": 0, - "NNE": 22, - "NE": 45, - "ENE": 67, - "E": 90, - "ESE": 112, - "SE": 135, - "SSE": 157, - "S": 180, - "SSW": 202, - "SW": 225, - "WSW": 247, - "W": 270, - "WNW": 292, - "NW": 315, - "NNW": 337 + N: 0, + NNE: 22, + NE: 45, + ENE: 67, + E: 90, + ESE: 112, + SE: 135, + SSE: 157, + S: 180, + SSW: 202, + SW: 225, + WSW: 247, + W: 270, + WNW: 292, + NW: 315, + NNW: 337 }; return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; diff --git a/modules/default/weather/weather.css b/modules/default/weather/weather.css index 639ce7a9ce..2d7600ad17 100644 --- a/modules/default/weather/weather.css +++ b/modules/default/weather/weather.css @@ -3,8 +3,6 @@ font-size: 75%; line-height: 65px; display: inline-block; - -ms-transform: translate(0, -3px); /* IE 9 */ - -webkit-transform: translate(0, -3px); /* Safari */ transform: translate(0, -3px); } diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 868316d97e..150ba08449 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -1,16 +1,14 @@ -/* global Module, WeatherProvider */ +/* global WeatherProvider */ /* Magic Mirror * Module: Weather * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -Module.register("weather",{ +Module.register("weather", { // Default module config. defaults: { - updateInterval: 10 * 60 * 1000, weatherProvider: "openweathermap", roundTemp: false, type: "current", //current, forecast @@ -33,6 +31,7 @@ Module.register("weather",{ useBeaufort: true, lang: config.language, showHumidity: false, + showSun: true, degreeLabel: false, decimalSymbol: ".", showIndoorTemperature: false, @@ -45,7 +44,7 @@ Module.register("weather",{ retryDelay: 2500, apiVersion: "2.5", - apiBase: "http://api.openweathermap.org/data/", + apiBase: "https://api.openweathermap.org/data/", weatherEndpoint: "/weather", appendLocationNameToHeader: true, @@ -62,23 +61,17 @@ Module.register("weather",{ weatherProvider: null, // Define required scripts. - getStyles: function() { + getStyles: function () { return ["font-awesome.css", "weather-icons.css", "weather.css"]; }, // Return the scripts that are necessary for the weather module. getScripts: function () { - return [ - "moment.js", - "weatherprovider.js", - "weatherobject.js", - "suncalc.js", - this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js") - ]; + return ["moment.js", "weatherprovider.js", "weatherobject.js", "suncalc.js", this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")]; }, // Override getHeader method. - getHeader: function() { + getHeader: function () { if (this.config.appendLocationNameToHeader && this.data.header !== undefined && this.weatherProvider) { return this.data.header + " " + this.weatherProvider.fetchedLocation(); } @@ -104,7 +97,7 @@ Module.register("weather",{ }, // Override notification handler. - notificationReceived: function(notification, payload, sender) { + notificationReceived: function (notification, payload, sender) { if (notification === "CALENDAR_EVENTS") { var senderClasses = sender.data.classes.toLowerCase().split(" "); if (senderClasses.indexOf(this.config.calendarClass.toLowerCase()) !== -1) { @@ -147,13 +140,13 @@ Module.register("weather",{ }, // What to do when the weather provider has new information available? - updateAvailable: function() { + updateAvailable: function () { Log.log("New weather information available."); this.updateDom(0); this.scheduleUpdate(); }, - scheduleUpdate: function(delay = null) { + scheduleUpdate: function (delay = null) { var nextLoad = this.config.updateInterval; if (delay !== null && delay >= 0) { nextLoad = delay; @@ -168,88 +161,106 @@ Module.register("weather",{ }, nextLoad); }, - roundValue: function(temperature) { + roundValue: function (temperature) { var decimals = this.config.roundTemp ? 0 : 1; return parseFloat(temperature).toFixed(decimals); }, addFilters() { - this.nunjucksEnvironment().addFilter("formatTime", function(date) { - date = moment(date); - - if (this.config.timeFormat !== 24) { - if (this.config.showPeriod) { - if (this.config.showPeriodUpper) { - return date.format("h:mm A"); + this.nunjucksEnvironment().addFilter( + "formatTime", + function (date) { + date = moment(date); + + if (this.config.timeFormat !== 24) { + if (this.config.showPeriod) { + if (this.config.showPeriodUpper) { + return date.format("h:mm A"); + } else { + return date.format("h:mm a"); + } } else { - return date.format("h:mm a"); + return date.format("h:mm"); } - } else { - return date.format("h:mm"); } - } - return date.format("HH:mm"); - }.bind(this)); + return date.format("HH:mm"); + }.bind(this) + ); - this.nunjucksEnvironment().addFilter("unit", function (value, type) { - if (type === "temperature") { - if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") { - value += "°"; - } - if (this.config.degreeLabel) { - if (this.config.tempUnits === "metric") { - value += "C"; - } else if (this.config.tempUnits === "imperial") { - value += "F"; + this.nunjucksEnvironment().addFilter( + "unit", + function (value, type) { + if (type === "temperature") { + if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") { + value += "°"; + } + if (this.config.degreeLabel) { + if (this.config.tempUnits === "metric") { + value += "C"; + } else if (this.config.tempUnits === "imperial") { + value += "F"; + } else { + value += "K"; + } + } + } else if (type === "precip") { + if (isNaN(value) || value === 0 || value.toFixed(2) === "0.00") { + value = ""; } else { - value += "K"; + if (this.config.weatherProvider === "ukmetoffice" || this.config.weatherProvider === "ukmetofficedatahub") { + value += "%"; + } else { + value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`; + } } + } else if (type === "humidity") { + value += "%"; } - } else if (type === "precip") { - if (isNaN(value) || value === 0 || value.toFixed(2) === "0.00") { - value = ""; - } else { - if (this.config.weatherProvider === "ukmetoffice") { - value += "%"; - } else { - value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`; - } - } - } else if (type === "humidity") { - value += "%"; - } - return value; - }.bind(this)); - - this.nunjucksEnvironment().addFilter("roundValue", function(value) { - return this.roundValue(value); - }.bind(this)); - - this.nunjucksEnvironment().addFilter("decimalSymbol", function(value) { - return value.toString().replace(/\./g, this.config.decimalSymbol); - }.bind(this)); - - this.nunjucksEnvironment().addFilter("calcNumSteps", function(forecast) { - return Math.min(forecast.length, this.config.maxNumberOfDays); - }.bind(this)); - - this.nunjucksEnvironment().addFilter("opacity", function(currentStep, numSteps) { - if (this.config.fade && this.config.fadePoint < 1) { - if (this.config.fadePoint < 0) { - this.config.fadePoint = 0; - } - var startingPoint = numSteps * this.config.fadePoint; - var numFadesteps = numSteps - startingPoint; - if (currentStep >= startingPoint) { - return 1 - (currentStep - startingPoint) / numFadesteps; + return value; + }.bind(this) + ); + + this.nunjucksEnvironment().addFilter( + "roundValue", + function (value) { + return this.roundValue(value); + }.bind(this) + ); + + this.nunjucksEnvironment().addFilter( + "decimalSymbol", + function (value) { + return value.toString().replace(/\./g, this.config.decimalSymbol); + }.bind(this) + ); + + this.nunjucksEnvironment().addFilter( + "calcNumSteps", + function (forecast) { + return Math.min(forecast.length, this.config.maxNumberOfDays); + }.bind(this) + ); + + this.nunjucksEnvironment().addFilter( + "opacity", + function (currentStep, numSteps) { + if (this.config.fade && this.config.fadePoint < 1) { + if (this.config.fadePoint < 0) { + this.config.fadePoint = 0; + } + var startingPoint = numSteps * this.config.fadePoint; + var numFadesteps = numSteps - startingPoint; + if (currentStep >= startingPoint) { + return 1 - (currentStep - startingPoint) / numFadesteps; + } else { + return 1; + } } else { return 1; } - } else { - return 1; - } - }.bind(this)); + }.bind(this) + ); } }); diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index ed455537b2..0ee42123fc 100755 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -1,20 +1,16 @@ -/* global Class */ - /* Magic Mirror * Module: Weather * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. * * This class is the blueprint for a day which includes weather information. + * + * Currently this is focused on the information which is necessary for the current weather. + * As soon as we start implementing the forecast, mode properties will be added. */ - -// Currently this is focused on the information which is necessary for the current weather. -// As soon as we start implementing the forecast, mode properties will be added. - class WeatherObject { constructor(units, tempUnits, windUnits) { - this.units = units; this.tempUnits = tempUnits; this.windUnits = windUnits; @@ -32,11 +28,10 @@ class WeatherObject { this.snow = null; this.precipitation = null; this.feelsLikeTemp = null; - } cardinalWindDirection() { - if (this.windDirection > 11.25 && this.windDirection <= 33.75){ + if (this.windDirection > 11.25 && this.windDirection <= 33.75) { return "NNE"; } else if (this.windDirection > 33.75 && this.windDirection <= 56.25) { return "NE"; @@ -72,7 +67,7 @@ class WeatherObject { } beaufortWindSpeed() { - const windInKmh = (this.windUnits === "imperial") ? this.windSpeed * 1.609344 : this.windSpeed * 60 * 60 / 1000; + const windInKmh = this.windUnits === "imperial" ? this.windSpeed * 1.609344 : (this.windSpeed * 60 * 60) / 1000; const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; for (const [index, speed] of speeds.entries()) { if (speed > windInKmh) { @@ -87,24 +82,28 @@ class WeatherObject { } feelsLike() { - if (this.feelsLikeTemp) { - return this.feelsLikeTemp; + if (this.feelsLikeTemp) { + return this.feelsLikeTemp; } - const windInMph = (this.windUnits === "imperial") ? this.windSpeed : this.windSpeed * 2.23694; - const tempInF = this.tempUnits === "imperial" ? this.temperature : this.temperature * 9 / 5 + 32; + const windInMph = this.windUnits === "imperial" ? this.windSpeed : this.windSpeed * 2.23694; + const tempInF = this.tempUnits === "imperial" ? this.temperature : (this.temperature * 9) / 5 + 32; let feelsLike = tempInF; if (windInMph > 3 && tempInF < 50) { feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16)); } else if (tempInF > 80 && this.humidity > 40) { - feelsLike = -42.379 + 2.04901523 * tempInF + 10.14333127 * this.humidity - - 0.22475541 * tempInF * this.humidity - 6.83783 * Math.pow(10, -3) * tempInF * tempInF - - 5.481717 * Math.pow(10, -2) * this.humidity * this.humidity - + 1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity - + 8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity - - 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; + feelsLike = + -42.379 + + 2.04901523 * tempInF + + 10.14333127 * this.humidity - + 0.22475541 * tempInF * this.humidity - + 6.83783 * Math.pow(10, -3) * tempInF * tempInF - + 5.481717 * Math.pow(10, -2) * this.humidity * this.humidity + + 1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity + + 8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity - + 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; } - return this.tempUnits === "imperial" ? feelsLike : (feelsLike - 32) * 5 / 9; + return this.tempUnits === "imperial" ? feelsLike : ((feelsLike - 32) * 5) / 9; } } diff --git a/modules/default/weather/weatherprovider.js b/modules/default/weather/weatherprovider.js index 1789b95caa..cfcb3ef626 100644 --- a/modules/default/weather/weatherprovider.js +++ b/modules/default/weather/weatherprovider.js @@ -3,15 +3,11 @@ /* Magic Mirror * Module: Weather * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. * * This class is the blueprint for a weather provider. */ - -/** - * Base BluePrint for the WeatherProvider - */ var WeatherProvider = Class.extend({ // Weather Provider Properties providerName: null, @@ -32,77 +28,77 @@ var WeatherProvider = Class.extend({ // All the following methods can be overwritten, although most are good as they are. // Called when a weather provider is initialized. - init: function(config) { + init: function (config) { this.config = config; Log.info(`Weather provider: ${this.providerName} initialized.`); }, // Called to set the config, this config is the same as the weather module's config. - setConfig: function(config) { + setConfig: function (config) { this.config = config; Log.info(`Weather provider: ${this.providerName} config set.`, this.config); }, // Called when the weather provider is about to start. - start: function() { + start: function () { Log.info(`Weather provider: ${this.providerName} started.`); }, // This method should start the API request to fetch the current weather. // This method should definitely be overwritten in the provider. - fetchCurrentWeather: function() { + fetchCurrentWeather: function () { Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchCurrentWeather method.`); }, // This method should start the API request to fetch the weather forecast. // This method should definitely be overwritten in the provider. - fetchWeatherForecast: function() { + fetchWeatherForecast: function () { Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchWeatherForecast method.`); }, // This returns a WeatherDay object for the current weather. - currentWeather: function() { + currentWeather: function () { return this.currentWeatherObject; }, // This returns an array of WeatherDay objects for the weather forecast. - weatherForecast: function() { + weatherForecast: function () { return this.weatherForecastArray; }, // This returns the name of the fetched location or an empty string. - fetchedLocation: function() { + fetchedLocation: function () { return this.fetchedLocationName || ""; }, // Set the currentWeather and notify the delegate that new information is available. - setCurrentWeather: function(currentWeatherObject) { + setCurrentWeather: function (currentWeatherObject) { // We should check here if we are passing a WeatherDay this.currentWeatherObject = currentWeatherObject; }, // Set the weatherForecastArray and notify the delegate that new information is available. - setWeatherForecast: function(weatherForecastArray) { + setWeatherForecast: function (weatherForecastArray) { // We should check here if we are passing a WeatherDay this.weatherForecastArray = weatherForecastArray; }, // Set the fetched location name. - setFetchedLocation: function(name) { + setFetchedLocation: function (name) { this.fetchedLocationName = name; }, // Notify the delegate that new weather is available. - updateAvailable: function() { + updateAvailable: function () { this.delegate.updateAvailable(this); }, // A convenience function to make requests. It returns a promise. - fetchData: function(url, method = "GET", data = null) { - return new Promise(function(resolve, reject) { + fetchData: function (url, method = "GET", data = null) { + return new Promise(function (resolve, reject) { var request = new XMLHttpRequest(); request.open(method, url, true); - request.onreadystatechange = function() { + request.onreadystatechange = function () { if (this.readyState === 4) { if (this.status === 200) { resolve(JSON.parse(this.response)); @@ -124,14 +120,14 @@ WeatherProvider.providers = []; /** * Static method to register a new weather provider. */ -WeatherProvider.register = function(providerIdentifier, providerDetails) { +WeatherProvider.register = function (providerIdentifier, providerDetails) { WeatherProvider.providers[providerIdentifier.toLowerCase()] = WeatherProvider.extend(providerDetails); }; /** * Static method to initialize a new weather provider. */ -WeatherProvider.initialize = function(providerIdentifier, delegate) { +WeatherProvider.initialize = function (providerIdentifier, delegate) { providerIdentifier = providerIdentifier.toLowerCase(); var provider = new WeatherProvider.providers[providerIdentifier](); diff --git a/modules/default/weatherforecast/README.md b/modules/default/weatherforecast/README.md index 7dfbd16fe4..035e23c0c2 100644 --- a/modules/default/weatherforecast/README.md +++ b/modules/default/weatherforecast/README.md @@ -1,4 +1,5 @@ # Module: Weather Forecast + 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. diff --git a/modules/default/weatherforecast/weatherforecast.css b/modules/default/weatherforecast/weatherforecast.css index 21be13b758..8c419ceeeb 100644 --- a/modules/default/weatherforecast/weatherforecast.css +++ b/modules/default/weatherforecast/weatherforecast.css @@ -19,9 +19,9 @@ } .weatherforecast tr.colored .min-temp { - color: #BCDDFF; + color: #bcddff; } .weatherforecast tr.colored .max-temp { - color: #FF8E99; + color: #ff8e99; } diff --git a/modules/default/weatherforecast/weatherforecast.js b/modules/default/weatherforecast/weatherforecast.js index b8fab9e4d1..83389911a5 100644 --- a/modules/default/weatherforecast/weatherforecast.js +++ b/modules/default/weatherforecast/weatherforecast.js @@ -1,14 +1,10 @@ -/* global Module */ - /* Magic Mirror * Module: WeatherForecast * - * By Michael Teeuw http://michaelteeuw.nl + * By Michael Teeuw https://michaelteeuw.nl * MIT Licensed. */ - -Module.register("weatherforecast",{ - +Module.register("weatherforecast", { // Default module config. defaults: { location: false, @@ -59,27 +55,27 @@ Module.register("weatherforecast",{ "11n": "wi-night-thunderstorm", "13n": "wi-night-snow", "50n": "wi-night-alt-cloudy-windy" - }, + } }, - // create a variable for the first upcoming calendaar event. Used if no location is specified. + // create a variable for the first upcoming calendar event. Used if no location is specified. firstEvent: false, // create a variable to hold the location name based on the API result. fetchedLocationName: "", // Define required scripts. - getScripts: function() { + getScripts: function () { return ["moment.js"]; }, // Define required scripts. - getStyles: function() { + getStyles: function () { return ["weather-icons.css", "weatherforecast.css"]; }, // Define required translations. - getTranslations: function() { + getTranslations: function () { // The translations for the default modules are defined in the core translation files. // Therefor we can just return false. Otherwise we should have returned a dictionary. // If you're trying to build your own module including translations, check out the documentation. @@ -87,7 +83,7 @@ Module.register("weatherforecast",{ }, // Define start sequence. - start: function() { + start: function () { Log.info("Starting module: " + this.name); // Set locale. @@ -98,11 +94,10 @@ Module.register("weatherforecast",{ this.scheduleUpdate(this.config.initialLoadDelay); this.updateTimer = null; - }, // Override dom generator. - getDom: function() { + getDom: function () { var wrapper = document.createElement("div"); if (this.config.appid === "") { @@ -146,17 +141,17 @@ Module.register("weatherforecast",{ if (this.config.units === "metric" || this.config.units === "imperial") { degreeLabel += "°"; } - if(this.config.scale) { - switch(this.config.units) { - case "metric": - degreeLabel += "C"; - break; - case "imperial": - degreeLabel += "F"; - break; - case "default": - degreeLabel = "K"; - break; + if (this.config.scale) { + switch (this.config.units) { + case "metric": + degreeLabel += "C"; + break; + case "imperial": + degreeLabel += "F"; + break; + case "default": + degreeLabel = "K"; + break; } } @@ -179,7 +174,7 @@ Module.register("weatherforecast",{ if (isNaN(forecast.rain)) { rainCell.innerHTML = ""; } else { - if(config.units !== "imperial") { + if (config.units !== "imperial") { rainCell.innerHTML = parseFloat(forecast.rain).toFixed(1).replace(".", this.config.decimalSymbol) + " mm"; } else { rainCell.innerHTML = (parseFloat(forecast.rain) / 25.4).toFixed(2).replace(".", this.config.decimalSymbol) + " in"; @@ -197,7 +192,7 @@ Module.register("weatherforecast",{ var steps = this.forecast.length - startingPoint; if (f >= startingPoint) { var currentStep = f - startingPoint; - row.style.opacity = 1 - (1 / steps * currentStep); + row.style.opacity = 1 - (1 / steps) * currentStep; } } } @@ -206,7 +201,7 @@ Module.register("weatherforecast",{ }, // Override getHeader method. - getHeader: function() { + getHeader: function () { if (this.config.appendLocationNameToHeader) { return this.data.header + " " + this.fetchedLocationName; } @@ -215,10 +210,10 @@ Module.register("weatherforecast",{ }, // Override notification handler. - notificationReceived: function(notification, payload, sender) { + notificationReceived: function (notification, payload, sender) { if (notification === "DOM_OBJECTS_CREATED") { if (this.config.appendLocationNameToHeader) { - this.hide(0, {lockString: this.identifier}); + this.hide(0, { lockString: this.identifier }); } } if (notification === "CALENDAR_EVENTS") { @@ -242,7 +237,7 @@ Module.register("weatherforecast",{ * Requests new data from openweather.org. * Calls processWeather on successful response. */ - updateWeather: function() { + updateWeather: function () { if (this.config.appid === "") { Log.error("WeatherForecast: APPID not set!"); return; @@ -254,7 +249,7 @@ Module.register("weatherforecast",{ var weatherRequest = new XMLHttpRequest(); weatherRequest.open("GET", url, true); - weatherRequest.onreadystatechange = function() { + weatherRequest.onreadystatechange = function () { if (this.readyState === 4) { if (this.status === 200) { self.processWeather(JSON.parse(this.response)); @@ -272,7 +267,7 @@ Module.register("weatherforecast",{ } if (retry) { - self.scheduleUpdate((self.loaded) ? -1 : self.config.retryDelay); + self.scheduleUpdate(self.loaded ? -1 : self.config.retryDelay); } } }; @@ -284,21 +279,23 @@ Module.register("weatherforecast",{ * * return String - URL params. */ - getParams: function() { + getParams: function () { var params = "?"; - if(this.config.locationID) { + if (this.config.locationID) { params += "id=" + this.config.locationID; - } else if(this.config.location) { + } else if (this.config.location) { params += "q=" + this.config.location; } else if (this.firstEvent && this.firstEvent.geo) { params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon; } else if (this.firstEvent && this.firstEvent.location) { params += "q=" + this.firstEvent.location; } else { - this.hide(this.config.animationSpeed, {lockString:this.identifier}); + this.hide(this.config.animationSpeed, { lockString: this.identifier }); return; } + params += "&cnt=" + (this.config.maxNumberOfDays < 1 || this.config.maxNumberOfDays > 17 ? 7 : this.config.maxNumberOfDays); + params += "&units=" + this.config.units; params += "&lang=" + this.config.lang; params += "&APPID=" + this.config.appid; @@ -310,12 +307,12 @@ Module.register("weatherforecast",{ * parserDataWeather(data) * * Use the parse to keep the same struct between daily and forecast Endpoint - * from Openweather + * from openweather.org * */ - parserDataWeather: function(data) { + parserDataWeather: function (data) { if (data.hasOwnProperty("main")) { - data["temp"] = {"min": data.main.temp_min, "max": data.main.temp_max}; + data["temp"] = { min: data.main.temp_min, max: data.main.temp_max }; } return data; }, @@ -325,7 +322,7 @@ Module.register("weatherforecast",{ * * argument data object - Weather information received form openweather.org. */ - processWeather: function(data) { + processWeather: function (data) { this.fetchedLocationName = data.city.name + ", " + data.city.country; this.forecast = []; @@ -333,13 +330,12 @@ Module.register("weatherforecast",{ var forecastData = {}; for (var i = 0, count = data.list.length; i < count; i++) { - var forecast = data.list[i]; this.parserDataWeather(forecast); // hack issue #1017 var day; var hour; - if(!!forecast.dt_txt) { + if (forecast.dt_txt) { day = moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss").format("ddd"); hour = moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss").format("H"); } else { @@ -348,7 +344,7 @@ Module.register("weatherforecast",{ } if (day !== lastDay) { - var forecastData = { + forecastData = { day: day, icon: this.config.iconTable[forecast.weather[0].icon], maxTemp: this.roundValue(forecast.temp.max), @@ -378,7 +374,7 @@ Module.register("weatherforecast",{ } //Log.log(this.forecast); - this.show(this.config.animationSpeed, {lockString:this.identifier}); + this.show(this.config.animationSpeed, { lockString: this.identifier }); this.loaded = true; this.updateDom(this.config.animationSpeed); }, @@ -388,7 +384,7 @@ Module.register("weatherforecast",{ * * argument delay number - Milliseconds before next update. If empty, this.config.updateInterval is used. */ - scheduleUpdate: function(delay) { + scheduleUpdate: function (delay) { var nextLoad = this.config.updateInterval; if (typeof delay !== "undefined" && delay >= 0) { nextLoad = delay; @@ -396,7 +392,7 @@ Module.register("weatherforecast",{ var self = this; clearTimeout(this.updateTimer); - this.updateTimer = setTimeout(function() { + this.updateTimer = setTimeout(function () { self.updateWeather(); }, nextLoad); }, @@ -405,15 +401,15 @@ Module.register("weatherforecast",{ * Converts m2 to beaufort (windspeed). * * see: - * http://www.spc.noaa.gov/faq/tornado/beaufort.html + * https://www.spc.noaa.gov/faq/tornado/beaufort.html * https://en.wikipedia.org/wiki/Beaufort_scale#Modern_scale * * argument ms number - Windspeed in m/s. * * return number - Windspeed in beaufort. */ - ms2Beaufort: function(ms) { - var kmh = ms * 60 * 60 / 1000; + ms2Beaufort: function (ms) { + var kmh = (ms * 60 * 60) / 1000; var speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; for (var beaufort in speeds) { var speed = speeds[beaufort]; @@ -431,7 +427,7 @@ Module.register("weatherforecast",{ * * return string - Rounded Temperature. */ - roundValue: function(temperature) { + roundValue: function (temperature) { var decimals = this.config.roundTemp ? 0 : 1; return parseFloat(temperature).toFixed(decimals); }, @@ -443,29 +439,31 @@ Module.register("weatherforecast",{ * That object has a property "3h" which contains the amount of rain since the previous forecast in the list. * This code finds all forecasts that is for the same day and sums the amount of rain and returns that. */ - processRain: function(forecast, allForecasts) { + processRain: function (forecast, allForecasts) { //If the amount of rain actually is a number, return it if (!isNaN(forecast.rain)) { return forecast.rain; } //Find all forecasts that is for the same day - var checkDateTime = (!!forecast.dt_txt) ? moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(forecast.dt, "X"); - var daysForecasts = allForecasts.filter(function(item) { - var itemDateTime = (!!item.dt_txt) ? moment(item.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(item.dt, "X"); + var checkDateTime = forecast.dt_txt ? moment(forecast.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(forecast.dt, "X"); + var daysForecasts = allForecasts.filter(function (item) { + var itemDateTime = item.dt_txt ? moment(item.dt_txt, "YYYY-MM-DD hh:mm:ss") : moment(item.dt, "X"); return itemDateTime.isSame(checkDateTime, "day") && item.rain instanceof Object; }); //If no rain this day return undefined so it wont be displayed for this day - if (daysForecasts.length == 0) { + if (daysForecasts.length === 0) { return undefined; } //Summarize all the rain from the matching days - return daysForecasts.map(function(item) { - return Object.values(item.rain)[0]; - }).reduce(function(a, b) { - return a + b; - }, 0); + return daysForecasts + .map(function (item) { + return Object.values(item.rain)[0]; + }) + .reduce(function (a, b) { + return a + b; + }, 0); } }); diff --git a/package-lock.json b/package-lock.json index 319f0d9016..15a6644aa9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.11.0", + "version": "2.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -8,25 +8,24 @@ "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.8.3" } }, "@babel/core": { - "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.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.9.0", - "@babel/types": "^7.9.0", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", + "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.2", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helpers": "^7.10.1", + "@babel/parser": "^7.10.2", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.2", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.1", @@ -37,6 +36,46 @@ "source-map": "^0.5.0" }, "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "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" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -47,35 +86,38 @@ } }, "json5": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.2.tgz", - "integrity": "sha512-MoUOQ4WdiN3yxhm7NEVJSJrieAo5hNSLQ5sj05OTRHPL9HOBy8u4Bu88jsC1jvqAdN+E1bJmsUcZH+1HQxliqQ==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", "dev": true, "requires": { "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", "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, "@babel/generator": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.9.4.tgz", - "integrity": "sha512-rjP8ahaDy/ouhrvCoU1E5mqaitWrxwuNGU+dy1EpaoK48jZay4MdkskKGIMHLZNewg8sAsqpGSREJwP0zH3YQA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", "dev": true, "requires": { - "@babel/types": "^7.9.0", + "@babel/types": "^7.10.2", "jsesc": "^2.5.1", "lodash": "^4.17.13", "source-map": "^0.5.0" @@ -90,120 +132,119 @@ } }, "@babel/helper-function-name": { - "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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", "dev": true, "requires": { - "@babel/helper-get-function-arity": "^7.8.3", - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/helper-get-function-arity": { - "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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", + "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", "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", + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", "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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", "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-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/types": "^7.8.3" + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@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", - "integrity": "sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", "dev": true, "requires": { - "@babel/types": "^7.8.3" + "@babel/types": "^7.10.1" } }, "@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==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", "dev": true }, "@babel/helpers": { - "version": "7.9.2", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.9.2.tgz", - "integrity": "sha512-JwLvzlXVPjO8eU9c/wF9/zOIN7X6h8DYf7mG4CiFRZRvZNKEF5dQ3H3V+ASkHoIB3mWhatgl5ONhyqHRI6MppA==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", "dev": true, "requires": { - "@babel/template": "^7.8.3", - "@babel/traverse": "^7.9.0", - "@babel/types": "^7.9.0" + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" } }, "@babel/highlight": { "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", "esutils": "^2.0.2", @@ -214,7 +255,6 @@ "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" } @@ -223,7 +263,6 @@ "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", @@ -234,7 +273,6 @@ "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" } @@ -242,9 +280,9 @@ } }, "@babel/parser": { - "version": "7.9.4", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.9.4.tgz", - "integrity": "sha512-bC49otXX6N0/VYhgOMh4gnP26E9xnDZK3TmbNpxYzzz9BQLBosQwfyOe9/cXUU3txYhTzLCbcqd5c8y/OmCjHA==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", "dev": true }, "@babel/runtime": { @@ -265,33 +303,124 @@ } }, "@babel/template": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.8.6.tgz", - "integrity": "sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/parser": "^7.8.6", - "@babel/types": "^7.8.6" + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + }, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "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" + } + }, + "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" + } + } } }, "@babel/traverse": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.9.0.tgz", - "integrity": "sha512-jAZQj0+kn4WTHO5dUZkZKhbFrqZE7K5LAQ5JysMnmvGij+wOdr+8lWqPeW0BcF4wFwrEXXtdGO7wcV6YPJcf3w==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", "dev": true, "requires": { - "@babel/code-frame": "^7.8.3", - "@babel/generator": "^7.9.0", - "@babel/helper-function-name": "^7.8.3", - "@babel/helper-split-export-declaration": "^7.8.3", - "@babel/parser": "^7.9.0", - "@babel/types": "^7.9.0", + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", "debug": "^4.1.0", "globals": "^11.1.0", "lodash": "^4.17.13" }, "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "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" + } + }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", @@ -306,16 +435,25 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } } } }, "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", + "@babel/helper-validator-identifier": "^7.10.1", "lodash": "^4.17.13", "to-fast-properties": "^2.0.0" } @@ -381,10 +519,34 @@ } } }, + "@stylelint/postcss-css-in-js": { + "version": "0.37.1", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.37.1.tgz", + "integrity": "sha512-UMf2Rni3JGKi3ZwYRGMYJ5ipOA5ENJSKMtYA/pE1ZLURwdh7B5+z2r73RmWvub+N0UuH1Lo+TGfCgYwPvqpXNw==", + "dev": true, + "requires": { + "@babel/core": ">=7.9.0" + } + }, + "@stylelint/postcss-markdown": { + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-markdown/-/postcss-markdown-0.36.1.tgz", + "integrity": "sha512-iDxMBWk9nB2BPi1VFQ+Dc5+XpvODBHw2n3tYpaBZuEAFQlbtF9If0Qh5LTTwSi/XwdbJ2jt+0dis3i8omyggpw==", + "dev": true, + "requires": { + "remark": "^12.0.0", + "unist-util-find-all-after": "^3.0.1" + } + }, "@types/color-name": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/@types/color-name/-/color-name-1.1.1.tgz", - "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==", + "integrity": "sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ==" + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", "dev": true }, "@types/minimist": { @@ -393,12 +555,6 @@ "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=", "dev": true }, - "@types/node": { - "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": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz", @@ -417,38 +573,12 @@ "integrity": "sha512-FvUupuM3rlRsRtCN+fDudtmytGO6iHJuuRKS1Ss0pG5z8oX0diNEw94UEL7hgDbpN94rgaK5R7sWm6RrSkZuAQ==", "dev": true }, - "@types/vfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", - "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/unist": "*", - "@types/vfile-message": "*" - } - }, - "@types/vfile-message": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", - "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", - "dev": true, - "requires": { - "vfile-message": "*" - } - }, "abab": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.3.tgz", "integrity": "sha512-tsFzPpcttalNjFBCFMqsKYQcWxxen1pgJR56by//QwvJc4/OUS3kPOOttx2tSIfjsylB0pYu7f5D3K1RCxUnUg==", "dev": true }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, "accepts": { "version": "1.3.7", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", @@ -459,10 +589,9 @@ } }, "acorn": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.1.0.tgz", - "integrity": "sha512-kL5CuoXA/dgxlBbVrflsflzQ3PAas7RYZB52NOm/6839iVYJgKMJ3cQJD+t2i5+qFa8h3MDpEOJiS64E8JLnSQ==", - "dev": true + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==" }, "acorn-globals": { "version": "4.3.4", @@ -475,18 +604,17 @@ }, "dependencies": { "acorn": { - "version": "6.4.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.0.tgz", - "integrity": "sha512-gac8OEcQ2Li1dxIEWGZzsp2BitJxwkwcOm0zHAJLcPJaVvm58FRnk6RkuLRpU1EujipU2ZFODv2P9DLMfnV8mw==", + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", "dev": true } } }, "acorn-jsx": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.1.0.tgz", - "integrity": "sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw==", - "dev": true + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.2.0.tgz", + "integrity": "sha512-HiUX/+K2YpkpJ+SzBffkM/AQ2YE03S0U1kjTLVpoJdhZMOWy8qvXVN9JdLqv2QsaQ6MPYQIuNmwD8zOiYUofLQ==" }, "acorn-walk": { "version": "6.2.0", @@ -522,17 +650,7 @@ "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", - "integrity": "sha512-EiYhwo0v255HUL6eDyuLrXEkTi7WwVCLAw+SeOQ7M7qdun1z1pum4DEm/nuqIVbPvi9RPPc9k9LbyBv6H0DwVg==", - "dev": true, - "requires": { - "type-fest": "^0.8.1" - } + "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==" }, "ansi-regex": { "version": "2.1.1", @@ -552,14 +670,6 @@ "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": { @@ -581,7 +691,6 @@ "version": "1.0.10", "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, "requires": { "sprintf-js": "~1.0.2" }, @@ -589,11 +698,16 @@ "sprintf-js": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=" } } }, + "array-differ": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", + "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", + "dev": true + }, "array-equal": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/array-equal/-/array-equal-1.0.0.tgz", @@ -622,9 +736,9 @@ "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog==" }, "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", "dev": true }, "asn1": { @@ -649,14 +763,7 @@ "astral-regex": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true - }, - "async": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", - "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=", - "dev": true + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==" }, "async-limiter": { "version": "1.0.1", @@ -675,18 +782,18 @@ "dev": true }, "autoprefixer": { - "version": "9.7.5", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.7.5.tgz", - "integrity": "sha512-URo6Zvt7VYifomeAfJlMFnYDhow1rk2bufwkbamPEAtQFcL11moLk4PnR7n9vlu7M+BkXAZkHFA0mIcY7tjQFg==", + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", + "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", "dev": true, "requires": { - "browserslist": "^4.11.0", - "caniuse-lite": "^1.0.30001036", + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001061", "chalk": "^2.4.2", "normalize-range": "^0.1.2", "num2fraction": "^1.2.2", - "postcss": "^7.0.27", - "postcss-value-parser": "^4.0.3" + "postcss": "^7.0.30", + "postcss-value-parser": "^4.1.0" }, "dependencies": { "ansi-styles": { @@ -726,9 +833,9 @@ "integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=" }, "aws4": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.9.0.tgz", - "integrity": "sha512-Uvq6hVe90D0B2WEnUqtdgY1bATGz3mw33nH9Y+dmA+w5DHvUmBgkr5rM/KCHpCsiFNRUfokW/szpPPgMK2hm4A==" + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/aws4/-/aws4-1.10.0.tgz", + "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==" }, "babel-polyfill": { "version": "6.26.0", @@ -773,8 +880,7 @@ "balanced-match": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", - "dev": true + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" }, "base64-arraybuffer": { "version": "0.1.5", @@ -885,7 +991,6 @@ "version": "1.1.11", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "dev": true, "requires": { "balanced-match": "^1.0.0", "concat-map": "0.0.1" @@ -913,13 +1018,13 @@ "dev": true }, "browserslist": { - "version": "4.11.1", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.11.1.tgz", - "integrity": "sha512-DCTr3kDrKEYNw6Jb9HFxVLQNaue8z+0ZfRBRjmCunKDEXEBajKDj2Y+Uelg+Pi29OnvaSGwjOsnRyNEkXzHg5g==", + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", + "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", "dev": true, "requires": { - "caniuse-lite": "^1.0.30001038", - "electron-to-chromium": "^1.3.390", + "caniuse-lite": "^1.0.30001043", + "electron-to-chromium": "^1.3.413", "node-releases": "^1.1.53", "pkg-up": "^2.0.0" } @@ -959,8 +1064,7 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=", - "dev": true + "integrity": "sha1-DTM+PwDqxQqhRUq9MO+MKl2ackI=" }, "buffer-equal-constant-time": { "version": "1.0.1", @@ -992,8 +1096,7 @@ "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "dev": true + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" }, "camelcase": { "version": "2.1.1", @@ -1015,9 +1118,9 @@ "integrity": "sha1-FkpUg+Yw+kMh5a8HAg5TGDGyYJs=" }, "caniuse-lite": { - "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==", + "version": "1.0.30001084", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001084.tgz", + "integrity": "sha512-ftdc5oGmhEbLUuMZ/Qp3mOpzfZLCxPYKcvGv6v2dJJ+8EdqcvZRbAGOiLmkM/PV1QGta/uwBs8/nCl6sokDW6w==", "dev": true }, "caseless": { @@ -1090,12 +1193,6 @@ "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", "dev": true }, - "chardet": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", - "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", - "dev": true - }, "check-error": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", @@ -1116,30 +1213,19 @@ "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 - } } }, + "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", "integrity": "sha512-Rx9Zw8KQkoPO3/O2yPRchCZm3cGubCQiRLmmFAlbkDKobUIPP3JYul+bKILR9DIv1gSVwPQSgF8JGGkXzX8Q0w==" }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, "cli-width": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", @@ -1204,12 +1290,6 @@ "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=" }, - "coffeescript": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.10.0.tgz", - "integrity": "sha1-56qDAZF+9iGzXYo580jc3R234z4=", - "dev": true - }, "collapse-white-space": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", @@ -1220,7 +1300,6 @@ "version": "1.9.3", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, "requires": { "color-name": "1.1.3" } @@ -1228,8 +1307,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" }, "colors": { "version": "1.4.0", @@ -1250,6 +1328,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", @@ -1268,8 +1352,7 @@ "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" }, "concat-stream": { "version": "1.6.2", @@ -1288,9 +1371,9 @@ "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1618,15 +1701,6 @@ } } }, - "date-time": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/date-time/-/date-time-1.1.0.tgz", - "integrity": "sha1-GIdtC9pMGf5w3Tv0sDTygbEqQLY=", - "dev": true, - "requires": { - "time-zone": "^0.1.0" - } - }, "dateformat": { "version": "1.0.12", "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-1.0.12.tgz", @@ -1682,8 +1756,7 @@ "deep-is": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", - "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", - "dev": true + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=" }, "define-properties": { "version": "1.1.3", @@ -1755,7 +1828,6 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, "requires": { "esutils": "^2.0.2" } @@ -1775,6 +1847,12 @@ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", "dev": true + }, + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true } } }, @@ -1899,16 +1977,15 @@ } }, "electron-to-chromium": { - "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==", + "version": "1.3.478", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.478.tgz", + "integrity": "sha512-pt9GUDD52uEO9ZXWcG4UuW/HwE8T+a8iFP7K2qqWrHB5wUxbbvCIXGBVpQDDQwSR766Nn4AkmLYxOUNd4Ji5Dw==", "dev": true }, "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==" }, "encodeurl": { "version": "1.0.2", @@ -2000,10 +2077,18 @@ "has-binary2": "~1.0.2" } }, + "enquirer": { + "version": "2.3.5", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.5.tgz", + "integrity": "sha512-BNT1C08P9XD0vNg3J475yIUG+mVdp9T6towYFHUv897X0KoHBjB1shyrNmhmtHWKP17iSWgo7Gqh7BBuzLZMSA==", + "requires": { + "ansi-colors": "^3.2.1" + } + }, "entities": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.0.tgz", - "integrity": "sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", "dev": true }, "env-paths": { @@ -2020,9 +2105,9 @@ } }, "es-abstract": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.3.tgz", - "integrity": "sha512-AwiVPKf3sKGMoWtFw0J7Y4MTZ4Iek67k4COWOwHqS8B9TOZ71DCfcoBmdamy8Y6mj4MDz0+VNUpC2HKHFHA3pg==", + "version": "1.17.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.5.tgz", + "integrity": "sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg==", "dev": true, "requires": { "es-to-primitive": "^1.2.1", @@ -2104,22 +2189,22 @@ } }, "eslint": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-6.8.0.tgz", - "integrity": "sha512-K+Iayyo2LtyYhDSYwz5D5QdWw0hCacNzyq1Y821Xna2xSJj7cijoLLYmLxTQgcgZ9mC61nryMy9S7GRbYpI5Ig==", - "dev": true, + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-7.3.0.tgz", + "integrity": "sha512-dJMVXwfU5PT1cj2Nv2VPPrKahKTGdX+5Dh0Q3YuKt+Y2UhdL2YbzsVaBMyG9HC0tBismlv/r1+eZqs6SMIV38Q==", "requires": { "@babel/code-frame": "^7.0.0", "ajv": "^6.10.0", - "chalk": "^2.1.0", - "cross-spawn": "^6.0.5", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", "debug": "^4.0.1", "doctrine": "^3.0.0", - "eslint-scope": "^5.0.0", - "eslint-utils": "^1.4.3", - "eslint-visitor-keys": "^1.1.0", - "espree": "^6.1.2", - "esquery": "^1.0.1", + "enquirer": "^2.3.5", + "eslint-scope": "^5.1.0", + "eslint-utils": "^2.0.0", + "eslint-visitor-keys": "^1.2.0", + "espree": "^7.1.0", + "esquery": "^1.2.0", "esutils": "^2.0.2", "file-entry-cache": "^5.0.1", "functional-red-black-tree": "^1.0.1", @@ -2128,149 +2213,254 @@ "ignore": "^4.0.6", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", - "inquirer": "^7.0.0", "is-glob": "^4.0.0", "js-yaml": "^3.13.1", "json-stable-stringify-without-jsonify": "^1.0.1", - "levn": "^0.3.0", + "levn": "^0.4.1", "lodash": "^4.17.14", "minimatch": "^3.0.4", - "mkdirp": "^0.5.1", "natural-compare": "^1.4.0", - "optionator": "^0.8.3", + "optionator": "^0.9.1", "progress": "^2.0.0", - "regexpp": "^2.0.1", - "semver": "^6.1.2", - "strip-ansi": "^5.2.0", - "strip-json-comments": "^3.0.1", + "regexpp": "^3.1.0", + "semver": "^7.2.1", + "strip-ansi": "^6.0.0", + "strip-json-comments": "^3.1.0", "table": "^5.2.3", "text-table": "^0.2.0", "v8-compile-cache": "^2.0.3" }, "dependencies": { "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==" }, "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, + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.2.1.tgz", + "integrity": "sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA==", "requires": { - "color-convert": "^1.9.0" + "@types/color-name": "^1.1.1", + "color-convert": "^2.0.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, + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "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==", + "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==" + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" } }, "debug": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", - "dev": true, "requires": { "ms": "^2.1.1" } }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" + }, + "levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "requires": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.3" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" + }, "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": "7.3.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.2.tgz", + "integrity": "sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==" + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" }, "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, + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", "requires": { - "ansi-regex": "^4.1.0" + "ansi-regex": "^5.0.0" } }, "strip-json-comments": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.0.1.tgz", - "integrity": "sha512-VTyMAUfdm047mwKl+u79WIdrZxtFtn+nBxHeb844XBQ9uMNTuTHdx2hc5RiAJYqwTj3wc/xe5HLSdJSkJ+WfZw==", - "dev": true + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.0.tgz", + "integrity": "sha512-e6/d0eBu7gHtdCqFt0xJr642LdToM5/cN4Qb9DbHjVx1CP5RyeM+zH7pbecEmDv/lBqb0QH+6Uqq75rxFPkM0w==" }, "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, + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", "requires": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "requires": { + "isexe": "^2.0.0" } } } }, - "eslint-scope": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.0.0.tgz", - "integrity": "sha512-oYrhJW7S0bxAFDvWqzvMPRm6pcgcnWc4QnofCAqRTRfQC0JcwenzGglTtsLyIuuWFfkqDG9vz67cnttSd53djw==", + "eslint-config-prettier": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-6.11.0.tgz", + "integrity": "sha512-oB8cpLWSAjOVFEJhhyMZh6NOEOtBVziaqdDQ86+qhDHFbZXoRTM7pNSvFRfW/W/L/LrQ38C99J5CGuRBBzBsdA==", "dev": true, + "requires": { + "get-stdin": "^6.0.0" + }, + "dependencies": { + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.4.tgz", + "integrity": "sha512-jZDa8z76klRqo+TdGDTFJSavwbnWK2ZpqGKNZ+VvweMW516pDUMmQ2koXvxEE4JhzNvTv+radye/bWGBmA6jmg==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-scope": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.0.tgz", + "integrity": "sha512-iiGRvtxWqgtx5m8EyQUJihBloE4EnYeGE/bz1wSPwJE6tZuJUtHlhqDM4Xj2ukE8Dyy1+HCZ4hE0fzIVMzb58w==", "requires": { "esrecurse": "^4.1.0", "estraverse": "^4.1.1" } }, "eslint-utils": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.4.3.tgz", - "integrity": "sha512-fbBN5W2xdY45KulGXmLHZ3c3FHfVYmKg0IrAKGOkT/464PQsx2UeIzfz1RmEci+KLm1bBaAzZAh8+/E+XAeZ8Q==", - "dev": true, + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-2.1.0.tgz", + "integrity": "sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==", "requires": { "eslint-visitor-keys": "^1.1.0" } }, "eslint-visitor-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.1.0.tgz", - "integrity": "sha512-8y9YjtM1JBJU/A9Kc+SbaOV4y29sSWckBwMHa+FGtVj5gN/sbnKDf6xJUl+8g7FAij9LVaP8C24DUiH/f/2Z9A==", - "dev": true + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==" }, "espree": { - "version": "6.1.2", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.1.2.tgz", - "integrity": "sha512-2iUPuuPP+yW1PZaMSDM9eyVf8D5P0Hi8h83YtZ5bPc/zHYjII5khoixIUTMO794NOY8F/ThF1Bo8ncZILarUTA==", - "dev": true, + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-7.1.0.tgz", + "integrity": "sha512-dcorZSyfmm4WTuTnE5Y7MEN1DyoPYy1ZR783QW1FJoenn7RailyWFsq/UL6ZAAA7uXurN9FIpYyUs3OfiIW+Qw==", "requires": { - "acorn": "^7.1.0", - "acorn-jsx": "^5.1.0", - "eslint-visitor-keys": "^1.1.0" + "acorn": "^7.2.0", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.2.0" } }, "esprima": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==" }, "esquery": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", - "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", - "dev": true, + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.3.1.tgz", + "integrity": "sha512-olpvt9QG0vniUBZspVRN6lwB7hOZoTRtT+jzR+tS4ffYx2mzbw+z0XCOk44aaLYKApNX5nMm+E+P6o25ip/DHQ==", "requires": { - "estraverse": "^4.0.0" + "estraverse": "^5.1.0" + }, + "dependencies": { + "estraverse": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.1.0.tgz", + "integrity": "sha512-FyohXK+R0vE+y1nHLoBM7ZTyqRpqAlhdZHCWIWEviFLiGB8b04H6bQs8G+XTthacvT8VuwvteiP7RJSxMs8UEw==" + } } }, "esrecurse": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, "requires": { "estraverse": "^4.1.0" } @@ -2278,26 +2468,18 @@ "estraverse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==" }, "esutils": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" }, "etag": { "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=" }, - "eventemitter2": { - "version": "0.4.14", - "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", - "integrity": "sha1-j2G3XN4BKy6esoTUVFWDtWQ7Yas=", - "dev": true - }, "eventyoshi": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/eventyoshi/-/eventyoshi-0.2.1.tgz", @@ -2327,12 +2509,6 @@ "clone-regexp": "^2.1.0" } }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, "expand-tilde": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", @@ -2434,37 +2610,15 @@ "is-extendable": "^0.1.0" } }, - "external-editor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz", - "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==", - "dev": true, - "requires": { - "chardet": "^0.7.0", - "iconv-lite": "^0.4.24", - "tmp": "^0.0.33" - }, - "dependencies": { - "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" - } - } - } - }, "extract-zip": { - "version": "1.6.7", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.6.7.tgz", - "integrity": "sha1-qEC0uK9kAyZMjbV/Txp0Mz74H+k=", + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-1.7.0.tgz", + "integrity": "sha512-xoh5G1W/PB0/27lXgMQyIhP5DSY/LhoCsOyZgb+6iMmRtCwVBo55uKaMoEYrDCKQhWvqEip5ZPKAc6eFNyf/MA==", "requires": { - "concat-stream": "1.6.2", - "debug": "2.6.9", - "mkdirp": "0.5.1", - "yauzl": "2.4.1" + "concat-stream": "^1.6.2", + "debug": "^2.6.9", + "mkdirp": "^0.5.4", + "yauzl": "^2.10.0" }, "dependencies": { "debug": { @@ -2492,10 +2646,16 @@ "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=" }, + "fast-diff": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", + "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", + "dev": true + }, "fast-glob": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.2.tgz", - "integrity": "sha512-UDV82o4uQyljznxwMxyVRJgZZt3O5wENYojjzbaGEGZgeOxkLFf+V4cnUD+krzb2F72E18RhamkMZ7AdeggF7A==", + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.4.tgz", + "integrity": "sha512-kr/Oo6PX51265qeuCYsyGypiO5uJFgBS0jksyG7FUeCyQzNwYnzrNIMR1NXfkZXsMYXYLRAHgISHBz8gQcxKHQ==", "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", @@ -2514,22 +2674,21 @@ "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fastq": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.6.1.tgz", - "integrity": "sha512-mpIH5sKYueh3YyeJwqtVo8sORi0CgtmkVbK6kZStpQlZBYQuTzG2CZ7idSiJuA7bY0SFCWUc5WIs+oYumGCQNw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.8.0.tgz", + "integrity": "sha512-SMIZoZdLh/fgofivvIkmknUXyPnvxRE3DhtZ5Me3Mrsk5gyPL42F0xr51TdRXskBxHfMp+07bcYzfsYEsSQA9Q==", "dev": true, "requires": { "reusify": "^1.0.4" } }, "fd-slicer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.0.1.tgz", - "integrity": "sha1-i1vL2ewyfFBBv5qwI/1nUPEXfmU=", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", "requires": { "pend": "~1.2.0" } @@ -2549,20 +2708,10 @@ "sax": "^1.0.0" } }, - "figures": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-3.1.0.tgz", - "integrity": "sha512-ravh8VRXqHuMvZt/d8GblBeqDMkdJMBdv/2KntFH+ra5MXkO7nxNKpzQ3n6QD/2da1kH0aWmNISdvhM7gl2gVg==", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5" - } - }, "file-entry-cache": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", - "dev": true, "requires": { "flat-cache": "^2.0.1" } @@ -2614,28 +2763,13 @@ "pinkie-promise": "^2.0.0" } }, - "findup-sync": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-0.3.0.tgz", - "integrity": "sha1-N5MKpdgWt3fANEXhlmzGeQpMCxY=", + "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": { - "glob": "~5.0.0" - }, - "dependencies": { - "glob": { - "version": "5.0.15", - "resolved": "https://registry.npmjs.org/glob/-/glob-5.0.15.tgz", - "integrity": "sha1-G8k2ueAvSmA/zCIuz3Yz0wuLk7E=", - "dev": true, - "requires": { - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "2 || 3", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - } + "semver-regex": "^2.0.0" } }, "flat": { @@ -2651,7 +2785,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, "requires": { "flatted": "^2.0.0", "rimraf": "2.6.3", @@ -2659,10 +2792,9 @@ } }, "flatted": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.1.tgz", - "integrity": "sha512-a1hQMktqW9Nmqr5aktAux3JMNqaucxGcjtjWnZLHX7yyPCmlSV3M54nGYbqT8K+0GhF3NBgmJCc3ma+WOgX8Jg==", - "dev": true + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==" }, "forever-agent": { "version": "0.6.1", @@ -2719,13 +2851,12 @@ "fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=" }, "fsevents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.2.tgz", - "integrity": "sha512-R4wDiBwZ0KzpgOWetKDug1FZcYhqYnUYKtfZYt4mD5SBz76q0KR4Q9o7GIPamsVPGmW3EYPPJ0dOOjvx32ldZA==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", "dev": true, "optional": true }, @@ -2738,8 +2869,7 @@ "functional-red-black-tree": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=" }, "gaze": { "version": "1.1.3", @@ -2782,12 +2912,6 @@ "pump": "^3.0.0" } }, - "getobject": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/getobject/-/getobject-0.1.0.tgz", - "integrity": "sha1-BHpEl4n6Fg0Bj1SG7ZEyC27HiFw=", - "dev": true - }, "getpass": { "version": "0.1.7", "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz", @@ -2808,15 +2932,14 @@ } }, "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", - "dev": true, + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", - "minimatch": "^3.0.2", + "minimatch": "^3.0.4", "once": "^1.3.0", "path-is-absolute": "^1.0.0" } @@ -2825,7 +2948,6 @@ "version": "5.1.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.0.tgz", "integrity": "sha512-qjtRgnIVmOfnKUE3NJAQEdk+lKrxfw8t5ke7SXtfMTHcjsBfOfWXCQfdb30zfDoZQ2IRSIiidmjtbHZPZ++Ihw==", - "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -2851,360 +2973,94 @@ } }, "globals": { - "version": "12.3.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-12.3.0.tgz", - "integrity": "sha512-wAfjdLgFsPZsklLJvOBUBmzYE8/CwhEqSBEMRXA3qxIiNtyqvjYurAtIfDh6chlEPUfmTY3MnZh5Hfh4q0UlIw==", - "dev": true, + "version": "12.4.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-12.4.0.tgz", + "integrity": "sha512-BWICuzzDvDoH54NHKCseDanAhE3CeDorgDL5MT6LMXXj2WCnd9UC2szdk4AWLfjdgNBCXLUanXYcpBBKOSWGwg==", "requires": { "type-fest": "^0.8.1" } }, "globby": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.0.tgz", - "integrity": "sha512-iuehFnR3xu5wBBtm4xi0dMe92Ob87ufyu/dHwpDYfbcpYpIbrO5OnS8M1vWvrBhSGEJ3/Ecj7gnX76P8YxpPEg==", - "dev": true, - "requires": { - "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": { - "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", - "dev": true - } - } - }, - "globjoin": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", - "dev": true - }, - "globule": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.0.tgz", - "integrity": "sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.0.1.tgz", + "integrity": "sha512-iH9RmgwCmUJHi2z5o2l3eTtGBtXek1OYlHrbcxOYugyHLmAsZrPj43OtHThd62Buh/Vv6VyCBD2bdyWcGNQqoQ==", "dev": true, - "requires": { - "glob": "~7.1.1", - "lodash": "~4.17.10", - "minimatch": "~3.0.2" - }, - "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" - } - } - } - }, - "gonzales-pe": { - "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.2.5" - }, - "dependencies": { - "minimist": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", - "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", - "dev": true - } - } - }, - "graceful-fs": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", - "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" - }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "grunt": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grunt/-/grunt-1.0.4.tgz", - "integrity": "sha512-PYsMOrOC+MsdGEkFVwMaMyc6Ob7pKmq+deg1Sjr+vvMWp35sztfwKE7qoN51V+UEtHsyNuMcGdgMLFkBHvMxHQ==", - "dev": true, - "requires": { - "coffeescript": "~1.10.0", - "dateformat": "~1.0.12", - "eventemitter2": "~0.4.13", - "exit": "~0.1.1", - "findup-sync": "~0.3.0", - "glob": "~7.0.0", - "grunt-cli": "~1.2.0", - "grunt-known-options": "~1.1.0", - "grunt-legacy-log": "~2.0.0", - "grunt-legacy-util": "~1.1.1", - "iconv-lite": "~0.4.13", - "js-yaml": "~3.13.0", - "minimatch": "~3.0.2", - "mkdirp": "~0.5.1", - "nopt": "~3.0.6", - "path-is-absolute": "~1.0.0", - "rimraf": "~2.6.2" - }, - "dependencies": { - "grunt-cli": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/grunt-cli/-/grunt-cli-1.2.0.tgz", - "integrity": "sha1-VisRnrsGndtGSs4oRVAb6Xs1tqg=", - "dev": true, - "requires": { - "findup-sync": "~0.3.0", - "grunt-known-options": "~1.1.0", - "nopt": "~3.0.6", - "resolve": "~1.1.0" - } - }, - "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" - } - }, - "resolve": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.1.7.tgz", - "integrity": "sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=", - "dev": true - } - } - }, - "grunt-eslint": { - "version": "22.0.0", - "resolved": "https://registry.npmjs.org/grunt-eslint/-/grunt-eslint-22.0.0.tgz", - "integrity": "sha512-I7vIU4x/mb20fmA6TAmLx6Wzn7mfs8ZXeuk7LbP2ujKVFV7KZmJ3qXUyqe2wnD+v/74Rs5uYOZrLL8EoBmlG9Q==", - "dev": true, - "requires": { - "chalk": "^2.1.0", - "eslint": "^6.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "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" - } - }, - "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" - } - } - } - }, - "grunt-jsonlint": { - "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" - } - }, - "grunt-known-options": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-known-options/-/grunt-known-options-1.1.1.tgz", - "integrity": "sha512-cHwsLqoighpu7TuYj5RonnEuxGVFnztcUqTqp5rXFGYL4OuPFofwC4Ycg7n9fYwvK6F5WbYgeVOwph9Crs2fsQ==", - "dev": true - }, - "grunt-legacy-log": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/grunt-legacy-log/-/grunt-legacy-log-2.0.0.tgz", - "integrity": "sha512-1m3+5QvDYfR1ltr8hjiaiNjddxGdQWcH0rw1iKKiQnF0+xtgTazirSTGu68RchPyh1OBng1bBUjLmX8q9NpoCw==", - "dev": true, - "requires": { - "colors": "~1.1.2", - "grunt-legacy-log-utils": "~2.0.0", - "hooker": "~0.2.3", - "lodash": "~4.17.5" - }, - "dependencies": { - "colors": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.1.2.tgz", - "integrity": "sha1-FopHAXVran9RoSzgyXv6KMCE7WM=", - "dev": true - } - } - }, - "grunt-legacy-log-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-log-utils/-/grunt-legacy-log-utils-2.0.1.tgz", - "integrity": "sha512-o7uHyO/J+i2tXG8r2bZNlVk20vlIFJ9IEYyHMCQGfWYru8Jv3wTqKZzvV30YW9rWEjq0eP3cflQ1qWojIe9VFA==", - "dev": true, - "requires": { - "chalk": "~2.4.1", - "lodash": "~4.17.10" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "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" - } - }, - "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" - } - } - } - }, - "grunt-legacy-util": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/grunt-legacy-util/-/grunt-legacy-util-1.1.1.tgz", - "integrity": "sha512-9zyA29w/fBe6BIfjGENndwoe1Uy31BIXxTH3s8mga0Z5Bz2Sp4UCjkeyv2tI449ymkx3x26B+46FV4fXEddl5A==", - "dev": true, - "requires": { - "async": "~1.5.2", - "exit": "~0.1.1", - "getobject": "~0.1.0", - "hooker": "~0.2.3", - "lodash": "~4.17.10", - "underscore.string": "~3.3.4", - "which": "~1.3.0" - } - }, - "grunt-markdownlint": { - "version": "2.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.19.0" - } - }, - "grunt-stylelint": { - "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" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "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" - } - }, - "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" - } + "requires": { + "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": { + "ignore": { + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", + "dev": true } } }, - "grunt-yamllint": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/grunt-yamllint/-/grunt-yamllint-0.3.0.tgz", - "integrity": "sha1-EAP3n5uluSMVedOOr8M/awmNdPM=", + "globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha1-L0SUrIkZ43Z8XLtpHp9GMyQoXUM=", + "dev": true + }, + "globule": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/globule/-/globule-1.3.0.tgz", + "integrity": "sha512-YlD4kdMqRCQHrhVdonet4TdRtv1/sZKepvoxNT4Nrhrp5HI8XFfc8kFlGlBn2myBo80aGp8Eft259mbcUJhgSg==", "dev": true, "requires": { - "async": "^2.1.5", - "chalk": "^1.1.3", - "js-yaml": "^3.8.1" + "glob": "~7.1.1", + "lodash": "~4.17.10", + "minimatch": "~3.0.2" }, "dependencies": { - "async": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", - "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "dev": true, "requires": { - "lodash": "^4.17.14" + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" } } } }, + "gonzales-pe": { + "version": "4.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.2.5" + } + }, + "graceful-fs": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.3.tgz", + "integrity": "sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==" + }, + "grapheme-splitter": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", + "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", + "dev": true + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, "har-schema": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", @@ -3265,8 +3121,7 @@ "has-flag": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=" }, "has-symbols": { "version": "1.0.1", @@ -3339,12 +3194,6 @@ "parse-passwd": "^1.0.0" } }, - "hooker": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/hooker/-/hooker-0.2.3.tgz", - "integrity": "sha1-uDT3I8xKJCqmWWNFnfbZhMXT2Vk=", - "dev": true - }, "hosted-git-info": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.5.tgz", @@ -3399,12 +3248,6 @@ "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", @@ -3505,12 +3348,100 @@ "debug": "^3.1.0" } }, + "husky": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/husky/-/husky-4.2.5.tgz", + "integrity": "sha512-SYZ95AjKcX7goYVZtVZF2i6XiZcHknw50iXvY7b0MiGoj5RwdgRQNEHdb+gPDPCXKlzwrybjFjkL6FOj8uRhZQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "ci-info": "^2.0.0", + "compare-versions": "^3.6.0", + "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": "4.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.0.0.tgz", + "integrity": "sha512-N9oWFcegS0sFr9oh1oz2d7Npos6vNoWW9HvtCg5N1KRFpUhaAhvTv5Y58g880fZaEYSNm3qDz8SU1UrGvp+n7A==", + "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", "integrity": "sha512-Ty8UblRWFEcfSuIaajM34LdPXIhbs1ajEX/BBPv24J+enSVaEVY63xQ6lTO9VRYS5LAoghIG0IDJ+p+IPzKUQQ==", "dev": true }, + "ical": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/ical/-/ical-0.8.0.tgz", + "integrity": "sha512-/viUSb/RGLLnlgm0lWRlPBtVeQguQRErSPYl3ugnUaKUnzQswKqOG3M8/P1v1AB5NJwlHTuvTq1cs4mpeG2rCg==", + "requires": { + "rrule": "2.4.1" + }, + "dependencies": { + "rrule": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.4.1.tgz", + "integrity": "sha512-+NcvhETefswZq13T8nkuEnnQ6YgUeZaqMqVbp+ZiFDPCbp3AVgQIwUvNVDdMNrP05bKZG9ddDULFp0qZZYDrxg==", + "requires": { + "luxon": "^1.3.3" + } + } + } + }, "iconv-lite": { "version": "0.5.1", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.5.1.tgz", @@ -3533,14 +3464,12 @@ "ignore": { "version": "4.0.6", "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==" }, "import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", "integrity": "sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ==", - "dev": true, "requires": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -3555,8 +3484,7 @@ "imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=" }, "indent-string": { "version": "2.1.0", @@ -3581,7 +3509,6 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, "requires": { "once": "^1.3.0", "wrappy": "1" @@ -3597,109 +3524,6 @@ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==" }, - "inquirer": { - "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", - "chalk": "^2.4.2", - "cli-cursor": "^3.1.0", - "cli-width": "^2.0.0", - "external-editor": "^3.0.3", - "figures": "^3.0.0", - "lodash": "^4.17.15", - "mute-stream": "0.0.8", - "run-async": "^2.2.0", - "rxjs": "^6.5.3", - "string-width": "^4.1.0", - "strip-ansi": "^5.1.0", - "through": "^2.3.6" - }, - "dependencies": { - "ansi-regex": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", - "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", - "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" - } - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "string-width": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.0.tgz", - "integrity": "sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg==", - "dev": true, - "requires": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "dependencies": { - "strip-ansi": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", - "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.0" - } - } - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - } - } - }, - "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" - } - } - } - }, "invert-kv": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", @@ -3790,8 +3614,7 @@ "is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=" }, "is-finite": { "version": "1.0.2", @@ -3813,7 +3636,6 @@ "version": "4.0.1", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, "requires": { "is-extglob": "^2.1.1" } @@ -3831,9 +3653,9 @@ "dev": true }, "is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true }, "is-promise": { @@ -3902,8 +3724,7 @@ "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=" }, "isstream": { "version": "0.1.2", @@ -3913,14 +3734,12 @@ "js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" }, "js-yaml": { "version": "3.13.1", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, "requires": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -4049,8 +3868,7 @@ "json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=" }, "json-stringify-safe": { "version": "5.0.1", @@ -4137,9 +3955,9 @@ "dev": true }, "known-css-properties": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.18.0.tgz", - "integrity": "sha512-69AgJ1rQa7VvUsd2kpvVq+VeObDuo3zrj0CzM5Slmf6yduQFAI2kXPDQJR2IE/u6MSAUOJrwSzjg5vlz8qcMiw==", + "version": "0.19.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.19.0.tgz", + "integrity": "sha512-eYboRV94Vco725nKMlpkn3nV2+96p9c3gKXRsYqAJSswSENvBhN7n5L+uDhY58xQa0UukWsDMTGELzmD8Q+wTA==", "dev": true }, "lazystream": { @@ -4226,15 +4044,6 @@ "integrity": "sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA=", "dev": true }, - "linkify-it": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", - "integrity": "sha512-GnAl/knGn+i1U/wjBz3akz2stz+HrHLsxMwHQGofCDfPvlf+gDKN58UtfmUquTY4/MXeE2x7k19KQmeoZi94Iw==", - "dev": true, - "requires": { - "uc.micro": "^1.0.1" - } - }, "load-json-file": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-1.1.0.tgz", @@ -4423,32 +4232,13 @@ "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", "dev": true }, - "markdown-it": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-10.0.0.tgz", - "integrity": "sha512-YWOP1j7UbDNz+TumYP1kpwnP0aEa711cJjrAQrzd0UXlbJfc5aAq0F/PZHjiioqDC1NKgvIMX+o+9Bk7yuM2dg==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "entities": "~2.0.0", - "linkify-it": "^2.0.0", - "mdurl": "^1.0.1", - "uc.micro": "^1.0.5" - } - }, "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "markdownlint": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/markdownlint/-/markdownlint-0.19.0.tgz", - "integrity": "sha512-+MsWOnYVUH4klcKM7iRx5cno9FQMDAb6FC6mWlZkeXPwIaK6Z5Vd9VkXkykPidRqmLHU2wI+MNyfUMnUCBw3pQ==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", "dev": true, "requires": { - "markdown-it": "10.0.0" + "repeat-string": "^1.0.0" } }, "mathml-tag-names": { @@ -4458,20 +4248,14 @@ "dev": true }, "mdast-util-compact": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", - "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-2.0.1.tgz", + "integrity": "sha512-7GlnT24gEwDrdAwEHrU4Vv5lLWrEer4KOkAiKT9nYstsTad7Oc1TwqT2zIMKRdZF7cTuaf+GA1E4Kv7jJh8mPA==", "dev": true, "requires": { - "unist-util-visit": "^1.1.0" + "unist-util-visit": "^2.0.0" } }, - "mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha1-/oWy7HWlkDfyrf7BAP1sYBdhFS4=", - "dev": true - }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -4515,10 +4299,16 @@ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=" }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, "merge2": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.3.0.tgz", - "integrity": "sha512-2j4DAdlBOkiSZIsaXk4mTE3sRS02yBHAtfy127xRV3bQUFqXkjHCHLW6Scv7DwNRbIWNHH8zpnz9zMaKXIdvYw==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", "dev": true }, "methods": { @@ -4561,54 +4351,61 @@ "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=", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", "dev": true }, "minimatch": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "dev": true, "requires": { "brace-expansion": "^1.1.7" } }, "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==" }, "minimist-options": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.0.2.tgz", - "integrity": "sha512-seq4hpWkYSUh1y7NXxzucwAN9yVlBc3Upgdjz8vLCP97jG8kaOmzYrVH/m7tQ1NYD1wdtZbSLfdy4zFmRWuc/w==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", + "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", "dev": true, "requires": { "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "dependencies": { + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + } } }, "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", "requires": { - "minimist": "0.0.8" - }, - "dependencies": { - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - } + "minimist": "^1.2.5" } }, "mocha": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.0.0.tgz", - "integrity": "sha512-CirsOPbO3jU86YKjjMzFLcXIb5YiGLUrjrXFHoJ3e2z9vWiaZVCZQ2+gtRGMPWF+nFhN6AWwLM/juzAQ6KRkbA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-7.1.2.tgz", + "integrity": "sha512-o96kdRKMKI3E8U0bjnfqW4QMk12MwZ4mhdBTf+B5a1q9+aq2HRnj+3ZdJu0B/ZhJeK78MgYuv6L8d/rA5AeBJA==", "dev": true, "requires": { "ansi-colors": "3.2.3", @@ -4622,9 +4419,9 @@ "growl": "1.10.5", "he": "1.2.0", "js-yaml": "3.13.1", - "log-symbols": "2.2.0", + "log-symbols": "3.0.0", "minimatch": "3.0.4", - "mkdirp": "0.5.1", + "mkdirp": "0.5.5", "ms": "2.1.1", "node-environment-flags": "1.0.6", "object.assign": "4.1.0", @@ -4632,8 +4429,8 @@ "supports-color": "6.0.0", "which": "1.3.1", "wide-align": "1.1.3", - "yargs": "13.3.0", - "yargs-parser": "13.1.1", + "yargs": "13.3.2", + "yargs-parser": "13.1.2", "yargs-unparser": "1.6.0" }, "dependencies": { @@ -4658,28 +4455,6 @@ "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", @@ -4712,20 +4487,6 @@ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, "he": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", @@ -4748,15 +4509,6 @@ "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", @@ -4764,9 +4516,9 @@ "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==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -4846,9 +4598,9 @@ "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==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -4860,13 +4612,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -4876,9 +4628,9 @@ } }, "mocha-each": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mocha-each/-/mocha-each-1.2.0.tgz", - "integrity": "sha512-WVNx7Rovf7ebZq5XSlhXqenuyN3xS1InqKYvdR544/mQkMoSfTLhT5iehXyK0xCvxx90QIltU6KojKh3Ptz7mA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mocha-each/-/mocha-each-2.0.1.tgz", + "integrity": "sha512-0ZgWY5ajbnROXkfyaDb+0RAYzDBH3QVow/1zJiyl7lYMRnj1Nid8RDP2+/2TTajB5n4vr21v35MjB72GjFFj2g==", "dev": true, "requires": { "sprintf-js": "^1.0.3" @@ -4940,6 +4692,21 @@ "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", "dev": true }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, "mocha": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", @@ -4986,22 +4753,42 @@ "resolved": "https://registry.npmjs.org/moment/-/moment-2.24.0.tgz", "integrity": "sha512-bV7f+6l2QigeBBZSM/6yTNq4P2fNpSWj/0e7jQcy87A8e7o2nAfP/34/2ky5Vw4B9S446EtIhodAzkFCcR4dQg==" }, + "mri": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.1.5.tgz", + "integrity": "sha512-d2RKzMD4JNyHMbnbWnznPaa8vbdlq/4pNZ3IgdaGrVbBhebBsGUUE/6qorTMYNS6TwuH3ilfOlD2bf4Igh8CKg==", + "dev": true + }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" }, - "mute-stream": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", - "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", - "dev": true + "multimatch": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", + "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "array-differ": "^3.0.0", + "array-union": "^2.1.0", + "arrify": "^2.0.1", + "minimatch": "^3.0.4" + }, + "dependencies": { + "arrify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", + "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "dev": true + } + } }, "natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=" }, "negotiator": { "version": "0.6.2", @@ -5042,20 +4829,11 @@ "dev": true }, "node-releases": { - "version": "1.1.53", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.53.tgz", - "integrity": "sha512-wp8zyQVwef2hpZ/dJH7SfSrIPD6YoJz6BDQDpGEkcA0s3LpAQoxBIYmfIq6QAhC1DhwsyCgTaTTcONwX8qzCuQ==", + "version": "1.1.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", + "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", "dev": true }, - "nopt": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-3.0.6.tgz", - "integrity": "sha1-xkZdvwirzU2zWTF/eaxopkayj/k=", - "dev": true, - "requires": { - "abbrev": "1" - } - }, "normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -5067,6 +4845,12 @@ "validate-npm-package-license": "^3.0.1" } }, + "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 + }, "normalize-range": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", @@ -5208,7 +4992,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, "requires": { "wrappy": "1" } @@ -5222,6 +5005,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", @@ -5327,7 +5116,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dev": true, "requires": { "callsites": "^3.0.0" } @@ -5339,9 +5127,9 @@ "dev": true }, "parse-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", + "integrity": "sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==", "dev": true, "requires": { "character-entities": "^1.0.0", @@ -5394,12 +5182,6 @@ } } }, - "parse-ms": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-1.0.1.tgz", - "integrity": "sha1-VjRtR0nXjyNDDKDHE4UK75GqNh0=", - "dev": true - }, "parse-passwd": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", @@ -5444,8 +5226,7 @@ "path-is-absolute": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" }, "path-key": { "version": "2.0.1", @@ -5490,9 +5271,9 @@ "integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=" }, "picomatch": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.1.tgz", - "integrity": "sha512-ISBaA8xQNmwELC7eOjqFKMESB2VIqt4PPDD0nsS95b/9dZXvVKOlz9keMSnoGGKcOHXfTvDD6WMaRoSc9UuhRA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", "dev": true }, "pify": { @@ -5519,6 +5300,66 @@ "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.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "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 + } + } + }, "pkg-up": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", @@ -5539,11 +5380,14 @@ } } }, - "plur": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/plur/-/plur-1.0.0.tgz", - "integrity": "sha1-24XGgU9eXlo7Se/CjWBP7GKXUVY=", - "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" + } }, "pn": { "version": "1.1.0", @@ -5552,9 +5396,9 @@ "dev": true }, "postcss": { - "version": "7.0.27", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.27.tgz", - "integrity": "sha512-WuQETPMcW9Uf1/22HWUWP9lgsIC+KEHg2kozMflKjbeUtw9ujvFX6QmIfozaErDkmLWS9WEnEdEe6Uo9/BNTdQ==", + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -5613,15 +5457,6 @@ "htmlparser2": "^3.10.0" } }, - "postcss-jsx": { - "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" - } - }, "postcss-less": { "version": "3.1.4", "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", @@ -5631,16 +5466,6 @@ "postcss": "^7.0.14" } }, - "postcss-markdown": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", - "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==", - "dev": true, - "requires": { - "remark": "^10.0.1", - "unist-util-find-all-after": "^1.0.2" - } - }, "postcss-media-query-parser": { "version": "0.2.3", "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", @@ -5715,22 +5540,22 @@ } }, "postcss-sass": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.2.tgz", - "integrity": "sha512-hcRgnd91OQ6Ot9R90PE/khUDCJHG8Uxxd3F7Y0+9VHjBiJgNv7sK5FxyHMCBtoLmmkzVbSj3M3OlqUfLJpq0CQ==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.4.4.tgz", + "integrity": "sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==", "dev": true, "requires": { - "gonzales-pe": "^4.2.4", + "gonzales-pe": "^4.3.0", "postcss": "^7.0.21" } }, "postcss-scss": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.0.0.tgz", - "integrity": "sha512-um9zdGKaDZirMm+kZFKKVsnKPF7zF7qBAtIfTSnZXD1jZ0JNZIxdB6TxQOjCnlSzLRInVl2v3YdBh/M881C4ug==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", "dev": true, "requires": { - "postcss": "^7.0.0" + "postcss": "^7.0.6" } }, "postcss-selector-parser": { @@ -5751,9 +5576,9 @@ "dev": true }, "postcss-value-parser": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.0.3.tgz", - "integrity": "sha512-N7h4pG+Nnu5BEIzyeaaIYWs0LI5XC40OrRh5L60z0QjFsqGWcHcbkBvpe1WYpcIS9yQ8sOi/vIPt1ejQCrMVrg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", "dev": true }, "prelude-ls": { @@ -5762,6 +5587,21 @@ "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", "dev": true }, + "prettier": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.0.5.tgz", + "integrity": "sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg==", + "dev": true + }, + "prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "requires": { + "fast-diff": "^1.1.2" + } + }, "pretty-bytes": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-1.0.4.tgz", @@ -5771,15 +5611,192 @@ "meow": "^3.1.0" } }, - "pretty-ms": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-2.1.0.tgz", - "integrity": "sha1-QlfCVt8/sLRR1q/6qwIYhBJpgdw=", + "pretty-quick": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-2.0.1.tgz", + "integrity": "sha512-y7bJt77XadjUr+P1uKqZxFWLddvj3SKY6EU4BuQtMxmmEFSMpbN132pUWdSG1g1mtUfO0noBvn7wBf0BVeomHg==", "dev": true, "requires": { - "is-finite": "^1.0.1", - "parse-ms": "^1.0.0", - "plur": "^1.0.0" + "chalk": "^2.4.2", + "execa": "^2.1.0", + "find-up": "^4.1.0", + "ignore": "^5.1.4", + "mri": "^1.1.4", + "multimatch": "^4.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "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" + } + }, + "cross-spawn": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.2.tgz", + "integrity": "sha512-PD6G8QG3S4FK/XCGFbEQrDqO2AnMMsy0meR7lerlIOHAAbkuavGU/pOqprrlvfTNjvowivTeBsjebAL0NSoMxw==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "execa": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-2.1.0.tgz", + "integrity": "sha512-Y/URAVapfbYy2Xp/gb6A0E7iR8xeqOCXsuuaoMn7A5PzrXUK84E1gyiEfq0wQd/GHA6GsoHWwhNq8anb0mleIw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "get-stream": "^5.0.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^3.0.0", + "onetime": "^5.1.0", + "p-finally": "^2.0.0", + "signal-exit": "^3.0.2", + "strip-final-newline": "^2.0.0" + } + }, + "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" + } + }, + "get-stream": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.1.0.tgz", + "integrity": "sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "ignore": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", + "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "dev": true + }, + "is-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", + "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "dev": true + }, + "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" + } + }, + "npm-run-path": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-3.1.0.tgz", + "integrity": "sha512-Dbl4A/VfiVGLgQv29URL9xshU8XDY1GeLy+fsaZ1AA8JDSfjvr5P5+pzRbWqRSBxk6/DW7MIh8lTM/PaGnP2kg==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "p-finally": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-2.0.1.tgz", + "integrity": "sha512-vpm09aKwq6H9phqRQzecoDpD8TmVyGw70qmWlyq5onxY7tqyTTFVvxMykxQSQKILBSFlbXpypIw2T1Ml7+DDtw==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "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 + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } } }, "process-nextick-args": { @@ -5790,8 +5807,7 @@ "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==" }, "progress-stream": { "version": "1.2.0", @@ -5973,42 +5989,42 @@ "dev": true }, "regexpp": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", - "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", - "dev": true + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.1.0.tgz", + "integrity": "sha512-ZOIzd8yVsQQA7j8GCSlPGXwg5PfmA1mrq0JP4nGhh54LaKN3xdai/vHUDu74pKwV8OxseMS65u2NImosQcSD0Q==" }, "remark": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", - "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", + "version": "12.0.0", + "resolved": "https://registry.npmjs.org/remark/-/remark-12.0.0.tgz", + "integrity": "sha512-oX4lMIS0csgk8AEbzY0h2jdR0ngiCHOpwwpxjmRa5TqAkeknY+tkhjRJGZqnCmvyuWh55/0SW5WY3R3nn3PH9A==", "dev": true, "requires": { - "remark-parse": "^6.0.0", - "remark-stringify": "^6.0.0", - "unified": "^7.0.0" + "remark-parse": "^8.0.0", + "remark-stringify": "^8.0.0", + "unified": "^9.0.0" } }, "remark-parse": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", - "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.2.tgz", + "integrity": "sha512-eMI6kMRjsAGpMXXBAywJwiwAse+KNpmt+BK55Oofy4KvBZEqUDj6mWbGLJZrujoPIPPxDXzn3T9baRlpsm2jnQ==", "dev": true, "requires": { + "ccount": "^1.0.0", "collapse-white-space": "^1.0.2", "is-alphabetical": "^1.0.0", "is-decimal": "^1.0.0", "is-whitespace-character": "^1.0.0", "is-word-character": "^1.0.0", "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", + "parse-entities": "^2.0.0", "repeat-string": "^1.5.4", "state-toggle": "^1.0.0", "trim": "0.0.1", "trim-trailing-lines": "^1.0.0", "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", + "unist-util-remove-position": "^2.0.0", + "vfile-location": "^3.0.0", "xtend": "^4.0.1" }, "dependencies": { @@ -6021,9 +6037,9 @@ } }, "remark-stringify": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", - "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-8.1.0.tgz", + "integrity": "sha512-FSPZv1ds76oAZjurhhuV5qXSUSoz6QRPuwYK38S41sLHwg4oB7ejnmZshj7qwjgYLf93kdz6BOX9j5aidNE7rA==", "dev": true, "requires": { "ccount": "^1.0.0", @@ -6032,12 +6048,12 @@ "is-whitespace-character": "^1.0.0", "longest-streak": "^2.0.1", "markdown-escapes": "^1.0.0", - "markdown-table": "^1.1.0", - "mdast-util-compact": "^1.0.0", - "parse-entities": "^1.0.2", + "markdown-table": "^2.0.0", + "mdast-util-compact": "^2.0.0", + "parse-entities": "^2.0.0", "repeat-string": "^1.5.4", "state-toggle": "^1.0.0", - "stringify-entities": "^1.0.1", + "stringify-entities": "^3.0.0", "unherit": "^1.0.4", "xtend": "^4.0.1" }, @@ -6077,9 +6093,9 @@ "dev": true }, "request": { - "version": "2.88.0", - "resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz", - "integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==", + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", "requires": { "aws-sign2": "~0.7.0", "aws4": "^1.8.0", @@ -6088,7 +6104,7 @@ "extend": "~3.0.2", "forever-agent": "~0.6.1", "form-data": "~2.3.2", - "har-validator": "~5.1.0", + "har-validator": "~5.1.3", "http-signature": "~1.2.0", "is-typedarray": "~1.0.0", "isstream": "~0.1.2", @@ -6098,9 +6114,20 @@ "performance-now": "^2.1.0", "qs": "~6.5.2", "safe-buffer": "^5.1.2", - "tough-cookie": "~2.4.3", + "tough-cookie": "~2.5.0", "tunnel-agent": "^0.6.0", "uuid": "^3.3.2" + }, + "dependencies": { + "tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "requires": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + } + } } }, "request-promise-core": { @@ -6152,8 +6179,7 @@ "resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", - "dev": true + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" }, "resolve-url": { "version": "0.2.1", @@ -6161,16 +6187,6 @@ "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", "dev": true }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, "reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -6193,25 +6209,8 @@ "version": "2.6.3", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, "requires": { "glob": "^7.1.3" - }, - "dependencies": { - "glob": { - "version": "7.1.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" - } - } } }, "rrule": { @@ -6258,15 +6257,6 @@ "rx-lite": "*" } }, - "rxjs": { - "version": "6.5.4", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.4.tgz", - "integrity": "sha512-naMQXcgEo3csAEGvw/NydRA0fuS2nDZJiw1YUWFKU7aPPAPGZEsD4Iimit96qwCieH6y614MCLYwdkrWx7z/7Q==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, "safe-buffer": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.0.tgz", @@ -6287,6 +6277,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", @@ -6407,7 +6409,6 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, "requires": { "ansi-styles": "^3.2.0", "astral-regex": "^1.0.0", @@ -6418,7 +6419,6 @@ "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" } @@ -6426,8 +6426,7 @@ "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" } } }, @@ -7063,24 +7062,46 @@ "strip-ansi": "^3.0.0" } }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz", + "integrity": "sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5", + "string.prototype.trimstart": "^1.0.0" } }, "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==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz", + "integrity": "sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg==", "dev": true, "requires": { "define-properties": "^1.1.3", - "function-bind": "^1.1.1" + "es-abstract": "^1.17.5", + "string.prototype.trimend": "^1.0.0" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" } }, "string_decoder": { @@ -7089,14 +7110,15 @@ "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" }, "stringify-entities": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-3.0.1.tgz", + "integrity": "sha512-Lsk3ISA2++eJYqBMPKcr/8eby1I6L0gP0NlxF8Zja6c05yr/yCYyb2c9PwXjd08Ib3If1vn1rbs1H5ZtVuOfvQ==", "dev": true, "requires": { "character-entities-html4": "^1.0.0", "character-entities-legacy": "^1.0.0", "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.2", "is-hexadecimal": "^1.0.0" } }, @@ -7122,6 +7144,12 @@ "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", "dev": true }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + }, "strip-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-1.0.1.tgz", @@ -7142,48 +7170,48 @@ "dev": true }, "stylelint": { - "version": "13.2.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.2.1.tgz", - "integrity": "sha512-461ZV4KpUe7pEHHgMOsH4kkjF7qsjkCIMJYOf7QQC4cvgPUJ0z4Nj+ah5fvKl1rzqBqc5EZa6P0nna4CGoJX+A==", + "version": "13.6.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-13.6.1.tgz", + "integrity": "sha512-XyvKyNE7eyrqkuZ85Citd/Uv3ljGiuYHC6UiztTR6sWS9rza8j3UeQv/eGcQS9NZz/imiC4GKdk1EVL3wst5vw==", "dev": true, "requires": { - "autoprefixer": "^9.7.4", + "@stylelint/postcss-css-in-js": "^0.37.1", + "@stylelint/postcss-markdown": "^0.36.1", + "autoprefixer": "^9.8.0", "balanced-match": "^1.0.0", - "chalk": "^3.0.0", + "chalk": "^4.1.0", "cosmiconfig": "^6.0.0", "debug": "^4.1.1", "execall": "^2.0.0", "file-entry-cache": "^5.0.1", - "get-stdin": "^7.0.0", + "get-stdin": "^8.0.0", "global-modules": "^2.0.0", - "globby": "^11.0.0", + "globby": "^11.0.1", "globjoin": "^0.1.4", "html-tags": "^3.1.0", - "ignore": "^5.1.4", + "ignore": "^5.1.8", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", - "known-css-properties": "^0.18.0", + "known-css-properties": "^0.19.0", "leven": "^3.1.0", "lodash": "^4.17.15", - "log-symbols": "^3.0.0", + "log-symbols": "^4.0.0", "mathml-tag-names": "^2.1.3", - "meow": "^6.0.1", + "meow": "^7.0.1", "micromatch": "^4.0.2", "normalize-selector": "^0.2.0", - "postcss": "^7.0.27", + "postcss": "^7.0.32", "postcss-html": "^0.36.0", - "postcss-jsx": "^0.36.4", "postcss-less": "^3.1.4", - "postcss-markdown": "^0.36.0", "postcss-media-query-parser": "^0.2.3", "postcss-reporter": "^6.0.1", "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^4.0.1", - "postcss-sass": "^0.4.2", - "postcss-scss": "^2.0.0", + "postcss-safe-parser": "^4.0.2", + "postcss-sass": "^0.4.4", + "postcss-scss": "^2.1.1", "postcss-selector-parser": "^6.0.2", "postcss-syntax": "^0.36.2", - "postcss-value-parser": "^4.0.3", + "postcss-value-parser": "^4.1.0", "resolve-from": "^5.0.0", "slash": "^3.0.0", "specificity": "^0.4.1", @@ -7193,7 +7221,7 @@ "sugarss": "^2.0.0", "svg-tags": "^1.0.0", "table": "^5.4.6", - "v8-compile-cache": "^2.1.0", + "v8-compile-cache": "^2.1.1", "write-file-atomic": "^3.0.3" }, "dependencies": { @@ -7214,26 +7242,34 @@ } }, "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.0.0.tgz", + "integrity": "sha512-8KMDF1Vz2gzOq54ONPJS65IvTUaB1cHJ2DMM7MbPmLZljDH1qpzzLsWdiN9pHh6qvkRVDTi/07+eNGch/oLU4w==", "dev": true }, "camelcase-keys": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.1.tgz", - "integrity": "sha512-BPCNVH56RVIxQQIXskp5tLQXUNGQ6sXr7iCv1FHDt81xBOQ/1r6H8SPxf19InVP6DexWar4s87q9thfuk8X9HA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", + "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", "dev": true, "requires": { "camelcase": "^5.3.1", "map-obj": "^4.0.0", "quick-lru": "^4.0.1" + }, + "dependencies": { + "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": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz", + "integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==", "dev": true, "requires": { "ansi-styles": "^4.1.0", @@ -7264,6 +7300,12 @@ "ms": "^2.1.1" } }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "find-up": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", @@ -7275,9 +7317,9 @@ } }, "get-stdin": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-7.0.0.tgz", - "integrity": "sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==", + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, "has-flag": { @@ -7287,9 +7329,9 @@ "dev": true }, "ignore": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz", - "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", + "version": "5.1.8", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.8.tgz", + "integrity": "sha512-BMpfD7PpiETpBl/A6S498BaIJ6Y/ABT93ETbby2fP00v4EbvPBXWEoaR1UBPKs3iR53pJY7EtZk5KACI57i1Uw==", "dev": true }, "indent-string": { @@ -7313,6 +7355,15 @@ "p-locate": "^4.1.0" } }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, "map-obj": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.1.0.tgz", @@ -7320,28 +7371,30 @@ "dev": true }, "meow": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-6.1.0.tgz", - "integrity": "sha512-iIAoeI01v6pmSfObAAWFoITAA4GgiT45m4SmJgoxtZfvI0fyZwhV4d0lTwiUXvAKIPlma05Feb2Xngl52Mj5Cg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.0.1.tgz", + "integrity": "sha512-tBKIQqVrAHqwit0vfuFPY3LlzJYkEOFyKa3bPgxzNl6q/RtN8KQ+ALYEASYuFayzSAsjlhXj/JZ10rH85Q6TUw==", "dev": true, "requires": { "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.1.1", + "arrify": "^2.0.1", + "camelcase": "^6.0.0", + "camelcase-keys": "^6.2.2", "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.0.0", - "minimist-options": "^4.0.1", + "hard-rejection": "^2.1.0", + "minimist-options": "^4.0.2", "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.0", + "read-pkg-up": "^7.0.1", "redent": "^3.0.0", "trim-newlines": "^3.0.0", - "type-fest": "^0.8.1", - "yargs-parser": "^18.1.1" + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" } }, "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==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -7409,6 +7462,14 @@ "find-up": "^4.1.0", "read-pkg": "^5.2.0", "type-fest": "^0.8.1" + }, + "dependencies": { + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } } }, "redent": { @@ -7471,18 +7532,38 @@ "integrity": "sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA==", "dev": true }, + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true + }, "yargs-parser": { - "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==", + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", "dev": true, "requires": { "camelcase": "^5.0.0", "decamelize": "^1.2.0" + }, + "dependencies": { + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + } } } } }, + "stylelint-config-prettier": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-8.0.2.tgz", + "integrity": "sha512-TN1l93iVTXpF9NJstlvP7nOu9zY2k+mN0NSFQ/VEGz15ZIP9ohdDZTtCWHs5LjctAhSAzaILULGbgiM0ItId3A==", + "dev": true + }, "stylelint-config-recommended": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-3.0.0.tgz", @@ -7498,6 +7579,15 @@ "stylelint-config-recommended": "^3.0.0" } }, + "stylelint-prettier": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-1.1.2.tgz", + "integrity": "sha512-8QZ+EtBpMCXYB6cY0hNE3aCDKMySIx4Q8/malLaqgU/KXXa6Cj2KK8ulG1AJvUMD5XSSP8rOotqaCzR/BW6qAA==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, "sugarss": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", @@ -7586,7 +7676,6 @@ "version": "5.4.6", "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, "requires": { "ajv": "^6.10.2", "lodash": "^4.17.14", @@ -7597,26 +7686,17 @@ "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 - }, - "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 + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==" }, "is-fullwidth-code-point": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=" }, "string-width": { "version": "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", @@ -7627,7 +7707,6 @@ "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" } @@ -7637,8 +7716,7 @@ "text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=" }, "throttleit": { "version": "0.0.2", @@ -7660,39 +7738,6 @@ "xtend": "~2.1.1" } }, - "time-grunt": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/time-grunt/-/time-grunt-2.0.0.tgz", - "integrity": "sha512-iQD2AeDYCAJrsPC/eUsfYZD9UT7TuBOmUIgFV5zeTQgRk6yLJKoc3aYR0gusJ0m+bG13B6qrDZ0SwPLe0/htHw==", - "dev": true, - "requires": { - "chalk": "^1.0.0", - "date-time": "^1.1.0", - "figures": "^1.0.0", - "hooker": "^0.2.3", - "number-is-nan": "^1.0.0", - "pretty-ms": "^2.1.0", - "text-table": "^0.2.0" - }, - "dependencies": { - "figures": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/figures/-/figures-1.7.0.tgz", - "integrity": "sha1-y+Hjr/zxzUS4DK3+0o3Hk6lwHS4=", - "dev": true, - "requires": { - "escape-string-regexp": "^1.0.5", - "object-assign": "^4.1.0" - } - } - } - }, - "time-zone": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/time-zone/-/time-zone-0.1.0.tgz", - "integrity": "sha1-Sncotqwo2w4Aj1FAQ/1VW9VXO0Y=", - "dev": true - }, "tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", @@ -7737,6 +7782,7 @@ "version": "2.4.3", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz", "integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==", + "dev": true, "requires": { "psl": "^1.1.24", "punycode": "^1.4.1" @@ -7745,7 +7791,8 @@ "punycode": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=" + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true } } }, @@ -7817,8 +7864,7 @@ "type-fest": { "version": "0.8.1", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==" }, "type-is": { "version": "1.6.18", @@ -7843,22 +7889,6 @@ "is-typedarray": "^1.0.0" } }, - "uc.micro": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-1.0.6.tgz", - "integrity": "sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==", - "dev": true - }, - "underscore.string": { - "version": "3.3.5", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.5.tgz", - "integrity": "sha512-g+dpmgn+XBneLmXXo+sGlW5xQEt4ErkS3mgeN2GFbremYeMBSJKr9Wf2KJplQVaiPY/f7FN6atosWYNm9ovrYg==", - "dev": true, - "requires": { - "sprintf-js": "^1.0.3", - "util-deprecate": "^1.0.2" - } - }, "unherit": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", @@ -7878,19 +7908,17 @@ } }, "unified": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", - "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-9.0.0.tgz", + "integrity": "sha512-ssFo33gljU3PdlWLjNp15Inqb77d6JnJSfyplGJPT/a+fNRNyCBeveBAYJdO5khKdF6WVHa/yYCC7Xl6BDwZUQ==", "dev": true, "requires": { - "@types/unist": "^2.0.0", - "@types/vfile": "^3.0.0", "bail": "^1.0.0", "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^2.0.0", "trough": "^1.0.0", - "vfile": "^3.0.0", - "x-is-string": "^0.1.0" + "vfile": "^4.0.0" } }, "uniq": { @@ -7900,27 +7928,27 @@ "dev": true }, "unist-util-find-all-after": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", - "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-3.0.1.tgz", + "integrity": "sha512-0GICgc++sRJesLwEYDjFVJPJttBpVQaTNgc6Jw0Jhzvfs+jtKePEMu+uD+PqkRUrAvGQqwhpDwLGWo1PK8PDEw==", "dev": true, "requires": { - "unist-util-is": "^3.0.0" + "unist-util-is": "^4.0.0" } }, "unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.0.2.tgz", + "integrity": "sha512-Ofx8uf6haexJwI1gxWMGg6I/dLnF2yE+KibhD3/diOqY2TinLcqHXCV6OI5gFVn3xQqDH+u0M625pfKwIwgBKQ==", "dev": true }, "unist-util-remove-position": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", - "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", + "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", "dev": true, "requires": { - "unist-util-visit": "^1.1.0" + "unist-util-visit": "^2.0.0" } }, "unist-util-stringify-position": { @@ -7933,21 +7961,24 @@ } }, "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.2.tgz", + "integrity": "sha512-HoHNhGnKj6y+Sq+7ASo2zpVdfdRifhTgX2KTU3B/sO/TTlZchp7E3S4vjRzDJ7L60KmrCPsQkVK3lEF3cz36XQ==", "dev": true, "requires": { - "unist-util-visit-parents": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" } }, "unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-3.0.2.tgz", + "integrity": "sha512-yJEfuZtzFpQmg1OSCyS9M5NJRrln/9FbYosH3iW0MG402QbdbaB8ZESwUv9RO6nRfLAKvWcMxCwdLWOov36x/g==", "dev": true, "requires": { - "unist-util-is": "^3.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0" } }, "universal-user-agent": { @@ -8029,10 +8060,9 @@ "integrity": "sha512-pW0No1RGHgzlpHJO1nsVrHKpOEIxkGg1xB+v0ZmdNH5OAeAwzAVrCnI2/6Mtx+Uys6iaylxa+D3g4j63IKKjSQ==" }, "v8-compile-cache": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.0.tgz", - "integrity": "sha512-usZBT3PW+LOjM25wbqIlZwPeJV+3OSz3M1k1Ws8snlW39dZyYL9lOGC5FgPVHfk0jKmjiDV8Z0mIbVQPiwFs7g==", - "dev": true + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz", + "integrity": "sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ==" }, "valid-url": { "version": "1.0.9", @@ -8064,38 +8094,22 @@ } }, "vfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", - "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.1.1.tgz", + "integrity": "sha512-lRjkpyDGjVlBA7cDQhQ+gNcvB1BGaTHYuSOcY3S7OhDmBtnzX95FhtZZDecSTDm6aajFymyve6S5DN4ZHGezdQ==", "dev": true, "requires": { + "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - }, - "dependencies": { - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true - }, - "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "dev": true, - "requires": { - "unist-util-stringify-position": "^1.1.1" - } - } + "unist-util-stringify-position": "^2.0.0", + "vfile-message": "^2.0.0" } }, "vfile-location": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.0.1.tgz", + "integrity": "sha512-yYBO06eeN/Ki6Kh1QAkgzYpWT1d3Qln+ZCtSbJqFExPl1S3y2qqotJQXoh6qEvl/jDlgpUJolBn3PItVnnZRqQ==", "dev": true }, "vfile-message": { @@ -8199,6 +8213,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", @@ -8220,8 +8240,7 @@ "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", - "dev": true + "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, "wordwrap": { "version": "0.0.3", @@ -8242,14 +8261,12 @@ "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=" }, "write": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, "requires": { "mkdirp": "^0.5.1" } @@ -8271,12 +8288,6 @@ "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.1.tgz", "integrity": "sha512-sucePNSafamSKoOqoNfBd8V0StlkzJKL2ZAhGQinCfNQ+oacw+Pk7lcdAElecBF2VkLNZRiIb5Oi1Q5lVUVt2A==" }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, "x-xss-protection": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/x-xss-protection/-/x-xss-protection-1.3.0.tgz", @@ -8308,12 +8319,12 @@ "dev": true }, "yaml": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.8.3.tgz", - "integrity": "sha512-X/v7VDnK+sxbQ2Imq4Jt2PRUsRsP7UcpSl3Llg6+NRRqWLIvxkMFYtH1FmvwNGYRKKPa+EPA4qDBlI9WVG1UKw==", + "version": "1.9.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.9.2.tgz", + "integrity": "sha512-HPT7cGGI0DuRcsO51qC1j9O16Dh1mZ2bnXwsi0jrSpsLz0WxOLSLXfkABVl6bZO629py3CU+OMJtpNHDLB97kg==", "dev": true, "requires": { - "@babel/runtime": "^7.8.7" + "@babel/runtime": "^7.9.2" } }, "yargs": { @@ -8476,9 +8487,9 @@ } }, "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==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -8549,9 +8560,9 @@ "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==", + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", "dev": true, "requires": { "cliui": "^5.0.0", @@ -8563,13 +8574,13 @@ "string-width": "^3.0.0", "which-module": "^2.0.0", "y18n": "^4.0.0", - "yargs-parser": "^13.1.1" + "yargs-parser": "^13.1.2" } }, "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", "dev": true, "requires": { "camelcase": "^5.0.0", @@ -8579,11 +8590,12 @@ } }, "yauzl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.4.1.tgz", - "integrity": "sha1-lSj0QtqxsihOWLQ3m7GU4i4MQAU=", + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", "requires": { - "fd-slicer": "~1.0.1" + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" } }, "yeast": { diff --git a/package.json b/package.json index 317969ee83..5b9562d5d6 100644 --- a/package.json +++ b/package.json @@ -1,83 +1,96 @@ { - "name": "magicmirror", - "version": "2.11.0", - "description": "The open source modular smart mirror platform.", - "main": "js/electron.js", - "scripts": { - "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", - "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", - "test:lint": "grunt --env=test", - "config:check": "node tests/configs/check_config.js", - "lint": "grunt --env=lint" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/MichMich/MagicMirror.git" - }, - "keywords": [ - "magic mirror", - "smart mirror", - "mirror UI", - "modular" - ], - "author": "Michael Teeuw", - "contributors": [ - "https://github.com/MichMich/MagicMirror/graphs/contributors" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/MichMich/MagicMirror/issues" - }, - "homepage": "https://magicmirror.builders", - "devDependencies": { - "chai": "^4.1.2", - "chai-as-promised": "^7.1.1", - "current-week-number": "^1.0.7", - "danger": "^3.1.3", - "grunt": "latest", - "grunt-eslint": "latest", - "grunt-jsonlint": "latest", - "grunt-markdownlint": "latest", - "grunt-stylelint": "latest", - "grunt-yamllint": "latest", - "http-auth": "^3.2.3", - "jsdom": "^11.6.2", - "mocha": "^7.0.0", - "mocha-each": "^1.1.0", - "mocha-logger": "^1.0.6", - "spectron": "^8.0.0", - "stylelint": "latest", - "stylelint-config-standard": "latest", - "time-grunt": "latest" - }, - "optionalDependencies": { - "electron": "^6.1.7" - }, - "dependencies": { - "colors": "^1.1.2", - "console-stamp": "^0.2.9", - "express": "^4.16.2", - "express-ipfilter": "^1.0.1", - "feedme": "latest", - "helmet": "^3.21.2", - "iconv-lite": "latest", - "lodash": "^4.17.15", - "module-alias": "^2.2.2", - "moment": "latest", - "request": "^2.88.0", - "rrule": "^2.6.2", - "rrule-alt": "^2.2.8", - "simple-git": "^1.85.0", - "socket.io": "^2.1.1", - "valid-url": "latest" - }, - "_moduleAliases": { - "node_helper": "js/node_helper.js" - } + "name": "magicmirror", + "version": "2.12.0", + "description": "The open source modular smart mirror platform.", + "main": "js/electron.js", + "scripts": { + "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", + "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", + "test:prettier": "prettier --check **/*.{js,css,json,md,yml}", + "test:js": "eslint *.js js/**/*.js modules/default/**/*.js clientonly/*.js serveronly/*.js translations/*.js vendor/*.js tests/**/*.js config/* --config .eslintrc.json --quiet", + "test:css": "stylelint css/main.css modules/default/**/*.css --config .stylelintrc.json", + "test:calendar": "node ./modules/default/calendar/debug.js", + "config:check": "node js/check_config.js", + "lint:prettier": "prettier --write **/*.{js,css,json,md,yml}", + "lint:js": "eslint *.js js/**/*.js modules/default/**/*.js clientonly/*.js serveronly/*.js translations/*.js vendor/*.js tests/**/*.js config/* --config .eslintrc.json --fix", + "lint:css": "stylelint css/main.css modules/default/**/*.css --config .stylelintrc.json --fix" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/MichMich/MagicMirror.git" + }, + "keywords": [ + "magic mirror", + "smart mirror", + "mirror UI", + "modular" + ], + "author": "Michael Teeuw", + "contributors": [ + "https://github.com/MichMich/MagicMirror/graphs/contributors" + ], + "license": "MIT", + "bugs": { + "url": "https://github.com/MichMich/MagicMirror/issues" + }, + "homepage": "https://magicmirror.builders", + "devDependencies": { + "@prantlf/jsonlint": "^10.2.0", + "chai": "^4.2.0", + "chai-as-promised": "^7.1.1", + "current-week-number": "^1.0.7", + "danger": "^3.1.3", + "eslint-config-prettier": "^6.11.0", + "eslint-plugin-prettier": "^3.1.4", + "http-auth": "^3.2.3", + "husky": "^4.2.5", + "jsdom": "^11.6.2", + "mocha": "^7.1.2", + "mocha-each": "^2.0.1", + "mocha-logger": "^1.0.6", + "prettier": "^2.0.5", + "pretty-quick": "^2.0.1", + "spectron": "^8.0.0", + "stylelint": "^13.6.1", + "stylelint-config-prettier": "^8.0.2", + "stylelint-config-standard": "^20.0.0", + "stylelint-prettier": "^1.1.2" + }, + "optionalDependencies": { + "electron": "^6.1.7" + }, + "dependencies": { + "colors": "^1.1.2", + "console-stamp": "^0.2.9", + "eslint": "^7.3.0", + "express": "^4.16.2", + "express-ipfilter": "^1.0.1", + "feedme": "latest", + "helmet": "^3.21.2", + "ical": "^0.8.0", + "iconv-lite": "latest", + "lodash": "^4.17.15", + "module-alias": "^2.2.2", + "moment": "latest", + "request": "^2.88.2", + "rrule": "^2.6.2", + "rrule-alt": "^2.2.8", + "simple-git": "^1.85.0", + "socket.io": "^2.1.1", + "valid-url": "latest" + }, + "_moduleAliases": { + "node_helper": "js/node_helper.js" + }, + "husky": { + "hooks": { + "pre-commit": "pretty-quick --staged" + } + } } diff --git a/serveronly/index.js b/serveronly/index.js index f7da58f5f4..9cc7d9425f 100644 --- a/serveronly/index.js +++ b/serveronly/index.js @@ -1,6 +1,8 @@ -var app = require("../js/app.js"); -app.start(function(config) { +const app = require("../js/app.js"); +const Log = require("../js/logger.js"); + +app.start(function (config) { var bindAddress = config.address ? config.address : "localhost"; var httpType = config.useHttps ? "https" : "http"; - console.log("\nReady to go! Please point your browser to: " + httpType + "://" + bindAddress + ":" + config.port); + Log.log("\nReady to go! Please point your browser to: " + httpType + "://" + bindAddress + ":" + config.port); }); diff --git a/tests/configs/check_config.js b/tests/configs/check_config.js deleted file mode 100644 index 917b6d32e4..0000000000 --- a/tests/configs/check_config.js +++ /dev/null @@ -1,72 +0,0 @@ -/* Magic Mirror - * - * Checker configuration file - * - * By Rodrigo Ramírez Norambuena - * https://rodrigoramirez.com - * - * MIT Licensed. - * - */ - -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"); - -/* getConfigFile() - * Return string with path of configuration file - * Check if set by environment variable MM_CONFIG_FILE - */ -function getConfigFile() { - // FIXME: This function should be in core. Do you want refactor me ;) ?, be good! - rootPath = path.resolve(__dirname + "/../../"); - var configFileName = path.resolve(rootPath + "/config/config.js"); - if (process.env.MM_CONFIG_FILE) { - configFileName = path.resolve(process.env.MM_CONFIG_FILE); - } - return configFileName; -} - -function checkConfigFile() { - var configFileName = getConfigFile(); - // Check if file is present - if (fs.existsSync(configFileName) === false) { - console.error(Utils.colors.error("File not found: "), configFileName); - return; - } - // check permission - try { - fs.accessSync(configFileName, fs.F_OK); - } catch (e) { - console.log(Utils.colors.error(e)); - return; - } - - // Validate syntax of the configuration file. - // In case the there errors show messages and - // return - console.info(Utils.colors.info("Checking file... ", configFileName)); - // I'm not sure if all ever is utf-8 - fs.readFile(configFileName, "utf-8", function (err, data) { - if (err) { throw err; } - const messages = linter.verify(data, config); - if (messages.length === 0) { - console.log("Your configuration file doesn't contain syntax errors :)"); - return true; - } else { - errors = messages; - for (var idx in errors) { - error = errors[idx]; - console.log("Line", error.line, "col", error.column, error.message); - } - } - }); -} - -if (process.env.NODE_ENV !== "test") { - checkConfigFile(); -} diff --git a/tests/configs/data/StripComments.json b/tests/configs/data/StripComments.json index 62d5d61866..e9d1c403c1 100644 --- a/tests/configs/data/StripComments.json +++ b/tests/configs/data/StripComments.json @@ -1,13 +1,13 @@ { - // Escaped - "FOO\"BAR": "Today", + // Escaped + "FOO\"BAR": "Today", - /* - * The following lines - * represent cardinal directions - */ - "N": "N", - "E": "E", - "S": "S", - "W": "W" + /* + * The following lines + * represent cardinal directions + */ + "N": "N", + "E": "E", + "S": "S", + "W": "W" } diff --git a/tests/configs/data/TranslationTest.json b/tests/configs/data/TranslationTest.json index bbb138453c..8a24a16fb3 100644 --- a/tests/configs/data/TranslationTest.json +++ b/tests/configs/data/TranslationTest.json @@ -1,33 +1,33 @@ { - "LOADING": "Loading …", + "LOADING": "Loading …", - "TODAY": "Today", - "TOMORROW": "Tomorrow", - "DAYAFTERTOMORROW": "In 2 days", - "RUNNING": "Ends in", - "EMPTY": "No upcoming events.", + "TODAY": "Today", + "TOMORROW": "Tomorrow", + "DAYAFTERTOMORROW": "In 2 days", + "RUNNING": "Ends in", + "EMPTY": "No upcoming events.", - "WEEK": "Week {weekNumber}", + "WEEK": "Week {weekNumber}", - "N": "N", - "NNE": "NNE", - "NE": "NE", - "ENE": "ENE", - "E": "E", - "ESE": "ESE", - "SE": "SE", - "SSE": "SSE", - "S": "S", - "SSW": "SSW", - "SW": "SW", - "WSW": "WSW", - "W": "W", - "WNW": "WNW", - "NW": "NW", - "NNW": "NNW", + "N": "N", + "NNE": "NNE", + "NE": "NE", + "ENE": "ENE", + "E": "E", + "ESE": "ESE", + "SE": "SE", + "SSE": "SSE", + "S": "S", + "SSW": "SSW", + "SW": "SW", + "WSW": "WSW", + "W": "W", + "WNW": "WNW", + "NW": "NW", + "NNW": "NNW", - "UPDATE_NOTIFICATION": "MagicMirror² update available.", - "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.", - "UPDATE_INFO_SINGLE": "The current installation is COMMIT_COUNT commit behind on the BRANCH_NAME branch.", - "UPDATE_INFO_MULTIPLE": "The current installation is COMMIT_COUNT commits behind on the BRANCH_NAME branch." + "UPDATE_NOTIFICATION": "MagicMirror² update available.", + "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.", + "UPDATE_INFO_SINGLE": "The current installation is COMMIT_COUNT commit behind on the BRANCH_NAME branch.", + "UPDATE_INFO_MULTIPLE": "The current installation is COMMIT_COUNT commits behind on the BRANCH_NAME branch." } diff --git a/tests/configs/data/en.json b/tests/configs/data/en.json index bbb138453c..8a24a16fb3 100644 --- a/tests/configs/data/en.json +++ b/tests/configs/data/en.json @@ -1,33 +1,33 @@ { - "LOADING": "Loading …", + "LOADING": "Loading …", - "TODAY": "Today", - "TOMORROW": "Tomorrow", - "DAYAFTERTOMORROW": "In 2 days", - "RUNNING": "Ends in", - "EMPTY": "No upcoming events.", + "TODAY": "Today", + "TOMORROW": "Tomorrow", + "DAYAFTERTOMORROW": "In 2 days", + "RUNNING": "Ends in", + "EMPTY": "No upcoming events.", - "WEEK": "Week {weekNumber}", + "WEEK": "Week {weekNumber}", - "N": "N", - "NNE": "NNE", - "NE": "NE", - "ENE": "ENE", - "E": "E", - "ESE": "ESE", - "SE": "SE", - "SSE": "SSE", - "S": "S", - "SSW": "SSW", - "SW": "SW", - "WSW": "WSW", - "W": "W", - "WNW": "WNW", - "NW": "NW", - "NNW": "NNW", + "N": "N", + "NNE": "NNE", + "NE": "NE", + "ENE": "ENE", + "E": "E", + "ESE": "ESE", + "SE": "SE", + "SSE": "SSE", + "S": "S", + "SSW": "SSW", + "SW": "SW", + "WSW": "WSW", + "W": "W", + "WNW": "WNW", + "NW": "NW", + "NNW": "NNW", - "UPDATE_NOTIFICATION": "MagicMirror² update available.", - "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.", - "UPDATE_INFO_SINGLE": "The current installation is COMMIT_COUNT commit behind on the BRANCH_NAME branch.", - "UPDATE_INFO_MULTIPLE": "The current installation is COMMIT_COUNT commits behind on the BRANCH_NAME branch." + "UPDATE_NOTIFICATION": "MagicMirror² update available.", + "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.", + "UPDATE_INFO_SINGLE": "The current installation is COMMIT_COUNT commit behind on the BRANCH_NAME branch.", + "UPDATE_INFO_MULTIPLE": "The current installation is COMMIT_COUNT commits behind on the BRANCH_NAME branch." } diff --git a/tests/configs/data/feed_test_rodrigoramirez.xml b/tests/configs/data/feed_test_rodrigoramirez.xml index e4d3730fa9..dbce18e99e 100644 --- a/tests/configs/data/feed_test_rodrigoramirez.xml +++ b/tests/configs/data/feed_test_rodrigoramirez.xml @@ -79,19 +79,19 @@

Starting virtual machine ... VirtualBox

Ninguna, pero ninguna maquina arrancó, se quedaban en ese mensaje. Fue de esos instantes en que sudas helado … 😉

Con un poco de investigación fue a parar al archivo ~/.VirtualBox/VBoxSVC.log que indicaba

-
$ tail -f ~/.VirtualBox/VBoxSVC.log
- 00:08:32.932717 nspr-7 Failed to open "/dev/vboxdrvu", errno=13, rc=VERR_VM_DRIVER_NOT_ACCESSIBLE
+
$ tail -f ~/.VirtualBox/VBoxSVC.log
+ 00:08:32.932717 nspr-7 Failed to open "/dev/vboxdrvu", errno=13, rc=VERR_VM_DRIVER_NOT_ACCESSIBLE
  00:08:33.555836 nspr-6 Failed to open "/dev/vboxdrvu", errno=13, rc=VERR_VM_DRIVER_NOT_ACCESSIBLE

 

Fui… algo de donde agarrarse. Mirando un poco mas se trataba de problemas con los permisos al vboxdrvu, mirando indicaba que tenía 0600.

 

-
$ ls -lh /dev/vboxdrvu 
+
$ ls -lh /dev/vboxdrvu 
  crw------- 1 root root 10, 56 Sep 10 12:47 /dev/vboxdrvu

 

El tema es que deben estar en 0666,  le cambias los permisos y eso soluciona el problema 🙂

-
-$ sudo chmod 0666 /dev/vboxdrvu
-$ ls -lh /dev/vboxdrvu
+
+$ sudo chmod 0666 /dev/vboxdrvu
+$ ls -lh /dev/vboxdrvu
  crw-rw-rw- 1 root root 10, 56 Sep 10 12:47 /dev/vboxdrvu

La entrada Problema VirtualBox “starting virtual machine” … aparece primero en Rodrigo Ramírez Norambuena.

]]> @@ -236,17 +236,17 @@ $ ls -lh /dev/vboxdrvu

El problema para mi es que algunos sistemas de maquinas virtuales no asignan por defecto un espacio para la Swap, lo que te lleva a que el sistema pueda tener crash durante la ejecución.

Para comprobar la asignación de memoria, al ejecutar el comando free nos debería mostrar como algo similar a lo siguiente

 

-
$  free -m
-             total       used       free     shared    buffers     cached
-Mem:           494        488          6          1         54         75
--/+ buffers/cache:        357        136
+
$  free -m
+             total       used       free     shared    buffers     cached
+Mem:           494        488          6          1         54         75
+-/+ buffers/cache:        357        136
 Swap:            0          0          0

En la zona de swap indica que no asignada, valor 0.

Para asignar swap al sistema se debe  un archivo en disco para que sea utilizado como espacio de intercambio, en este caso lo vamos  crear uno  de 3GB en la raíz del sistema

fallocate -l 3G /swapfile

Comprobamos que ha sido creado

-
$ ls -lh /swapfile
--rw-r--r-- 1 root root 3.0G Jul 11 13:10 /swapfile
+
$ ls -lh /swapfile
+-rw-r--r-- 1 root root 3.0G Jul 11 13:10 /swapfile
 

Habilitación del archivo Swap

Ahora nos toca habilitar el archivo creado. Para eso le asignaremos los permisos

@@ -256,10 +256,10 @@ Swap:            0          0          0

Para habilitar y asignarla eso como memoria swap al sistema usamos

swapon /swapfile

Ya con esto podrémos ver en nuestro sistema la memoria asignada para swap

-
$ free -m
-             total       used       free     shared    buffers     cached
-Mem:           494        486          7          1         51         77
--/+ buffers/cache:        358        136
+
$ free -m
+             total       used       free     shared    buffers     cached
+Mem:           494        486          7          1         51         77
+-/+ buffers/cache:        358        136
 Swap:         3071          0       3071

 

Para que al reiniciar el sistema esto se mantenga, debemos agregar la siguiente línea al archivo /etc/fstab

@@ -323,7 +323,7 @@ Swap:         3071          0       3071
Días atrás estuve participando en el evento llamado Nerdearla en Buenos Aires.  El ambiente era genial si eres de esas personas que desde niño sintio curiosidad por ver como funcionan las cosas, donde desarmabas para volver armar lo juguetes. Habían muchas cosas interesantes tanto en las presentaciones, co-working y workshop que se hubieron. Si te […]

La entrada Nerdearla 2016, WebRTC Glue aparece primero en Rodrigo Ramírez Norambuena.

]]>
- Días atrás estuve participando en el evento llamado Nerdearla en Buenos Aires.  El ambiente era genial si eres de esas personas que desde niño sintio curiosidad por ver como funcionan las cosas, donde desarmabas para volver armar lo juguetes.

+ Días atrás estuve participando en el evento llamado Nerdearla en Buenos Aires.  El ambiente era genial si eres de esas personas que desde niño sintio curiosidad por ver como funcionan las cosas, donde desarmabas para volver armar lo juguetes.

Habían muchas cosas interesantes tanto en las presentaciones, co-working y workshop que se hubieron. Si te lo perdiste te recomiendo que estés pendiente para el proximo año.

 

Te podias encontrar con una nuestra como estaKaypro II

@@ -357,7 +357,7 @@ Swap:         3071          0       3071
- http://rodrigoramirez.com/?p=1206 + https://rodrigoramirez.com/?p=1206 El Panel monitor callcenter para colas de Asterisk ya cuenta con una nueva versión, la 0.9.0 Para instalar esta nueva versión, debes visitar la siguiente URL https://github.com/roramirez/qpanel/tree/0.9.0 Esta versión versión nos preocupamos de realizar mejoras y refactorizaciones en el codigo para dar un mejor rendimiento, como también de la compatibilidad con la versión 11 de […]

La entrada QPanel 0.9.0 aparece primero en Rodrigo Ramírez Norambuena.

]]>
@@ -394,7 +394,7 @@ Swap:         3071          0       3071
- http://rodrigoramirez.com/?p=1172 + https://rodrigoramirez.com/?p=1172 Dejo esto por acá ya que es algo que siempre me olvido como es. El tema es enviar un email mediante el comando mail en un servidor con Linux. Si usas mail a secas te va pidiendo los datos para crear el correo, principalmente el body del correo. Para automatizar esto a través de un […]

La entrada Mandar un email desde la shell aparece primero en Rodrigo Ramírez Norambuena.

]]>
diff --git a/tests/configs/empty_ipWhiteList.js b/tests/configs/empty_ipWhiteList.js index 232836c311..991ca8e5f7 100644 --- a/tests/configs/empty_ipWhiteList.js +++ b/tests/configs/empty_ipWhiteList.js @@ -13,13 +13,14 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, - modules: [ - ] + modules: [] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/env.js b/tests/configs/env.js index ef244c393b..998c1b8dfd 100644 --- a/tests/configs/env.js +++ b/tests/configs/env.js @@ -13,13 +13,14 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, - modules: [ - ] + modules: [] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/auth-default.js b/tests/configs/modules/calendar/auth-default.js index 3fee5015c2..19259119ce 100644 --- a/tests/configs/modules/calendar/auth-default.js +++ b/tests/configs/modules/calendar/auth-default.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -38,4 +38,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/basic-auth.js b/tests/configs/modules/calendar/basic-auth.js index 1b21010216..cd6a069543 100644 --- a/tests/configs/modules/calendar/basic-auth.js +++ b/tests/configs/modules/calendar/basic-auth.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -39,4 +39,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/default.js b/tests/configs/modules/calendar/default.js index 3f70d930dd..9fecc1f9ec 100644 --- a/tests/configs/modules/calendar/default.js +++ b/tests/configs/modules/calendar/default.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -34,4 +34,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/fail-basic-auth.js b/tests/configs/modules/calendar/fail-basic-auth.js index ad22046a20..922c3cdb42 100644 --- a/tests/configs/modules/calendar/fail-basic-auth.js +++ b/tests/configs/modules/calendar/fail-basic-auth.js @@ -15,8 +15,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -41,4 +41,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/old-basic-auth.js b/tests/configs/modules/calendar/old-basic-auth.js index 76e2df3a09..b580be9280 100644 --- a/tests/configs/modules/calendar/old-basic-auth.js +++ b/tests/configs/modules/calendar/old-basic-auth.js @@ -1,5 +1,5 @@ /* Magic Mirror Test config default calendar - * with authenticacion old config + * with authentication old config * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -36,4 +36,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_12hr.js b/tests/configs/modules/clock/clock_12hr.js index 31f9e4ea2a..d938fc5df9 100644 --- a/tests/configs/modules/clock/clock_12hr.js +++ b/tests/configs/modules/clock/clock_12hr.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -26,4 +26,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_24hr.js b/tests/configs/modules/clock/clock_24hr.js index e5dd89f6e0..cd47d14b5f 100644 --- a/tests/configs/modules/clock/clock_24hr.js +++ b/tests/configs/modules/clock/clock_24hr.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -26,4 +26,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_displaySeconds_false.js b/tests/configs/modules/clock/clock_displaySeconds_false.js index 91bbebba90..5e2a1d3f4d 100644 --- a/tests/configs/modules/clock/clock_displaySeconds_false.js +++ b/tests/configs/modules/clock/clock_displaySeconds_false.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -29,4 +29,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_showPeriodUpper.js b/tests/configs/modules/clock/clock_showPeriodUpper.js index e7ee7d0ad7..a001f6bc2a 100644 --- a/tests/configs/modules/clock/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/clock_showPeriodUpper.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -29,4 +29,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_showWeek.js b/tests/configs/modules/clock/clock_showWeek.js index 8a5f305aba..dc36d7d497 100644 --- a/tests/configs/modules/clock/clock_showWeek.js +++ b/tests/configs/modules/clock/clock_showWeek.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -29,4 +29,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/es/clock_12hr.js b/tests/configs/modules/clock/es/clock_12hr.js index d546e6085a..4b0f7f8362 100644 --- a/tests/configs/modules/clock/es/clock_12hr.js +++ b/tests/configs/modules/clock/es/clock_12hr.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -26,4 +26,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/es/clock_24hr.js b/tests/configs/modules/clock/es/clock_24hr.js index abdf7a446d..ae5b2e24e1 100644 --- a/tests/configs/modules/clock/es/clock_24hr.js +++ b/tests/configs/modules/clock/es/clock_24hr.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -26,4 +26,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/es/clock_showPeriodUpper.js b/tests/configs/modules/clock/es/clock_showPeriodUpper.js index 6bb396dbf0..7aac8efea9 100644 --- a/tests/configs/modules/clock/es/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/es/clock_showPeriodUpper.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -29,4 +29,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/es/clock_showWeek.js b/tests/configs/modules/clock/es/clock_showWeek.js index 29550f04ab..1c20388d4d 100644 --- a/tests/configs/modules/clock/es/clock_showWeek.js +++ b/tests/configs/modules/clock/es/clock_showWeek.js @@ -1,7 +1,4 @@ - -/* Magic Mirror - * - * Test config for default clock module +/* Magic Mirror Test config for default clock module * Language es for showWeek feature * * By Rodrigo Ramírez Norambuena @@ -19,8 +16,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -35,4 +32,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_anytime.js b/tests/configs/modules/compliments/compliments_anytime.js index 1d2818bc95..9b0ab3407c 100644 --- a/tests/configs/modules/compliments/compliments_anytime.js +++ b/tests/configs/modules/compliments/compliments_anytime.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -27,7 +27,6 @@ var config = { afternoon: [], evening: [], anytime: ["Anytime here"] - } } } @@ -35,4 +34,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js index 7ea984b15b..919754109f 100644 --- a/tests/configs/modules/compliments/compliments_date.js +++ b/tests/configs/modules/compliments/compliments_date.js @@ -14,8 +14,8 @@ let config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -28,9 +28,7 @@ let config = { morning: [], afternoon: [], evening: [], - "....-01-01": [ - "Happy new year!" - ] + "....-01-01": ["Happy new year!"] } } } @@ -38,4 +36,6 @@ let config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_only_anytime.js b/tests/configs/modules/compliments/compliments_only_anytime.js index f01896528d..47c22480e2 100644 --- a/tests/configs/modules/compliments/compliments_only_anytime.js +++ b/tests/configs/modules/compliments/compliments_only_anytime.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -24,7 +24,6 @@ var config = { config: { compliments: { anytime: ["Anytime here"] - } } } @@ -32,4 +31,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_parts_day.js b/tests/configs/modules/compliments/compliments_parts_day.js index b444356735..0976622718 100644 --- a/tests/configs/modules/compliments/compliments_parts_day.js +++ b/tests/configs/modules/compliments/compliments_parts_day.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -23,15 +23,9 @@ var config = { position: "middle_center", config: { compliments: { - morning: [ - "Hi", "Good Morning", "Morning test" - ], - afternoon: [ - "Hello", "Good Afternoon", "Afternoon test" - ], - evening: [ - "Hello There", "Good Evening", "Evening test" - ] + morning: ["Hi", "Good Morning", "Morning test"], + afternoon: ["Hello", "Good Afternoon", "Afternoon test"], + evening: ["Hello There", "Good Evening", "Evening test"] } } } @@ -39,4 +33,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/helloworld/helloworld.js b/tests/configs/modules/helloworld/helloworld.js index 6b617cf261..17603be139 100644 --- a/tests/configs/modules/helloworld/helloworld.js +++ b/tests/configs/modules/helloworld/helloworld.js @@ -13,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -29,4 +29,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/helloworld/helloworld_default.js b/tests/configs/modules/helloworld/helloworld_default.js index 710000f0a7..1218ec80c6 100644 --- a/tests/configs/modules/helloworld/helloworld_default.js +++ b/tests/configs/modules/helloworld/helloworld_default.js @@ -1,6 +1,4 @@ -/* Magic Mirror - * - * Test config sample module hello world default config +/* Magic Mirror Test config sample module hello world default config * * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. @@ -15,8 +13,8 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -28,4 +26,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/newsfeed/default.js b/tests/configs/modules/newsfeed/default.js index 5cb9d31170..3da874cf90 100644 --- a/tests/configs/modules/newsfeed/default.js +++ b/tests/configs/modules/newsfeed/default.js @@ -13,13 +13,12 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ { - module: "newsfeed", position: "bottom_bar", config: { @@ -27,7 +26,7 @@ var config = { { title: "Rodrigo Ramirez Blog", url: "http://localhost:8080/tests/configs/data/feed_test_rodrigoramirez.xml" - }, + } ] } } @@ -35,4 +34,6 @@ var config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js index d56fab913b..bbb07da8b3 100644 --- a/tests/configs/modules/positions.js +++ b/tests/configs/modules/positions.js @@ -9,24 +9,22 @@ var config = { port: 8080, ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], - ipWhitelist: [], language: "en", timeFormat: 24, units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, + modules: // Using exotic content. This is why dont accept go to JSON configuration file - (function() { - var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", - "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", - "bottom_bar", "fullscreen_above", "fullscreen_below"]; + (function () { + var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; var modules = Array(); - for (idx in positions) { + for (var idx in positions) { modules.push({ module: "helloworld", position: positions[idx], @@ -36,7 +34,9 @@ var config = { }); } return modules; - })(), + })() }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/currentweather_default.js b/tests/configs/modules/weather/currentweather_default.js index d52a7962e5..57ce23e436 100644 --- a/tests/configs/modules/weather/currentweather_default.js +++ b/tests/configs/modules/weather/currentweather_default.js @@ -14,8 +14,8 @@ let config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -32,4 +32,6 @@ let config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/currentweather_options.js b/tests/configs/modules/weather/currentweather_options.js index abea5bd1a0..3c9021f548 100644 --- a/tests/configs/modules/weather/currentweather_options.js +++ b/tests/configs/modules/weather/currentweather_options.js @@ -14,8 +14,8 @@ let config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -28,6 +28,7 @@ let config = { initialLoadDelay: 3000, useBeaufort: false, showWindDirectionAsArrow: true, + showSun: false, showHumidity: true, roundTemp: true, degreeLabel: true @@ -37,4 +38,6 @@ let config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/currentweather_units.js b/tests/configs/modules/weather/currentweather_units.js index e7ad1dbce2..f7303784d3 100644 --- a/tests/configs/modules/weather/currentweather_units.js +++ b/tests/configs/modules/weather/currentweather_units.js @@ -14,8 +14,8 @@ let config = { units: "imperial", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -34,4 +34,6 @@ let config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/forecastweather_default.js b/tests/configs/modules/weather/forecastweather_default.js index c87ca260c6..ad4aff7663 100644 --- a/tests/configs/modules/weather/forecastweather_default.js +++ b/tests/configs/modules/weather/forecastweather_default.js @@ -14,8 +14,8 @@ let config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -34,4 +34,6 @@ let config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/forecastweather_options.js b/tests/configs/modules/weather/forecastweather_options.js index 82e3da08a3..877c4ac6b0 100644 --- a/tests/configs/modules/weather/forecastweather_options.js +++ b/tests/configs/modules/weather/forecastweather_options.js @@ -14,8 +14,8 @@ let config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, modules: [ @@ -37,4 +37,6 @@ let config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/noIpWhiteList.js b/tests/configs/noIpWhiteList.js index 79366e099e..68c711e63e 100644 --- a/tests/configs/noIpWhiteList.js +++ b/tests/configs/noIpWhiteList.js @@ -13,13 +13,14 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, - modules: [ - ] + modules: [] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/port_8090.js b/tests/configs/port_8090.js index d1dc546f96..433508df18 100644 --- a/tests/configs/port_8090.js +++ b/tests/configs/port_8090.js @@ -13,13 +13,14 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } }, - modules: [ - ] + modules: [] }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/without_modules.js b/tests/configs/without_modules.js index 921e71d762..051b350972 100644 --- a/tests/configs/without_modules.js +++ b/tests/configs/without_modules.js @@ -13,11 +13,12 @@ var config = { units: "metric", electronOptions: { webPreferences: { - nodeIntegration: true, - }, + nodeIntegration: true + } } - }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/e2e/dev_console.js b/tests/e2e/dev_console.js index 42f8ac99f9..4e5d1ca197 100644 --- a/tests/e2e/dev_console.js +++ b/tests/e2e/dev_console.js @@ -4,58 +4,59 @@ const expect = require("chai").expect; const describe = global.describe; const it = global.it; -describe("Development console tests", function() { - // This tests fail and crash another tests +describe("Development console tests", function () { + // FIXME: This tests fail and crash another tests // Suspect problem with window focus - // FIXME return false; + /* eslint-disable */ helpers.setupTimeout(this); var app = null; - before(function() { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/env.js"; }); - describe("Without 'dev' commandline argument", function() { - before(function() { + describe("Without 'dev' commandline argument", function () { + before(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - after(function() { + after(function () { return helpers.stopApplication(app); }); - it("should not open dev console when absent", function() { + it("should not open dev console when absent", function () { return expect(app.browserWindow.isDevToolsOpened()).to.eventually.equal(false); }); }); - describe("With 'dev' commandline argument", function() { - before(function() { + describe("With 'dev' commandline argument", function () { + before(function () { return helpers .startApplication({ args: ["js/electron.js", "dev"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - after(function() { + after(function () { return helpers.stopApplication(app); }); - it("should open dev console when provided", function() { + it("should open dev console when provided", function () { return expect(app.browserWindow.isDevToolsOpened()).to.eventually.equal(true); }); }); + /* eslint-enable */ }); diff --git a/tests/e2e/env_spec.js b/tests/e2e/env_spec.js index 73784e96bc..7fef9f3c73 100644 --- a/tests/e2e/env_spec.js +++ b/tests/e2e/env_spec.js @@ -7,59 +7,61 @@ const it = global.it; const beforeEach = global.beforeEach; const afterEach = global.afterEach; -describe("Electron app environment", function() { +describe("Electron app environment", function () { helpers.setupTimeout(this); var app = null; - before(function() { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/env.js"; }); - beforeEach(function() { + beforeEach(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); - it("should open a browserwindow", function() { - return app.client - .waitUntilWindowLoaded() - // .browserWindow.focus() - .getWindowCount() - .should.eventually.equal(1) - .browserWindow.isMinimized() - .should.eventually.be.false.browserWindow.isDevToolsOpened() - .should.eventually.be.false.browserWindow.isVisible() - .should.eventually.be.true.browserWindow.isFocused() - .should.eventually.be.true.browserWindow.getBounds() - .should.eventually.have.property("width") - .and.be.above(0) - .browserWindow.getBounds() - .should.eventually.have.property("height") - .and.be.above(0) - .browserWindow.getTitle() - .should.eventually.equal("MagicMirror²"); + it("should open a browserwindow", function () { + return ( + app.client + .waitUntilWindowLoaded() + // .browserWindow.focus() + .getWindowCount() + .should.eventually.equal(1) + .browserWindow.isMinimized() + .should.eventually.be.false.browserWindow.isDevToolsOpened() + .should.eventually.be.false.browserWindow.isVisible() + .should.eventually.be.true.browserWindow.isFocused() + .should.eventually.be.true.browserWindow.getBounds() + .should.eventually.have.property("width") + .and.be.above(0) + .browserWindow.getBounds() + .should.eventually.have.property("height") + .and.be.above(0) + .browserWindow.getTitle() + .should.eventually.equal("MagicMirror²") + ); }); - it("get request from http://localhost:8080 should return 200", function(done) { - request.get("http://localhost:8080", function(err, res, body) { + it("get request from http://localhost:8080 should return 200", function (done) { + request.get("http://localhost:8080", function (err, res, body) { expect(res.statusCode).to.equal(200); done(); }); }); - it("get request from http://localhost:8080/nothing should return 404", function(done) { - request.get("http://localhost:8080/nothing", function(err, res, body) { + it("get request from http://localhost:8080/nothing should return 404", function (done) { + request.get("http://localhost:8080/nothing", function (err, res, body) { expect(res.statusCode).to.equal(404); done(); }); diff --git a/tests/e2e/fonts.js b/tests/e2e/fonts.js index 7df36ad805..d6c69e502b 100644 --- a/tests/e2e/fonts.js +++ b/tests/e2e/fonts.js @@ -5,9 +5,10 @@ const forEach = require("mocha-each"); const describe = global.describe; -describe("All font files from roboto.css should be downloadable", function() { +describe("All font files from roboto.css should be downloadable", function () { helpers.setupTimeout(this); + var app; var fontFiles = []; // Statements below filters out all 'url' lines in the CSS file var fileContent = require("fs").readFileSync(__dirname + "/../../fonts/roboto.css", "utf8"); @@ -20,7 +21,7 @@ describe("All font files from roboto.css should be downloadable", function() { match = regex.exec(fileContent); } - before(function() { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/without_modules.js"; @@ -28,18 +29,18 @@ describe("All font files from roboto.css should be downloadable", function() { .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - after(function() { + after(function () { return helpers.stopApplication(app); }); forEach(fontFiles).it("should return 200 HTTP code for file '%s'", (fontFile, done) => { var fontUrl = "http://localhost:8080/fonts/" + fontFile; - request.get(fontUrl, function(err, res, body) { + request.get(fontUrl, function (err, res, body) { expect(res.statusCode).to.equal(200); done(); }); diff --git a/tests/e2e/global-setup.js b/tests/e2e/global-setup.js index c4b170fe29..cce9fc05be 100644 --- a/tests/e2e/global-setup.js +++ b/tests/e2e/global-setup.js @@ -6,7 +6,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. * -*/ + */ const Application = require("spectron").Application; const assert = require("assert"); @@ -14,12 +14,12 @@ const chai = require("chai"); const chaiAsPromised = require("chai-as-promised"); const path = require("path"); -global.before(function() { +global.before(function () { chai.should(); chai.use(chaiAsPromised); }); -exports.getElectronPath = function() { +exports.getElectronPath = function () { var electronPath = path.join(__dirname, "..", "..", "node_modules", ".bin", "electron"); if (process.platform === "win32") { electronPath += ".cmd"; @@ -28,7 +28,7 @@ exports.getElectronPath = function() { }; // Set timeout - if this is run within Travis, increase timeout -exports.setupTimeout = function(test) { +exports.setupTimeout = function (test) { if (process.env.CI) { test.timeout(30000); } else { @@ -36,26 +36,26 @@ exports.setupTimeout = function(test) { } }; -exports.startApplication = function(options) { +exports.startApplication = function (options) { options.path = exports.getElectronPath(); if (process.env.CI) { options.startTimeout = 30000; } var app = new Application(options); - return app.start().then(function() { + return app.start().then(function () { assert.equal(app.isRunning(), true); chaiAsPromised.transferPromiseness = app.transferPromiseness; return app; }); }; -exports.stopApplication = function(app) { +exports.stopApplication = function (app) { if (!app || !app.isRunning()) { return; } - return app.stop().then(function() { + return app.stop().then(function () { assert.equal(app.isRunning(), false); }); }; diff --git a/tests/e2e/ipWhistlist_spec.js b/tests/e2e/ipWhistlist_spec.js index c544465ebc..e22231b996 100644 --- a/tests/e2e/ipWhistlist_spec.js +++ b/tests/e2e/ipWhistlist_spec.js @@ -13,9 +13,13 @@ describe("ipWhitelist directive configuration", function () { var app = null; beforeEach(function () { - return helpers.startApplication({ - args: ["js/electron.js"] - }).then(function (startedApp) { app = startedApp; }); + return helpers + .startApplication({ + args: ["js/electron.js"] + }) + .then(function (startedApp) { + app = startedApp; + }); }); afterEach(function () { @@ -47,5 +51,4 @@ describe("ipWhitelist directive configuration", function () { }); }); }); - }); diff --git a/tests/e2e/modules/calendar_spec.js b/tests/e2e/modules/calendar_spec.js index beeba1482e..7af7820184 100644 --- a/tests/e2e/modules/calendar_spec.js +++ b/tests/e2e/modules/calendar_spec.js @@ -6,96 +6,96 @@ const it = global.it; const beforeEach = global.beforeEach; const afterEach = global.afterEach; -describe("Calendar module", function() { +describe("Calendar module", function () { helpers.setupTimeout(this); var app = null; - beforeEach(function() { + beforeEach(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); - describe("Default configuration", function() { - before(function() { + describe("Default configuration", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/default.js"; }); - it("Should return TestEvents", function() { + it("Should return TestEvents", function () { return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000); }); }); - describe("Basic auth", function() { - before(function() { + describe("Basic auth", function () { + before(function () { serverBasicAuth.listen(8010); // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/basic-auth.js"; }); - after(function(done) { + after(function (done) { serverBasicAuth.close(done()); }); - it("Should return TestEvents", function() { + it("Should return TestEvents", function () { return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000); }); }); - describe("Basic auth by default", function() { - before(function() { + describe("Basic auth by default", function () { + before(function () { serverBasicAuth.listen(8011); // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/auth-default.js"; }); - after(function(done) { + after(function (done) { serverBasicAuth.close(done()); }); - it("Should return TestEvents", function() { + it("Should return TestEvents", function () { return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000); }); }); - describe("Basic auth backward compatibility configuration: DEPRECATED", function() { - before(function() { + describe("Basic auth backward compatibility configuration: DEPRECATED", function () { + before(function () { serverBasicAuth.listen(8012); // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/old-basic-auth.js"; }); - after(function(done) { + after(function (done) { serverBasicAuth.close(done()); }); - it("Should return TestEvents", function() { + it("Should return TestEvents", function () { return app.client.waitUntilTextExists(".calendar", "TestEvent", 10000); }); }); - describe("Fail Basic auth", function() { - before(function() { + describe("Fail Basic auth", function () { + before(function () { serverBasicAuth.listen(8020); // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/calendar/fail-basic-auth.js"; }); - after(function(done) { + after(function (done) { serverBasicAuth.close(done()); }); - it("Should return No upcoming events", function() { + it("Should return No upcoming events", function () { return app.client.waitUntilTextExists(".calendar", "No upcoming events.", 10000); }); }); diff --git a/tests/e2e/modules/clock_es_spec.js b/tests/e2e/modules/clock_es_spec.js index 7ad4ae6423..6006aeb6f5 100644 --- a/tests/e2e/modules/clock_es_spec.js +++ b/tests/e2e/modules/clock_es_spec.js @@ -5,81 +5,80 @@ const it = global.it; const beforeEach = global.beforeEach; const afterEach = global.afterEach; -describe("Clock set to spanish language module", function() { +describe("Clock set to spanish language module", function () { helpers.setupTimeout(this); var app = null; - beforeEach(function() { + beforeEach(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); - describe("with default 24hr clock config", function() { - before(function() { + describe("with default 24hr clock config", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_24hr.js"; }); - it("shows date with correct format", function() { + it("shows date with correct format", function () { const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex); }); - it("shows time in 24hr format", function() { + it("shows time in 24hr format", function () { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex); }); }); - describe("with default 12hr clock config", function() { - before(function() { + describe("with default 12hr clock config", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_12hr.js"; }); - it("shows date with correct format", function() { + it("shows date with correct format", function () { const dateRegex = /^(?:lunes|martes|miércoles|jueves|viernes|sábado|domingo), \d{1,2} de (?:enero|febrero|marzo|abril|mayo|junio|julio|agosto|septiembre|octubre|noviembre|diciembre) de \d{4}$/; return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex); }); - it("shows time in 12hr format", function() { + it("shows time in 12hr format", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex); }); }); - describe("with showPeriodUpper config enabled", function() { - before(function() { + describe("with showPeriodUpper config enabled", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showPeriodUpper.js"; }); - it("shows 12hr time with upper case AM/PM", function() { + it("shows 12hr time with upper case AM/PM", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex); }); }); - describe("with showWeek config enabled", function() { - before(function() { + describe("with showWeek config enabled", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/es/clock_showWeek.js"; }); - it("shows week with correct format", function() { + it("shows week with correct format", function () { const weekRegex = /^Semana [0-9]{1,2}$/; - return app.client.waitUntilWindowLoaded() - .getText(".clock .week").should.eventually.match(weekRegex); + return app.client.waitUntilWindowLoaded().getText(".clock .week").should.eventually.match(weekRegex); }); }); }); diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js index be4ef0e3d5..372d61afc9 100644 --- a/tests/e2e/modules/clock_spec.js +++ b/tests/e2e/modules/clock_spec.js @@ -5,95 +5,95 @@ const it = global.it; const beforeEach = global.beforeEach; const afterEach = global.afterEach; -describe("Clock module", function() { +describe("Clock module", function () { helpers.setupTimeout(this); var app = null; - beforeEach(function() { + beforeEach(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); - describe("with default 24hr clock config", function() { - before(function() { + describe("with default 24hr clock config", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_24hr.js"; }); - it("shows date with correct format", function() { + it("shows date with correct format", function () { const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex); }); - it("shows time in 24hr format", function() { + it("shows time in 24hr format", function () { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex); }); }); - describe("with default 12hr clock config", function() { - before(function() { + describe("with default 12hr clock config", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_12hr.js"; }); - it("shows date with correct format", function() { + it("shows date with correct format", function () { const dateRegex = /^(?:Monday|Tuesday|Wednesday|Thursday|Friday|Saturday|Sunday), (?:January|February|March|April|May|June|July|August|September|October|November|December) \d{1,2}, \d{4}$/; return app.client.waitUntilWindowLoaded().getText(".clock .date").should.eventually.match(dateRegex); }); - it("shows time in 12hr format", function() { + it("shows time in 12hr format", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex); }); }); - describe("with showPeriodUpper config enabled", function() { - before(function() { + describe("with showPeriodUpper config enabled", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showPeriodUpper.js"; }); - it("shows 12hr time with upper case AM/PM", function() { + it("shows 12hr time with upper case AM/PM", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex); }); }); - describe("with displaySeconds config disabled", function() { - before(function() { + describe("with displaySeconds config disabled", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_displaySeconds_false.js"; }); - it("shows 12hr time without seconds am/pm", function() { + it("shows 12hr time without seconds am/pm", function () { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/; return app.client.waitUntilWindowLoaded().getText(".clock .time").should.eventually.match(timeRegex); }); }); - describe("with showWeek config enabled", function() { - before(function() { + describe("with showWeek config enabled", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/clock/clock_showWeek.js"; }); - it("shows week with correct format", function() { + it("shows week with correct format", function () { const weekRegex = /^Week [0-9]{1,2}$/; return app.client.waitUntilWindowLoaded().getText(".clock .week").should.eventually.match(weekRegex); }); - it("shows week with correct number of week of year", function() { + it("shows week with correct number of week of year", function () { it("FIXME: if the day is a sunday this not match"); // const currentWeekNumber = require("current-week-number")(); // const weekToShow = "Week " + currentWeekNumber; diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 97fd0ed929..841aae036a 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -6,101 +6,119 @@ const it = global.it; const beforeEach = global.beforeEach; const afterEach = global.afterEach; -describe("Compliments module", function() { +describe("Compliments module", function () { helpers.setupTimeout(this); var app = null; - beforeEach(function() { + beforeEach(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); - describe("parts of days", function() { - before(function() { + describe("parts of days", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_parts_day.js"; }); - it("if Morning compliments for that part of day", function() { + it("if Morning compliments for that part of day", function () { var hour = new Date().getHours(); if (hour >= 3 && hour < 12) { // if morning check - return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { - expect(text).to.be.oneOf(["Hi", "Good Morning", "Morning test"]); - }); + return app.client + .waitUntilWindowLoaded() + .getText(".compliments") + .then(function (text) { + expect(text).to.be.oneOf(["Hi", "Good Morning", "Morning test"]); + }); } }); - it("if Afternoon show Compliments for that part of day", function() { + it("if Afternoon show Compliments for that part of day", function () { var hour = new Date().getHours(); if (hour >= 12 && hour < 17) { // if morning check - return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { - expect(text).to.be.oneOf(["Hello", "Good Afternoon", "Afternoon test"]); - }); + return app.client + .waitUntilWindowLoaded() + .getText(".compliments") + .then(function (text) { + expect(text).to.be.oneOf(["Hello", "Good Afternoon", "Afternoon test"]); + }); } }); - it("if Evening show Compliments for that part of day", function() { + it("if Evening show Compliments for that part of day", function () { var hour = new Date().getHours(); if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) { // if evening check - return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { - expect(text).to.be.oneOf(["Hello There", "Good Evening", "Evening test"]); - }); + return app.client + .waitUntilWindowLoaded() + .getText(".compliments") + .then(function (text) { + expect(text).to.be.oneOf(["Hello There", "Good Evening", "Evening test"]); + }); } }); }); - describe("Feature anytime in compliments module", function() { - describe("Set anytime and empty compliments for morning, evening and afternoon ", function() { - before(function() { + describe("Feature anytime in compliments module", function () { + describe("Set anytime and empty compliments for morning, evening and afternoon ", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_anytime.js"; }); - it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function() { - return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { - expect(text).to.be.oneOf(["Anytime here"]); - }); + it("Show anytime because if configure empty parts of day compliments and set anytime compliments", function () { + return app.client + .waitUntilWindowLoaded() + .getText(".compliments") + .then(function (text) { + expect(text).to.be.oneOf(["Anytime here"]); + }); }); }); - describe("Only anytime present in configuration compliments", function() { - before(function() { + describe("Only anytime present in configuration compliments", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_only_anytime.js"; }); - it("Show anytime compliments", function() { - return app.client.waitUntilWindowLoaded().getText(".compliments").then(function(text) { - expect(text).to.be.oneOf(["Anytime here"]); - }); + it("Show anytime compliments", function () { + return app.client + .waitUntilWindowLoaded() + .getText(".compliments") + .then(function (text) { + expect(text).to.be.oneOf(["Anytime here"]); + }); }); }); }); - describe("Feature date in compliments module", function() { - describe("Set date and empty compliments for anytime, morning, evening and afternoon", function() { - before(function() { + describe("Feature date in compliments module", function () { + describe("Set date and empty compliments for anytime, morning, evening and afternoon", function () { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/compliments/compliments_date.js"; }); - 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 new year!"]); - }); + 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 new year!"]); + }); }); }); }); diff --git a/tests/e2e/modules/helloworld_spec.js b/tests/e2e/modules/helloworld_spec.js index a59e2ae458..e215b3aa49 100644 --- a/tests/e2e/modules/helloworld_spec.js +++ b/tests/e2e/modules/helloworld_spec.js @@ -5,46 +5,44 @@ const it = global.it; const beforeEach = global.beforeEach; const afterEach = global.afterEach; -describe("Test helloworld module", function() { +describe("Test helloworld module", function () { helpers.setupTimeout(this); var app = null; - beforeEach(function() { + beforeEach(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); describe("helloworld set config text", function () { - before(function() { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld.js"; }); it("Test message helloworld module", function () { - return app.client.waitUntilWindowLoaded() - .getText(".helloworld").should.eventually.equal("Test HelloWorld Module"); + return app.client.waitUntilWindowLoaded().getText(".helloworld").should.eventually.equal("Test HelloWorld Module"); }); }); describe("helloworld default config text", function () { - before(function() { + before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/helloworld/helloworld_default.js"; }); it("Test message helloworld module", function () { - return app.client.waitUntilWindowLoaded() - .getText(".helloworld").should.eventually.equal("Hello World!"); + return app.client.waitUntilWindowLoaded().getText(".helloworld").should.eventually.equal("Hello World!"); }); }); }); diff --git a/tests/e2e/modules/mocks/index.js b/tests/e2e/modules/mocks/index.js index afd061c6c4..c708263857 100644 --- a/tests/e2e/modules/mocks/index.js +++ b/tests/e2e/modules/mocks/index.js @@ -1,4 +1,4 @@ const generateWeather = require("./weather_current"); const generateWeatherForecast = require("./weather_forecast"); -module.exports = {generateWeather, generateWeatherForecast}; +module.exports = { generateWeather, generateWeatherForecast }; diff --git a/tests/e2e/modules/mocks/weather_current.js b/tests/e2e/modules/mocks/weather_current.js index 807ee5594e..a0c3401d59 100644 --- a/tests/e2e/modules/mocks/weather_current.js +++ b/tests/e2e/modules/mocks/weather_current.js @@ -1,54 +1,60 @@ const _ = require("lodash"); function generateWeather(extendedData = {}) { - return JSON.stringify(_.merge({}, { - coord:{ - lon: 11.58, - lat: 48.14 - }, - weather:[ + return JSON.stringify( + _.merge( + {}, { - id: 615, - main: "Snow", - description: "light rain and snow", - icon: "13d" + 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 }, - { - 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)); + extendedData + ) + ); } module.exports = generateWeather; diff --git a/tests/e2e/modules/mocks/weather_forecast.js b/tests/e2e/modules/mocks/weather_forecast.js index 9e74262f6a..eaf2e37520 100644 --- a/tests/e2e/modules/mocks/weather_forecast.js +++ b/tests/e2e/modules/mocks/weather_forecast.js @@ -1,97 +1,111 @@ 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/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js index 88cb8c3e8b..9c9ee2ca94 100644 --- a/tests/e2e/modules/newsfeed_spec.js +++ b/tests/e2e/modules/newsfeed_spec.js @@ -5,31 +5,31 @@ const it = global.it; const beforeEach = global.beforeEach; const afterEach = global.afterEach; -describe("Newsfeed module", function() { +describe("Newsfeed module", function () { helpers.setupTimeout(this); var app = null; - beforeEach(function() { + beforeEach(function () { return helpers .startApplication({ args: ["js/electron.js"] }) - .then(function(startedApp) { + .then(function (startedApp) { app = startedApp; }); }); - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); - describe("Default configuration", function() { - before(function() { + describe("Default configuration", function () { + before(function () { process.env.MM_CONFIG_FILE = "tests/configs/modules/newsfeed/default.js"; }); - it("show title newsfeed", function() { + it("show title newsfeed", function () { return app.client.waitUntilTextExists(".newsfeed .small", "Rodrigo Ramirez Blog", 10000).should.be.fulfilled; }); }); diff --git a/tests/e2e/modules/weather_spec.js b/tests/e2e/modules/weather_spec.js index ea916e5e02..d87a44cd8c 100644 --- a/tests/e2e/modules/weather_spec.js +++ b/tests/e2e/modules/weather_spec.js @@ -6,10 +6,9 @@ const wdajaxstub = require("webdriverajaxstub"); const helpers = require("../global-setup"); -const {generateWeather, generateWeatherForecast} = require("./mocks"); - -describe("Weather module", function() { +const { generateWeather, generateWeatherForecast } = require("./mocks"); +describe("Weather module", function () { let app; helpers.setupTimeout(this); @@ -24,85 +23,85 @@ describe("Weather module", function() { app.client.setupStub(); } - afterEach(function() { + afterEach(function () { return helpers.stopApplication(app); }); - describe("Current weather", function() { + describe("Current weather", function () { let template; - before(function() { + before(function () { template = fs.readFileSync(path.join(__dirname, "..", "..", "..", "modules", "default", "weather", "current.njk"), "utf8"); }); - describe("Default configuration", function() { - before(function() { + describe("Default configuration", function () { + before(function () { process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_default.js"; }); - it("should render wind speed and wind direction", async function() { + it("should render wind speed and wind direction", async function () { const weather = generateWeather(); - await setup({template, data: weather}); + await setup({ template, data: weather }); return app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(2)", "6 WSW", 10000); }); - it("should render sunrise", async function() { + it("should render sunrise", async function () { const sunrise = moment().startOf("day").unix(); const sunset = moment().startOf("day").unix(); - const weather = generateWeather({sys: {sunrise, sunset}}); - await setup({template, data: weather}); + const weather = generateWeather({ sys: { sunrise, sunset } }); + await setup({ template, data: weather }); await app.client.waitForExist(".weather .normal.medium span.wi.dimmed.wi-sunrise", 10000); return app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(4)", "12:00 am", 10000); }); - it("should render sunset", async function() { + it("should render sunset", async function () { const sunrise = moment().startOf("day").unix(); const sunset = moment().endOf("day").unix(); - const weather = generateWeather({sys: {sunrise, sunset}}); - await setup({template, data: weather}); + const weather = generateWeather({ sys: { sunrise, sunset } }); + await setup({ template, data: weather }); await app.client.waitForExist(".weather .normal.medium span.wi.dimmed.wi-sunset", 10000); return app.client.waitUntilTextExists(".weather .normal.medium span:nth-child(4)", "11:59 pm", 10000); }); - it("should render temperature with icon", async function() { + it("should render temperature with icon", async function () { const weather = generateWeather(); - await setup({template, data: weather}); + await setup({ template, data: weather }); await app.client.waitForExist(".weather .large.light span.wi.weathericon.wi-snow", 10000); return app.client.waitUntilTextExists(".weather .large.light span.bright", "1.5°", 10000); }); - it("should render feels like temperature", async function() { + it("should render feels like temperature", async function () { const weather = generateWeather(); - await setup({template, data: weather}); + await setup({ template, data: weather }); return app.client.waitUntilTextExists(".weather .normal.medium span.dimmed", "Feels like -5.6°", 10000); }); }); - describe("Configuration Options", function() { - before(function() { + describe("Configuration Options", function () { + before(function () { process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_options.js"; }); - it("should render useBeaufort = false", async function() { + it("should render useBeaufort = false", async function () { const weather = generateWeather(); - await setup({template, data: weather}); + 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() { + it("should render showWindDirectionAsArrow = true", async function () { const weather = generateWeather(); - await setup({template, data: weather}); + 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"); @@ -110,17 +109,17 @@ describe("Weather module", function() { expect(element).to.include("transform:rotate(250deg);"); }); - it("should render showHumidity = true", async function() { + it("should render showHumidity = true", async function () { const weather = generateWeather(); - await setup({template, data: weather}); + 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); }); - it("should render degreeLabel = true", async function() { + it("should render degreeLabel = true", async function () { const weather = generateWeather(); - await setup({template, data: weather}); + await setup({ template, data: weather }); await app.client.waitUntilTextExists(".weather .large.light span.bright", "1°C", 10000); @@ -128,41 +127,41 @@ describe("Weather module", function() { }); }); - describe("Current weather units", function() { - before(function() { + describe("Current weather units", function () { + before(function () { process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/currentweather_units.js"; }); - it("should render imperial units", async function() { + it("should render imperial units", async function () { const weather = generateWeather({ - main:{ - temp: 1.49 * 9 / 5 + 32, - temp_min: 1 * 9 / 5 + 32, - temp_max: 2 * 9 / 5 + 32 + main: { + temp: (1.49 * 9) / 5 + 32, + temp_min: (1 * 9) / 5 + 32, + temp_max: (2 * 9) / 5 + 32 }, - wind:{ + wind: { speed: 11.8 * 2.23694 - }, + } }); - await setup({template, data: weather}); + 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); return app.client.waitUntilTextExists(".weather .normal.medium span.dimmed", "22,0°", 10000); }); - it("should render decimalSymbol = ','", async function() { + it("should render decimalSymbol = ','", async function () { const weather = generateWeather({ - main:{ - temp: 1.49 * 9 / 5 + 32, - temp_min: 1 * 9 / 5 + 32, - temp_max: 2 * 9 / 5 + 32 + main: { + temp: (1.49 * 9) / 5 + 32, + temp_min: (1 * 9) / 5 + 32, + temp_max: (2 * 9) / 5 + 32 }, - wind:{ + wind: { speed: 11.8 * 2.23694 - }, + } }); - await setup({template, data: weather}); + 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); @@ -171,21 +170,21 @@ describe("Weather module", function() { }); }); - describe("Weather Forecast", function() { + describe("Weather Forecast", function () { let template; - before(function() { + before(function () { template = fs.readFileSync(path.join(__dirname, "..", "..", "..", "modules", "default", "weather", "forecast.njk"), "utf8"); }); - describe("Default configuration", function() { - before(function() { + describe("Default configuration", function () { + before(function () { process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/forecastweather_default.js"; }); - it("should render days", async function() { + it("should render days", async function () { const weather = generateWeatherForecast(); - await setup({template, data: weather}); + await setup({ template, data: weather }); const days = ["Fri", "Sat", "Sun", "Mon", "Tue"]; @@ -194,9 +193,9 @@ describe("Weather module", function() { } }); - it("should render icons", async function() { + it("should render icons", async function () { const weather = generateWeatherForecast(); - await setup({template, data: weather}); + await setup({ template, data: weather }); const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"]; @@ -205,9 +204,9 @@ describe("Weather module", function() { } }); - it("should render max temperatures", async function() { + it("should render max temperatures", async function () { const weather = generateWeatherForecast(); - await setup({template, data: weather}); + await setup({ template, data: weather }); const temperatures = ["24.4°", "21.0°", "22.9°", "23.4°", "20.6°"]; @@ -216,9 +215,9 @@ describe("Weather module", function() { } }); - it("should render min temperatures", async function() { + it("should render min temperatures", async function () { const weather = generateWeatherForecast(); - await setup({template, data: weather}); + await setup({ template, data: weather }); const temperatures = ["15.3°", "13.6°", "13.8°", "13.9°", "10.9°"]; @@ -227,9 +226,9 @@ describe("Weather module", function() { } }); - it("should render fading of rows", async function() { + it("should render fading of rows", async function () { const weather = generateWeatherForecast(); - await setup({template, data: weather}); + await setup({ template, data: weather }); const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667]; @@ -242,21 +241,21 @@ describe("Weather module", function() { }); }); - describe("Configuration Options", function() { - before(function() { + describe("Configuration Options", function () { + before(function () { process.env.MM_CONFIG_FILE = "tests/configs/modules/weather/forecastweather_options.js"; }); - it("should render custom table class", async function() { + it("should render custom table class", async function () { const weather = generateWeatherForecast(); - await setup({template, data: weather}); + await setup({ template, data: weather }); await app.client.waitForExist(".weather table.myTableClass", 10000); }); - it("should render colored rows", async function() { + it("should render colored rows", async function () { const weather = generateWeatherForecast(); - await setup({template, data: weather}); + await setup({ template, data: weather }); await app.client.waitForExist(".weather table.myTableClass", 10000); diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js index 4039968000..930acbfdcb 100644 --- a/tests/e2e/modules_position_spec.js +++ b/tests/e2e/modules_position_spec.js @@ -9,7 +9,6 @@ describe("Position of modules", function () { var app = null; describe("Using helloworld", function () { - after(function () { return helpers.stopApplication(app); }); @@ -17,23 +16,27 @@ describe("Position of modules", function () { before(function () { // Set config sample for use in test process.env.MM_CONFIG_FILE = "tests/configs/modules/positions.js"; - return helpers.startApplication({ - args: ["js/electron.js"] - }).then(function (startedApp) { app = startedApp; }); + return helpers + .startApplication({ + args: ["js/electron.js"] + }) + .then(function (startedApp) { + app = startedApp; + }); }); - var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", - "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", - "bottom_bar", "fullscreen_above", "fullscreen_below"]; + var positions = ["top_bar", "top_left", "top_center", "top_right", "upper_third", "middle_center", "lower_third", "bottom_left", "bottom_center", "bottom_right", "bottom_bar", "fullscreen_above", "fullscreen_below"]; var position; var className; - for (idx in positions) { + for (var idx in positions) { position = positions[idx]; className = position.replace("_", "."); it("show text in " + position, function () { - return app.client.waitUntilWindowLoaded() - .getText("." + className).should.eventually.equal("Text in " + position); + return app.client + .waitUntilWindowLoaded() + .getText("." + className) + .should.eventually.equal("Text in " + position); }); } }); diff --git a/tests/e2e/port_config.js b/tests/e2e/port_config.js index 41f50e75b8..7788974811 100644 --- a/tests/e2e/port_config.js +++ b/tests/e2e/port_config.js @@ -13,9 +13,13 @@ describe("port directive configuration", function () { var app = null; beforeEach(function () { - return helpers.startApplication({ - args: ["js/electron.js"] - }).then(function (startedApp) { app = startedApp; }); + return helpers + .startApplication({ + args: ["js/electron.js"] + }) + .then(function (startedApp) { + app = startedApp; + }); }); afterEach(function () { diff --git a/tests/e2e/translations_spec.js b/tests/e2e/translations_spec.js index e589689e2c..cf039eb1dd 100644 --- a/tests/e2e/translations_spec.js +++ b/tests/e2e/translations_spec.js @@ -5,13 +5,13 @@ const expect = chai.expect; const mlog = require("mocha-logger"); const translations = require("../../translations/translations.js"); const helmet = require("helmet"); -const {JSDOM} = require("jsdom"); +const { JSDOM } = require("jsdom"); const express = require("express"); -describe("Translations", function() { +describe("Translations", function () { let server; - before(function() { + before(function () { const app = express(); app.use(helmet()); app.use(function (req, res, next) { @@ -23,12 +23,12 @@ describe("Translations", function() { server = app.listen(3000); }); - after(function() { + after(function () { server.close(); }); - it("should have a translation file in the specified path", function() { - for(let language in translations) { + it("should have a translation file in the specified path", function () { + for (let language in translations) { const file = fs.statSync(translations[language]); expect(file.isFile()).to.be.equal(true); } @@ -41,16 +41,18 @@ describe("Translations", function() { } }; - describe("Parsing language files through the Translator class", function() { - for(let language in translations) { - it(`should parse ${language}`, function(done) { - const dom = new JSDOM(`\ - \ + \ - \ + \ - \ + \ - \ + \ - \ + \ - \ + \ - \ + \ - \ + \ - \ +